netwerk/test/TestUDPSocket.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "TestCommon.h"
michael@0 6 #include "TestHarness.h"
michael@0 7 #include "nsIUDPSocket.h"
michael@0 8 #include "nsISocketTransportService.h"
michael@0 9 #include "nsISocketTransport.h"
michael@0 10 #include "nsIOutputStream.h"
michael@0 11 #include "nsIInputStream.h"
michael@0 12 #include "nsINetAddr.h"
michael@0 13 #include "mozilla/net/DNS.h"
michael@0 14 #include "prerror.h"
michael@0 15
michael@0 16 #define REQUEST 0x68656c6f
michael@0 17 #define RESPONSE 0x6f6c6568
michael@0 18
michael@0 19 #define EXPECT_SUCCESS(rv, ...) \
michael@0 20 PR_BEGIN_MACRO \
michael@0 21 if (NS_FAILED(rv)) { \
michael@0 22 fail(__VA_ARGS__); \
michael@0 23 return false; \
michael@0 24 } \
michael@0 25 PR_END_MACRO
michael@0 26
michael@0 27
michael@0 28 #define EXPECT_FAILURE(rv, ...) \
michael@0 29 PR_BEGIN_MACRO \
michael@0 30 if (NS_SUCCEEDED(rv)) { \
michael@0 31 fail(__VA_ARGS__); \
michael@0 32 return false; \
michael@0 33 } \
michael@0 34 PR_END_MACRO
michael@0 35
michael@0 36 #define REQUIRE_EQUAL(a, b, ...) \
michael@0 37 PR_BEGIN_MACRO \
michael@0 38 if (a != b) { \
michael@0 39 fail(__VA_ARGS__); \
michael@0 40 return false; \
michael@0 41 } \
michael@0 42 PR_END_MACRO
michael@0 43
michael@0 44 enum TestPhase {
michael@0 45 TEST_OUTPUT_STREAM,
michael@0 46 TEST_SEND_API,
michael@0 47 TEST_NONE
michael@0 48 };
michael@0 49
michael@0 50 static TestPhase phase = TEST_NONE;
michael@0 51
michael@0 52 static bool CheckMessageContent(nsIUDPMessage *aMessage, uint32_t aExpectedContent)
michael@0 53 {
michael@0 54 nsCString data;
michael@0 55 aMessage->GetData(data);
michael@0 56
michael@0 57 const char* buffer = data.get();
michael@0 58 uint32_t len = data.Length();
michael@0 59
michael@0 60 FallibleTArray<uint8_t>& rawData = aMessage->GetDataAsTArray();
michael@0 61 uint32_t rawLen = rawData.Length();
michael@0 62
michael@0 63 if (len != rawLen) {
michael@0 64 fail("Raw data length(%d) do not matches String data length(%d).", rawLen, len);
michael@0 65 return false;
michael@0 66 }
michael@0 67
michael@0 68 for (uint32_t i = 0; i < len; i++) {
michael@0 69 if (buffer[i] != rawData[i]) {
michael@0 70 fail("Raw data(%s) do not matches String data(%s)", rawData.Elements() ,buffer);
michael@0 71 return false;
michael@0 72 }
michael@0 73 }
michael@0 74
michael@0 75 uint32_t input = 0;
michael@0 76 for (uint32_t i = 0; i < len; i++) {
michael@0 77 input += buffer[i] << (8 * i);
michael@0 78 }
michael@0 79
michael@0 80 if (len != sizeof(uint32_t) || input != aExpectedContent)
michael@0 81 {
michael@0 82 fail("Request 0x%x received, expected 0x%x", input, aExpectedContent);
michael@0 83 return false;
michael@0 84 } else {
michael@0 85 passed("Request 0x%x received as expected", input);
michael@0 86 return true;
michael@0 87 }
michael@0 88 }
michael@0 89
michael@0 90 /*
michael@0 91 * UDPClientListener: listens for incomming UDP packets
michael@0 92 */
michael@0 93 class UDPClientListener : public nsIUDPSocketListener
michael@0 94 {
michael@0 95 public:
michael@0 96 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 97 NS_DECL_NSIUDPSOCKETLISTENER
michael@0 98 virtual ~UDPClientListener();
michael@0 99 nsresult mResult;
michael@0 100 };
michael@0 101
michael@0 102 NS_IMPL_ISUPPORTS(UDPClientListener, nsIUDPSocketListener)
michael@0 103
michael@0 104 UDPClientListener::~UDPClientListener()
michael@0 105 {
michael@0 106 }
michael@0 107
michael@0 108 NS_IMETHODIMP
michael@0 109 UDPClientListener::OnPacketReceived(nsIUDPSocket* socket, nsIUDPMessage* message)
michael@0 110 {
michael@0 111 mResult = NS_OK;
michael@0 112
michael@0 113 uint16_t port;
michael@0 114 nsCString ip;
michael@0 115 nsCOMPtr<nsINetAddr> fromAddr;
michael@0 116 message->GetFromAddr(getter_AddRefs(fromAddr));
michael@0 117 fromAddr->GetPort(&port);
michael@0 118 fromAddr->GetAddress(ip);
michael@0 119 passed("Packet received on client from %s:%d", ip.get(), port);
michael@0 120
michael@0 121 if (TEST_SEND_API == phase && CheckMessageContent(message, REQUEST)) {
michael@0 122 uint32_t count;
michael@0 123 const uint32_t data = RESPONSE;
michael@0 124 printf("*** Attempting to write response 0x%x to server by SendWithAddr...\n", RESPONSE);
michael@0 125 mResult = socket->SendWithAddr(fromAddr, (const uint8_t*)&data,
michael@0 126 sizeof(uint32_t), &count);
michael@0 127 if (mResult == NS_OK && count == sizeof(uint32_t)) {
michael@0 128 passed("Response written");
michael@0 129 } else {
michael@0 130 fail("Response written");
michael@0 131 }
michael@0 132 return NS_OK;
michael@0 133 } else if (TEST_OUTPUT_STREAM != phase || !CheckMessageContent(message, RESPONSE)) {
michael@0 134 mResult = NS_ERROR_FAILURE;
michael@0 135 }
michael@0 136
michael@0 137 // Notify thread
michael@0 138 QuitPumpingEvents();
michael@0 139 return NS_OK;
michael@0 140 }
michael@0 141
michael@0 142 NS_IMETHODIMP
michael@0 143 UDPClientListener::OnStopListening(nsIUDPSocket*, nsresult)
michael@0 144 {
michael@0 145 QuitPumpingEvents();
michael@0 146 return NS_OK;
michael@0 147 }
michael@0 148
michael@0 149 /*
michael@0 150 * UDPServerListener: listens for incomming UDP packets
michael@0 151 */
michael@0 152 class UDPServerListener : public nsIUDPSocketListener
michael@0 153 {
michael@0 154 public:
michael@0 155 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 156 NS_DECL_NSIUDPSOCKETLISTENER
michael@0 157
michael@0 158 virtual ~UDPServerListener();
michael@0 159
michael@0 160 nsresult mResult;
michael@0 161 };
michael@0 162
michael@0 163 NS_IMPL_ISUPPORTS(UDPServerListener, nsIUDPSocketListener)
michael@0 164
michael@0 165 UDPServerListener::~UDPServerListener()
michael@0 166 {
michael@0 167 }
michael@0 168
michael@0 169 NS_IMETHODIMP
michael@0 170 UDPServerListener::OnPacketReceived(nsIUDPSocket* socket, nsIUDPMessage* message)
michael@0 171 {
michael@0 172 mResult = NS_OK;
michael@0 173
michael@0 174 uint16_t port;
michael@0 175 nsCString ip;
michael@0 176 nsCOMPtr<nsINetAddr> fromAddr;
michael@0 177 message->GetFromAddr(getter_AddRefs(fromAddr));
michael@0 178 fromAddr->GetPort(&port);
michael@0 179 fromAddr->GetAddress(ip);
michael@0 180 passed("Packet received on server from %s:%d", ip.get(), port);
michael@0 181
michael@0 182 if (TEST_OUTPUT_STREAM == phase && CheckMessageContent(message, REQUEST))
michael@0 183 {
michael@0 184 nsCOMPtr<nsIOutputStream> outstream;
michael@0 185 message->GetOutputStream(getter_AddRefs(outstream));
michael@0 186
michael@0 187 uint32_t count;
michael@0 188 const uint32_t data = RESPONSE;
michael@0 189 printf("*** Attempting to write response 0x%x to client by OutputStream...\n", RESPONSE);
michael@0 190 mResult = outstream->Write((const char*)&data, sizeof(uint32_t), &count);
michael@0 191
michael@0 192 if (mResult == NS_OK && count == sizeof(uint32_t)) {
michael@0 193 passed("Response written");
michael@0 194 } else {
michael@0 195 fail("Response written");
michael@0 196 }
michael@0 197 return NS_OK;
michael@0 198 } else if (TEST_SEND_API != phase || !CheckMessageContent(message, RESPONSE)) {
michael@0 199 mResult = NS_ERROR_FAILURE;
michael@0 200 }
michael@0 201
michael@0 202 // Notify thread
michael@0 203 QuitPumpingEvents();
michael@0 204 return NS_OK;
michael@0 205 }
michael@0 206
michael@0 207 NS_IMETHODIMP
michael@0 208 UDPServerListener::OnStopListening(nsIUDPSocket*, nsresult)
michael@0 209 {
michael@0 210 QuitPumpingEvents();
michael@0 211 return NS_OK;
michael@0 212 }
michael@0 213
michael@0 214 /**** Main ****/
michael@0 215 int
michael@0 216 main(int32_t argc, char *argv[])
michael@0 217 {
michael@0 218 nsresult rv;
michael@0 219 ScopedXPCOM xpcom("UDP ServerSocket");
michael@0 220 if (xpcom.failed())
michael@0 221 return -1;
michael@0 222
michael@0 223 // Create UDPSocket
michael@0 224 nsCOMPtr<nsIUDPSocket> server, client;
michael@0 225 server = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
michael@0 226 NS_ENSURE_SUCCESS(rv, -1);
michael@0 227 client = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
michael@0 228 NS_ENSURE_SUCCESS(rv, -1);
michael@0 229
michael@0 230 // Create UDPServerListener to process UDP packets
michael@0 231 nsRefPtr<UDPServerListener> serverListener = new UDPServerListener();
michael@0 232
michael@0 233 // Bind server socket to 127.0.0.1
michael@0 234 rv = server->Init(0, true);
michael@0 235 NS_ENSURE_SUCCESS(rv, -1);
michael@0 236 int32_t serverPort;
michael@0 237 server->GetPort(&serverPort);
michael@0 238 server->AsyncListen(serverListener);
michael@0 239
michael@0 240 // Bind clinet on arbitrary port
michael@0 241 nsRefPtr<UDPClientListener> clientListener = new UDPClientListener();
michael@0 242 client->Init(0, true);
michael@0 243 client->AsyncListen(clientListener);
michael@0 244
michael@0 245 // Write data to server
michael@0 246 uint32_t count;
michael@0 247 const uint32_t data = REQUEST;
michael@0 248
michael@0 249 phase = TEST_OUTPUT_STREAM;
michael@0 250 rv = client->Send(NS_LITERAL_CSTRING("127.0.0.1"), serverPort, (uint8_t*)&data, sizeof(uint32_t), &count);
michael@0 251 NS_ENSURE_SUCCESS(rv, -1);
michael@0 252 REQUIRE_EQUAL(count, sizeof(uint32_t), "Error");
michael@0 253 passed("Request written by Send");
michael@0 254
michael@0 255 // Wait for server
michael@0 256 PumpEvents();
michael@0 257 NS_ENSURE_SUCCESS(serverListener->mResult, -1);
michael@0 258
michael@0 259 // Read response from server
michael@0 260 NS_ENSURE_SUCCESS(clientListener->mResult, -1);
michael@0 261
michael@0 262 mozilla::net::NetAddr clientAddr;
michael@0 263 rv = client->GetAddress(&clientAddr);
michael@0 264 NS_ENSURE_SUCCESS(rv, -1);
michael@0 265
michael@0 266 phase = TEST_SEND_API;
michael@0 267 rv = server->SendWithAddress(&clientAddr, (uint8_t*)&data, sizeof(uint32_t), &count);
michael@0 268 NS_ENSURE_SUCCESS(rv, -1);
michael@0 269 REQUIRE_EQUAL(count, sizeof(uint32_t), "Error");
michael@0 270 passed("Request written by SendWithAddress");
michael@0 271
michael@0 272 // Wait for server
michael@0 273 PumpEvents();
michael@0 274 NS_ENSURE_SUCCESS(serverListener->mResult, -1);
michael@0 275
michael@0 276 // Read response from server
michael@0 277 NS_ENSURE_SUCCESS(clientListener->mResult, -1);
michael@0 278
michael@0 279 // Close server
michael@0 280 printf("*** Attempting to close server ...\n");
michael@0 281 server->Close();
michael@0 282 client->Close();
michael@0 283 PumpEvents();
michael@0 284 passed("Server closed");
michael@0 285
michael@0 286 return 0; // failure is a non-zero return
michael@0 287 }

mercurial