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

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

mercurial