/* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include #include #ifdef _WIN32 #include #include #else #include #define Sleep(x) usleep(x*1000) #endif #include "udp_transport.h" #include "common_types.h" #include "trace.h" //#define QOS_TEST //#define QOS_TEST_WITH_OVERRIDE // require admin on Win7 //#define TOS_TEST // require admin on Win7 //#define TOS_TEST_USING_SETSOCKOPT //#define PCP_TEST class UdpTransportDataA: public UdpTransportData { public: UdpTransportDataA() : _counterRTP(0), _counterRTCP(0) { }; virtual void IncomingRTPPacket(const WebRtc_Word8* incommingRtpPacket, const WebRtc_Word32 rtpPacketLength, const WebRtc_Word8* fromIP, const WebRtc_UWord16 fromPort) { _counterRTP++; }; virtual void IncomingRTCPPacket(const WebRtc_Word8* incommingRtcpPacket, const WebRtc_Word32 rtcpPacketLength, const WebRtc_Word8* fromIP, const WebRtc_UWord16 fromPort) { _counterRTCP++; }; WebRtc_UWord32 _counterRTP; WebRtc_UWord32 _counterRTCP; }; class UdpTransportDataB: public UdpTransportData { public: UdpTransportDataB() : _counterRTP(0), _counterRTCP(0) { }; virtual void IncomingRTPPacket(const WebRtc_Word8* incommingRtpPacket, const WebRtc_Word32 rtpPacketLength, const WebRtc_Word8* fromIP, const WebRtc_UWord16 fromPort) { _counterRTP++; }; virtual void IncomingRTCPPacket(const WebRtc_Word8* incommingRtcpPacket, const WebRtc_Word32 rtcpPacketLength, const WebRtc_Word8* fromIP, const WebRtc_UWord16 fromPort) { _counterRTCP++; }; WebRtc_UWord32 _counterRTP; WebRtc_UWord32 _counterRTCP; }; #ifdef _WIN32 int _tmain(int argc, _TCHAR* argv[]) #else int main(int argc, char* argv[]) #endif { Trace::CreateTrace(); Trace::SetTraceFile("testTrace.txt"); Trace::SetEncryptedTraceFile("testTraceDebug.txt"); Trace::SetLevelFilter(webrtc::kTraceAll); printf("Start UdpTransport test\n"); WebRtc_UWord8 numberOfSocketThreads = 5; UdpTransport* client1 = UdpTransport::Create(1,numberOfSocketThreads,NULL); numberOfSocketThreads = 0; UdpTransport* client2 = UdpTransport::Create(2,numberOfSocketThreads,NULL); assert(5 == numberOfSocketThreads); UdpTransportDataA* client1Callback = new UdpTransportDataA(); UdpTransportDataB* client2Callback = new UdpTransportDataB(); WebRtc_UWord32 localIP = 0; WebRtc_Word8 localIPAddr[64]; assert( 0 == client1->LocalHostAddress(localIP)); // network host order aka big-endian sprintf(localIPAddr,"%lu.%lu.%lu.%lu",(localIP>>24)& 0x0ff,(localIP>>16)& 0x0ff ,(localIP>>8)& 0x0ff, localIP & 0x0ff); printf("\tLocal IP:%s\n", localIPAddr); WebRtc_UWord8 localIPV6[16]; WebRtc_Word8 localIPAddrV6[128]; if( 0 == client1->LocalHostAddressIPV6(localIPV6)) { sprintf(localIPAddrV6,"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", localIPV6[0],localIPV6[1],localIPV6[2],localIPV6[3],localIPV6[4],localIPV6[5],localIPV6[6],localIPV6[7], localIPV6[8],localIPV6[9],localIPV6[10],localIPV6[11],localIPV6[12],localIPV6[13],localIPV6[14],localIPV6[15]); printf("\tLocal IPV6:%s\n", localIPAddrV6); } WebRtc_Word8 test[9] = "testtest"; assert( 0 == client1->InitializeReceiveSockets(client1Callback,1234, localIPAddr)); #if defined QOS_TEST_WITH_OVERRIDE || defined QOS_TEST || defined TOS_TEST || defined TOS_TEST_USING_SETSOCKOPT assert( -1 == client1->SetQoS(true, 3, 1000)); // should fail assert( 0 == client1->InitializeSendSockets("192.168.200.1", 1236,1237)); #else assert( 0 == client1->InitializeSendSockets(localIPAddr, 1236,1237)); #endif assert( 0 == client1->StartReceiving(20)); assert( 0 == client2->InitializeReceiveSockets(client2Callback,1236)); assert( 0 == client2->InitializeSendSockets(localIPAddr, 1234,1235)); assert( 0 == client2->StartReceiving(20)); Sleep(10); #ifdef TOS_TEST // note: you need to have QOS installed on your interface for this test // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 assert( 0 == client1->SetToS(2)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetToS(3)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetToS(0)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); printf("Tested TOS \n"); Sleep(5000); return 0; #endif #ifdef TOS_TEST_USING_SETSOCKOPT // note: you need to have QOS installed on your interface for this test // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 assert( 0 == client1->SetToS(2, true)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetToS(3, true)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetToS(0, true)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); printf("Tested TOS using setsockopt \n"); Sleep(5000); return 0; #endif #ifdef QOS_TEST // note: you need to have QOS installed on your interface for this test // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 assert( 0 == client1->SetQoS(true, 2, 1000)); // SERVICETYPE_CONTROLLEDLOAD 2 Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetQoS(true, 3, 1000)); // SERVICETYPE_GUARANTEED 3 Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetQoS(false, 0)); // Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); printf("Tested QOS \n"); Sleep(5000); return 0; #endif #ifdef QOS_TEST_WITH_OVERRIDE // note: you need to have QOS installed on your interface for this test // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 assert( 0 == client1->SetQoS(true, 2, 1000, 1)); // SERVICETYPE_CONTROLLEDLOAD 2 Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetQoS(true, 2, 1000, 2)); // SERVICETYPE_GUARANTEED 3 Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); Sleep(10); assert( 0 == client1->SetQoS(false, 0)); // Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); printf("Tested QOS with override \n"); Sleep(5000); return 0; #endif #ifdef PCP_TEST // Note: We currently don't know how to test that the bits are actually set in the frame, // this test simply tests the API and that we can send a packet after setting PCP. assert( -1 == client1->SetPCP(-1)); // should fail assert( -1 == client1->SetPCP(8)); // should fail printf("Setting PCP to 7 returned %d \n", client1->SetPCP(7)); printf("(Failing is normal, requires the CAP_NET_ADMIN capability to succeed.) \n"); Sleep(10); for (int pcp = 6; pcp >= 0; --pcp) { assert( 0 == client1->SetPCP(pcp)); Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); } printf("Tested PCP \n"); Sleep(5000); return 0; #endif Sleep(10); assert( 9 == client1->SendPacket(-1, test, 9)); // test start rec after a socket has revceived data // result: packets received before first startReceive is saved by the OS /* for(int i = 0; i < 100; i++) { assert( 9 == client1->SendPacket(-1, test, 9)); } Sleep(10); assert( 0 == client2->StartReceiving(20)); // assert( 0 == client2->StopReceiving()); Sleep(10); for(int i = 0; i < 100; i++) { assert( 9 == client1->SendPacket(-1, test, 9)); } assert( 0 == client2->StartReceiving(20)); for(int i = 0; i < 100; i++) { assert( 9 == client1->SendPacket(-1, test, 9)); } */ Sleep(10); assert( 0 == client1Callback->_counterRTP); assert( 1 == client2Callback->_counterRTP); assert( 0 == client1Callback->_counterRTCP); assert( 0 == client2Callback->_counterRTCP); printf("Sent 1 packet on one socket \n"); WebRtc_Word8 ipAddr[64]; WebRtc_Word8 tempIpAddr[64]; WebRtc_Word8 ipMulticastAddr[64]; WebRtc_UWord16 rtpPort = 0; WebRtc_UWord16 rtcpPort = 0; bool reusableSocket = true; assert( 0 == client2->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort)); assert( rtpPort == 1234); assert( strncmp(ipAddr, localIPAddr, 16) == 0); assert( 0 == client2->ReceiveSocketInformation(ipAddr, rtpPort, rtcpPort, ipMulticastAddr, reusableSocket)); assert( rtpPort == 1236); assert( rtcpPort == 1237); assert( strncmp(ipAddr, "0.0.0.0", 16) == 0); assert( ipMulticastAddr[0] == 0); assert( reusableSocket == false); assert( 0 == client2->SendSocketInformation(ipAddr, rtpPort, rtcpPort)); assert( rtpPort == 1234); assert( rtcpPort == 1235); assert( strncmp(ipAddr,localIPAddr, 16) == 0); const int numberOfPackets = 1000; int n = 0; while(n < numberOfPackets) { assert( 9 == client1->SendPacket(-1, test, 9)); assert( 9 == client2->SendPacket(-1, test, 9)); assert( 9 == client1->SendRTCPPacket(-1, test, 9)); assert( 9 == client2->SendRTCPPacket(-1, test, 9)); n++; } int loops = 0; for(; loops < 100 && !(client1Callback->_counterRTP == numberOfPackets && client1Callback->_counterRTCP == numberOfPackets && client2Callback->_counterRTP == numberOfPackets+1 && client2Callback->_counterRTCP == numberOfPackets); loops++) { Sleep(10); } printf("\tSent %d packets on 4 sockets in:%d ms\n", numberOfPackets, loops*10); assert( numberOfPackets == client1Callback->_counterRTP); assert( numberOfPackets+1 == client2Callback->_counterRTP); assert( numberOfPackets == client1Callback->_counterRTCP); assert( numberOfPackets == client2Callback->_counterRTCP); assert( 0 == client1->StopReceiving()); assert( 0 == client2->StopReceiving()); printf("Tear down client 2\n"); // configure that fail assert( -1 == client2->InitializeReceiveSockets(client2Callback,1234, localIPAddr)); // port in use assert( !client2->ReceiveSocketsInitialized()); assert( 0 == client2->InitializeReceiveSockets(client2Callback,1236)); assert( 0 == client2->StartReceiving(20)); printf("Client 2 re-configured\n"); assert( client1->SendSocketsInitialized()); assert( client1->ReceiveSocketsInitialized()); assert( client2->SendSocketsInitialized()); assert( client2->ReceiveSocketsInitialized()); assert( 9 == client1->SendPacket(-1, test, 9)); // this should not be received since we dont receive in client 1 assert( 9 == client2->SendPacket(-1, test, 9)); Sleep(10); assert( numberOfPackets == client1Callback->_counterRTP); assert( numberOfPackets+2 == client2Callback->_counterRTP); assert( numberOfPackets == client1Callback->_counterRTCP); assert( numberOfPackets == client2Callback->_counterRTCP); printf("\tSent 1 packet on one socket \n"); printf("Start filter test\n"); assert( 0 == client1->StartReceiving(20)); assert( 0 == client1->SetFilterPorts(1234, 1235)); // should filter out what we send assert( 0 == client1->SetFilterIP(localIPAddr)); assert( 0 == client1->FilterIP(tempIpAddr)); assert( strncmp(tempIpAddr, localIPAddr, 16) == 0); assert( 9 == client2->SendPacket(-1, test, 9)); assert( 9 == client2->SendRTCPPacket(-1, test, 9)); Sleep(10); assert( numberOfPackets == client1Callback->_counterRTP); assert( numberOfPackets+2 == client2Callback->_counterRTP); assert( numberOfPackets == client1Callback->_counterRTCP); assert( numberOfPackets == client2Callback->_counterRTCP); assert( 0 == client1->SetFilterPorts(1236, 1237)); // should pass through assert( 9 == client2->SendPacket(-1, test, 9)); assert( 9 == client2->SendRTCPPacket(-1, test, 9)); printf("\tSent 1 packet on two sockets \n"); Sleep(10); assert( numberOfPackets+1 == client1Callback->_counterRTP); assert( numberOfPackets+2 == client2Callback->_counterRTP); assert( numberOfPackets+1 == client1Callback->_counterRTCP); assert( numberOfPackets == client2Callback->_counterRTCP); assert( 0 == client1->SetFilterIP("127.0.0.2")); assert( 9 == client2->SendPacket(-1, test, 9)); assert( 9 == client2->SendRTCPPacket(-1, test, 9)); printf("\tSent 1 packet on two sockets \n"); Sleep(10); assert( numberOfPackets+1 == client1Callback->_counterRTP); assert( numberOfPackets+2 == client2Callback->_counterRTP); assert( numberOfPackets+1 == client1Callback->_counterRTCP); assert( numberOfPackets == client2Callback->_counterRTCP); assert( 0 == client1->SetFilterIP(NULL)); assert( 0 == client1->SetFilterPorts(0, 0)); printf("Tested filter \n"); assert( 0 == client2->InitializeSourcePorts(1238, 1239)); assert( 9 == client2->SendPacket(-1, test, 9)); assert( 9 == client2->SendRTCPPacket(-1, test, 9)); printf("\tSent 1 packet on two sockets \n"); Sleep(10); assert( numberOfPackets+2 == client1Callback->_counterRTP); assert( numberOfPackets+2 == client2Callback->_counterRTP); assert( numberOfPackets+2 == client1Callback->_counterRTCP); assert( numberOfPackets == client2Callback->_counterRTCP); assert( 0 == client1->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort)); assert( rtpPort == 1238); assert( rtcpPort == 1239); assert( strncmp(ipAddr, localIPAddr, 16) == 0); printf("Tested source port \n"); assert( 0 == client2->InitializeSourcePorts(1240 )); assert( 9 == client2->SendPacket(-1, test, 9)); assert( 9 == client2->SendRTCPPacket(-1, test, 9)); printf("\tSent 1 packet on two sockets \n"); Sleep(10); assert( 0 == client1->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort)); assert( rtpPort == 1240); assert( rtcpPort == 1241); printf("Tested SetSendPorts source port \n"); UdpTransport::Destroy(client1); UdpTransport::Destroy(client2); printf("\n\nUdpTransport test done\n"); delete client1Callback; delete client2Callback; Sleep(5000); Trace::ReturnTrace(); };