diff options
Diffstat (limited to 'Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc')
-rw-r--r-- | Plugins/jingle/libjingle/talk/p2p/base/stunserver_unittest.cc | 107 |
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; +} |