summaryrefslogtreecommitdiff
path: root/Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc')
-rw-r--r--Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc107
1 files changed, 107 insertions, 0 deletions
diff --git a/Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc b/Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc
new file mode 100644
index 0000000..b56da4e
--- /dev/null
+++ b/Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc
@@ -0,0 +1,107 @@
+#include "talk/base/testclient.h"
+#include "talk/base/thread.h"
+#include "talk/base/physicalsocketserver.h"
+#include "talk/base/host.h"
+#include "talk/p2p/base/stunserver.h"
+#include <cstring>
+#include <iostream>
+#include <cassert>
+
+using namespace cricket;
+
+StunMessage* GetResponse(talk_base::TestClient* client) {
+ talk_base::TestClient::Packet* packet = client->NextPacket();
+ assert(packet);
+ talk_base::ByteBuffer buf(packet->buf, packet->size);
+ StunMessage* msg = new StunMessage();
+ assert(msg->Read(&buf));
+ delete packet;
+ return msg;
+}
+
+int main(int argc, char* argv[]) {
+ assert(talk_base::LocalHost().networks().size() >= 2);
+ talk_base::SocketAddress server_addr(talk_base::LocalHost().networks()[1]->ip(), 7000);
+ talk_base::SocketAddress client_addr(talk_base::LocalHost().networks()[1]->ip(), 6000);
+
+ talk_base::Thread th;
+
+ talk_base::AsyncUDPSocket* server_socket = 0;
+ StunServer* server = 0;
+ if (argc >= 2) {
+ server_addr.SetIP(argv[1]);
+ client_addr.SetIP(0);
+ if (argc == 3)
+ server_addr.SetPort(atoi(argv[2]));
+ std::cout << "Using server at " << server_addr.ToString() << std::endl;
+ } else {
+ server_socket = talk_base::CreateAsyncUDPSocket(th.socketserver());
+ assert(server_socket->Bind(server_addr) >= 0);
+ server = new StunServer(server_socket);
+ }
+
+ talk_base::AsyncUDPSocket* client_socket = talk_base::CreateAsyncUDPSocket(th.socketserver());
+ assert(client_socket->Bind(client_addr) >= 0);
+ talk_base::TestClient* client = new talk_base::TestClient(client_socket, &th);
+
+ th.Start();
+
+ const char* bad = "this is a completely nonsensical message whose only "
+ "purpose is to make the parser go 'ack'. it doesn't "
+ "look anything like a normal stun message";
+
+ client->SendTo(bad, std::strlen(bad), server_addr);
+ StunMessage* msg = GetResponse(client);
+ assert(msg->type() == STUN_BINDING_ERROR_RESPONSE);
+
+ const StunErrorCodeAttribute* err = msg->GetErrorCode();
+ assert(err);
+ assert(err->error_class() == 4);
+ assert(err->number() == 0);
+ assert(err->reason() == std::string("Bad Request"));
+
+ delete msg;
+
+ std::string transaction_id = "0123456789abcdef";
+
+ StunMessage req;
+ req.SetType(STUN_BINDING_REQUEST);
+ req.SetTransactionID(transaction_id);
+
+ talk_base::ByteBuffer buf;
+ req.Write(&buf);
+
+ client->SendTo(buf.Data(), buf.Length(), server_addr);
+ StunMessage* msg2 = GetResponse(client);
+ assert(msg2->type() == STUN_BINDING_RESPONSE);
+ assert(msg2->transaction_id() == transaction_id);
+
+ const StunAddressAttribute* mapped_addr =
+ msg2->GetAddress(STUN_ATTR_MAPPED_ADDRESS);
+ assert(mapped_addr);
+ assert(mapped_addr->family() == 1);
+ assert(mapped_addr->port() == client_addr.port());
+ if (mapped_addr->ip() != client_addr.ip()) {
+ printf("Warning: mapped IP (%s) != local IP (%s)\n",
+ talk_base::SocketAddress::IPToString(mapped_addr->ip()).c_str(),
+ client_addr.IPAsString().c_str());
+ }
+
+ const StunAddressAttribute* source_addr =
+ msg2->GetAddress(STUN_ATTR_SOURCE_ADDRESS);
+ assert(source_addr);
+ assert(source_addr->family() == 1);
+ assert(source_addr->port() == server_addr.port());
+ assert(source_addr->ip() == server_addr.ip());
+
+ delete msg2;
+
+ th.Stop();
+
+ delete server;
+ delete server_socket;
+ delete client;
+
+ std::cout << "PASS" << std::endl;
+ return 0;
+}