450 lines
15 KiB
C++
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();
|
|
};
|