1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/test/TestUDPSocket.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,287 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "TestCommon.h" 1.9 +#include "TestHarness.h" 1.10 +#include "nsIUDPSocket.h" 1.11 +#include "nsISocketTransportService.h" 1.12 +#include "nsISocketTransport.h" 1.13 +#include "nsIOutputStream.h" 1.14 +#include "nsIInputStream.h" 1.15 +#include "nsINetAddr.h" 1.16 +#include "mozilla/net/DNS.h" 1.17 +#include "prerror.h" 1.18 + 1.19 +#define REQUEST 0x68656c6f 1.20 +#define RESPONSE 0x6f6c6568 1.21 + 1.22 +#define EXPECT_SUCCESS(rv, ...) \ 1.23 + PR_BEGIN_MACRO \ 1.24 + if (NS_FAILED(rv)) { \ 1.25 + fail(__VA_ARGS__); \ 1.26 + return false; \ 1.27 + } \ 1.28 + PR_END_MACRO 1.29 + 1.30 + 1.31 +#define EXPECT_FAILURE(rv, ...) \ 1.32 + PR_BEGIN_MACRO \ 1.33 + if (NS_SUCCEEDED(rv)) { \ 1.34 + fail(__VA_ARGS__); \ 1.35 + return false; \ 1.36 + } \ 1.37 + PR_END_MACRO 1.38 + 1.39 +#define REQUIRE_EQUAL(a, b, ...) \ 1.40 + PR_BEGIN_MACRO \ 1.41 + if (a != b) { \ 1.42 + fail(__VA_ARGS__); \ 1.43 + return false; \ 1.44 + } \ 1.45 + PR_END_MACRO 1.46 + 1.47 +enum TestPhase { 1.48 + TEST_OUTPUT_STREAM, 1.49 + TEST_SEND_API, 1.50 + TEST_NONE 1.51 +}; 1.52 + 1.53 +static TestPhase phase = TEST_NONE; 1.54 + 1.55 +static bool CheckMessageContent(nsIUDPMessage *aMessage, uint32_t aExpectedContent) 1.56 +{ 1.57 + nsCString data; 1.58 + aMessage->GetData(data); 1.59 + 1.60 + const char* buffer = data.get(); 1.61 + uint32_t len = data.Length(); 1.62 + 1.63 + FallibleTArray<uint8_t>& rawData = aMessage->GetDataAsTArray(); 1.64 + uint32_t rawLen = rawData.Length(); 1.65 + 1.66 + if (len != rawLen) { 1.67 + fail("Raw data length(%d) do not matches String data length(%d).", rawLen, len); 1.68 + return false; 1.69 + } 1.70 + 1.71 + for (uint32_t i = 0; i < len; i++) { 1.72 + if (buffer[i] != rawData[i]) { 1.73 + fail("Raw data(%s) do not matches String data(%s)", rawData.Elements() ,buffer); 1.74 + return false; 1.75 + } 1.76 + } 1.77 + 1.78 + uint32_t input = 0; 1.79 + for (uint32_t i = 0; i < len; i++) { 1.80 + input += buffer[i] << (8 * i); 1.81 + } 1.82 + 1.83 + if (len != sizeof(uint32_t) || input != aExpectedContent) 1.84 + { 1.85 + fail("Request 0x%x received, expected 0x%x", input, aExpectedContent); 1.86 + return false; 1.87 + } else { 1.88 + passed("Request 0x%x received as expected", input); 1.89 + return true; 1.90 + } 1.91 +} 1.92 + 1.93 +/* 1.94 + * UDPClientListener: listens for incomming UDP packets 1.95 + */ 1.96 +class UDPClientListener : public nsIUDPSocketListener 1.97 +{ 1.98 +public: 1.99 + NS_DECL_THREADSAFE_ISUPPORTS 1.100 + NS_DECL_NSIUDPSOCKETLISTENER 1.101 + virtual ~UDPClientListener(); 1.102 + nsresult mResult; 1.103 +}; 1.104 + 1.105 +NS_IMPL_ISUPPORTS(UDPClientListener, nsIUDPSocketListener) 1.106 + 1.107 +UDPClientListener::~UDPClientListener() 1.108 +{ 1.109 +} 1.110 + 1.111 +NS_IMETHODIMP 1.112 +UDPClientListener::OnPacketReceived(nsIUDPSocket* socket, nsIUDPMessage* message) 1.113 +{ 1.114 + mResult = NS_OK; 1.115 + 1.116 + uint16_t port; 1.117 + nsCString ip; 1.118 + nsCOMPtr<nsINetAddr> fromAddr; 1.119 + message->GetFromAddr(getter_AddRefs(fromAddr)); 1.120 + fromAddr->GetPort(&port); 1.121 + fromAddr->GetAddress(ip); 1.122 + passed("Packet received on client from %s:%d", ip.get(), port); 1.123 + 1.124 + if (TEST_SEND_API == phase && CheckMessageContent(message, REQUEST)) { 1.125 + uint32_t count; 1.126 + const uint32_t data = RESPONSE; 1.127 + printf("*** Attempting to write response 0x%x to server by SendWithAddr...\n", RESPONSE); 1.128 + mResult = socket->SendWithAddr(fromAddr, (const uint8_t*)&data, 1.129 + sizeof(uint32_t), &count); 1.130 + if (mResult == NS_OK && count == sizeof(uint32_t)) { 1.131 + passed("Response written"); 1.132 + } else { 1.133 + fail("Response written"); 1.134 + } 1.135 + return NS_OK; 1.136 + } else if (TEST_OUTPUT_STREAM != phase || !CheckMessageContent(message, RESPONSE)) { 1.137 + mResult = NS_ERROR_FAILURE; 1.138 + } 1.139 + 1.140 + // Notify thread 1.141 + QuitPumpingEvents(); 1.142 + return NS_OK; 1.143 +} 1.144 + 1.145 +NS_IMETHODIMP 1.146 +UDPClientListener::OnStopListening(nsIUDPSocket*, nsresult) 1.147 +{ 1.148 + QuitPumpingEvents(); 1.149 + return NS_OK; 1.150 +} 1.151 + 1.152 +/* 1.153 + * UDPServerListener: listens for incomming UDP packets 1.154 + */ 1.155 +class UDPServerListener : public nsIUDPSocketListener 1.156 +{ 1.157 +public: 1.158 + NS_DECL_THREADSAFE_ISUPPORTS 1.159 + NS_DECL_NSIUDPSOCKETLISTENER 1.160 + 1.161 + virtual ~UDPServerListener(); 1.162 + 1.163 + nsresult mResult; 1.164 +}; 1.165 + 1.166 +NS_IMPL_ISUPPORTS(UDPServerListener, nsIUDPSocketListener) 1.167 + 1.168 +UDPServerListener::~UDPServerListener() 1.169 +{ 1.170 +} 1.171 + 1.172 +NS_IMETHODIMP 1.173 +UDPServerListener::OnPacketReceived(nsIUDPSocket* socket, nsIUDPMessage* message) 1.174 +{ 1.175 + mResult = NS_OK; 1.176 + 1.177 + uint16_t port; 1.178 + nsCString ip; 1.179 + nsCOMPtr<nsINetAddr> fromAddr; 1.180 + message->GetFromAddr(getter_AddRefs(fromAddr)); 1.181 + fromAddr->GetPort(&port); 1.182 + fromAddr->GetAddress(ip); 1.183 + passed("Packet received on server from %s:%d", ip.get(), port); 1.184 + 1.185 + if (TEST_OUTPUT_STREAM == phase && CheckMessageContent(message, REQUEST)) 1.186 + { 1.187 + nsCOMPtr<nsIOutputStream> outstream; 1.188 + message->GetOutputStream(getter_AddRefs(outstream)); 1.189 + 1.190 + uint32_t count; 1.191 + const uint32_t data = RESPONSE; 1.192 + printf("*** Attempting to write response 0x%x to client by OutputStream...\n", RESPONSE); 1.193 + mResult = outstream->Write((const char*)&data, sizeof(uint32_t), &count); 1.194 + 1.195 + if (mResult == NS_OK && count == sizeof(uint32_t)) { 1.196 + passed("Response written"); 1.197 + } else { 1.198 + fail("Response written"); 1.199 + } 1.200 + return NS_OK; 1.201 + } else if (TEST_SEND_API != phase || !CheckMessageContent(message, RESPONSE)) { 1.202 + mResult = NS_ERROR_FAILURE; 1.203 + } 1.204 + 1.205 + // Notify thread 1.206 + QuitPumpingEvents(); 1.207 + return NS_OK; 1.208 +} 1.209 + 1.210 +NS_IMETHODIMP 1.211 +UDPServerListener::OnStopListening(nsIUDPSocket*, nsresult) 1.212 +{ 1.213 + QuitPumpingEvents(); 1.214 + return NS_OK; 1.215 +} 1.216 + 1.217 +/**** Main ****/ 1.218 +int 1.219 +main(int32_t argc, char *argv[]) 1.220 +{ 1.221 + nsresult rv; 1.222 + ScopedXPCOM xpcom("UDP ServerSocket"); 1.223 + if (xpcom.failed()) 1.224 + return -1; 1.225 + 1.226 + // Create UDPSocket 1.227 + nsCOMPtr<nsIUDPSocket> server, client; 1.228 + server = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); 1.229 + NS_ENSURE_SUCCESS(rv, -1); 1.230 + client = do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv); 1.231 + NS_ENSURE_SUCCESS(rv, -1); 1.232 + 1.233 + // Create UDPServerListener to process UDP packets 1.234 + nsRefPtr<UDPServerListener> serverListener = new UDPServerListener(); 1.235 + 1.236 + // Bind server socket to 127.0.0.1 1.237 + rv = server->Init(0, true); 1.238 + NS_ENSURE_SUCCESS(rv, -1); 1.239 + int32_t serverPort; 1.240 + server->GetPort(&serverPort); 1.241 + server->AsyncListen(serverListener); 1.242 + 1.243 + // Bind clinet on arbitrary port 1.244 + nsRefPtr<UDPClientListener> clientListener = new UDPClientListener(); 1.245 + client->Init(0, true); 1.246 + client->AsyncListen(clientListener); 1.247 + 1.248 + // Write data to server 1.249 + uint32_t count; 1.250 + const uint32_t data = REQUEST; 1.251 + 1.252 + phase = TEST_OUTPUT_STREAM; 1.253 + rv = client->Send(NS_LITERAL_CSTRING("127.0.0.1"), serverPort, (uint8_t*)&data, sizeof(uint32_t), &count); 1.254 + NS_ENSURE_SUCCESS(rv, -1); 1.255 + REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); 1.256 + passed("Request written by Send"); 1.257 + 1.258 + // Wait for server 1.259 + PumpEvents(); 1.260 + NS_ENSURE_SUCCESS(serverListener->mResult, -1); 1.261 + 1.262 + // Read response from server 1.263 + NS_ENSURE_SUCCESS(clientListener->mResult, -1); 1.264 + 1.265 + mozilla::net::NetAddr clientAddr; 1.266 + rv = client->GetAddress(&clientAddr); 1.267 + NS_ENSURE_SUCCESS(rv, -1); 1.268 + 1.269 + phase = TEST_SEND_API; 1.270 + rv = server->SendWithAddress(&clientAddr, (uint8_t*)&data, sizeof(uint32_t), &count); 1.271 + NS_ENSURE_SUCCESS(rv, -1); 1.272 + REQUIRE_EQUAL(count, sizeof(uint32_t), "Error"); 1.273 + passed("Request written by SendWithAddress"); 1.274 + 1.275 + // Wait for server 1.276 + PumpEvents(); 1.277 + NS_ENSURE_SUCCESS(serverListener->mResult, -1); 1.278 + 1.279 + // Read response from server 1.280 + NS_ENSURE_SUCCESS(clientListener->mResult, -1); 1.281 + 1.282 + // Close server 1.283 + printf("*** Attempting to close server ...\n"); 1.284 + server->Close(); 1.285 + client->Close(); 1.286 + PumpEvents(); 1.287 + passed("Server closed"); 1.288 + 1.289 + return 0; // failure is a non-zero return 1.290 +}