webrtc/modules/udp_transport/test/SocketManagerTest.cpp

450 lines
15 KiB
C++

/*
* 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 <cassert>
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#else
#include <stdio.h>
#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();
};