diff --git a/webrtc/voice_engine/BUILD.gn b/webrtc/voice_engine/BUILD.gn index 847cbddb6a..65f6af96de 100644 --- a/webrtc/voice_engine/BUILD.gn +++ b/webrtc/voice_engine/BUILD.gn @@ -179,73 +179,8 @@ rtc_static_library("level_indicator") { } if (rtc_include_tests) { - config("channel_transport_warnings_config") { - if (is_win) { - cflags = [ "/wd4302" ] # cast truncation - - if (is_clang) { - # GN orders flags on a target before flags from configs. The default - # config adds -Wall, and this flag have to be after -Wall -- so they need - # to come from a config and cannot be on the target directly. - cflags += [ - "-Wno-parentheses-equality", - "-Wno-reorder", - "-Wno-tautological-constant-out-of-range-compare", - - # See https://bugs.chromium.org/p/webrtc/issues/detail?id=6268 - # for -Wno-thread-safety-analysis - "-Wno-thread-safety-analysis", - "-Wno-unused-private-field", - ] - } - } - } - - rtc_static_library("channel_transport") { - testonly = true - sources = [ - "test/channel_transport/channel_transport.cc", - "test/channel_transport/channel_transport.h", - "test/channel_transport/traffic_control_win.cc", - "test/channel_transport/traffic_control_win.h", - "test/channel_transport/udp_socket2_manager_win.cc", - "test/channel_transport/udp_socket2_manager_win.h", - "test/channel_transport/udp_socket2_win.cc", - "test/channel_transport/udp_socket2_win.h", - "test/channel_transport/udp_socket_manager_posix.cc", - "test/channel_transport/udp_socket_manager_posix.h", - "test/channel_transport/udp_socket_manager_wrapper.cc", - "test/channel_transport/udp_socket_manager_wrapper.h", - "test/channel_transport/udp_socket_posix.cc", - "test/channel_transport/udp_socket_posix.h", - "test/channel_transport/udp_socket_wrapper.cc", - "test/channel_transport/udp_socket_wrapper.h", - "test/channel_transport/udp_transport.h", - "test/channel_transport/udp_transport_impl.cc", - "test/channel_transport/udp_transport_impl.h", - ] - - configs += [ ":channel_transport_warnings_config" ] - - if (!build_with_chromium && is_clang) { - # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163). - suppressed_configs += [ "//build/config/clang:find_bad_constructs" ] - } - - deps = [ - ":voice_engine", - "..:webrtc_common", - "../api:transport_api", - "../base:rtc_base_approved", - "../system_wrappers", - "../test:test_support", - "//testing/gtest", - ] - } - rtc_test("voice_engine_unittests") { deps = [ - ":channel_transport", ":file_player", ":voice_engine", "../base:rtc_base_approved", @@ -275,9 +210,6 @@ if (rtc_include_tests) { sources = [ "channel_unittest.cc", "file_player_unittests.cc", - "test/channel_transport/udp_socket_manager_unittest.cc", - "test/channel_transport/udp_socket_wrapper_unittest.cc", - "test/channel_transport/udp_transport_unittest.cc", "transport_feedback_packet_loss_tracker_unittest.cc", "utility_unittest.cc", "voe_audio_processing_unittest.cc", @@ -313,7 +245,6 @@ if (rtc_include_tests) { testonly = true deps = [ - ":channel_transport", ":voice_engine", "..:webrtc_common", "../base:rtc_base_approved", diff --git a/webrtc/voice_engine/test/channel_transport/channel_transport.cc b/webrtc/voice_engine/test/channel_transport/channel_transport.cc deleted file mode 100644 index 91c83d74a1..0000000000 --- a/webrtc/voice_engine/test/channel_transport/channel_transport.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2013 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 "webrtc/voice_engine/test/channel_transport/channel_transport.h" - -#include - -#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS) -#include "webrtc/test/gtest.h" -#endif -#include "webrtc/voice_engine/test/channel_transport/udp_transport.h" -#include "webrtc/voice_engine/include/voe_network.h" - -#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) -#undef NDEBUG -#include -#endif - -namespace webrtc { -namespace test { - -VoiceChannelTransport::VoiceChannelTransport(VoENetwork* voe_network, - int channel) - : channel_(channel), - voe_network_(voe_network) { - uint8_t socket_threads = 1; - socket_transport_ = UdpTransport::Create(channel, socket_threads); - int registered = voe_network_->RegisterExternalTransport(channel, - *socket_transport_); -#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS) - EXPECT_EQ(0, registered); -#else - assert(registered == 0); -#endif -} - -VoiceChannelTransport::~VoiceChannelTransport() { - voe_network_->DeRegisterExternalTransport(channel_); - UdpTransport::Destroy(socket_transport_); -} - -void VoiceChannelTransport::IncomingRTPPacket( - const int8_t* incoming_rtp_packet, - const size_t packet_length, - const char* /*from_ip*/, - const uint16_t /*from_port*/) { - voe_network_->ReceivedRTPPacket( - channel_, incoming_rtp_packet, packet_length, PacketTime()); -} - -void VoiceChannelTransport::IncomingRTCPPacket( - const int8_t* incoming_rtcp_packet, - const size_t packet_length, - const char* /*from_ip*/, - const uint16_t /*from_port*/) { - voe_network_->ReceivedRTCPPacket(channel_, incoming_rtcp_packet, - packet_length); -} - -int VoiceChannelTransport::SetLocalReceiver(uint16_t rtp_port) { - static const int kNumReceiveSocketBuffers = 500; - int return_value = socket_transport_->InitializeReceiveSockets(this, - rtp_port); - if (return_value == 0) { - return socket_transport_->StartReceiving(kNumReceiveSocketBuffers); - } - return return_value; -} - -int VoiceChannelTransport::SetSendDestination(const char* ip_address, - uint16_t rtp_port) { - return socket_transport_->InitializeSendSockets(ip_address, rtp_port); -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/channel_transport.h b/webrtc/voice_engine/test/channel_transport/channel_transport.h deleted file mode 100644 index 9604b512de..0000000000 --- a/webrtc/voice_engine/test/channel_transport/channel_transport.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_CHANNEL_TRANSPORT_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_CHANNEL_TRANSPORT_H_ - -#include "webrtc/voice_engine/test/channel_transport/udp_transport.h" - -namespace webrtc { - -class VoENetwork; - -namespace test { - -// Helper class for VoiceEngine tests. -class VoiceChannelTransport : public UdpTransportData { - public: - VoiceChannelTransport(VoENetwork* voe_network, int channel); - - virtual ~VoiceChannelTransport(); - - // Start implementation of UdpTransportData. - void IncomingRTPPacket(const int8_t* incoming_rtp_packet, - const size_t packet_length, - const char* /*from_ip*/, - const uint16_t /*from_port*/) override; - - void IncomingRTCPPacket(const int8_t* incoming_rtcp_packet, - const size_t packet_length, - const char* /*from_ip*/, - const uint16_t /*from_port*/) override; - // End implementation of UdpTransportData. - - // Specifies the ports to receive RTP packets on. - int SetLocalReceiver(uint16_t rtp_port); - - // Specifies the destination port and IP address for a specified channel. - int SetSendDestination(const char* ip_address, uint16_t rtp_port); - - private: - int channel_; - VoENetwork* voe_network_; - UdpTransport* socket_transport_; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_CHANNEL_TRANSPORT_H_ diff --git a/webrtc/voice_engine/test/channel_transport/traffic_control_win.cc b/webrtc/voice_engine/test/channel_transport/traffic_control_win.cc deleted file mode 100644 index fb9f9c8c14..0000000000 --- a/webrtc/voice_engine/test/channel_transport/traffic_control_win.cc +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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 "webrtc/voice_engine/test/channel_transport/traffic_control_win.h" - -#include - -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { -namespace test { - -TrafficControlWindows* TrafficControlWindows::instance = NULL; -uint32_t TrafficControlWindows::refCounter = 0; - -TrafficControlWindows::TrafficControlWindows(const int32_t id) -{ -} - -TrafficControlWindows* TrafficControlWindows::GetInstance( - const int32_t id) -{ - if(instance != NULL) - { - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - id, - "TrafficControlWindows - Returning already created object"); - refCounter++; - return instance; - } - - WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, - "TrafficControlWindows - Creating new object"); - instance = new TrafficControlWindows(id); - if(instance == NULL) - { - WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, - "TrafficControlWindows - Error allocating memory"); - return NULL; - } - - instance->tcRegister = NULL; - instance->tcDeregister = NULL; - - instance->tcEnumerate = NULL; - instance->tcOpenInterface = NULL; - instance->tcCloseInterface = NULL; - - instance->tcAddFlow = NULL; - instance->tcDeleteFlow = NULL; - - instance->tcAddFilter = NULL; - instance->tcDeleteFilter = NULL; - - HMODULE trafficLib = LoadLibrary(TEXT("traffic.dll")); - if(trafficLib == NULL) - { - WEBRTC_TRACE( - kTraceWarning, - kTraceTransport, - id, - "TrafficControlWindows - No QOS support, LoadLibrary returned NULL,\ - last error: %d\n", - GetLastError()); - delete instance; - instance = NULL; - return NULL; - } - - instance->tcRegister = (registerFn)GetProcAddress(trafficLib, - "TcRegisterClient"); - instance->tcDeregister = (deregisterFn)GetProcAddress(trafficLib, - "TcDeregisterClient"); - instance->tcEnumerate = (enumerateFn)GetProcAddress( - trafficLib, - "TcEnumerateInterfaces"); - instance->tcOpenInterface = (openInterfaceFn)GetProcAddress( - trafficLib, - "TcOpenInterfaceW"); - instance->tcCloseInterface = (closeInterfaceFn)GetProcAddress( - trafficLib, - "TcCloseInterface"); - instance->tcAddFlow = (flowAddFn)GetProcAddress(trafficLib, - "TcAddFlow"); - instance->tcDeleteFlow = (flowDeleteFn)GetProcAddress(trafficLib, - "TcDeleteFlow"); - - instance->tcAddFilter = (filterAddFn)GetProcAddress(trafficLib, - "TcAddFilter"); - instance->tcDeleteFilter = (filterDeleteFn)GetProcAddress(trafficLib, - "TcDeleteFilter"); - - if(instance->tcRegister == NULL || - instance->tcDeregister == NULL || - instance->tcEnumerate == NULL || - instance->tcOpenInterface == NULL || - instance->tcCloseInterface == NULL || - instance->tcAddFlow == NULL || - instance->tcAddFilter == NULL || - instance->tcDeleteFlow == NULL || - instance->tcDeleteFilter == NULL) - { - delete instance; - instance = NULL; - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - id, - "TrafficControlWindows - Could not find function pointer for\ - traffic control functions"); - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - id, - "Tcregister : %x, tcDeregister: %x, tcEnumerate: %x,\ - tcOpenInterface: %x, tcCloseInterface: %x, tcAddFlow: %x, tcAddFilter: %x,\ - tcDeleteFlow: %x, tcDeleteFilter: %x", - instance->tcRegister, - instance->tcDeregister, - instance->tcEnumerate, - instance->tcOpenInterface, - instance->tcCloseInterface, - instance->tcAddFlow, - instance->tcAddFilter, - instance->tcDeleteFlow, - instance->tcDeleteFilter ); - return NULL; - } - refCounter++; - return instance; -} - -void TrafficControlWindows::Release(TrafficControlWindows* gtc) -{ - if (0 == refCounter) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, -1, - "TrafficControlWindows - Cannot release, refCounter is 0"); - return; - } - if (NULL == gtc) - { - WEBRTC_TRACE(kTraceDebug, kTraceTransport, -1, - "TrafficControlWindows - Not releasing, gtc is NULL"); - return; - } - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, -1, - "TrafficControlWindows - Releasing object"); - refCounter--; - if ((0 == refCounter) && instance) - { - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "TrafficControlWindows - Deleting object"); - delete instance; - instance = NULL; - } -} - -ULONG TrafficControlWindows::TcRegisterClient( - ULONG TciVersion, - HANDLE ClRegCtx, - PTCI_CLIENT_FUNC_LIST ClientHandlerList, - PHANDLE pClientHandle) -{ - assert(tcRegister != NULL); - - return tcRegister(TciVersion, ClRegCtx, ClientHandlerList, pClientHandle); -} - -ULONG TrafficControlWindows::TcDeregisterClient(HANDLE clientHandle) -{ - assert(tcDeregister != NULL); - - return tcDeregister(clientHandle); -} - - -ULONG TrafficControlWindows::TcEnumerateInterfaces( - HANDLE ClientHandle, - PULONG pBufferSize, - PTC_IFC_DESCRIPTOR interfaceBuffer) -{ - assert(tcEnumerate != NULL); - - return tcEnumerate(ClientHandle, pBufferSize, interfaceBuffer); -} - - -ULONG TrafficControlWindows::TcOpenInterfaceW(LPWSTR pInterfaceName, - HANDLE ClientHandle, - HANDLE ClIfcCtx, - PHANDLE pIfcHandle) -{ - assert(tcOpenInterface != NULL); - - return tcOpenInterface(pInterfaceName, ClientHandle, ClIfcCtx, pIfcHandle); - -} - -ULONG TrafficControlWindows::TcCloseInterface(HANDLE IfcHandle) -{ - assert(tcCloseInterface != NULL); - - return tcCloseInterface(IfcHandle); -} - -ULONG TrafficControlWindows::TcAddFlow(HANDLE IfcHandle, HANDLE ClFlowCtx, - ULONG Flags, PTC_GEN_FLOW pGenericFlow, - PHANDLE pFlowHandle) -{ - assert(tcAddFlow != NULL); - return tcAddFlow(IfcHandle, ClFlowCtx, Flags, pGenericFlow, pFlowHandle); -} - -ULONG TrafficControlWindows::TcAddFilter(HANDLE FlowHandle, - PTC_GEN_FILTER pGenericFilter, - PHANDLE pFilterHandle) -{ - assert(tcAddFilter != NULL); - return tcAddFilter(FlowHandle, pGenericFilter, pFilterHandle); -} - -ULONG TrafficControlWindows::TcDeleteFlow(HANDLE FlowHandle) -{ - assert(tcDeleteFlow != NULL); - return tcDeleteFlow(FlowHandle); - -} - -ULONG TrafficControlWindows::TcDeleteFilter(HANDLE FilterHandle) -{ - assert(tcDeleteFilter != NULL); - return tcDeleteFilter(FilterHandle); -} - -void CALLBACK MyClNotifyHandler(HANDLE ClRegCtx, HANDLE ClIfcCtx, ULONG Event, - HANDLE SubCode, ULONG BufSize, PVOID Buffer) -{ -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/traffic_control_win.h b/webrtc/voice_engine/test/channel_transport/traffic_control_win.h deleted file mode 100644 index 8909a80833..0000000000 --- a/webrtc/voice_engine/test/channel_transport/traffic_control_win.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_TRAFFIC_CONTROL_WINDOWS_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_TRAFFIC_CONTROL_WINDOWS_H_ - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -// Disable deprication warning from traffic.h -#pragma warning(disable : 4995) - -#include -#include -#include -#include - -#include "webrtc/system_wrappers/include/trace.h" - -namespace webrtc { -namespace test { -void CALLBACK MyClNotifyHandler(HANDLE ClRegCtx, HANDLE ClIfcCtx, ULONG Event, - HANDLE SubCode, ULONG BufSize, PVOID Buffer); - - -typedef ULONG (WINAPI *registerFn)(ULONG, HANDLE, PTCI_CLIENT_FUNC_LIST, - PHANDLE); -typedef ULONG (WINAPI *deregisterFn)(HANDLE); -typedef ULONG (WINAPI *enumerateFn)(HANDLE, PULONG, PTC_IFC_DESCRIPTOR); -typedef ULONG (WINAPI *openInterfaceFn)(LPWSTR, HANDLE, HANDLE, PHANDLE); -typedef ULONG (WINAPI *closeInterfaceFn)(HANDLE); -typedef ULONG (WINAPI *flowAddFn)(HANDLE, HANDLE, ULONG, PTC_GEN_FLOW, PHANDLE); -typedef ULONG (WINAPI *filterAddFn)(HANDLE, PTC_GEN_FILTER, PHANDLE); -typedef ULONG (WINAPI *flowDeleteFn)(HANDLE); -typedef ULONG (WINAPI *filterDeleteFn)(HANDLE); - -class TrafficControlWindows -{ - public: - // Factory method. Constructor disabled. - static TrafficControlWindows* GetInstance(const int32_t id); - static void Release(TrafficControlWindows* gtc); - - ULONG TcRegisterClient(ULONG TciVersion, HANDLE ClRegCtx, - PTCI_CLIENT_FUNC_LIST ClientHandlerList, - PHANDLE pClientHandle); - - ULONG TcDeregisterClient(HANDLE clientHandle); - - ULONG TcEnumerateInterfaces(HANDLE ClientHandle, PULONG pBufferSize, - PTC_IFC_DESCRIPTOR interfaceBuffer); - - ULONG TcOpenInterfaceW(LPWSTR pInterfaceName, HANDLE ClientHandle, - HANDLE ClIfcCtx, PHANDLE pIfcHandle); - - ULONG TcCloseInterface(HANDLE IfcHandle); - - ULONG TcAddFlow(HANDLE IfcHandle, HANDLE ClFlowCtx, ULONG Flags, - PTC_GEN_FLOW pGenericFlow, PHANDLE pFlowHandle); - - ULONG TcAddFilter(HANDLE FlowHandle, PTC_GEN_FILTER pGenericFilter, - PHANDLE pFilterHandle); - - ULONG TcDeleteFlow(HANDLE FlowHandle); - ULONG TcDeleteFilter(HANDLE FilterHandle); -private: - TrafficControlWindows(const int32_t id); - TCI_CLIENT_FUNC_LIST QoSFunctions; - - static TrafficControlWindows* instance; - - registerFn tcRegister; - deregisterFn tcDeregister; - - enumerateFn tcEnumerate; - openInterfaceFn tcOpenInterface; - closeInterfaceFn tcCloseInterface; - - flowAddFn tcAddFlow; - flowDeleteFn tcDeleteFlow; - - filterAddFn tcAddFilter; - filterDeleteFn tcDeleteFilter; - - static uint32_t refCounter; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_TRAFFIC_CONTROL_WINDOWS_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.cc b/webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.cc deleted file mode 100644 index bb268539f3..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.cc +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h" - -#include -#include - -#include "webrtc/system_wrappers/include/aligned_malloc.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h" - -namespace webrtc { -namespace test { - -uint32_t UdpSocket2ManagerWindows::_numOfActiveManagers = 0; -bool UdpSocket2ManagerWindows::_wsaInit = false; - -UdpSocket2ManagerWindows::UdpSocket2ManagerWindows() - : UdpSocketManager(), - _id(-1), - _stopped(false), - _init(false), - _pCrit(CriticalSectionWrapper::CreateCriticalSection()), - _ioCompletionHandle(NULL), - _numActiveSockets(0), - _event(EventWrapper::Create()) -{ - _managerNumber = _numOfActiveManagers++; - - if(_numOfActiveManagers == 1) - { - WORD wVersionRequested = MAKEWORD(2, 2); - WSADATA wsaData; - _wsaInit = WSAStartup(wVersionRequested, &wsaData) == 0; - // TODO (hellner): seems safer to use RAII for this. E.g. what happens - // if a UdpSocket2ManagerWindows() created and destroyed - // without being initialized. - } -} - -UdpSocket2ManagerWindows::~UdpSocket2ManagerWindows() -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2ManagerWindows(%d)::~UdpSocket2ManagerWindows()", - _managerNumber); - - if(_init) - { - _pCrit->Enter(); - if(_numActiveSockets) - { - _pCrit->Leave(); - _event->Wait(INFINITE); - } - else - { - _pCrit->Leave(); - } - StopWorkerThreads(); - - for (WorkerList::iterator iter = _workerThreadsList.begin(); - iter != _workerThreadsList.end(); ++iter) { - delete *iter; - } - _workerThreadsList.clear(); - _ioContextPool.Free(); - - _numOfActiveManagers--; - if(_ioCompletionHandle) - { - CloseHandle(_ioCompletionHandle); - } - if (_numOfActiveManagers == 0) - { - if(_wsaInit) - { - WSACleanup(); - } - } - } - if(_pCrit) - { - delete _pCrit; - } - if(_event) - { - delete _event; - } -} - -bool UdpSocket2ManagerWindows::Init(int32_t id, - uint8_t& numOfWorkThreads) { - CriticalSectionScoped cs(_pCrit); - if ((_id != -1) || (_numOfWorkThreads != 0)) { - assert(_id != -1); - assert(_numOfWorkThreads != 0); - return false; - } - _id = id; - _numOfWorkThreads = numOfWorkThreads; - return true; -} - -bool UdpSocket2ManagerWindows::Start() -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2ManagerWindows(%d)::Start()",_managerNumber); - if(!_init) - { - StartWorkerThreads(); - } - - if(!_init) - { - return false; - } - _pCrit->Enter(); - // Start worker threads. - _stopped = false; - int32_t error = 0; - for (WorkerList::iterator iter = _workerThreadsList.begin(); - iter != _workerThreadsList.end() && !error; ++iter) { - if(!(*iter)->Start()) - error = 1; - } - if(error) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::Start() error starting worker\ - threads", - _managerNumber); - _pCrit->Leave(); - return false; - } - _pCrit->Leave(); - return true; -} - -bool UdpSocket2ManagerWindows::StartWorkerThreads() -{ - if(!_init) - { - _pCrit->Enter(); - - _ioCompletionHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, - 0, 0); - if(_ioCompletionHandle == NULL) - { - int32_t error = GetLastError(); - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StartWorkerThreads()" - "_ioCompletioHandle == NULL: error:%d", - _managerNumber,error); - _pCrit->Leave(); - return false; - } - - // Create worker threads. - uint32_t i = 0; - bool error = false; - while(i < _numOfWorkThreads && !error) - { - UdpSocket2WorkerWindows* pWorker = - new UdpSocket2WorkerWindows(_ioCompletionHandle); - if(pWorker->Init() != 0) - { - error = true; - delete pWorker; - break; - } - _workerThreadsList.push_front(pWorker); - i++; - } - if(error) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error " - "creating work threads", - _managerNumber); - // Delete worker threads. - for (WorkerList::iterator iter = _workerThreadsList.begin(); - iter != _workerThreadsList.end(); ++iter) { - delete *iter; - } - _workerThreadsList.clear(); - _pCrit->Leave(); - return false; - } - if(_ioContextPool.Init()) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error " - "initiating _ioContextPool", - _managerNumber); - _pCrit->Leave(); - return false; - } - _init = true; - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows::StartWorkerThreads %d number of work " - "threads created and initialized", - _numOfWorkThreads); - _pCrit->Leave(); - } - return true; -} - -bool UdpSocket2ManagerWindows::Stop() -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2ManagerWindows(%d)::Stop()",_managerNumber); - - if(!_init) - { - return false; - } - _pCrit->Enter(); - _stopped = true; - if(_numActiveSockets) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::Stop() there is still active\ - sockets", - _managerNumber); - _pCrit->Leave(); - return false; - } - // No active sockets. Stop all worker threads. - bool result = StopWorkerThreads(); - _pCrit->Leave(); - return result; -} - -bool UdpSocket2ManagerWindows::StopWorkerThreads() -{ - int32_t error = 0; - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StopWorkerThreads() Worker\ - threadsStoped, numActicve Sockets=%d", - _managerNumber, - _numActiveSockets); - - // Release all threads waiting for GetQueuedCompletionStatus(..). - if(_ioCompletionHandle) - { - uint32_t i = 0; - for(i = 0; i < _workerThreadsList.size(); i++) - { - PostQueuedCompletionStatus(_ioCompletionHandle, 0 ,0 , NULL); - } - } - for (WorkerList::iterator iter = _workerThreadsList.begin(); - iter != _workerThreadsList.end(); ++iter) { - if((*iter)->Stop() == false) - { - error = -1; - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, - "failed to stop worker thread"); - } - } - - if(error) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StopWorkerThreads() error stopping\ - worker threads", - _managerNumber); - return false; - } - return true; -} - -bool UdpSocket2ManagerWindows::AddSocketPrv(UdpSocket2Windows* s) -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2ManagerWindows(%d)::AddSocketPrv()",_managerNumber); - if(!_init) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::AddSocketPrv() manager not\ - initialized", - _managerNumber); - return false; - } - _pCrit->Enter(); - if(s == NULL) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::AddSocketPrv() socket == NULL", - _managerNumber); - _pCrit->Leave(); - return false; - } - if(s->GetFd() == NULL || s->GetFd() == INVALID_SOCKET) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::AddSocketPrv() socket->GetFd() ==\ - %d", - _managerNumber, - (int32_t)s->GetFd()); - _pCrit->Leave(); - return false; - - } - _ioCompletionHandle = CreateIoCompletionPort((HANDLE)s->GetFd(), - _ioCompletionHandle, - (ULONG_PTR)(s), 0); - if(_ioCompletionHandle == NULL) - { - int32_t error = GetLastError(); - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::AddSocketPrv() Error adding to IO\ - completion: %d", - _managerNumber, - error); - _pCrit->Leave(); - return false; - } - _numActiveSockets++; - _pCrit->Leave(); - return true; -} -bool UdpSocket2ManagerWindows::RemoveSocketPrv(UdpSocket2Windows* s) -{ - if(!_init) - { - return false; - } - _pCrit->Enter(); - _numActiveSockets--; - if(_numActiveSockets == 0) - { - _event->Set(); - } - _pCrit->Leave(); - return true; -} - -PerIoContext* UdpSocket2ManagerWindows::PopIoContext() -{ - if(!_init) - { - return NULL; - } - - PerIoContext* pIoC = NULL; - if(!_stopped) - { - pIoC = _ioContextPool.PopIoContext(); - }else - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::PopIoContext() Manager Not started", - _managerNumber); - } - return pIoC; -} - -int32_t UdpSocket2ManagerWindows::PushIoContext(PerIoContext* pIoContext) -{ - return _ioContextPool.PushIoContext(pIoContext); -} - -IoContextPool::IoContextPool() - : _pListHead(NULL), - _init(false), - _size(0), - _inUse(0) -{ -} - -IoContextPool::~IoContextPool() -{ - Free(); - assert(_size.Value() == 0); - AlignedFree(_pListHead); -} - -int32_t IoContextPool::Init(uint32_t /*increaseSize*/) -{ - if(_init) - { - return 0; - } - - _pListHead = (PSLIST_HEADER)AlignedMalloc(sizeof(SLIST_HEADER), - MEMORY_ALLOCATION_ALIGNMENT); - if(_pListHead == NULL) - { - return -1; - } - InitializeSListHead(_pListHead); - _init = true; - return 0; -} - -PerIoContext* IoContextPool::PopIoContext() -{ - if(!_init) - { - return NULL; - } - - PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead); - if(pListEntry == NULL) - { - IoContextPoolItem* item = (IoContextPoolItem*) - AlignedMalloc( - sizeof(IoContextPoolItem), - MEMORY_ALLOCATION_ALIGNMENT); - if(item == NULL) - { - return NULL; - } - memset(&item->payload.ioContext,0,sizeof(PerIoContext)); - item->payload.base = item; - pListEntry = &(item->itemEntry); - ++_size; - } - ++_inUse; - return &((IoContextPoolItem*)pListEntry)->payload.ioContext; -} - -int32_t IoContextPool::PushIoContext(PerIoContext* pIoContext) -{ - // TODO (hellner): Overlapped IO should be completed at this point. Perhaps - // add an assert? - const bool overlappedIOCompleted = HasOverlappedIoCompleted( - (LPOVERLAPPED)pIoContext); - - IoContextPoolItem* item = ((IoContextPoolItemPayload*)pIoContext)->base; - - const int32_t usedItems = --_inUse; - const int32_t totalItems = _size.Value(); - const int32_t freeItems = totalItems - usedItems; - if(freeItems < 0) - { - assert(false); - AlignedFree(item); - return -1; - } - if((freeItems >= totalItems>>1) && - overlappedIOCompleted) - { - AlignedFree(item); - --_size; - return 0; - } - InterlockedPushEntrySList(_pListHead, &(item->itemEntry)); - return 0; -} - -int32_t IoContextPool::Free() -{ - if(!_init) - { - return 0; - } - - int32_t itemsFreed = 0; - PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead); - while(pListEntry != NULL) - { - IoContextPoolItem* item = ((IoContextPoolItem*)pListEntry); - AlignedFree(item); - --_size; - itemsFreed++; - pListEntry = InterlockedPopEntrySList(_pListHead); - } - return itemsFreed; -} - -int32_t UdpSocket2WorkerWindows::_numOfWorkers = 0; - -UdpSocket2WorkerWindows::UdpSocket2WorkerWindows(HANDLE ioCompletionHandle) - : _ioCompletionHandle(ioCompletionHandle), - _pThread(Run, this, "UdpSocket2ManagerWindows_thread"), - _init(false) { - _workerNumber = _numOfWorkers++; - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocket2WorkerWindows created"); -} - -UdpSocket2WorkerWindows::~UdpSocket2WorkerWindows() -{ - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocket2WorkerWindows deleted"); -} - -bool UdpSocket2WorkerWindows::Start() -{ - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Start UdpSocket2WorkerWindows"); - _pThread.Start(); - - _pThread.SetPriority(rtc::kRealtimePriority); - return true; -} - -bool UdpSocket2WorkerWindows::Stop() -{ - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Stop UdpSocket2WorkerWindows"); - _pThread.Stop(); - return true; -} - -int32_t UdpSocket2WorkerWindows::Init() -{ - _init = true; - return 0; -} - -bool UdpSocket2WorkerWindows::Run(void* obj) -{ - UdpSocket2WorkerWindows* pWorker = - static_cast(obj); - return pWorker->Process(); -} - -// Process should always return true. Stopping the worker threads is done in -// the UdpSocket2ManagerWindows::StopWorkerThreads() function. -bool UdpSocket2WorkerWindows::Process() -{ - int32_t success = 0; - DWORD ioSize = 0; - UdpSocket2Windows* pSocket = NULL; - PerIoContext* pIOContext = 0; - OVERLAPPED* pOverlapped = 0; - success = GetQueuedCompletionStatus(_ioCompletionHandle, - &ioSize, - (ULONG_PTR*)&pSocket, &pOverlapped, 200); - - uint32_t error = 0; - if(!success) - { - error = GetLastError(); - if(error == WAIT_TIMEOUT) - { - return true; - } - // This may happen if e.g. PostQueuedCompletionStatus() has been called. - // The IO context still needs to be reclaimed or re-used which is done - // in UdpSocket2Windows::IOCompleted(..). - } - if(pSocket == NULL) - { - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - -1, - "UdpSocket2WorkerWindows(%d)::Process(), pSocket == 0, end thread", - _workerNumber); - return true; - } - pIOContext = (PerIoContext*)pOverlapped; - pSocket->IOCompleted(pIOContext,ioSize,error); - return true; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h b/webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h deleted file mode 100644 index ceba9c99e9..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_ - -#include -#include - -#include "webrtc/system_wrappers/include/atomic32.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/base/platform_thread.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_transport.h" - -#define MAX_IO_BUFF_SIZE 1600 - -namespace webrtc { -namespace test { - -enum IO_OPERATION { - OP_READ, - OP_WRITE -}; - -class UdpSocket2Windows; - -// Struct used for all socket I/O operations. -struct PerIoContext { - WSAOVERLAPPED overlapped; - char buffer[MAX_IO_BUFF_SIZE]; - WSABUF wsabuf; - size_t nTotalBytes; - int nSentBytes; - int bytes; - IO_OPERATION ioOperation; - SocketAddress from; - int fromLen; - // Should be set to true if the I/O context was passed to the system by - // a thread not controlled by the socket implementation. - bool ioInitiatedByPlatformThread; - // TODO (hellner): Not used. Delete it. - PerIoContext* pNextFree; -}; - -struct IoContextPoolItem; -struct IoContextPoolItemPayload -{ - PerIoContext ioContext; - IoContextPoolItem* base; -}; - -struct IoContextPoolItem -{ - // Atomic single linked list entry header. - SLIST_ENTRY itemEntry; - // Atomic single linked list payload - IoContextPoolItemPayload payload; -}; - -class IoContextPool -{ -public: - IoContextPool(); - virtual ~IoContextPool(); - virtual int32_t Init(uint32_t increaseSize = 128); - // Re-use an old unused IO context or create a new one. - virtual PerIoContext* PopIoContext(); - virtual int32_t PushIoContext(PerIoContext* pIoContext); - virtual inline int32_t GetSize(uint32_t* inUse = 0) - {return _size.Value();} - virtual int32_t Free(); -private: - // Sample code for use of msfts single linked atomic list can be found here: - // http://msdn.microsoft.com/en-us/library/ms686962(VS.85).aspx - - // Atomic single linked list head. - PSLIST_HEADER _pListHead; - - bool _init; - Atomic32 _size; - Atomic32 _inUse; -}; - -class UdpSocket2WorkerWindows -{ -public: - UdpSocket2WorkerWindows(HANDLE ioCompletionHandle); - virtual ~UdpSocket2WorkerWindows(); - - virtual bool Start(); - virtual bool Stop(); - virtual int32_t Init(); -protected: - static bool Run(void* obj); - bool Process(); -private: - HANDLE _ioCompletionHandle; - rtc::PlatformThread _pThread; - static int32_t _numOfWorkers; - int32_t _workerNumber; - volatile bool _stop; - bool _init; -}; - -class UdpSocket2ManagerWindows : public UdpSocketManager -{ -public: - UdpSocket2ManagerWindows(); - virtual ~UdpSocket2ManagerWindows(); - - virtual bool Init(int32_t id, uint8_t& numOfWorkThreads); - - virtual bool Start(); - virtual bool Stop(); - - virtual inline bool AddSocket(UdpSocketWrapper* s) - {if(s) return AddSocketPrv(reinterpret_cast(s)); - return false;} - virtual bool RemoveSocket(UdpSocketWrapper* s) - {if(s) return RemoveSocketPrv(reinterpret_cast(s)); - return false;} - - PerIoContext* PopIoContext(void); - int32_t PushIoContext(PerIoContext* pIoContext); - -private: - typedef std::list WorkerList; - bool StopWorkerThreads(); - bool StartWorkerThreads(); - bool AddSocketPrv(UdpSocket2Windows* s); - bool RemoveSocketPrv(UdpSocket2Windows* s); - - static uint32_t _numOfActiveManagers; - static bool _wsaInit; - - int32_t _id; - CriticalSectionWrapper* _pCrit; - int32_t _managerNumber; - volatile bool _stopped; - bool _init; - int32_t _numActiveSockets; - WorkerList _workerThreadsList; - EventWrapper* _event; - - HANDLE _ioCompletionHandle; - IoContextPool _ioContextPool; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket2_win.cc b/webrtc/voice_engine/test/channel_transport/udp_socket2_win.cc deleted file mode 100644 index ffe7139093..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket2_win.cc +++ /dev/null @@ -1,1353 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h" - -#include -#include -#include - -#include "webrtc/base/format_macros.h" -#include "webrtc/system_wrappers/include/sleep.h" -#include "webrtc/voice_engine/test/channel_transport/traffic_control_win.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h" - -#pragma warning(disable : 4311) - -namespace webrtc { -namespace test { - -typedef struct _QOS_DESTADDR -{ - QOS_OBJECT_HDR ObjectHdr; - const struct sockaddr* SocketAddress; - ULONG SocketAddressLength; -} QOS_DESTADDR, *LPQOS_DESTADDR; - -typedef const QOS_DESTADDR* LPCQOS_DESTADDR; - -// TODO (patrikw): seems to be defined in ws2ipdef.h as 3. How come it's -// redefined here (as a different value)? -#define IP_TOS 8 - -#define QOS_GENERAL_ID_BASE 2000 -#define QOS_OBJECT_DESTADDR (0x00000004 + QOS_GENERAL_ID_BASE) - -UdpSocket2Windows::UdpSocket2Windows(const int32_t id, - UdpSocketManager* mgr, bool ipV6Enable, - bool disableGQOS) - : _id(id), - _qos(true), - _iProtocol(0), - _outstandingCalls(0), - _outstandingCallComplete(0), - _terminate(false), - _addedToMgr(false), - delete_event_(true, false), - _outstandingCallsDisabled(false), - _clientHandle(NULL), - _flowHandle(NULL), - _filterHandle(NULL), - _flow(NULL), - _gtc(NULL), - _pcp(-2), - _receiveBuffers(0) -{ - WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id, - "UdpSocket2Windows::UdpSocket2Windows()"); - - _wantsIncoming = false; - _mgr = static_cast(mgr); - - _obj = NULL; - _incomingCb = NULL; - _socket = INVALID_SOCKET; - _ptrCbRWLock = RWLockWrapper::CreateRWLock(); - _ptrDestRWLock = RWLockWrapper::CreateRWLock(); - _ptrSocketRWLock = RWLockWrapper::CreateRWLock(); - - // Check if QoS is supported. - BOOL bProtocolFound = FALSE; - WSAPROTOCOL_INFO *lpProtocolBuf = NULL; - WSAPROTOCOL_INFO pProtocolInfo; - - if(!disableGQOS) - { - DWORD dwBufLen = 0; - // Set dwBufLen to the size needed to retreive all the requested - // information from WSAEnumProtocols. - int32_t nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); - lpProtocolBuf = (WSAPROTOCOL_INFO*)malloc(dwBufLen); - nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); - - if (ipV6Enable) - { - _iProtocol=AF_INET6; - } else { - _iProtocol=AF_INET; - } - - for (int32_t i=0; iTcDeleteFilter(_filterHandle); - } - if(_flowHandle) - { - _gtc->TcDeleteFlow(_flowHandle); - } - TrafficControlWindows::Release( _gtc); - } -} - -bool UdpSocket2Windows::ValidHandle() -{ - return GetFd() != INVALID_SOCKET; -} - -bool UdpSocket2Windows::SetCallback(CallbackObj obj, IncomingSocketCallback cb) -{ - _ptrCbRWLock->AcquireLockExclusive(); - _obj = obj; - _incomingCb = cb; - _ptrCbRWLock->ReleaseLockExclusive(); - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback ",(int32_t)this); - if(_addedToMgr) - { - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback alreadey added", - (int32_t) this); - return false; - - } - if (_mgr->AddSocket(this)) - { - WEBRTC_TRACE( - kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback socket added to manager", - (int32_t)this); - _addedToMgr = true; - return true; - } - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback error adding me to mgr", - (int32_t) this); - return false; -} - -bool UdpSocket2Windows::SetSockopt(int32_t level, int32_t optname, - const int8_t* optval, int32_t optlen) -{ - bool returnValue = true; - if(!AquireSocket()) - { - return false; - } - if(0 != setsockopt(_socket, level, optname, - reinterpret_cast(optval), optlen )) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::SetSockopt(), WSAerror:%d", - WSAGetLastError()); - returnValue = false; - } - ReleaseSocket(); - return returnValue; -} - -bool UdpSocket2Windows::StartReceiving(uint32_t receiveBuffers) -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::StartReceiving(%d)", (int32_t)this, - receiveBuffers); - - _wantsIncoming = true; - - int32_t numberOfReceiveBuffersToCreate = - receiveBuffers - _receiveBuffers.Value(); - numberOfReceiveBuffersToCreate = (numberOfReceiveBuffersToCreate < 0) ? - 0 : numberOfReceiveBuffersToCreate; - - int32_t error = 0; - for(int32_t i = 0; - i < numberOfReceiveBuffersToCreate; - i++) - { - if(PostRecv()) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::StartReceiving() i=%d", i); - error = -1; - break; - } - ++_receiveBuffers; - } - if(error == -1) - { - return false; - } - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "Socket receiving using:%d number of buffers", - _receiveBuffers.Value()); - return true; -} - -bool UdpSocket2Windows::StopReceiving() -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows::StopReceiving()"); - _wantsIncoming = false; - return true; -} - -bool UdpSocket2Windows::Bind(const SocketAddress& name) -{ - const struct sockaddr* addr = - reinterpret_cast(&name); - bool returnValue = true; - if(!AquireSocket()) - { - return false; - } - if (0 != bind(_socket, addr, sizeof(SocketAddress))) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::Bind() WSAerror: %d", - WSAGetLastError()); - returnValue = false; - } - ReleaseSocket(); - return returnValue; -} - -int32_t UdpSocket2Windows::SendTo(const int8_t* buf, size_t len, - const SocketAddress& to) -{ - int32_t retVal = 0; - int32_t error = 0; - PerIoContext* pIoContext = _mgr->PopIoContext(); - if(pIoContext == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SendTo(), pIoContext==0", - (int32_t) this); - return -1; - } - // sizeof(pIoContext->buffer) is smaller than the highest number that - // can be represented by a size_t. - if(len >= sizeof(pIoContext->buffer)) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::SendTo(), len= %" PRIuS - " > buffer_size = %d", - (int32_t) this, - len,sizeof(pIoContext->buffer)); - len = sizeof(pIoContext->buffer); - } - - memcpy(pIoContext->buffer,buf,len); - pIoContext->wsabuf.buf = pIoContext->buffer; - pIoContext->wsabuf.len = static_cast(len); - pIoContext->fromLen=sizeof(SocketAddress); - pIoContext->ioOperation = OP_WRITE; - pIoContext->nTotalBytes = len; - pIoContext->nSentBytes=0; - - DWORD numOfbytesSent = 0; - const struct sockaddr* addr = reinterpret_cast(&to); - - if(!AquireSocket()) - { - _mgr->PushIoContext(pIoContext); - return -1; - } - // Assume that the WSASendTo call will be successfull to make sure that - // _outstandingCalls is positive. Roll back if WSASendTo failed. - if(!NewOutstandingCall()) - { - _mgr->PushIoContext(pIoContext); - ReleaseSocket(); - return -1; - } - retVal = WSASendTo(_socket, &pIoContext->wsabuf, 1, &numOfbytesSent, - 0, addr, sizeof(SocketAddress), - &(pIoContext->overlapped), 0); - ReleaseSocket(); - - if( retVal == SOCKET_ERROR ) - { - error = WSAGetLastError(); - if(error != ERROR_IO_PENDING) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::SendTo() WSAerror: %d",error); - } - } - if(retVal == 0 || (retVal == SOCKET_ERROR && error == ERROR_IO_PENDING)) - { - return static_cast(len); - } - error = _mgr->PushIoContext(pIoContext); - if(error) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::SendTo(), error:%d pushing ioContext", - (int32_t)this, error); - } - - // Roll back. - OutstandingCallCompleted(); - return -1; -} - -void UdpSocket2Windows::IOCompleted(PerIoContext* pIOContext, - uint32_t ioSize, uint32_t error) -{ - if(pIOContext == NULL || error == ERROR_OPERATION_ABORTED) - { - if ((pIOContext != NULL) && - !pIOContext->ioInitiatedByPlatformThread && - (error == ERROR_OPERATION_ABORTED) && - (pIOContext->ioOperation == OP_READ) && - _outstandingCallsDisabled) - { - // !pIOContext->initiatedIOByPlatformThread indicate that the I/O - // was not initiated by a PlatformThread thread. - // This may happen if the thread that initiated receiving (e.g. - // by calling StartListen())) is deleted before any packets have - // been received. - // In this case there is no packet in the PerIoContext. Re-use it - // to post a new PostRecv(..). - // Note 1: the PerIoContext will henceforth be posted by a thread - // that is controlled by the socket implementation. - // Note 2: This is more likely to happen to RTCP packets as - // they are less frequent than RTP packets. - // Note 3: _outstandingCallsDisabled being false indicates - // that the socket isn't being shut down. - // Note 4: This should only happen buffers set to receive packets - // (OP_READ). - } else { - if(pIOContext == NULL) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows::IOCompleted(%d,%d,%d), %d", - (int32_t)pIOContext, - ioSize, - error, - pIOContext ? (int32_t)pIOContext->ioOperation : -1); - } else { - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - _id, - "UdpSocket2Windows::IOCompleted() Operation aborted"); - } - if(pIOContext) - { - int32_t remainingReceiveBuffers = --_receiveBuffers; - if(remainingReceiveBuffers < 0) - { - assert(false); - } - int32_t err = _mgr->PushIoContext(pIOContext); - if(err) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows::IOCompleted(), err = %d, when\ - pushing ioContext after error", - err); - } - } - OutstandingCallCompleted(); - return; - } - } // if (pIOContext == NULL || error == ERROR_OPERATION_ABORTED) - - if(pIOContext->ioOperation == OP_WRITE) - { - _mgr->PushIoContext(pIOContext); - } - else if(pIOContext->ioOperation == OP_READ) - { - if(!error && ioSize != 0) - { - _ptrCbRWLock->AcquireLockShared(); - if(_wantsIncoming && _incomingCb) - { - _incomingCb(_obj, - reinterpret_cast( - pIOContext->wsabuf.buf), - ioSize, - &pIOContext->from); - } - _ptrCbRWLock->ReleaseLockShared(); - } - int32_t err = PostRecv(pIOContext); - if(err == 0) - { - // The PerIoContext was posted by a thread controlled by the socket - // implementation. - pIOContext->ioInitiatedByPlatformThread = true; - } - OutstandingCallCompleted(); - return; - } else { - // Unknown operation. Should not happen. Return pIOContext to avoid - // memory leak. - assert(false); - _mgr->PushIoContext(pIOContext); - } - OutstandingCallCompleted(); - // Don't touch any members after OutstandingCallCompleted() since the socket - // may be deleted at this point. -} - -int32_t UdpSocket2Windows::PostRecv() -{ - PerIoContext* pIoContext=_mgr->PopIoContext(); - if(pIoContext == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::PostRecv(), pIoContext == 0", - (int32_t)this); - return -1; - } - // This function may have been called by thread not controlled by the socket - // implementation. - pIoContext->ioInitiatedByPlatformThread = false; - return PostRecv(pIoContext); -} - -int32_t UdpSocket2Windows::PostRecv(PerIoContext* pIoContext) -{ - if(pIoContext==0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::PostRecv(?), pIoContext==0", - (int32_t)this); - return -1; - } - - DWORD numOfRecivedBytes = 0; - DWORD flags = 0; - pIoContext->wsabuf.buf = pIoContext->buffer; - pIoContext->wsabuf.len = sizeof(pIoContext->buffer); - pIoContext->fromLen = sizeof(SocketAddress); - pIoContext->ioOperation = OP_READ; - int32_t rxError = 0; - int32_t nRet = 0; - int32_t postingSucessfull = false; - - if(!AquireSocket()) - { - _mgr->PushIoContext(pIoContext); - return -1; - } - - // Assume that the WSARecvFrom() call will be successfull to make sure that - // _outstandingCalls is positive. Roll back if WSARecvFrom() failed. - if(!NewOutstandingCall()) - { - _mgr->PushIoContext(pIoContext); - ReleaseSocket(); - return -1; - } - for(int32_t tries = 0; tries < 10; tries++) - { - nRet = WSARecvFrom( - _socket, - &(pIoContext->wsabuf), - 1, - &numOfRecivedBytes, - &flags, - reinterpret_cast(&(pIoContext->from)), - &(pIoContext->fromLen), - &(pIoContext->overlapped), - 0); - - if( nRet == SOCKET_ERROR) - { - rxError = WSAGetLastError(); - if(rxError != ERROR_IO_PENDING) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::PostRecv(?), WSAerror:%d when\ - posting new recieve,trie:%d", - (int32_t)this, - rxError, - tries); - // Tell the OS that this is a good place to context switch if - // it wants to. - SleepMs(0); - } - } - if((rxError == ERROR_IO_PENDING) || (nRet == 0)) - { - postingSucessfull = true; - break; - } - } - ReleaseSocket(); - - if(postingSucessfull) - { - return 0; - } - int32_t remainingReceiveBuffers = --_receiveBuffers; - if(remainingReceiveBuffers < 0) - { - assert(false); - } - int32_t error = _mgr->PushIoContext(pIoContext); - if(error) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::PostRecv(?), error:%d when PushIoContext", - (int32_t)this, - error); - } - // Roll back. - OutstandingCallCompleted(); - return -1; -} - -void UdpSocket2Windows::CloseBlocking() -{ - LINGER lingerStruct; - - lingerStruct.l_onoff = 1; - lingerStruct.l_linger = 0; - if(AquireSocket()) - { - setsockopt(_socket, SOL_SOCKET, SO_LINGER, - reinterpret_cast(&lingerStruct), - sizeof(lingerStruct)); - ReleaseSocket(); - } - - _wantsIncoming = false; - // Reclaims the socket and prevents it from being used again. - InvalidateSocket(); - DisableNewOutstandingCalls(); - delete this; -} - -bool UdpSocket2Windows::SetQos(int32_t serviceType, - int32_t tokenRate, - int32_t bucketSize, - int32_t peekBandwith, - int32_t minPolicedSize, - int32_t maxSduSize, - const SocketAddress &stRemName, - int32_t overrideDSCP) -{ - if(_qos == false) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::SetQos(), socket not capable of QOS"); - return false; - } - if(overrideDSCP != 0) - { - FLOWSPEC f; - int32_t err = CreateFlowSpec(serviceType, tokenRate, bucketSize, - peekBandwith, minPolicedSize, - maxSduSize, &f); - if(err == -1) - { - return false; - } - - SocketAddress socketName; - struct sockaddr_in* name = - reinterpret_cast(&socketName); - int nameLength = sizeof(SocketAddress); - if(AquireSocket()) - { - getsockname(_socket, (struct sockaddr*)name, &nameLength); - ReleaseSocket(); - } - - if(serviceType == 0) - { - // Disable TOS byte setting. - return SetTrafficControl(0, -1, name, &f, &f) == 0; - } - return SetTrafficControl(overrideDSCP, -1, name, &f, &f) == 0; - } - - QOS Qos; - DWORD BytesRet; - QOS_DESTADDR QosDestaddr; - - memset (&Qos, QOS_NOT_SPECIFIED, sizeof(QOS)); - - Qos.SendingFlowspec.ServiceType = serviceType; - Qos.SendingFlowspec.TokenRate = tokenRate; - Qos.SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; - Qos.SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; - Qos.SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; - Qos.SendingFlowspec.Latency = QOS_NOT_SPECIFIED; - Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; - Qos.SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; - - // Only ServiceType is needed for receiving. - Qos.ReceivingFlowspec.ServiceType = serviceType; - Qos.ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; - - Qos.ProviderSpecific.len = 0; - - Qos.ProviderSpecific.buf = NULL; - - ZeroMemory((int8_t *)&QosDestaddr, sizeof(QosDestaddr)); - - OSVERSIONINFOEX osvie; - osvie.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - GetVersionEx((LPOSVERSIONINFO)&osvie); - -// Operating system Version number dwMajorVersion dwMinorVersion -// Windows 7 6.1 6 1 -// Windows Server 2008 R2 6.1 6 1 -// Windows Server 2008 6.0 6 0 -// Windows Vista 6.0 6 0 -// Windows Server 2003 R2 5.2 5 2 -// Windows Server 2003 5.2 5 2 -// Windows XP 5.1 5 1 -// Windows 2000 5.0 5 0 - - // SERVICE_NO_QOS_SIGNALING and QOS_DESTADDR should not be used if version - // is 6.0 or greater. - if(osvie.dwMajorVersion >= 6) - { - Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; - Qos.ReceivingFlowspec.ServiceType = serviceType; - - } else { - Qos.SendingFlowspec.MinimumPolicedSize = - QOS_NOT_SPECIFIED | SERVICE_NO_QOS_SIGNALING; - Qos.ReceivingFlowspec.ServiceType = - serviceType | SERVICE_NO_QOS_SIGNALING; - - QosDestaddr.ObjectHdr.ObjectType = QOS_OBJECT_DESTADDR; - QosDestaddr.ObjectHdr.ObjectLength = sizeof(QosDestaddr); - QosDestaddr.SocketAddress = (SOCKADDR *)&stRemName; - if (AF_INET6 == _iProtocol) - { - QosDestaddr.SocketAddressLength = sizeof(SocketAddressInVersion6); - } else { - QosDestaddr.SocketAddressLength = sizeof(SocketAddressIn); - } - - Qos.ProviderSpecific.len = QosDestaddr.ObjectHdr.ObjectLength; - Qos.ProviderSpecific.buf = (char*)&QosDestaddr; - } - - if(!AquireSocket()) { - return false; - } - // To set QoS with SIO_SET_QOS the socket must be locally bound first - // or the call will fail with error code 10022. - int32_t result = WSAIoctl(GetFd(), SIO_SET_QOS, &Qos, sizeof(QOS), - NULL, 0, &BytesRet, NULL,NULL); - ReleaseSocket(); - if (result == SOCKET_ERROR) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::SetQos() WSAerror : %d", - WSAGetLastError()); - return false; - } - return true; -} - -int32_t UdpSocket2Windows::SetTOS(int32_t serviceType) -{ - SocketAddress socketName; - - struct sockaddr_in* name = - reinterpret_cast(&socketName); - int nameLength = sizeof(SocketAddress); - if(AquireSocket()) - { - getsockname(_socket, (struct sockaddr*)name, &nameLength); - ReleaseSocket(); - } - - int32_t res = SetTrafficControl(serviceType, -1, name); - if (res == -1) - { - OSVERSIONINFO OsVersion; - OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx (&OsVersion); - - if ((OsVersion.dwMajorVersion == 4)) // NT 4.0 - { - if(SetSockopt(IPPROTO_IP,IP_TOS , - (int8_t*)&serviceType, 4) != 0) - { - return -1; - } - } - } - return res; -} - -int32_t UdpSocket2Windows::SetPCP(int32_t pcp) -{ - SocketAddress socketName; - struct sockaddr_in* name = - reinterpret_cast(&socketName); - int nameLength = sizeof(SocketAddress); - if(AquireSocket()) - { - getsockname(_socket, (struct sockaddr*)name, &nameLength); - ReleaseSocket(); - } - return SetTrafficControl(-1, pcp, name); -} - -int32_t UdpSocket2Windows::SetTrafficControl( - int32_t dscp, - int32_t pcp, - const struct sockaddr_in* name, - FLOWSPEC* send, FLOWSPEC* recv) -{ - if (pcp == _pcp) - { - // No change. - pcp = -1; - } - if ((-1 == pcp) && (-1 == dscp)) - { - return 0; - } - if (!_gtc) - { - _gtc = TrafficControlWindows::GetInstance(_id); - } - if (!_gtc) - { - return -1; - } - if(_filterHandle) - { - _gtc->TcDeleteFilter(_filterHandle); - _filterHandle = NULL; - } - if(_flowHandle) - { - _gtc->TcDeleteFlow(_flowHandle); - _flowHandle = NULL; - } - if(_clientHandle) - { - _gtc->TcDeregisterClient(_clientHandle); - _clientHandle = NULL; - } - if ((0 == dscp) && (-2 == _pcp) && (-1 == pcp)) - { - // TODO (pwestin): why is this not done before deleting old filter and - // flow? This scenario should probably be documented in - // the function declaration. - return 0; - } - - TCI_CLIENT_FUNC_LIST QoSFunctions; - QoSFunctions.ClAddFlowCompleteHandler = NULL; - QoSFunctions.ClDeleteFlowCompleteHandler = NULL; - QoSFunctions.ClModifyFlowCompleteHandler = NULL; - QoSFunctions.ClNotifyHandler = (TCI_NOTIFY_HANDLER)MyClNotifyHandler; - // Register the client with Traffic control interface. - HANDLE ClientHandle; - ULONG result = _gtc->TcRegisterClient(CURRENT_TCI_VERSION, NULL, - &QoSFunctions,&ClientHandle); - if(result != NO_ERROR) - { - // This is likely caused by the application not being run as - // administrator. - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "TcRegisterClient returned %d", result); - return result; - } - - // Find traffic control-enabled network interfaces that matches this - // socket's IP address. - ULONG BufferSize = 0; - result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, NULL); - - if(result != NO_ERROR && result != ERROR_INSUFFICIENT_BUFFER) - { - _gtc->TcDeregisterClient(ClientHandle); - return result; - } - - if(result != ERROR_INSUFFICIENT_BUFFER) - { - // Empty buffer contains all control-enabled network interfaces. I.e. - // QoS is not enabled. - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "QOS faild since QOS is not installed on the interface"); - - _gtc->TcDeregisterClient(ClientHandle); - return -1; - } - - PTC_IFC_DESCRIPTOR pInterfaceBuffer = - (PTC_IFC_DESCRIPTOR)malloc(BufferSize); - if(pInterfaceBuffer == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Out ot memory failure"); - _gtc->TcDeregisterClient(ClientHandle); - return ERROR_NOT_ENOUGH_MEMORY; - } - - result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, - pInterfaceBuffer); - - if(result != NO_ERROR) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "Critical: error enumerating interfaces when passing in correct\ - buffer size: %d", result); - _gtc->TcDeregisterClient(ClientHandle); - free(pInterfaceBuffer); - return result; - } - - PTC_IFC_DESCRIPTOR oneinterface; - HANDLE ifcHandle, iFilterHandle, iflowHandle; - bool addrFound = false; - ULONG filterSourceAddress = ULONG_MAX; - - // Find the interface corresponding to the local address. - for(oneinterface = pInterfaceBuffer; - oneinterface != (PTC_IFC_DESCRIPTOR) - (((int8_t*)pInterfaceBuffer) + BufferSize); - oneinterface = (PTC_IFC_DESCRIPTOR) - ((int8_t *)oneinterface + oneinterface->Length)) - { - - char interfaceName[500]; - WideCharToMultiByte(CP_ACP, 0, oneinterface->pInterfaceName, -1, - interfaceName, sizeof(interfaceName), 0, 0 ); - - PNETWORK_ADDRESS_LIST addresses = - &(oneinterface->AddressListDesc.AddressList); - for(LONG i = 0; i < addresses->AddressCount ; i++) - { - // Only look at TCP/IP addresses. - if(addresses->Address[i].AddressType != NDIS_PROTOCOL_ID_TCP_IP) - { - continue; - } - - NETWORK_ADDRESS_IP* pIpAddr = - (NETWORK_ADDRESS_IP*)&(addresses->Address[i].Address); - struct in_addr in; - in.S_un.S_addr = pIpAddr->in_addr; - if(pIpAddr->in_addr == name->sin_addr.S_un.S_addr) - { - filterSourceAddress = pIpAddr->in_addr; - addrFound = true; - } - } - if(!addrFound) - { - continue; - } else - { - break; - } - } - if(!addrFound) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "QOS faild since address is not found"); - _gtc->TcDeregisterClient(ClientHandle); - free(pInterfaceBuffer); - return -1; - } - result = _gtc->TcOpenInterfaceW(oneinterface->pInterfaceName, ClientHandle, - NULL, &ifcHandle); - if(result != NO_ERROR) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Error opening interface: %d", result); - _gtc->TcDeregisterClient(ClientHandle); - free(pInterfaceBuffer); - return result; - } - - // Create flow if one doesn't exist. - if (!_flow) - { - bool addPCP = ((pcp >= 0) || ((-1 == pcp) && (_pcp >= 0))); - int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) + - (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); - _flow = (PTC_GEN_FLOW)malloc(allocSize); - - _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; - _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED; - - _flow->ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; - _flow->ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED; - - QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; - dsClass->DSField = 0; - dsClass->ObjectHdr.ObjectType = QOS_OBJECT_DS_CLASS; - dsClass->ObjectHdr.ObjectLength = sizeof(QOS_DS_CLASS); - - if (addPCP) - { - QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1); - trafficClass->TrafficClass = 0; - trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS; - trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS); - } - - _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) + - (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); - } else if (-1 != pcp) { - // Reallocate memory since pcp has changed. - PTC_GEN_FLOW oldFlow = _flow; - bool addPCP = (pcp >= 0); - int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) + - (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); - _flow = (PTC_GEN_FLOW)malloc(allocSize); - - // Copy old flow. - _flow->ReceivingFlowspec = oldFlow->ReceivingFlowspec; - _flow->SendingFlowspec = oldFlow->SendingFlowspec; - // The DS info is always the first object. - QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; - QOS_DS_CLASS* oldDsClass = (QOS_DS_CLASS*)oldFlow->TcObjects; - dsClass->DSField = oldDsClass->DSField; - dsClass->ObjectHdr.ObjectType = oldDsClass->ObjectHdr.ObjectType; - dsClass->ObjectHdr.ObjectLength = oldDsClass->ObjectHdr.ObjectLength; - - if (addPCP) - { - QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1); - trafficClass->TrafficClass = 0; - trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS; - trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS); - } - - _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) + - (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0); - free(oldFlow); - } - - // Setup send and receive flow and DS object. - if (dscp >= 0) - { - if (!send || (0 == dscp)) - { - _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED; - _flow->SendingFlowspec.PeakBandwidth = - (0 == dscp ? QOS_NOT_SPECIFIED : POSITIVE_INFINITY_RATE); - _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT; - _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED; - // 128000 * 10 is 10mbit/s. - _flow->SendingFlowspec.TokenRate = - (0 == dscp ? QOS_NOT_SPECIFIED : 128000 * 10); - } - else - { - _flow->SendingFlowspec.DelayVariation = send->DelayVariation; - _flow->SendingFlowspec.Latency = send->Latency; - _flow->SendingFlowspec.MaxSduSize = send->MaxSduSize; - _flow->SendingFlowspec.MinimumPolicedSize = - send->MinimumPolicedSize; - _flow->SendingFlowspec.PeakBandwidth = send->PeakBandwidth; - _flow->SendingFlowspec.PeakBandwidth = POSITIVE_INFINITY_RATE; - _flow->SendingFlowspec.ServiceType = send->ServiceType; - _flow->SendingFlowspec.TokenBucketSize = send->TokenBucketSize; - _flow->SendingFlowspec.TokenRate = send->TokenRate; - } - - if (!recv || (0 == dscp)) - { - _flow->ReceivingFlowspec.DelayVariation = - _flow->SendingFlowspec.DelayVariation; - _flow->ReceivingFlowspec.Latency = _flow->SendingFlowspec.Latency; - _flow->ReceivingFlowspec.MaxSduSize = - _flow->SendingFlowspec.MaxSduSize; - _flow->ReceivingFlowspec.MinimumPolicedSize = - _flow->SendingFlowspec.MinimumPolicedSize; - _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED; - _flow->ReceivingFlowspec.ServiceType = - 0 == dscp ? SERVICETYPE_BESTEFFORT : SERVICETYPE_CONTROLLEDLOAD; - _flow->ReceivingFlowspec.TokenBucketSize = - _flow->SendingFlowspec.TokenBucketSize; - _flow->ReceivingFlowspec.TokenRate = - _flow->SendingFlowspec.TokenRate; - } else { - _flow->ReceivingFlowspec.DelayVariation = recv->DelayVariation; - _flow->ReceivingFlowspec.Latency = recv->Latency; - _flow->ReceivingFlowspec.MaxSduSize = recv->MaxSduSize; - _flow->ReceivingFlowspec.MinimumPolicedSize = - recv->MinimumPolicedSize; - _flow->ReceivingFlowspec.PeakBandwidth = recv->PeakBandwidth; - _flow->ReceivingFlowspec.ServiceType = recv->ServiceType; - _flow->ReceivingFlowspec.TokenBucketSize = recv->TokenBucketSize; - _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED; - } - - // Setup DS (for DSCP value). - // DS is always the first object. - QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; - dsClass->DSField = dscp; - } - - // Setup PCP (802.1p priority in 802.1Q/VLAN tagging) - if (pcp >= 0) - { - // DS is always first object. - QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects; - QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1); - trafficClass->TrafficClass = pcp; - } - - result = _gtc->TcAddFlow(ifcHandle, NULL, 0, _flow, &iflowHandle); - if(result != NO_ERROR) - { - _gtc->TcCloseInterface(ifcHandle); - _gtc->TcDeregisterClient(ClientHandle); - free(pInterfaceBuffer); - return -1; - } - - IP_PATTERN filterPattern, mask; - - ZeroMemory((int8_t*)&filterPattern, sizeof(IP_PATTERN)); - ZeroMemory((int8_t*)&mask, sizeof(IP_PATTERN)); - - filterPattern.ProtocolId = IPPROTO_UDP; - // "name" fields already in network order. - filterPattern.S_un.S_un_ports.s_srcport = name->sin_port; - filterPattern.SrcAddr = filterSourceAddress; - - // Unsigned max of a type corresponds to a bitmask with all bits set to 1. - // I.e. the filter should allow all ProtocolIds, any source port and any - // IP address - mask.ProtocolId = UCHAR_MAX; - mask.S_un.S_un_ports.s_srcport = USHRT_MAX; - mask.SrcAddr = ULONG_MAX; - - TC_GEN_FILTER filter; - - filter.AddressType = NDIS_PROTOCOL_ID_TCP_IP; - filter.Mask = (LPVOID)&mask; - filter.Pattern = (LPVOID)&filterPattern; - filter.PatternSize = sizeof(IP_PATTERN); - - result = _gtc->TcAddFilter(iflowHandle, &filter, &iFilterHandle); - if(result != NO_ERROR) - { - _gtc->TcDeleteFlow(iflowHandle); - _gtc->TcCloseInterface(ifcHandle); - _gtc->TcDeregisterClient(ClientHandle); - free(pInterfaceBuffer); - return result; - } - - _flowHandle = iflowHandle; - _filterHandle = iFilterHandle; - _clientHandle = ClientHandle; - if (-1 != pcp) - { - _pcp = pcp; - } - - _gtc->TcCloseInterface(ifcHandle); - free(pInterfaceBuffer); - - return 0; -} - -int32_t UdpSocket2Windows::CreateFlowSpec(int32_t serviceType, - int32_t tokenRate, - int32_t bucketSize, - int32_t peekBandwith, - int32_t minPolicedSize, - int32_t maxSduSize, - FLOWSPEC* f) -{ - if (!f) - { - return -1; - } - - f->ServiceType = serviceType; - f->TokenRate = tokenRate; - f->TokenBucketSize = QOS_NOT_SPECIFIED; - f->PeakBandwidth = QOS_NOT_SPECIFIED; - f->DelayVariation = QOS_NOT_SPECIFIED; - f->Latency = QOS_NOT_SPECIFIED; - f->MaxSduSize = QOS_NOT_SPECIFIED; - f->MinimumPolicedSize = QOS_NOT_SPECIFIED; - return 0; -} - -bool UdpSocket2Windows::NewOutstandingCall() -{ - assert(!_outstandingCallsDisabled); - - ++_outstandingCalls; - return true; -} - -void UdpSocket2Windows::OutstandingCallCompleted() -{ - _ptrDestRWLock->AcquireLockShared(); - ++_outstandingCallComplete; - if((--_outstandingCalls == 0) && _outstandingCallsDisabled) - { - // When there are no outstanding calls and new outstanding calls are - // disabled it is time to terminate. - _terminate = true; - } - _ptrDestRWLock->ReleaseLockShared(); - - if((--_outstandingCallComplete == 0) && - (_terminate)) - { - // Only one thread will enter here. The thread with the last outstanding - // call. - delete_event_.Set(); - } -} - -void UdpSocket2Windows::DisableNewOutstandingCalls() -{ - _ptrDestRWLock->AcquireLockExclusive(); - if(_outstandingCallsDisabled) - { - // Outstandning calls are already disabled. - _ptrDestRWLock->ReleaseLockExclusive(); - return; - } - _outstandingCallsDisabled = true; - const bool noOutstandingCalls = (_outstandingCalls.Value() == 0); - _ptrDestRWLock->ReleaseLockExclusive(); - - RemoveSocketFromManager(); - - if(noOutstandingCalls) - { - delete_event_.Set(); - } -} - -void UdpSocket2Windows::RemoveSocketFromManager() -{ - // New outstanding calls should be disabled at this point. - assert(_outstandingCallsDisabled); - - if(_addedToMgr) - { - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "calling UdpSocketManager::RemoveSocket()"); - if(_mgr->RemoveSocket(this)) - { - _addedToMgr=false; - } - } -} - -bool UdpSocket2Windows::AquireSocket() -{ - _ptrSocketRWLock->AcquireLockShared(); - const bool returnValue = _socket != INVALID_SOCKET; - if(!returnValue) - { - _ptrSocketRWLock->ReleaseLockShared(); - } - return returnValue; -} - -void UdpSocket2Windows::ReleaseSocket() -{ - _ptrSocketRWLock->ReleaseLockShared(); -} - -bool UdpSocket2Windows::InvalidateSocket() -{ - _ptrSocketRWLock->AcquireLockExclusive(); - if(_socket == INVALID_SOCKET) - { - _ptrSocketRWLock->ReleaseLockExclusive(); - return true; - } - // Give the socket back to the system. All socket calls will fail from now - // on. - if(closesocket(_socket) == SOCKET_ERROR) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::InvalidateSocket() WSAerror: %d", - (int32_t)this, WSAGetLastError()); - } - _socket = INVALID_SOCKET; - _ptrSocketRWLock->ReleaseLockExclusive(); - return true; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket2_win.h b/webrtc/voice_engine/test/channel_transport/udp_socket2_win.h deleted file mode 100644 index dd1aed80b8..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket2_win.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_WINDOWS_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_WINDOWS_H_ - -// Disable deprication warning from traffic.h -#pragma warning(disable : 4995) - -// Don't change include order for these header files. -#include -#include -#include - -#include "webrtc/base/event.h" -#include "webrtc/system_wrappers/include/atomic32.h" -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/system_wrappers/include/rw_lock_wrapper.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -namespace webrtc { -namespace test { - -class UdpSocket2ManagerWindows; -class TrafficControlWindows; -struct PerIoContext; - -class UdpSocket2Windows : public UdpSocketWrapper -{ -public: - UdpSocket2Windows(const int32_t id, UdpSocketManager* mgr, - bool ipV6Enable = false, bool disableGQOS = false); - virtual ~UdpSocket2Windows(); - - bool ValidHandle() override; - - bool SetCallback(CallbackObj, IncomingSocketCallback) override; - - bool Bind(const SocketAddress& name) override; - bool SetSockopt(int32_t level, - int32_t optname, - const int8_t* optval, - int32_t optlen) override; - - bool StartReceiving(const uint32_t receiveBuffers) override; - inline bool StartReceiving() override { return StartReceiving(8); } - bool StopReceiving() override; - - int32_t SendTo(const int8_t* buf, - size_t len, - const SocketAddress& to) override; - - void CloseBlocking() override; - - SOCKET GetFd() { return _socket;} - - bool SetQos(int32_t serviceType, - int32_t tokenRate, - int32_t bucketSize, - int32_t peekBandwith, - int32_t minPolicedSize, - int32_t maxSduSize, - const SocketAddress& stRemName, - int32_t overrideDSCP = 0) override; - - int32_t SetTOS(const int32_t serviceType) override; - int32_t SetPCP(const int32_t pcp) override; - - uint32_t ReceiveBuffers() override { return _receiveBuffers.Value(); } - -protected: - void IOCompleted(PerIoContext* pIOContext, uint32_t ioSize, uint32_t error); - - int32_t PostRecv(); - // Use pIoContext to post a new WSARecvFrom(..). - int32_t PostRecv(PerIoContext* pIoContext); - -private: - friend class UdpSocket2WorkerWindows; - - // Set traffic control (TC) flow adding it the interface that matches this - // sockets address. - // A filter is created and added to the flow. - // The flow consists of: - // (1) QoS send and receive information (flow specifications). - // (2) A DS object (for specifying exact DSCP value). - // (3) Possibly a traffic object (for specifying exact 802.1p priority (PCP) - // value). - // - // dscp values: - // -1 don't change the current dscp value. - // 0 don't add any flow to TC, unless pcp is specified. - // 1-63 Add a flow to TC with the specified dscp value. - // pcp values: - // -2 Don't add pcp info to the flow, (3) will not be added. - // -1 Don't change the current value. - // 0-7 Add pcp info to the flow with the specified value, - // (3) will be added. - // - // If both dscp and pcp are -1 no flow will be created or added to TC. - // If dscp is 0 and pcp is 0-7 (1), (2) and (3) will be created. - // Note: input parameter values are assumed to be in valid range, checks - // must be done by caller. - int32_t SetTrafficControl(int32_t dscp, int32_t pcp, - const struct sockaddr_in* name, - FLOWSPEC* send = NULL, - FLOWSPEC* recv = NULL); - int32_t CreateFlowSpec(int32_t serviceType, - int32_t tokenRate, - int32_t bucketSize, - int32_t peekBandwith, - int32_t minPolicedSize, - int32_t maxSduSize, FLOWSPEC *f); - - int32_t _id; - RWLockWrapper* _ptrCbRWLock; - IncomingSocketCallback _incomingCb; - CallbackObj _obj; - bool _qos; - - SocketAddress _remoteAddr; - SOCKET _socket; - int32_t _iProtocol; - UdpSocket2ManagerWindows* _mgr; - - Atomic32 _outstandingCalls; - Atomic32 _outstandingCallComplete; - volatile bool _terminate; - volatile bool _addedToMgr; - - rtc::Event delete_event_; - - RWLockWrapper* _ptrDestRWLock; - bool _outstandingCallsDisabled; - bool NewOutstandingCall(); - void OutstandingCallCompleted(); - void DisableNewOutstandingCalls(); - - void RemoveSocketFromManager(); - - // RWLockWrapper is used as a reference counter for the socket. Write lock - // is used for creating and deleting socket. Read lock is used for - // accessing the socket. - RWLockWrapper* _ptrSocketRWLock; - bool AquireSocket(); - void ReleaseSocket(); - bool InvalidateSocket(); - - // Traffic control handles and structure pointers. - HANDLE _clientHandle; - HANDLE _flowHandle; - HANDLE _filterHandle; - PTC_GEN_FLOW _flow; - // TrafficControlWindows implements TOS and PCP. - TrafficControlWindows* _gtc; - // Holds the current pcp value. Can be -2 or 0 - 7. - int _pcp; - - Atomic32 _receiveBuffers; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_WINDOWS_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.cc b/webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.cc deleted file mode 100644 index 6447e8bec1..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.cc +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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 "webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h" - -#include -#include -#include -#include -#include -#include - -#include "webrtc/system_wrappers/include/sleep.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_posix.h" - -namespace webrtc { -namespace test { - -UdpSocketManagerPosix::UdpSocketManagerPosix() - : UdpSocketManager(), - _id(-1), - _critSect(CriticalSectionWrapper::CreateCriticalSection()), - _numberOfSocketMgr(-1), - _incSocketMgrNextTime(0), - _nextSocketMgrToAssign(0), - _socketMgr() -{ -} - -bool UdpSocketManagerPosix::Init(int32_t id, uint8_t& numOfWorkThreads) { - CriticalSectionScoped cs(_critSect); - if ((_id != -1) || (_numOfWorkThreads != 0)) { - assert(_id != -1); - assert(_numOfWorkThreads != 0); - return false; - } - - _id = id; - _numberOfSocketMgr = numOfWorkThreads; - _numOfWorkThreads = numOfWorkThreads; - - if(MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX < _numberOfSocketMgr) - { - _numberOfSocketMgr = MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX; - } - for(int i = 0;i < _numberOfSocketMgr; i++) - { - _socketMgr[i] = new UdpSocketManagerPosixImpl(); - } - return true; -} - - -UdpSocketManagerPosix::~UdpSocketManagerPosix() -{ - Stop(); - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketManagerPosix(%d)::UdpSocketManagerPosix()", - _numberOfSocketMgr); - - for(int i = 0;i < _numberOfSocketMgr; i++) - { - delete _socketMgr[i]; - } - delete _critSect; -} - -bool UdpSocketManagerPosix::Start() -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketManagerPosix(%d)::Start()", - _numberOfSocketMgr); - - _critSect->Enter(); - bool retVal = true; - for(int i = 0;i < _numberOfSocketMgr && retVal; i++) - { - retVal = _socketMgr[i]->Start(); - } - if(!retVal) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocketManagerPosix(%d)::Start() error starting socket managers", - _numberOfSocketMgr); - } - _critSect->Leave(); - return retVal; -} - -bool UdpSocketManagerPosix::Stop() -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketManagerPosix(%d)::Stop()",_numberOfSocketMgr); - - _critSect->Enter(); - bool retVal = true; - for(int i = 0; i < _numberOfSocketMgr && retVal; i++) - { - retVal = _socketMgr[i]->Stop(); - } - if(!retVal) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocketManagerPosix(%d)::Stop() there are still active socket " - "managers", - _numberOfSocketMgr); - } - _critSect->Leave(); - return retVal; -} - -bool UdpSocketManagerPosix::AddSocket(UdpSocketWrapper* s) -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketManagerPosix(%d)::AddSocket()",_numberOfSocketMgr); - - _critSect->Enter(); - bool retVal = _socketMgr[_nextSocketMgrToAssign]->AddSocket(s); - if(!retVal) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocketManagerPosix(%d)::AddSocket() failed to add socket to\ - manager", - _numberOfSocketMgr); - } - - // Distribute sockets on UdpSocketManagerPosixImpls in a round-robin - // fashion. - if(_incSocketMgrNextTime == 0) - { - _incSocketMgrNextTime++; - } else { - _incSocketMgrNextTime = 0; - _nextSocketMgrToAssign++; - if(_nextSocketMgrToAssign >= _numberOfSocketMgr) - { - _nextSocketMgrToAssign = 0; - } - } - _critSect->Leave(); - return retVal; -} - -bool UdpSocketManagerPosix::RemoveSocket(UdpSocketWrapper* s) -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketManagerPosix(%d)::RemoveSocket()", - _numberOfSocketMgr); - - _critSect->Enter(); - bool retVal = false; - for(int i = 0;i < _numberOfSocketMgr && (retVal == false); i++) - { - retVal = _socketMgr[i]->RemoveSocket(s); - } - if(!retVal) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocketManagerPosix(%d)::RemoveSocket() failed to remove socket\ - from manager", - _numberOfSocketMgr); - } - _critSect->Leave(); - return retVal; -} - -UdpSocketManagerPosixImpl::UdpSocketManagerPosixImpl() - : _thread(UdpSocketManagerPosixImpl::Run, - this, - "UdpSocketManagerPosixImplThread"), - _critSectList(CriticalSectionWrapper::CreateCriticalSection()) { - FD_ZERO(&_readFds); - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocketManagerPosix created"); -} - -UdpSocketManagerPosixImpl::~UdpSocketManagerPosixImpl() -{ - if (_critSectList != NULL) - { - UpdateSocketMap(); - - _critSectList->Enter(); - for (std::map::iterator it = - _socketMap.begin(); - it != _socketMap.end(); - ++it) { - delete it->second; - } - _socketMap.clear(); - _critSectList->Leave(); - - delete _critSectList; - } - - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocketManagerPosix deleted"); -} - -bool UdpSocketManagerPosixImpl::Start() -{ - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Start UdpSocketManagerPosix"); - _thread.Start(); - _thread.SetPriority(rtc::kRealtimePriority); - return true; -} - -bool UdpSocketManagerPosixImpl::Stop() -{ - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Stop UdpSocketManagerPosix"); - _thread.Stop(); - return true; -} - -bool UdpSocketManagerPosixImpl::Process() -{ - bool doSelect = false; - // Timeout = 1 second. - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 10000; - - FD_ZERO(&_readFds); - - UpdateSocketMap(); - - SOCKET maxFd = 0; - for (std::map::iterator it = _socketMap.begin(); - it != _socketMap.end(); - ++it) { - doSelect = true; - if (it->first > maxFd) - maxFd = it->first; - FD_SET(it->first, &_readFds); - } - - int num = 0; - if (doSelect) - { - num = select(maxFd+1, &_readFds, NULL, NULL, &timeout); - - if (num == SOCKET_ERROR) - { - // Timeout = 10 ms. - SleepMs(10); - return true; - } - }else - { - // Timeout = 10 ms. - SleepMs(10); - return true; - } - - for (std::map::iterator it = _socketMap.begin(); - it != _socketMap.end(); - ++it) { - if (FD_ISSET(it->first, &_readFds)) { - it->second->HasIncoming(); - --num; - } - } - - return true; -} - -bool UdpSocketManagerPosixImpl::Run(void* obj) -{ - UdpSocketManagerPosixImpl* mgr = - static_cast(obj); - return mgr->Process(); -} - -bool UdpSocketManagerPosixImpl::AddSocket(UdpSocketWrapper* s) -{ - UdpSocketPosix* sl = static_cast(s); - if(sl->GetFd() == INVALID_SOCKET || !(sl->GetFd() < FD_SETSIZE)) - { - return false; - } - _critSectList->Enter(); - _addList.push_back(s); - _critSectList->Leave(); - return true; -} - -bool UdpSocketManagerPosixImpl::RemoveSocket(UdpSocketWrapper* s) -{ - // Put in remove list if this is the correct UdpSocketManagerPosixImpl. - _critSectList->Enter(); - - // If the socket is in the add list it's safe to remove and delete it. - for (SocketList::iterator iter = _addList.begin(); - iter != _addList.end(); ++iter) { - UdpSocketPosix* addSocket = static_cast(*iter); - unsigned int addFD = addSocket->GetFd(); - unsigned int removeFD = static_cast(s)->GetFd(); - if(removeFD == addFD) - { - _removeList.push_back(removeFD); - _critSectList->Leave(); - return true; - } - } - - // Checking the socket map is safe since all Erase and Insert calls to this - // map are also protected by _critSectList. - if (_socketMap.find(static_cast(s)->GetFd()) != - _socketMap.end()) { - _removeList.push_back(static_cast(s)->GetFd()); - _critSectList->Leave(); - return true; - } - _critSectList->Leave(); - return false; -} - -void UdpSocketManagerPosixImpl::UpdateSocketMap() -{ - // Remove items in remove list. - _critSectList->Enter(); - for (FdList::iterator iter = _removeList.begin(); - iter != _removeList.end(); ++iter) { - UdpSocketPosix* deleteSocket = NULL; - SOCKET removeFD = *iter; - - // If the socket is in the add list it hasn't been added to the socket - // map yet. Just remove the socket from the add list. - for (SocketList::iterator iter = _addList.begin(); - iter != _addList.end(); ++iter) { - UdpSocketPosix* addSocket = static_cast(*iter); - SOCKET addFD = addSocket->GetFd(); - if(removeFD == addFD) - { - deleteSocket = addSocket; - _addList.erase(iter); - break; - } - } - - // Find and remove socket from _socketMap. - std::map::iterator it = - _socketMap.find(removeFD); - if(it != _socketMap.end()) - { - deleteSocket = it->second; - _socketMap.erase(it); - } - if(deleteSocket) - { - deleteSocket->ReadyForDeletion(); - delete deleteSocket; - } - } - _removeList.clear(); - - // Add sockets from add list. - for (SocketList::iterator iter = _addList.begin(); - iter != _addList.end(); ++iter) { - UdpSocketPosix* s = static_cast(*iter); - if(s) { - _socketMap[s->GetFd()] = s; - } - } - _addList.clear(); - _critSectList->Leave(); -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h b/webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h deleted file mode 100644 index fe32cf0160..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_POSIX_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_POSIX_H_ - -#include -#include - -#include -#include - -#include "webrtc/base/platform_thread.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -namespace webrtc { -namespace test { - -class UdpSocketPosix; -class UdpSocketManagerPosixImpl; -#define MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX 8 - -class UdpSocketManagerPosix : public UdpSocketManager -{ -public: - UdpSocketManagerPosix(); - virtual ~UdpSocketManagerPosix(); - - bool Init(int32_t id, uint8_t& numOfWorkThreads) override; - - bool Start() override; - bool Stop() override; - - bool AddSocket(UdpSocketWrapper* s) override; - bool RemoveSocket(UdpSocketWrapper* s) override; - -private: - int32_t _id; - CriticalSectionWrapper* _critSect; - uint8_t _numberOfSocketMgr; - uint8_t _incSocketMgrNextTime; - uint8_t _nextSocketMgrToAssign; - UdpSocketManagerPosixImpl* _socketMgr[MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX]; -}; - -class UdpSocketManagerPosixImpl -{ -public: - UdpSocketManagerPosixImpl(); - virtual ~UdpSocketManagerPosixImpl(); - - virtual bool Start(); - virtual bool Stop(); - - virtual bool AddSocket(UdpSocketWrapper* s); - virtual bool RemoveSocket(UdpSocketWrapper* s); - -protected: - static bool Run(void* obj); - bool Process(); - void UpdateSocketMap(); - -private: - typedef std::list SocketList; - typedef std::list FdList; - rtc::PlatformThread _thread; - CriticalSectionWrapper* _critSectList; - - fd_set _readFds; - - std::map _socketMap; - SocketList _addList; - FdList _removeList; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_POSIX_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_unittest.cc b/webrtc/voice_engine/test/channel_transport/udp_socket_manager_unittest.cc deleted file mode 100644 index 178474a11c..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_unittest.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -// Tests for the UdpSocketManager interface. -// Note: This tests UdpSocketManager together with UdpSocketWrapper, -// due to the way the code is full of static-casts to the platform dependent -// subtypes. -// It also uses the static UdpSocketManager object. -// The most important property of these tests is that they do not leak memory. - -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/test/gtest.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -namespace webrtc { -namespace test { - -TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) { - int32_t id = 42; - uint8_t threads = 1; - UdpSocketManager* mgr = UdpSocketManager::Create(id, threads); - // Create is supposed to have called init on the object. - EXPECT_FALSE(mgr->Init(id, threads)) - << "Init should return false since Create is supposed to call it."; - UdpSocketManager::Return(); -} - -// Creates a socket and adds it to the socket manager, and then removes it -// before destroying the socket manager. -TEST(UdpSocketManager, AddAndRemoveSocketDoesNotLeakMemory) { - int32_t id = 42; - uint8_t threads = 1; - UdpSocketManager* mgr = UdpSocketManager::Create(id, threads); - UdpSocketWrapper* socket = - UdpSocketWrapper::CreateSocket(id, - mgr, - NULL, // CallbackObj - NULL, // IncomingSocketCallback - false, // ipV6Enable - false); // disableGQOS - // The constructor will do AddSocket on the manager. - // RemoveSocket indirectly calls Delete. - EXPECT_EQ(true, mgr->RemoveSocket(socket)); - UdpSocketManager::Return(); -} - -// Creates a socket and add it to the socket manager, but does not remove it -// before destroying the socket manager. -// On Posix, this destroys the socket. -// On Winsock2 Windows, it enters an infinite wait for all the sockets -// to go away. -TEST(UdpSocketManager, UnremovedSocketsGetCollectedAtManagerDeletion) { -#if defined(_WIN32) - // It's hard to test an infinite wait, so we don't. -#else - int32_t id = 42; - uint8_t threads = 1; - UdpSocketManager* mgr = UdpSocketManager::Create(id, threads); - UdpSocketWrapper* unused_socket = UdpSocketWrapper::CreateSocket( - id, - mgr, - NULL, // CallbackObj - NULL, // IncomingSocketCallback - false, // ipV6Enable - false); // disableGQOS - // The constructor will do AddSocket on the manager. - // Call a member funtion to work around "set but not used" compliation - // error on ChromeOS ARM. - unused_socket->SetEventToNull(); - unused_socket = NULL; - UdpSocketManager::Return(); -#endif -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.cc b/webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.cc deleted file mode 100644 index 4585c98e56..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" - -#include - -#ifdef _WIN32 -#include "webrtc/system_wrappers/include/fix_interlocked_exchange_pointer_win.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h" -#else -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h" -#endif - -namespace webrtc { -namespace test { - -UdpSocketManager* UdpSocketManager::CreateInstance() -{ -#if defined(_WIN32) - return static_cast(new UdpSocket2ManagerWindows()); -#else - return new UdpSocketManagerPosix(); -#endif -} - -UdpSocketManager* UdpSocketManager::StaticInstance( - CountOperation count_operation, - const int32_t id, - uint8_t& numOfWorkThreads) -{ - UdpSocketManager* impl = - GetStaticInstance(count_operation); - if (count_operation == kAddRef && impl != NULL) { - if (impl->Init(id, numOfWorkThreads)) { - impl->Start(); - } - } - return impl; -} - -UdpSocketManager* UdpSocketManager::Create(const int32_t id, - uint8_t& numOfWorkThreads) -{ - return UdpSocketManager::StaticInstance(kAddRef, id, numOfWorkThreads); -} - -void UdpSocketManager::Return() -{ - uint8_t numOfWorkThreads = 0; - UdpSocketManager::StaticInstance(kRelease, -1, - numOfWorkThreads); -} - -UdpSocketManager::UdpSocketManager() : _numOfWorkThreads(0) -{ -} - -uint8_t UdpSocketManager::WorkThreads() const -{ - return _numOfWorkThreads; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h b/webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h deleted file mode 100644 index 6484a72a83..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_WRAPPER_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_WRAPPER_H_ - -#include "webrtc/system_wrappers/include/static_instance.h" -#include "webrtc/typedefs.h" - -namespace webrtc { -namespace test { - -class UdpSocketWrapper; - -class UdpSocketManager -{ -public: - static UdpSocketManager* Create(const int32_t id, - uint8_t& numOfWorkThreads); - static void Return(); - - // Initializes the socket manager. Returns true if the manager wasn't - // already initialized. - virtual bool Init(int32_t id, uint8_t& numOfWorkThreads) = 0; - - // Start listening to sockets that have been registered via the - // AddSocket(..) API. - virtual bool Start() = 0; - // Stop listening to sockets. - virtual bool Stop() = 0; - - virtual uint8_t WorkThreads() const; - - // Register a socket with the socket manager. - virtual bool AddSocket(UdpSocketWrapper* s) = 0; - // Unregister a socket from the manager. - virtual bool RemoveSocket(UdpSocketWrapper* s) = 0; - -protected: - UdpSocketManager(); - virtual ~UdpSocketManager() {} - - uint8_t _numOfWorkThreads; - - // Factory method. - static UdpSocketManager* CreateInstance(); - -private: - // Friend function to allow the UDP destructor to be accessed from the - // instance template. - friend UdpSocketManager* webrtc::GetStaticInstance( - CountOperation count_operation); - - static UdpSocketManager* StaticInstance( - CountOperation count_operation, - const int32_t id, - uint8_t& numOfWorkThreads); -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_WRAPPER_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_posix.cc b/webrtc/voice_engine/test/channel_transport/udp_socket_posix.cc deleted file mode 100644 index e28396afe8..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_posix.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/voice_engine/test/channel_transport/udp_socket_posix.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -namespace webrtc { -namespace test { -UdpSocketPosix::UdpSocketPosix(const int32_t id, UdpSocketManager* mgr, - bool ipV6Enable) - : _id(id), - _closeBlockingCompletedCond(true, false), - _readyForDeletionCond(true, false) -{ - WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, - "UdpSocketPosix::UdpSocketPosix()"); - - _wantsIncoming = false; - _mgr = mgr; - - _obj = NULL; - _incomingCb = NULL; - _readyForDeletion = false; - _closeBlockingActive = false; - _closeBlockingCompleted = false; - if(ipV6Enable) - { - _socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); - } - else { - _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - } - - // Set socket to nonblocking mode. - int enable_non_blocking = 1; - if(ioctl(_socket, FIONBIO, &enable_non_blocking) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, id, - "Failed to make socket nonblocking"); - } - // Enable close on fork for file descriptor so that it will not block until - // forked process terminates. - if(fcntl(_socket, F_SETFD, FD_CLOEXEC) == -1) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, id, - "Failed to set FD_CLOEXEC for socket"); - } -} - -UdpSocketPosix::~UdpSocketPosix() -{ - if(_socket != INVALID_SOCKET) - { - close(_socket); - _socket = INVALID_SOCKET; - } -} - -bool UdpSocketPosix::SetCallback(CallbackObj obj, IncomingSocketCallback cb) -{ - _obj = obj; - _incomingCb = cb; - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketPosix(%p)::SetCallback", this); - - if (_mgr->AddSocket(this)) - { - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketPosix(%p)::SetCallback socket added to manager", - this); - return true; // socket is now ready for action - } - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocketPosix(%p)::SetCallback error adding me to mgr", - this); - return false; -} - -bool UdpSocketPosix::SetSockopt(int32_t level, int32_t optname, - const int8_t* optval, int32_t optlen) -{ - if(0 == setsockopt(_socket, level, optname, optval, optlen )) - { - return true; - } - - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocketPosix::SetSockopt(), error:%d", errno); - return false; -} - -int32_t UdpSocketPosix::SetTOS(int32_t serviceType) -{ - if (SetSockopt(IPPROTO_IP, IP_TOS ,(int8_t*)&serviceType ,4) != 0) - { - return -1; - } - return 0; -} - -bool UdpSocketPosix::Bind(const SocketAddress& name) -{ - int size = sizeof(sockaddr); - if (0 == bind(_socket, reinterpret_cast(&name),size)) - { - return true; - } - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocketPosix::Bind() error: %d", errno); - return false; -} - -int32_t UdpSocketPosix::SendTo(const int8_t* buf, size_t len, - const SocketAddress& to) -{ - int size = sizeof(sockaddr); - int retVal = sendto(_socket,buf, len, 0, - reinterpret_cast(&to), size); - if(retVal == SOCKET_ERROR) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocketPosix::SendTo() error: %d", errno); - } - - return retVal; -} - -SOCKET UdpSocketPosix::GetFd() { return _socket; } - -bool UdpSocketPosix::ValidHandle() -{ - return _socket != INVALID_SOCKET; -} - -bool UdpSocketPosix::SetQos(int32_t /*serviceType*/, - int32_t /*tokenRate*/, - int32_t /*bucketSize*/, - int32_t /*peekBandwith*/, - int32_t /*minPolicedSize*/, - int32_t /*maxSduSize*/, - const SocketAddress& /*stRemName*/, - int32_t /*overrideDSCP*/) { - return false; -} - -void UdpSocketPosix::HasIncoming() -{ - // replace 2048 with a mcro define and figure out - // where 2048 comes from - int8_t buf[2048]; - int retval; - SocketAddress from; -#if defined(WEBRTC_MAC) - sockaddr sockaddrfrom; - memset(&from, 0, sizeof(from)); - memset(&sockaddrfrom, 0, sizeof(sockaddrfrom)); - socklen_t fromlen = sizeof(sockaddrfrom); -#else - memset(&from, 0, sizeof(from)); - socklen_t fromlen = sizeof(from); -#endif - -#if defined(WEBRTC_MAC) - retval = recvfrom(_socket,buf, sizeof(buf), 0, - reinterpret_cast(&sockaddrfrom), &fromlen); - memcpy(&from, &sockaddrfrom, fromlen); - from._sockaddr_storage.sin_family = sockaddrfrom.sa_family; -#else - retval = recvfrom(_socket,buf, sizeof(buf), 0, - reinterpret_cast(&from), &fromlen); -#endif - - switch(retval) - { - case 0: - // The peer has performed an orderly shutdown. - break; - case SOCKET_ERROR: - break; - default: - if (_wantsIncoming && _incomingCb) - { - _incomingCb(_obj, buf, retval, &from); - } - break; - } -} - -bool UdpSocketPosix::WantsIncoming() { return _wantsIncoming; } - -void UdpSocketPosix::CloseBlocking() -{ - rtc::CritScope lock(&_cs); - _closeBlockingActive = true; - if(!CleanUp()) - { - _closeBlockingActive = false; - return; - } - - if(!_readyForDeletion) - { - _cs.Leave(); - _readyForDeletionCond.Wait(rtc::Event::kForever); - _cs.Enter(); - } - _closeBlockingCompleted = true; - _closeBlockingCompletedCond.Set(); -} - -void UdpSocketPosix::ReadyForDeletion() -{ - rtc::CritScope lock(&_cs); - if(!_closeBlockingActive) - { - return; - } - - close(_socket); - _socket = INVALID_SOCKET; - _readyForDeletion = true; - _readyForDeletionCond.Set(); - if(!_closeBlockingCompleted) - { - _cs.Leave(); - _closeBlockingCompletedCond.Wait(rtc::Event::kForever); - _cs.Enter(); - } -} - -bool UdpSocketPosix::CleanUp() -{ - _wantsIncoming = false; - - if (_socket == INVALID_SOCKET) - { - return false; - } - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "calling UdpSocketManager::RemoveSocket()..."); - _mgr->RemoveSocket(this); - // After this, the socket should may be or will be as deleted. Return - // immediately. - return true; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_posix.h b/webrtc/voice_engine/test/channel_transport/udp_socket_posix.h deleted file mode 100644 index 98301330c2..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_posix.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_POSIX_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_POSIX_H_ - -#include -#include -#include -#include - -#include "webrtc/base/event.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -namespace webrtc { -namespace test { - -#define SOCKET_ERROR -1 - -class UdpSocketPosix : public UdpSocketWrapper -{ -public: - UdpSocketPosix(const int32_t id, UdpSocketManager* mgr, - bool ipV6Enable = false); - - virtual ~UdpSocketPosix(); - - bool SetCallback(CallbackObj obj, IncomingSocketCallback cb) override; - - bool Bind(const SocketAddress& name) override; - - bool SetSockopt(int32_t level, - int32_t optname, - const int8_t* optval, - int32_t optlen) override; - - int32_t SetTOS(const int32_t serviceType) override; - - int32_t SendTo(const int8_t* buf, - size_t len, - const SocketAddress& to) override; - - // Deletes socket in addition to closing it. - // TODO (hellner): make destructor protected. - void CloseBlocking() override; - - SOCKET GetFd(); - - bool ValidHandle() override; - - bool SetQos(int32_t /*serviceType*/, - int32_t /*tokenRate*/, - int32_t /*bucketSize*/, - int32_t /*peekBandwith*/, - int32_t /*minPolicedSize*/, - int32_t /*maxSduSize*/, - const SocketAddress& /*stRemName*/, - int32_t /*overrideDSCP*/) override; - - bool CleanUp(); - void HasIncoming(); - bool WantsIncoming(); - void ReadyForDeletion(); -private: - friend class UdpSocketManagerPosix; - - const int32_t _id; - IncomingSocketCallback _incomingCb; - CallbackObj _obj; - - SOCKET _socket; - UdpSocketManager* _mgr; - rtc::Event _closeBlockingCompletedCond; - rtc::Event _readyForDeletionCond; - - bool _closeBlockingActive; - bool _closeBlockingCompleted; - bool _readyForDeletion; - - rtc::CriticalSection _cs; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_POSIX_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.cc b/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.cc deleted file mode 100644 index e02f0c5cb4..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.cc +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -#include -#include - -#include "webrtc/system_wrappers/include/event_wrapper.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" - -#if defined(_WIN32) - #include "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h" -#else - #include "webrtc/voice_engine/test/channel_transport/udp_socket_posix.h" -#endif - - -namespace webrtc { -namespace test { - -bool UdpSocketWrapper::_initiated = false; - -// Temporary Android hack. The value 1024 is taken from -// /build/platforms/android-1.5/arch-arm/usr/include/linux/posix_types.h -// TODO (tomasl): can we remove this now? -#ifndef FD_SETSIZE -#define FD_SETSIZE 1024 -#endif - -UdpSocketWrapper::UdpSocketWrapper() - : _wantsIncoming(false), - _deleteEvent(NULL) -{ -} - -UdpSocketWrapper::~UdpSocketWrapper() -{ - if(_deleteEvent) - { - _deleteEvent->Set(); - _deleteEvent = NULL; - } -} - -void UdpSocketWrapper::SetEventToNull() -{ - if (_deleteEvent) - { - _deleteEvent = NULL; - } -} - -UdpSocketWrapper* UdpSocketWrapper::CreateSocket(const int32_t id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable, - bool disableGQOS) - -{ - WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, - "UdpSocketWrapper::CreateSocket"); - - UdpSocketWrapper* s = 0; - -#ifdef _WIN32 - if (!_initiated) - { - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD( 2, 2 ); - int32_t err = WSAStartup( wVersionRequested, &wsaData); - if (err != 0) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - id, - "UdpSocketWrapper::CreateSocket failed to initialize sockets\ - WSAStartup error:%d", - err); - return NULL; - } - - _initiated = true; - } - - s = new UdpSocket2Windows(id, mgr, ipV6Enable, disableGQOS); - -#else - if (!_initiated) - { - _initiated = true; - } - s = new UdpSocketPosix(id, mgr, ipV6Enable); - if (s) - { - UdpSocketPosix* sl = static_cast(s); - if (sl->GetFd() != INVALID_SOCKET && sl->GetFd() < FD_SETSIZE) - { - // ok - } else - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - id, - "UdpSocketWrapper::CreateSocket failed to initialize socket"); - delete s; - s = NULL; - } - } -#endif - if (s) - { - s->_deleteEvent = NULL; - if (!s->SetCallback(obj, cb)) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - id, - "UdpSocketWrapper::CreateSocket failed to ser callback"); - return(NULL); - } - } - return s; -} - -bool UdpSocketWrapper::StartReceiving() -{ - _wantsIncoming = true; - return true; -} - -bool UdpSocketWrapper::StartReceiving(const uint32_t /*receiveBuffers*/) { - return StartReceiving(); -} - -bool UdpSocketWrapper::StopReceiving() -{ - _wantsIncoming = false; - return true; -} - -int32_t UdpSocketWrapper::SetPCP(const int32_t /*pcp*/) { return -1; } - -uint32_t UdpSocketWrapper::ReceiveBuffers() { return 0; } - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h b/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h deleted file mode 100644 index 57f391cb21..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_WRAPPER_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_WRAPPER_H_ - -#include "webrtc/voice_engine/test/channel_transport/udp_transport.h" - -namespace webrtc { - -class EventWrapper; - -namespace test { - -class UdpSocketManager; - -#define SOCKET_ERROR_NO_QOS -1000 - -#ifndef _WIN32 -typedef int SOCKET; -#endif - -#ifndef INVALID_SOCKET -#define INVALID_SOCKET (SOCKET)(~0) - -#ifndef AF_INET -#define AF_INET 2 -#endif - -#endif - -typedef void* CallbackObj; -typedef void(*IncomingSocketCallback)(CallbackObj obj, const int8_t* buf, - size_t len, const SocketAddress* from); - -class UdpSocketWrapper -{ -public: - static UdpSocketWrapper* CreateSocket(const int32_t id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable = false, - bool disableGQOS = false); - - // Register cb for receiving callbacks when there are incoming packets. - // Register obj so that it will be passed in calls to cb. - virtual bool SetCallback(CallbackObj obj, IncomingSocketCallback cb) = 0; - - // Socket to local address specified by name. - virtual bool Bind(const SocketAddress& name) = 0; - - // Start receiving UDP data. - virtual bool StartReceiving(); - virtual bool StartReceiving(const uint32_t /*receiveBuffers*/); - // Stop receiving UDP data. - virtual bool StopReceiving(); - - virtual bool ValidHandle() = 0; - - // Set socket options. - virtual bool SetSockopt(int32_t level, int32_t optname, - const int8_t* optval, int32_t optlen) = 0; - - // Set TOS for outgoing packets. - virtual int32_t SetTOS(const int32_t serviceType) = 0; - - // Set 802.1Q PCP field (802.1p) for outgoing VLAN traffic. - virtual int32_t SetPCP(const int32_t /*pcp*/); - - // Send buf of length len to the address specified by to. - virtual int32_t SendTo(const int8_t* buf, size_t len, - const SocketAddress& to) = 0; - - virtual void SetEventToNull(); - - // Close socket and don't return until completed. - virtual void CloseBlocking() {} - - // tokenRate is in bit/s. peakBandwidt is in byte/s - virtual bool SetQos(int32_t serviceType, int32_t tokenRate, - int32_t bucketSize, int32_t peekBandwith, - int32_t minPolicedSize, int32_t maxSduSize, - const SocketAddress &stRemName, - int32_t overrideDSCP = 0) = 0; - - virtual uint32_t ReceiveBuffers(); - -protected: - // Creating the socket is done via CreateSocket(). - UdpSocketWrapper(); - // Destroying the socket is done via CloseBlocking(). - virtual ~UdpSocketWrapper(); - - bool _wantsIncoming; - EventWrapper* _deleteEvent; - -private: - static bool _initiated; -}; - -} // namespac test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_WRAPPER_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper_unittest.cc b/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper_unittest.cc deleted file mode 100644 index befd61108d..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_socket_wrapper_unittest.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -// Tests for the UdpSocketWrapper interface. -// This will test the UdpSocket implementations on various platforms. -// Note that this test is using a real SocketManager, which starts up -// an extra worker thread, making the testing more complex than it -// should be. -// This is because on Posix, the CloseBlocking function waits for the -// ReadyForDeletion function to be called, which has to be called after -// CloseBlocking, and thus has to be called from another thread. -// The manager is the one actually doing the deleting. -// This is done differently in the Winsock2 code, but that code -// will also hang if the destructor is called directly. - -#include "webrtc/test/gmock.h" -#include "webrtc/test/gtest.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" - -using ::testing::_; -using ::testing::Return; - -namespace webrtc { -namespace test { - -class MockSocketManager : public UdpSocketManager { - public: - MockSocketManager() {} - // Access to protected destructor. - void Destroy() { - delete this; - } - MOCK_METHOD2(Init, bool(int32_t, uint8_t&)); - MOCK_METHOD0(Start, bool()); - MOCK_METHOD0(Stop, bool()); - MOCK_METHOD1(AddSocket, bool(UdpSocketWrapper*)); - MOCK_METHOD1(RemoveSocket, bool(UdpSocketWrapper*)); -}; - -// Creates a socket using the static constructor method and verifies that -// it's added to the socket manager. -TEST(UdpSocketWrapper, CreateSocket) { - int32_t id = 42; - // We can't test deletion of sockets without a socket manager. - uint8_t threads = 1; - UdpSocketManager* mgr = UdpSocketManager::Create(id, threads); - UdpSocketWrapper* socket = - UdpSocketWrapper::CreateSocket(id, - mgr, - NULL, // CallbackObj - NULL, // IncomingSocketCallback - false, // ipV6Enable - false); // disableGQOS - socket->CloseBlocking(); - UdpSocketManager::Return(); -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_transport.h b/webrtc/voice_engine/test/channel_transport/udp_transport.h deleted file mode 100644 index 4b9e67db85..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_transport.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ - -#include "webrtc/api/call/transport.h" -#include "webrtc/common_types.h" -#include "webrtc/typedefs.h" - -/* - * WARNING - * This code is not use in production/testing and might have security issues - * for example: http://code.google.com/p/webrtc/issues/detail?id=1028 - * - */ - -#define SS_MAXSIZE 128 -#define SS_ALIGNSIZE (sizeof (uint64_t)) -#define SS_PAD1SIZE (SS_ALIGNSIZE - sizeof(int16_t)) -#define SS_PAD2SIZE (SS_MAXSIZE - (sizeof(int16_t) + SS_PAD1SIZE +\ - SS_ALIGNSIZE)) - -// BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN -namespace webrtc { -namespace test { - -struct SocketAddressIn { - // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - int8_t sin_length; - int8_t sin_family; -#else - int16_t sin_family; -#endif - uint16_t sin_port; - uint32_t sin_addr; - int8_t sin_zero[8]; -}; - -struct Version6InAddress { - union { - uint8_t _s6_u8[16]; - uint32_t _s6_u32[4]; - uint64_t _s6_u64[2]; - } Version6AddressUnion; -}; - -struct SocketAddressInVersion6 { - // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - int8_t sin_length; - int8_t sin_family; -#else - int16_t sin_family; -#endif - // Transport layer port number. - uint16_t sin6_port; - // IPv6 traffic class and flow info or ip4 address. - uint32_t sin6_flowinfo; - // IPv6 address - struct Version6InAddress sin6_addr; - // Set of interfaces for a scope. - uint32_t sin6_scope_id; -}; - -struct SocketAddressStorage { - // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - int8_t sin_length; - int8_t sin_family; -#else - int16_t sin_family; -#endif - int8_t __ss_pad1[SS_PAD1SIZE]; - uint64_t __ss_align; - int8_t __ss_pad2[SS_PAD2SIZE]; -}; - -struct SocketAddress { - union { - struct SocketAddressIn _sockaddr_in; - struct SocketAddressInVersion6 _sockaddr_in6; - struct SocketAddressStorage _sockaddr_storage; - }; -}; - -// Callback class that receives packets from UdpTransport. -class UdpTransportData { - public: - virtual ~UdpTransportData() {}; - - virtual void IncomingRTPPacket(const int8_t* incomingRtpPacket, - const size_t rtpPacketLength, - const char* fromIP, - const uint16_t fromPort) = 0; - - virtual void IncomingRTCPPacket(const int8_t* incomingRtcpPacket, - const size_t rtcpPacketLength, - const char* fromIP, - const uint16_t fromPort) = 0; -}; - -class UdpTransport : public Transport { - public: - enum - { - kIpAddressVersion6Length = 64, - kIpAddressVersion4Length = 16 - }; - enum ErrorCode - { - kNoSocketError = 0, - kFailedToBindPort = 1, - kIpAddressInvalid = 2, - kAddressInvalid = 3, - kSocketInvalid = 4, - kPortInvalid = 5, - kTosInvalid = 6, - kMulticastAddressInvalid = 7, - kQosError = 8, - kSocketAlreadyInitialized = 9, - kIpVersion6Error = 10, - FILTER_ERROR = 11, - kStartReceiveError = 12, - kStopReceiveError = 13, - kCannotFindLocalIp = 14, - kTosError = 16, - kNotInitialized = 17, - kPcpError = 18 - }; - - // Factory method. Constructor disabled. - static UdpTransport* Create(const int32_t id, uint8_t& numSocketThreads); - static void Destroy(UdpTransport* module); - - // Prepares the class for sending RTP packets to ipAddr:rtpPort and RTCP - // packets to ipAddr:rtpPort+1 if rtcpPort is zero. Otherwise to - // ipAddr:rtcpPort. - virtual int32_t InitializeSendSockets(const char* ipAddr, - const uint16_t rtpPort, - const uint16_t rtcpPort = 0) = 0; - - // Register packetCallback for receiving incoming packets. Set the local - // RTP port to rtpPort. Bind local IP address to ipAddr. If ipAddr is NULL - // bind to local IP ANY. Set the local rtcp port to rtcpPort or rtpPort + 1 - // if rtcpPort is 0. - virtual int32_t InitializeReceiveSockets( - UdpTransportData* const packetCallback, - const uint16_t rtpPort, - const char* ipAddr = NULL, - const char* multicastIpAddr = NULL, - const uint16_t rtcpPort = 0) = 0; - - // Set local RTP port to rtpPort and RTCP port to rtcpPort or rtpPort + 1 if - // rtcpPort is 0. These ports will be used for sending instead of the local - // ports set by InitializeReceiveSockets(..). - virtual int32_t InitializeSourcePorts(const uint16_t rtpPort, - const uint16_t rtcpPort = 0) = 0; - - // Retrieve local ports used for sending if other than the ports specified - // by InitializeReceiveSockets(..). rtpPort is set to the RTP port. - // rtcpPort is set to the RTCP port. - virtual int32_t SourcePorts(uint16_t& rtpPort, - uint16_t& rtcpPort) const = 0; - - // Set ipAddr to the IP address that is currently being listened on. rtpPort - // to the RTP port listened to. rtcpPort to the RTCP port listened on. - // multicastIpAddr to the multicast IP address group joined (the address - // is NULL terminated). - virtual int32_t ReceiveSocketInformation( - char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort, - char multicastIpAddr[kIpAddressVersion6Length]) const = 0; - - // Set ipAddr to the IP address being sent from. rtpPort to the local RTP - // port used for sending and rtcpPort to the local RTCP port used for - // sending. - virtual int32_t SendSocketInformation(char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort) const = 0; - - // Put the IP address, RTP port and RTCP port from the last received packet - // into ipAddr, rtpPort and rtcpPort respectively. - virtual int32_t RemoteSocketInformation( - char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort) const = 0; - - // Enable/disable quality of service if QoS is true or false respectively. - // Set the type of service to serviceType, max bitrate in kbit/s to - // maxBitrate and override DSCP if overrideDSCP is not 0. - // Note: Must be called both InitializeSendSockets() and - // InitializeReceiveSockets() has been called. - virtual int32_t SetQoS(const bool QoS, - const int32_t serviceType, - const uint32_t maxBitrate = 0, - const int32_t overrideDSCP = 0, - const bool audio = false) = 0; - - // Set QoS to true if quality of service has been turned on. If QoS is true, - // also set serviceType to type of service and overrideDSCP to override - // DSCP. - virtual int32_t QoS(bool& QoS, - int32_t& serviceType, - int32_t& overrideDSCP) const = 0; - - // Set type of service. - virtual int32_t SetToS(const int32_t DSCP, - const bool useSetSockOpt = false) = 0; - - // Get type of service configuration. - virtual int32_t ToS(int32_t& DSCP, - bool& useSetSockOpt) const = 0; - - // Set Priority Code Point (IEEE 802.1Q) - // Note: for Linux this function will set the priority for the socket, - // which then can be mapped to a PCP value with vconfig. - virtual int32_t SetPCP(const int32_t PCP) = 0; - - // Get Priority Code Point - virtual int32_t PCP(int32_t& PCP) const = 0; - - // Enable IPv6. - // Note: this API must be called before any call to - // InitializeReceiveSockets() or InitializeSendSockets(). It is not - // possible to go back to IPv4 (default) after this call. - virtual int32_t EnableIpV6() = 0; - - // Return true if IPv6 has been enabled. - virtual bool IpV6Enabled() const = 0; - - // Only allow packets received from filterIPAddress to be processed. - // Note: must be called after EnableIPv6(), if IPv6 is used. - virtual int32_t SetFilterIP( - const char filterIPAddress[kIpAddressVersion6Length]) = 0; - - // Write the filter IP address (if any) to filterIPAddress. - virtual int32_t FilterIP( - char filterIPAddress[kIpAddressVersion6Length]) const = 0; - - // Only allow RTP packets from rtpFilterPort and RTCP packets from - // rtcpFilterPort be processed. - // Note: must be called after EnableIPv6(), if IPv6 is used. - virtual int32_t SetFilterPorts(const uint16_t rtpFilterPort, - const uint16_t rtcpFilterPort) = 0; - - // Set rtpFilterPort to the filter RTP port and rtcpFilterPort to the - // filter RTCP port (if filtering based on port is enabled). - virtual int32_t FilterPorts(uint16_t& rtpFilterPort, - uint16_t& rtcpFilterPort) const = 0; - - // Set the number of buffers that the socket implementation may use for - // receiving packets to numberOfSocketBuffers. I.e. the number of packets - // that can be received in parallell. - // Note: this API only has effect on Windows. - virtual int32_t StartReceiving(const uint32_t numberOfSocketBuffers) = 0; - - // Stop receive incoming packets. - virtual int32_t StopReceiving() = 0; - - // Return true incoming packets are received. - virtual bool Receiving() const = 0; - - // Return true if send sockets have been initialized. - virtual bool SendSocketsInitialized() const = 0; - - // Return true if local ports for sending has been set. - virtual bool SourcePortsInitialized() const = 0; - - // Return true if receive sockets have been initialized. - virtual bool ReceiveSocketsInitialized() const = 0; - - // Send data with size length to ip:portnr. The same port as the set - // with InitializeSendSockets(..) is used if portnr is 0. The same IP - // address as set with InitializeSendSockets(..) is used if ip is NULL. - // If isRTCP is true the port used will be the RTCP port. - virtual int32_t SendRaw(const int8_t* data, - size_t length, - int32_t isRTCP, - uint16_t portnr = 0, - const char* ip = NULL) = 0; - - // Send RTP data with size length to the address specified by to. - virtual int32_t SendRTPPacketTo(const int8_t* data, - size_t length, - const SocketAddress& to) = 0; - - - // Send RTCP data with size length to the address specified by to. - virtual int32_t SendRTCPPacketTo(const int8_t* data, - size_t length, - const SocketAddress& to) = 0; - - // Send RTP data with size length to ip:rtpPort where ip is the ip set by - // the InitializeSendSockets(..) call. - virtual int32_t SendRTPPacketTo(const int8_t* data, - size_t length, - uint16_t rtpPort) = 0; - - - // Send RTCP data with size length to ip:rtcpPort where ip is the ip set by - // the InitializeSendSockets(..) call. - virtual int32_t SendRTCPPacketTo(const int8_t* data, - size_t length, - uint16_t rtcpPort) = 0; - - // Set the IP address to which packets are sent to ipaddr. - virtual int32_t SetSendIP( - const char ipaddr[kIpAddressVersion6Length]) = 0; - - // Set the send RTP and RTCP port to rtpPort and rtcpPort respectively. - virtual int32_t SetSendPorts(const uint16_t rtpPort, - const uint16_t rtcpPort = 0) = 0; - - // Retreive the last registered error code. - virtual ErrorCode LastError() const = 0; - - // Put the local IPv4 address in localIP. - // Note: this API is for IPv4 only. - static int32_t LocalHostAddress(uint32_t& localIP); - - // Put the local IP6 address in localIP. - // Note: this API is for IPv6 only. - static int32_t LocalHostAddressIPV6(char localIP[16]); - - // Return a copy of hostOrder (host order) in network order. - static uint16_t Htons(uint16_t hostOrder); - - // Return a copy of hostOrder (host order) in network order. - static uint32_t Htonl(uint32_t hostOrder); - - // Return IPv4 address in ip as 32 bit integer. - static uint32_t InetAddrIPV4(const char* ip); - - // Convert the character string src into a network address structure in - // the af address family and put it in dst. - // Note: same functionality as inet_pton(..) - static int32_t InetPresentationToNumeric(int32_t af, - const char* src, - void* dst); - - // Set ip and sourcePort according to address. As input parameter ipSize - // is the length of ip. As output parameter it's the number of characters - // written to ip (not counting the '\0' character). - // Note: this API is only implemented on Windows and Linux. - static int32_t IPAddress(const SocketAddress& address, - char* ip, - uint32_t& ipSize, - uint16_t& sourcePort); - - // Set ip and sourcePort according to address. As input parameter ipSize - // is the length of ip. As output parameter it's the number of characters - // written to ip (not counting the '\0' character). - // Note: this API is only implemented on Windows and Linux. - // Additional note: this API caches the address of the last call to it. If - // address is likley to be the same for multiple calls it may be beneficial - // to call this API instead of IPAddress(). - virtual int32_t IPAddressCached(const SocketAddress& address, - char* ip, - uint32_t& ipSize, - uint16_t& sourcePort) = 0; - - // Return true if ipaddr is a valid IP address. - // If ipV6 is false ipaddr is interpreted as an IPv4 address otherwise it - // is interptreted as IPv6. - static bool IsIpAddressValid(const char* ipaddr, const bool ipV6); -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc b/webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc deleted file mode 100644 index c44cf9e172..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc +++ /dev/null @@ -1,3009 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/voice_engine/test/channel_transport/udp_transport_impl.h" - -#include -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef WEBRTC_IOS -#include -#endif -#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - -#if defined(WEBRTC_MAC) -#include -#include -#endif -#if defined(WEBRTC_LINUX) -#include -#include -#endif - -#include "webrtc/common_types.h" -#include "webrtc/system_wrappers/include/critical_section_wrapper.h" -#include "webrtc/system_wrappers/include/rw_lock_wrapper.h" -#include "webrtc/system_wrappers/include/trace.h" -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" -#include "webrtc/typedefs.h" - -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) -#define GetLastError() errno - -#define IFRSIZE ((int)(size * sizeof (struct ifreq))) - -#define NLMSG_OK_NO_WARNING(nlh,len) \ - ((len) >= (int)sizeof(struct nlmsghdr) && \ - (int)(nlh)->nlmsg_len >= (int)sizeof(struct nlmsghdr) && \ - (int)(nlh)->nlmsg_len <= (len)) - -#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - -namespace webrtc { -namespace test { - -class SocketFactory : public UdpTransportImpl::SocketFactoryInterface { - public: - UdpSocketWrapper* CreateSocket(const int32_t id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable, - bool disableGQOS) override { - return UdpSocketWrapper::CreateSocket(id, mgr, obj, cb, ipV6Enable, - disableGQOS); - } -}; - -// Creates an UdpTransport using the definition of SocketFactory above, -// and passes (creating if needed) a pointer to the static singleton -// UdpSocketManager. -UdpTransport* UdpTransport::Create(const int32_t id, - uint8_t& numSocketThreads) -{ - return new UdpTransportImpl(id, - new SocketFactory(), - UdpSocketManager::Create(id, numSocketThreads)); -} - -// Deletes the UdpTransport and decrements the refcount of the -// static singleton UdpSocketManager, possibly destroying it. -// Should only be used on UdpTransports that are created using Create. -void UdpTransport::Destroy(UdpTransport* module) -{ - if(module) - { - delete module; - UdpSocketManager::Return(); - } -} - -UdpTransportImpl::UdpTransportImpl(const int32_t id, - SocketFactoryInterface* maker, - UdpSocketManager* socket_manager) - : _id(id), - _socket_creator(maker), - _crit(CriticalSectionWrapper::CreateCriticalSection()), - _critFilter(CriticalSectionWrapper::CreateCriticalSection()), - _critPacketCallback(CriticalSectionWrapper::CreateCriticalSection()), - _mgr(socket_manager), - _lastError(kNoSocketError), - _destPort(0), - _destPortRTCP(0), - _localPort(0), - _localPortRTCP(0), - _srcPort(0), - _srcPortRTCP(0), - _fromPort(0), - _fromPortRTCP(0), - _fromIP(), - _destIP(), - _localIP(), - _localMulticastIP(), - _ptrRtpSocket(NULL), - _ptrRtcpSocket(NULL), - _ptrSendRtpSocket(NULL), - _ptrSendRtcpSocket(NULL), - _remoteRTPAddr(), - _remoteRTCPAddr(), - _localRTPAddr(), - _localRTCPAddr(), - _tos(0), - _receiving(false), - _useSetSockOpt(false), - _qos(false), - _pcp(0), - _ipV6Enabled(false), - _serviceType(0), - _overrideDSCP(0), - _maxBitrate(0), - _cachLock(RWLockWrapper::CreateRWLock()), - _previousAddress(), - _previousIP(), - _previousIPSize(0), - _previousSourcePort(0), - _filterIPAddress(), - _rtpFilterPort(0), - _rtcpFilterPort(0), - _packetCallback(0) -{ - memset(&_remoteRTPAddr, 0, sizeof(_remoteRTPAddr)); - memset(&_remoteRTCPAddr, 0, sizeof(_remoteRTCPAddr)); - memset(&_localRTPAddr, 0, sizeof(_localRTPAddr)); - memset(&_localRTCPAddr, 0, sizeof(_localRTCPAddr)); - - memset(_fromIP, 0, sizeof(_fromIP)); - memset(_destIP, 0, sizeof(_destIP)); - memset(_localIP, 0, sizeof(_localIP)); - memset(_localMulticastIP, 0, sizeof(_localMulticastIP)); - - memset(&_filterIPAddress, 0, sizeof(_filterIPAddress)); - - WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, "%s created", __FUNCTION__); -} - -UdpTransportImpl::~UdpTransportImpl() -{ - CloseSendSockets(); - CloseReceiveSockets(); - delete _crit; - delete _critFilter; - delete _critPacketCallback; - delete _cachLock; - delete _socket_creator; - - WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id, "%s deleted", - __FUNCTION__); -} - -UdpTransport::ErrorCode UdpTransportImpl::LastError() const -{ - return _lastError; -} - -bool SameAddress(const SocketAddress& address1, const SocketAddress& address2) -{ - return (memcmp(&address1,&address2,sizeof(address1)) == 0); -} - -void UdpTransportImpl::GetCachedAddress(char* ip, - uint32_t& ipSize, - uint16_t& sourcePort) -{ - const uint32_t originalIPSize = ipSize; - // If the incoming string is too small, fill it as much as there is room - // for. Make sure that there is room for the '\0' character. - ipSize = (ipSize - 1 < _previousIPSize) ? ipSize - 1 : _previousIPSize; - memcpy(ip,_previousIP,sizeof(int8_t)*(ipSize + 1)); - ip[originalIPSize - 1] = '\0'; - sourcePort = _previousSourcePort; -} - -int32_t UdpTransportImpl::IPAddressCached(const SocketAddress& address, - char* ip, - uint32_t& ipSize, - uint16_t& sourcePort) -{ - { - ReadLockScoped rl(*_cachLock); - // Check if the old address can be re-used (is the same). - if(SameAddress(address,_previousAddress)) - { - GetCachedAddress(ip,ipSize,sourcePort); - return 0; - } - } - // Get the new address and store it. - WriteLockScoped wl(*_cachLock); - ipSize = kIpAddressVersion6Length; - if(IPAddress(address,_previousIP,ipSize,_previousSourcePort) != 0) - { - return -1; - } - _previousIPSize = ipSize; - memcpy(&_previousAddress, &address, sizeof(address)); - // Address has been cached at this point. - GetCachedAddress(ip,ipSize,sourcePort); - return 0; -} - -int32_t UdpTransportImpl::InitializeReceiveSockets( - UdpTransportData* const packetCallback, - const uint16_t portnr, - const char* ip, - const char* multicastIpAddr, - const uint16_t rtcpPort) -{ - { - CriticalSectionScoped cs(_critPacketCallback); - _packetCallback = packetCallback; - - if(packetCallback == NULL) - { - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id, - "Closing down receive sockets"); - return 0; - } - } - - CriticalSectionScoped cs(_crit); - CloseReceiveSockets(); - - if(portnr == 0) - { - // TODO (hellner): why not just fail here? - if(_destPort == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeReceiveSockets port 0 not allowed"); - _lastError = kPortInvalid; - return -1; - } - _localPort = _destPort; - } else { - _localPort = portnr; - } - if(rtcpPort) - { - _localPortRTCP = rtcpPort; - }else { - _localPortRTCP = _localPort + 1; - WEBRTC_TRACE( - kTraceStateInfo, - kTraceTransport, - _id, - "InitializeReceiveSockets RTCP port not configured using RTP\ - port+1=%d", - _localPortRTCP); - } - - if(ip) - { - if(IsIpAddressValid(ip,IpV6Enabled())) - { - strncpy(_localIP, ip,kIpAddressVersion6Length); - } else - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeReceiveSockets invalid IP address"); - _lastError = kIpAddressInvalid; - return -1; - } - }else - { - // Don't bind to a specific IP address. - if(! IpV6Enabled()) - { - strncpy(_localIP, "0.0.0.0",16); - } else - { - strncpy(_localIP, "0000:0000:0000:0000:0000:0000:0000:0000", - kIpAddressVersion6Length); - } - } - if(multicastIpAddr && !IpV6Enabled()) - { - if(IsIpAddressValid(multicastIpAddr,IpV6Enabled())) - { - strncpy(_localMulticastIP, multicastIpAddr, - kIpAddressVersion6Length); - } else - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeReceiveSockets invalid IP address"); - _lastError = kIpAddressInvalid; - return -1; - } - } - if(_mgr == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeReceiveSockets no socket manager"); - return -1; - } - - _useSetSockOpt=false; - _tos=0; - _pcp=0; - - _ptrRtpSocket = _socket_creator->CreateSocket(_id, _mgr, this, - IncomingRTPCallback, - IpV6Enabled(), false); - - _ptrRtcpSocket = _socket_creator->CreateSocket(_id, _mgr, this, - IncomingRTCPCallback, - IpV6Enabled(), false); - - ErrorCode retVal = BindLocalRTPSocket(); - if(retVal != kNoSocketError) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeReceiveSockets faild to bind RTP socket"); - _lastError = retVal; - CloseReceiveSockets(); - return -1; - } - retVal = BindLocalRTCPSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeReceiveSockets faild to bind RTCP socket"); - CloseReceiveSockets(); - return -1; - } - return 0; -} - -int32_t UdpTransportImpl::ReceiveSocketInformation( - char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort, - char multicastIpAddr[kIpAddressVersion6Length]) const -{ - CriticalSectionScoped cs(_crit); - rtpPort = _localPort; - rtcpPort = _localPortRTCP; - if (ipAddr) - { - strncpy(ipAddr, _localIP, IpV6Enabled() ? - UdpTransport::kIpAddressVersion6Length : - UdpTransport::kIpAddressVersion4Length); - } - if (multicastIpAddr) - { - strncpy(multicastIpAddr, _localMulticastIP, IpV6Enabled() ? - UdpTransport::kIpAddressVersion6Length : - UdpTransport::kIpAddressVersion4Length); - } - return 0; -} - -int32_t UdpTransportImpl::SendSocketInformation( - char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort) const -{ - CriticalSectionScoped cs(_crit); - rtpPort = _destPort; - rtcpPort = _destPortRTCP; - strncpy(ipAddr, _destIP, IpV6Enabled() ? - UdpTransport::kIpAddressVersion6Length : - UdpTransport::kIpAddressVersion4Length); - return 0; -} - -int32_t UdpTransportImpl::RemoteSocketInformation( - char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort) const -{ - CriticalSectionScoped cs(_crit); - rtpPort = _fromPort; - rtcpPort = _fromPortRTCP; - if(ipAddr) - { - strncpy(ipAddr, _fromIP, IpV6Enabled() ? - kIpAddressVersion6Length : - kIpAddressVersion4Length); - } - return 0; -} - -int32_t UdpTransportImpl::FilterPorts( - uint16_t& rtpFilterPort, - uint16_t& rtcpFilterPort) const -{ - CriticalSectionScoped cs(_critFilter); - rtpFilterPort = _rtpFilterPort; - rtcpFilterPort = _rtcpFilterPort; - return 0; -} - -int32_t UdpTransportImpl::SetQoS(bool QoS, int32_t serviceType, - uint32_t maxBitrate, - int32_t overrideDSCP, bool audio) -{ - if(QoS) - { - return EnableQoS(serviceType, audio, maxBitrate, overrideDSCP); - }else - { - return DisableQoS(); - } -} - -int32_t UdpTransportImpl::EnableQoS(int32_t serviceType, - bool audio, uint32_t maxBitrate, - int32_t overrideDSCP) -{ - if (_ipV6Enabled) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is enabled but will be ignored since IPv6 is enabled"); - _lastError = kQosError; - return -1; - } - if (_tos) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "TOS already enabled, can't use TOS and QoS at the same time"); - _lastError = kQosError; - return -1; - } - if (_pcp) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "PCP already enabled, can't use PCP and QoS at the same time"); - _lastError = kQosError; - return -1; - } - if(_destPort == 0) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is enabled but not started since we have not yet configured\ - the send destination"); - return -1; - } - if(_qos) - { - if(_overrideDSCP == 0 && overrideDSCP != 0) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is already enabled and overrideDSCP differs, not allowed"); - return -1; - } - } - CriticalSectionScoped cs(_crit); - - UdpSocketWrapper* rtpSock = _ptrSendRtpSocket ? - _ptrSendRtpSocket : - _ptrRtpSocket; - if (!rtpSock || !rtpSock->ValidHandle()) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is enabled but not started since we have not yet created the\ - RTP socket"); - return -1; - } - UdpSocketWrapper* rtcpSock = _ptrSendRtcpSocket ? - _ptrSendRtcpSocket : - _ptrRtcpSocket; - if (!rtcpSock || !rtcpSock->ValidHandle()) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is enabled but not started since we have not yet created the\ - RTCP socket"); - return -1; - } - - // Minimum packet size in bytes for which the requested quality of service - // will be provided. The smallest RTP header is 12 byte. - const int32_t min_policed_size = 12; - // Max SDU, maximum packet size permitted or used in the traffic flow, in - // bytes. - const int32_t max_sdu_size = 1500; - - // Enable QoS for RTP sockets. - if(maxBitrate) - { - // Note: 1 kbit is 125 bytes. - // Token Rate is typically set to the average bit rate from peak to - // peak. - // Bucket size is normally set to the largest average frame size. - if(audio) - { - WEBRTC_TRACE(kTraceStateInfo, - kTraceTransport, - _id, - "Enable QOS for audio with max bitrate:%d", - maxBitrate); - - const int32_t token_rate = maxBitrate*125; - // The largest audio packets are 60ms frames. This is a fraction - // more than 16 packets/second. These 16 frames are sent, at max, - // at a bitrate of maxBitrate*125 -> 1 frame is maxBitrate*125/16 ~ - // maxBitrate * 8. - const int32_t bucket_size = maxBitrate * 8; - const int32_t peek_bandwith = maxBitrate * 125; - if (!rtpSock->SetQos(serviceType, token_rate, bucket_size, - peek_bandwith, min_policed_size, - max_sdu_size, _remoteRTPAddr, overrideDSCP)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "QOS failed on the RTP socket"); - _lastError = kQosError; - return -1; - } - }else - { - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id, - "Enable QOS for video with max bitrate:%d", - maxBitrate); - - // Allow for a token rate that is twice that of the maximum bitrate - // (in bytes). - const int32_t token_rate = maxBitrate*250; - // largest average frame size (key frame size). Assuming that a - // keyframe is 25% of the bitrate during the second its sent - // Assume that a key frame is 25% of the bitrate the second that it - // is sent. The largest frame size is then maxBitrate* 125 * 0.25 ~ - // 31. - const int32_t bucket_size = maxBitrate*31; - const int32_t peek_bandwith = maxBitrate*125; - if (!rtpSock->SetQos(serviceType, token_rate, bucket_size, - peek_bandwith, min_policed_size, max_sdu_size, - _remoteRTPAddr, overrideDSCP)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "QOS failed on the RTP socket"); - _lastError = kQosError; - return -1; - } - } - } else if(audio) - { - // No max bitrate set. Audio. - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id, - "Enable QOS for audio with default max bitrate"); - - // Let max bitrate be 240kbit/s. - const int32_t token_rate = 30000; - const int32_t bucket_size = 2000; - const int32_t peek_bandwith = 30000; - if (!rtpSock->SetQos(serviceType, token_rate, bucket_size, - peek_bandwith, min_policed_size, max_sdu_size, - _remoteRTPAddr, overrideDSCP)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "QOS failed on the RTP socket"); - _lastError = kQosError; - return -1; - } - }else - { - // No max bitrate set. Video. - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id, - "Enable QOS for video with default max bitrate"); - - // Let max bitrate be 10mbit/s. - const int32_t token_rate = 128000*10; - const int32_t bucket_size = 32000; - const int32_t peek_bandwith = 256000; - if (!rtpSock->SetQos(serviceType, token_rate, bucket_size, - peek_bandwith, min_policed_size, max_sdu_size, - _remoteRTPAddr, overrideDSCP)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "QOS failed on the RTP socket"); - _lastError = kQosError; - return -1; - } - } - - // Enable QoS for RTCP sockets. - // TODO (hellner): shouldn't RTCP be based on 5% of the maximum bandwidth? - if(audio) - { - const int32_t token_rate = 200; - const int32_t bucket_size = 200; - const int32_t peek_bandwith = 400; - if (!rtcpSock->SetQos(serviceType, token_rate, bucket_size, - peek_bandwith, min_policed_size, max_sdu_size, - _remoteRTCPAddr, overrideDSCP)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "QOS failed on the RTCP socket"); - _lastError = kQosError; - } - }else - { - const int32_t token_rate = 5000; - const int32_t bucket_size = 100; - const int32_t peek_bandwith = 10000; - if (!rtcpSock->SetQos(serviceType, token_rate, bucket_size, - peek_bandwith, min_policed_size, max_sdu_size, - _remoteRTCPAddr, _overrideDSCP)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "QOS failed on the RTCP socket"); - _lastError = kQosError; - } - } - _qos = true; - _serviceType = serviceType; - _maxBitrate = maxBitrate; - _overrideDSCP = overrideDSCP; - return 0; -} - -int32_t UdpTransportImpl::DisableQoS() -{ - if(_qos == false) - { - return 0; - } - CriticalSectionScoped cs(_crit); - - UdpSocketWrapper* rtpSock = (_ptrSendRtpSocket ? - _ptrSendRtpSocket : _ptrRtpSocket); - if (!rtpSock || !rtpSock->ValidHandle()) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is enabled but not started since we have not yet created the\ - RTP socket"); - return -1; - } - UdpSocketWrapper* rtcpSock = (_ptrSendRtcpSocket ? - _ptrSendRtcpSocket : _ptrRtcpSocket); - if (!rtcpSock || !rtcpSock->ValidHandle()) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "QOS is enabled but not started since we have not yet created the\ - RTCP socket"); - return -1; - } - - const int32_t service_type = 0; // = SERVICETYPE_NOTRAFFIC - const int32_t not_specified = -1; - if (!rtpSock->SetQos(service_type, not_specified, not_specified, - not_specified, not_specified, not_specified, - _remoteRTPAddr, _overrideDSCP)) - { - _lastError = kQosError; - return -1; - } - if (!rtcpSock->SetQos(service_type, not_specified, not_specified, - not_specified, not_specified, not_specified, - _remoteRTCPAddr,_overrideDSCP)) - { - _lastError = kQosError; - } - _qos = false; - return 0; -} - -int32_t UdpTransportImpl::QoS(bool& QoS, int32_t& serviceType, - int32_t& overrideDSCP) const -{ - CriticalSectionScoped cs(_crit); - QoS = _qos; - serviceType = _serviceType; - overrideDSCP = _overrideDSCP; - return 0; -} - -int32_t UdpTransportImpl::SetToS(int32_t DSCP, bool useSetSockOpt) -{ - if (_qos) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "QoS already enabled"); - _lastError = kQosError; - return -1; - } - if (DSCP < 0 || DSCP > 63) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "Invalid DSCP"); - _lastError = kTosInvalid; - return -1; - } - if(_tos) - { - if(useSetSockOpt != _useSetSockOpt) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "Can't switch SetSockOpt method without disabling TOS first"); - _lastError = kTosInvalid; - return -1; - } - } - CriticalSectionScoped cs(_crit); - UdpSocketWrapper* rtpSock = NULL; - UdpSocketWrapper* rtcpSock = NULL; - if(_ptrSendRtpSocket) - { - rtpSock = _ptrSendRtpSocket; - }else - { - rtpSock = _ptrRtpSocket; - } - if (rtpSock == NULL) - { - _lastError = kSocketInvalid; - return -1; - } - if(!rtpSock->ValidHandle()) - { - _lastError = kSocketInvalid; - return -1; - } - if(_ptrSendRtcpSocket) - { - rtcpSock = _ptrSendRtcpSocket; - }else - { - rtcpSock = _ptrRtcpSocket; - } - if (rtcpSock == NULL) - { - _lastError = kSocketInvalid; - return -1; - } - if(!rtcpSock->ValidHandle()) - { - _lastError = kSocketInvalid; - return -1; - } - - if (useSetSockOpt) - { -#ifdef _WIN32 - OSVERSIONINFO OsVersion; - OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&OsVersion); - // Disable QoS before setting ToS on Windows XP. This is done by closing - // and re-opening the sockets. - // TODO (hellner): why not just fail here and force the user to - // re-initialize sockets? Doing this may trick the user - // into thinking that the sockets are in a state which - // they aren't. - if (OsVersion.dwMajorVersion == 5 && - OsVersion.dwMinorVersion == 1) - { - if(!_useSetSockOpt) - { - if(_ptrSendRtpSocket) - { - CloseSendSockets(); - _ptrSendRtpSocket = - _socket_creator->CreateSocket(_id, _mgr, NULL, - NULL, IpV6Enabled(), - true); - _ptrSendRtcpSocket = - _socket_creator->CreateSocket(_id, _mgr, NULL, - NULL, IpV6Enabled(), - true); - rtpSock=_ptrSendRtpSocket; - rtcpSock=_ptrSendRtcpSocket; - ErrorCode retVal = BindRTPSendSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - return -1; - } - retVal = BindRTCPSendSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - return -1; - } - } - else - { - bool receiving=_receiving; - uint32_t noOfReceiveBuffers = 0; - if(receiving) - { - noOfReceiveBuffers=_ptrRtpSocket->ReceiveBuffers(); - if(StopReceiving()!=0) - { - return -1; - } - } - CloseReceiveSockets(); - _ptrRtpSocket = _socket_creator->CreateSocket( - _id, _mgr, this, IncomingRTPCallback, IpV6Enabled(), - true); - _ptrRtcpSocket = _socket_creator->CreateSocket( - _id, _mgr, this, IncomingRTCPCallback, IpV6Enabled(), - true); - rtpSock=_ptrRtpSocket; - rtcpSock=_ptrRtcpSocket; - ErrorCode retVal = BindLocalRTPSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - return -1; - } - retVal = BindLocalRTCPSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - return -1; - } - if(receiving) - { - if(StartReceiving(noOfReceiveBuffers) != - kNoSocketError) - { - return -1; - } - } - } - } - } -#endif // #ifdef _WIN32 - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "Setting TOS using SetSockopt"); - int32_t TOSShifted = DSCP << 2; - if (!rtpSock->SetSockopt(IPPROTO_IP, IP_TOS, - (int8_t*) &TOSShifted, 4)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not SetSockopt tos value on RTP socket"); - _lastError = kTosInvalid; - return -1; - } - if (!rtcpSock->SetSockopt(IPPROTO_IP, IP_TOS, - (int8_t*) &TOSShifted, 4)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not sSetSockopt tos value on RTCP socket"); - _lastError = kTosInvalid; - return -1; - } - } else - { - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "Setting TOS NOT using SetSockopt"); - if (rtpSock->SetTOS(DSCP) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not set tos value on RTP socket"); - _lastError = kTosError; - return -1; - } - if (rtcpSock->SetTOS(DSCP) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not set tos value on RTCP socket"); - _lastError = kTosError; - return -1; - } - } - _useSetSockOpt = useSetSockOpt; - _tos = DSCP; - return 0; -} - -int32_t UdpTransportImpl::ToS(int32_t& DSCP, - bool& useSetSockOpt) const -{ - CriticalSectionScoped cs(_crit); - DSCP = _tos; - useSetSockOpt = _useSetSockOpt; - return 0; -} - -int32_t UdpTransportImpl::SetPCP(int32_t PCP) -{ - - if (_qos) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "QoS already enabled"); - _lastError = kQosError; - return -1; - } - if ((PCP < 0) || (PCP > 7)) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "Invalid PCP"); - _lastError = kPcpError; - return -1; - } - - CriticalSectionScoped cs(_crit); - UdpSocketWrapper* rtpSock = NULL; - UdpSocketWrapper* rtcpSock = NULL; - if(_ptrSendRtpSocket) - { - rtpSock = _ptrSendRtpSocket; - }else - { - rtpSock = _ptrRtpSocket; - } - if (rtpSock == NULL) - { - _lastError = kSocketInvalid; - return -1; - } - if(!rtpSock->ValidHandle()) - { - _lastError = kSocketInvalid; - return -1; - } - if(_ptrSendRtcpSocket) - { - rtcpSock = _ptrSendRtcpSocket; - }else - { - rtcpSock = _ptrRtcpSocket; - } - if (rtcpSock == NULL) - { - _lastError = kSocketInvalid; - return -1; - } - if(!rtcpSock->ValidHandle()) - { - _lastError = kSocketInvalid; - return -1; - } - -#if defined(_WIN32) - if (rtpSock->SetPCP(PCP) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not set PCP value on RTP socket"); - _lastError = kPcpError; - return -1; - } - if (rtcpSock->SetPCP(PCP) != 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not set PCP value on RTCP socket"); - _lastError = kPcpError; - return -1; - } - -#elif defined(WEBRTC_LINUX) - if (!rtpSock->SetSockopt(SOL_SOCKET, SO_PRIORITY, (int8_t*) &PCP, - sizeof(PCP))) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not SetSockopt PCP value on RTP socket"); - _lastError = kPcpError; - return -1; - } - if (!rtcpSock->SetSockopt(SOL_SOCKET, SO_PRIORITY, (int8_t*) &PCP, - sizeof(PCP))) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Could not SetSockopt PCP value on RTCP socket"); - _lastError = kPcpError; - return -1; - } -#else - // Not supported on other platforms (WEBRTC_MAC) - _lastError = kPcpError; - return -1; -#endif - _pcp = PCP; - return 0; -} - -int32_t UdpTransportImpl::PCP(int32_t& PCP) const -{ - CriticalSectionScoped cs(_crit); - PCP = _pcp; - return 0; -} - -bool UdpTransportImpl::SetSockOptUsed() -{ - return _useSetSockOpt; -} - -int32_t UdpTransportImpl::EnableIpV6() { - - CriticalSectionScoped cs(_crit); - const bool initialized = (_ptrSendRtpSocket || _ptrRtpSocket); - - if (_ipV6Enabled) { - return 0; - } - if (initialized) { - _lastError = kIpVersion6Error; - return -1; - } - _ipV6Enabled = true; - return 0; -} - -int32_t UdpTransportImpl::FilterIP( - char filterIPAddress[kIpAddressVersion6Length]) const -{ - - if(filterIPAddress == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "FilterIP: Invalid argument"); - return -1; - } - if(_filterIPAddress._sockaddr_storage.sin_family == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "No Filter configured"); - return -1; - } - CriticalSectionScoped cs(_critFilter); - uint32_t ipSize = kIpAddressVersion6Length; - uint16_t sourcePort; - return IPAddress(_filterIPAddress, filterIPAddress, ipSize, sourcePort); -} - -int32_t UdpTransportImpl::SetFilterIP( - const char filterIPAddress[kIpAddressVersion6Length]) -{ - if(filterIPAddress == NULL) - { - memset(&_filterIPAddress, 0, sizeof(_filterIPAddress)); - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, "Filter IP reset"); - return 0; - } - CriticalSectionScoped cs(_critFilter); - if (_ipV6Enabled) - { - _filterIPAddress._sockaddr_storage.sin_family = AF_INET6; - - if (InetPresentationToNumeric( - AF_INET6, - filterIPAddress, - &_filterIPAddress._sockaddr_in6.sin6_addr) < 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "Failed to set\ - filter IP for IPv6"); - _lastError = FILTER_ERROR; - return -1; - } - } - else - { - _filterIPAddress._sockaddr_storage.sin_family = AF_INET; - - if(InetPresentationToNumeric( - AF_INET, - filterIPAddress, - &_filterIPAddress._sockaddr_in.sin_addr) < 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Failed to set filter IP for IPv4"); - _lastError = FILTER_ERROR; - return -1; - } - } - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, "Filter IP set"); - return 0; -} - -int32_t UdpTransportImpl::SetFilterPorts(uint16_t rtpFilterPort, - uint16_t rtcpFilterPort) -{ - CriticalSectionScoped cs(_critFilter); - _rtpFilterPort = rtpFilterPort; - _rtcpFilterPort = rtcpFilterPort; - return 0; -} - -bool UdpTransportImpl::SendSocketsInitialized() const -{ - CriticalSectionScoped cs(_crit); - if(_ptrSendRtpSocket) - { - return true; - } - if(_destPort !=0) - { - return true; - } - return false; -} - -bool UdpTransportImpl::ReceiveSocketsInitialized() const -{ - if(_ptrRtpSocket) - { - return true; - } - return false; -} - -bool UdpTransportImpl::SourcePortsInitialized() const -{ - if(_ptrSendRtpSocket) - { - return true; - } - return false; -} - -bool UdpTransportImpl::IpV6Enabled() const -{ - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, "%s", __FUNCTION__); - return _ipV6Enabled; -} - -void UdpTransportImpl::BuildRemoteRTPAddr() -{ - if(_ipV6Enabled) - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _remoteRTPAddr.sin_length = 0; - _remoteRTPAddr.sin_family = PF_INET6; -#else - _remoteRTPAddr._sockaddr_storage.sin_family = PF_INET6; -#endif - - _remoteRTPAddr._sockaddr_in6.sin6_flowinfo=0; - _remoteRTPAddr._sockaddr_in6.sin6_scope_id=0; - _remoteRTPAddr._sockaddr_in6.sin6_port = Htons(_destPort); - InetPresentationToNumeric(AF_INET6,_destIP, - &_remoteRTPAddr._sockaddr_in6.sin6_addr); - } else - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _remoteRTPAddr.sin_length = 0; - _remoteRTPAddr.sin_family = PF_INET; -#else - _remoteRTPAddr._sockaddr_storage.sin_family = PF_INET; -#endif - _remoteRTPAddr._sockaddr_in.sin_port = Htons(_destPort); - _remoteRTPAddr._sockaddr_in.sin_addr = InetAddrIPV4(_destIP); - } -} - -void UdpTransportImpl::BuildRemoteRTCPAddr() -{ - if(_ipV6Enabled) - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _remoteRTCPAddr.sin_length = 0; - _remoteRTCPAddr.sin_family = PF_INET6; -#else - _remoteRTCPAddr._sockaddr_storage.sin_family = PF_INET6; -#endif - - _remoteRTCPAddr._sockaddr_in6.sin6_flowinfo=0; - _remoteRTCPAddr._sockaddr_in6.sin6_scope_id=0; - _remoteRTCPAddr._sockaddr_in6.sin6_port = Htons(_destPortRTCP); - InetPresentationToNumeric(AF_INET6,_destIP, - &_remoteRTCPAddr._sockaddr_in6.sin6_addr); - - } else - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _remoteRTCPAddr.sin_length = 0; - _remoteRTCPAddr.sin_family = PF_INET; -#else - _remoteRTCPAddr._sockaddr_storage.sin_family = PF_INET; -#endif - _remoteRTCPAddr._sockaddr_in.sin_port = Htons(_destPortRTCP); - _remoteRTCPAddr._sockaddr_in.sin_addr= InetAddrIPV4(_destIP); - } -} - -UdpTransportImpl::ErrorCode UdpTransportImpl::BindRTPSendSocket() -{ - if(!_ptrSendRtpSocket) - { - return kSocketInvalid; - } - if(!_ptrSendRtpSocket->ValidHandle()) - { - return kIpAddressInvalid; - } - if(_ipV6Enabled) - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _localRTPAddr.sin_length = 0; - _localRTPAddr.sin_family = PF_INET6; -#else - _localRTPAddr._sockaddr_storage.sin_family = PF_INET6; -#endif - _localRTPAddr._sockaddr_in6.sin6_flowinfo=0; - _localRTPAddr._sockaddr_in6.sin6_scope_id=0; - _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[0] = - 0; // = INADDR_ANY - _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[1] = - 0; - _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[2] = - 0; - _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[3] = - 0; - _localRTPAddr._sockaddr_in6.sin6_port = Htons(_srcPort); - if(_ptrSendRtpSocket->Bind(_localRTPAddr) == false) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _srcPort); - return kFailedToBindPort; - } - - } else { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _localRTPAddr.sin_length = 0; - _localRTPAddr.sin_family = PF_INET; -#else - _localRTPAddr._sockaddr_storage.sin_family = PF_INET; -#endif - _localRTPAddr._sockaddr_in.sin_addr = 0; - _localRTPAddr._sockaddr_in.sin_port = Htons(_srcPort); - if(_ptrSendRtpSocket->Bind(_localRTPAddr) == false) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _srcPort); - return kFailedToBindPort; - } - } - return kNoSocketError; -} - -UdpTransportImpl::ErrorCode UdpTransportImpl::BindRTCPSendSocket() -{ - if(!_ptrSendRtcpSocket) - { - return kSocketInvalid; - } - - if(_ipV6Enabled) - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _localRTCPAddr.sin_length = 0; - _localRTCPAddr.sin_family = PF_INET6; -#else - _localRTCPAddr._sockaddr_storage.sin_family = PF_INET6; -#endif - _localRTCPAddr._sockaddr_in6.sin6_flowinfo=0; - _localRTCPAddr._sockaddr_in6.sin6_scope_id=0; - _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[0] = - 0; // = INADDR_ANY - _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[1] = - 0; - _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[2] = - 0; - _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[3] = - 0; - _localRTCPAddr._sockaddr_in6.sin6_port = Htons(_srcPortRTCP); - if(_ptrSendRtcpSocket->Bind(_localRTCPAddr) == false) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _srcPortRTCP); - return kFailedToBindPort; - } - } else { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - _localRTCPAddr.sin_length = 0; - _localRTCPAddr.sin_family = PF_INET; -#else - _localRTCPAddr._sockaddr_storage.sin_family = PF_INET; -#endif - _localRTCPAddr._sockaddr_in.sin_addr= 0; - _localRTCPAddr._sockaddr_in.sin_port = Htons(_srcPortRTCP); - if(_ptrSendRtcpSocket->Bind(_localRTCPAddr) == false) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _srcPortRTCP); - return kFailedToBindPort; - } - } - return kNoSocketError; -} - -UdpTransportImpl::ErrorCode UdpTransportImpl::BindLocalRTPSocket() -{ - if(!_ptrRtpSocket) - { - return kSocketInvalid; - } - if(!IpV6Enabled()) - { - SocketAddress recAddr; - memset(&recAddr, 0, sizeof(SocketAddress)); - recAddr._sockaddr_storage.sin_family = AF_INET; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - recAddr.sin_length = 0; - recAddr.sin_family = PF_INET; -#else - recAddr._sockaddr_storage.sin_family = PF_INET; -#endif - recAddr._sockaddr_in.sin_addr = InetAddrIPV4(_localIP); - recAddr._sockaddr_in.sin_port = Htons(_localPort); - - if (!_ptrRtpSocket->Bind(recAddr)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _localPort); - return kFailedToBindPort; - } - } - else - { - SocketAddress stLclName; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - stLclName.sin_lenght = 0; - stLclName.sin_family = PF_INET6; -#else - stLclName._sockaddr_storage.sin_family = PF_INET6; -#endif - InetPresentationToNumeric(AF_INET6,_localIP, - &stLclName._sockaddr_in6.sin6_addr); - stLclName._sockaddr_in6.sin6_port = Htons(_localPort); - stLclName._sockaddr_in6.sin6_flowinfo = 0; - stLclName._sockaddr_in6.sin6_scope_id = 0; - - if (!_ptrRtpSocket->Bind(stLclName)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _localPort); - return kFailedToBindPort; - } - } - - if(_localMulticastIP[0] != 0) - { - // Join the multicast group from which to receive datagrams. - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = InetAddrIPV4(_localMulticastIP); - mreq.imr_interface.s_addr = INADDR_ANY; - - if (!_ptrRtpSocket->SetSockopt(IPPROTO_IP,IP_ADD_MEMBERSHIP, - (int8_t*)&mreq,sizeof (mreq))) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "setsockopt() for multicast failed, not closing socket"); - }else - { - WEBRTC_TRACE(kTraceInfo, kTraceTransport, _id, - "multicast group successfully joined"); - } - } - return kNoSocketError; -} - -UdpTransportImpl::ErrorCode UdpTransportImpl::BindLocalRTCPSocket() -{ - if(!_ptrRtcpSocket) - { - return kSocketInvalid; - } - if(! IpV6Enabled()) - { - SocketAddress recAddr; - memset(&recAddr, 0, sizeof(SocketAddress)); -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - recAddr.sin_length = 0; - recAddr.sin_family = AF_INET; -#else - recAddr._sockaddr_storage.sin_family = AF_INET; -#endif - recAddr._sockaddr_in.sin_addr = InetAddrIPV4(_localIP); - recAddr._sockaddr_in.sin_port = Htons(_localPortRTCP); - - if (!_ptrRtcpSocket->Bind(recAddr)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _localPortRTCP); - return kFailedToBindPort; - } - } - else - { - SocketAddress stLclName; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - stLclName.sin_length = 0; - stLclName.sin_family = PF_INET6; -#else - stLclName._sockaddr_storage.sin_family = PF_INET6; -#endif - stLclName._sockaddr_in6.sin6_flowinfo = 0; - stLclName._sockaddr_in6.sin6_scope_id = 0; - stLclName._sockaddr_in6.sin6_port = Htons(_localPortRTCP); - - InetPresentationToNumeric(AF_INET6,_localIP, - &stLclName._sockaddr_in6.sin6_addr); - if (!_ptrRtcpSocket->Bind(stLclName)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id, - "Failed to bind to port:%d ", _localPortRTCP); - return kFailedToBindPort; - } - } - if(_localMulticastIP[0] != 0) - { - // Join the multicast group from which to receive datagrams. - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = InetAddrIPV4(_localMulticastIP); - mreq.imr_interface.s_addr = INADDR_ANY; - - if (!_ptrRtcpSocket->SetSockopt(IPPROTO_IP,IP_ADD_MEMBERSHIP, - (int8_t*)&mreq,sizeof (mreq))) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "setsockopt() for multicast failed, not closing socket"); - }else - { - WEBRTC_TRACE(kTraceInfo, kTraceTransport, _id, - "multicast group successfully joined"); - } - } - return kNoSocketError; -} - -int32_t UdpTransportImpl::InitializeSourcePorts(uint16_t rtpPort, - uint16_t rtcpPort) -{ - - if(rtpPort == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "InitializeSourcePorts port 0 not allowed"); - _lastError = kPortInvalid; - return -1; - } - - CriticalSectionScoped cs(_crit); - - CloseSendSockets(); - - if(_mgr == NULL) - { - return -1; - } - - _srcPort = rtpPort; - if(rtcpPort == 0) - { - _srcPortRTCP = rtpPort+1; - } else - { - _srcPortRTCP = rtcpPort; - } - _useSetSockOpt =false; - _tos=0; - _pcp=0; - - _ptrSendRtpSocket = _socket_creator->CreateSocket(_id, _mgr, NULL, NULL, - IpV6Enabled(), false); - _ptrSendRtcpSocket = _socket_creator->CreateSocket(_id, _mgr, NULL, NULL, - IpV6Enabled(), false); - - ErrorCode retVal = BindRTPSendSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - return -1; - } - retVal = BindRTCPSendSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - return -1; - } - return 0; -} - -int32_t UdpTransportImpl::SourcePorts(uint16_t& rtpPort, - uint16_t& rtcpPort) const -{ - CriticalSectionScoped cs(_crit); - - rtpPort = (_srcPort != 0) ? _srcPort : _localPort; - rtcpPort = (_srcPortRTCP != 0) ? _srcPortRTCP : _localPortRTCP; - return 0; -} - - -#ifdef _WIN32 -int32_t UdpTransportImpl::StartReceiving(uint32_t numberOfSocketBuffers) -#else -int32_t UdpTransportImpl::StartReceiving(uint32_t /*numberOfSocketBuffers*/) -#endif -{ - CriticalSectionScoped cs(_crit); - if(_receiving) - { - return 0; - } - if(_ptrRtpSocket) - { -#ifdef _WIN32 - if(!_ptrRtpSocket->StartReceiving(numberOfSocketBuffers)) -#else - if(!_ptrRtpSocket->StartReceiving()) -#endif - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Failed to start receive on RTP socket"); - _lastError = kStartReceiveError; - return -1; - } - } - if(_ptrRtcpSocket) - { - if(!_ptrRtcpSocket->StartReceiving()) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Failed to start receive on RTCP socket"); - _lastError = kStartReceiveError; - return -1; - } - } - if( _ptrRtpSocket == NULL && - _ptrRtcpSocket == NULL) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Failed to StartReceiving, no socket initialized"); - _lastError = kStartReceiveError; - return -1; - } - _receiving = true; - return 0; -} - -bool UdpTransportImpl::Receiving() const -{ - return _receiving; -} - -int32_t UdpTransportImpl::StopReceiving() -{ - - CriticalSectionScoped cs(_crit); - - _receiving = false; - - if (_ptrRtpSocket) - { - if (!_ptrRtpSocket->StopReceiving()) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Failed to stop receiving on RTP socket"); - _lastError = kStopReceiveError; - return -1; - } - } - if (_ptrRtcpSocket) - { - if (!_ptrRtcpSocket->StopReceiving()) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "Failed to stop receiving on RTCP socket"); - _lastError = kStopReceiveError; - return -1; - } - } - return 0; -} - -int32_t UdpTransportImpl::InitializeSendSockets( - const char* ipaddr, - const uint16_t rtpPort, - const uint16_t rtcpPort) -{ - { - CriticalSectionScoped cs(_crit); - _destPort = rtpPort; - if(rtcpPort == 0) - { - _destPortRTCP = _destPort+1; - } else - { - _destPortRTCP = rtcpPort; - } - - if(ipaddr == NULL) - { - if (!IsIpAddressValid(_destIP, IpV6Enabled())) - { - _destPort = 0; - _destPortRTCP = 0; - _lastError = kIpAddressInvalid; - return -1; - } - } else - { - if (IsIpAddressValid(ipaddr, IpV6Enabled())) - { - strncpy( - _destIP, - ipaddr, - IpV6Enabled() ? kIpAddressVersion6Length : - kIpAddressVersion4Length); - } else { - _destPort = 0; - _destPortRTCP = 0; - _lastError = kIpAddressInvalid; - return -1; - } - } - BuildRemoteRTPAddr(); - BuildRemoteRTCPAddr(); - } - - if (_ipV6Enabled) - { - if (_qos) - { - WEBRTC_TRACE( - kTraceWarning, - kTraceTransport, - _id, - "QOS is enabled but will be ignored since IPv6 is enabled"); - } - }else - { - // TODO (grunell): Multicast support is experimantal. - - // Put the first digit of the remote address in val. - int32_t val = ntohl(_remoteRTPAddr._sockaddr_in.sin_addr)>> 24; - - if((val > 223) && (val < 240)) - { - // Multicast address. - CriticalSectionScoped cs(_crit); - - UdpSocketWrapper* rtpSock = (_ptrSendRtpSocket ? - _ptrSendRtpSocket : _ptrRtpSocket); - if (!rtpSock || !rtpSock->ValidHandle()) - { - _lastError = kSocketInvalid; - return -1; - } - UdpSocketWrapper* rtcpSock = (_ptrSendRtcpSocket ? - _ptrSendRtcpSocket : _ptrRtcpSocket); - if (!rtcpSock || !rtcpSock->ValidHandle()) - { - _lastError = kSocketInvalid; - return -1; - } - - // Set Time To Live to same region - int32_t iOptVal = 64; - if (!rtpSock->SetSockopt(IPPROTO_IP, IP_MULTICAST_TTL, - (int8_t*)&iOptVal, - sizeof (int32_t))) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "setsockopt for multicast error on RTP socket"); - _ptrRtpSocket->CloseBlocking(); - _ptrRtpSocket = NULL; - _lastError = kMulticastAddressInvalid; - return -1; - } - if (!rtcpSock->SetSockopt(IPPROTO_IP, IP_MULTICAST_TTL, - (int8_t*)&iOptVal, - sizeof (int32_t))) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "setsockopt for multicast error on RTCP socket"); - _ptrRtpSocket->CloseBlocking(); - _ptrRtpSocket = NULL; - _lastError = kMulticastAddressInvalid; - return -1; - } - } - } - return 0; -} - -void UdpTransportImpl::BuildSockaddrIn(uint16_t portnr, - const char* ip, - SocketAddress& remoteAddr) const -{ - if(_ipV6Enabled) - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - remoteAddr.sin_length = 0; - remoteAddr.sin_family = PF_INET6; -#else - remoteAddr._sockaddr_storage.sin_family = PF_INET6; -#endif - remoteAddr._sockaddr_in6.sin6_port = Htons(portnr); - InetPresentationToNumeric(AF_INET6, ip, - &remoteAddr._sockaddr_in6.sin6_addr); - remoteAddr._sockaddr_in6.sin6_flowinfo=0; - remoteAddr._sockaddr_in6.sin6_scope_id=0; - } else - { -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - remoteAddr.sin_length = 0; - remoteAddr.sin_family = PF_INET; -#else - remoteAddr._sockaddr_storage.sin_family = PF_INET; -#endif - remoteAddr._sockaddr_in.sin_port = Htons(portnr); - remoteAddr._sockaddr_in.sin_addr= InetAddrIPV4( - const_cast(ip)); - } -} - -int32_t UdpTransportImpl::SendRaw(const int8_t *data, - size_t length, - int32_t isRTCP, - uint16_t portnr, - const char* ip) -{ - CriticalSectionScoped cs(_crit); - if(isRTCP) - { - UdpSocketWrapper* rtcpSock = NULL; - if(_ptrSendRtcpSocket) - { - rtcpSock = _ptrSendRtcpSocket; - } else if(_ptrRtcpSocket) - { - rtcpSock = _ptrRtcpSocket; - } else - { - return -1; - } - if(portnr == 0 && ip == NULL) - { - return rtcpSock->SendTo(data,length,_remoteRTCPAddr); - - } else if(portnr != 0 && ip != NULL) - { - SocketAddress remoteAddr; - BuildSockaddrIn(portnr, ip, remoteAddr); - return rtcpSock->SendTo(data,length,remoteAddr); - } else if(ip != NULL) - { - SocketAddress remoteAddr; - BuildSockaddrIn(_destPortRTCP, ip, remoteAddr); - return rtcpSock->SendTo(data,length,remoteAddr); - } else - { - SocketAddress remoteAddr; - BuildSockaddrIn(portnr, _destIP, remoteAddr); - return rtcpSock->SendTo(data,length,remoteAddr); - } - } else { - UdpSocketWrapper* rtpSock = NULL; - if(_ptrSendRtpSocket) - { - rtpSock = _ptrSendRtpSocket; - - } else if(_ptrRtpSocket) - { - rtpSock = _ptrRtpSocket; - } else - { - return -1; - } - if(portnr == 0 && ip == NULL) - { - return rtpSock->SendTo(data,length,_remoteRTPAddr); - - } else if(portnr != 0 && ip != NULL) - { - SocketAddress remoteAddr; - BuildSockaddrIn(portnr, ip, remoteAddr); - return rtpSock->SendTo(data,length,remoteAddr); - } else if(ip != NULL) - { - SocketAddress remoteAddr; - BuildSockaddrIn(_destPort, ip, remoteAddr); - return rtpSock->SendTo(data,length,remoteAddr); - } else - { - SocketAddress remoteAddr; - BuildSockaddrIn(portnr, _destIP, remoteAddr); - return rtpSock->SendTo(data,length,remoteAddr); - } - } -} - -int32_t UdpTransportImpl::SendRTPPacketTo(const int8_t* data, - size_t length, - const SocketAddress& to) -{ - CriticalSectionScoped cs(_crit); - if(_ptrSendRtpSocket) - { - return _ptrSendRtpSocket->SendTo(data,length,to); - - } else if(_ptrRtpSocket) - { - return _ptrRtpSocket->SendTo(data,length,to); - } - return -1; -} - -int32_t UdpTransportImpl::SendRTCPPacketTo(const int8_t* data, - size_t length, - const SocketAddress& to) -{ - - CriticalSectionScoped cs(_crit); - - if(_ptrSendRtcpSocket) - { - return _ptrSendRtcpSocket->SendTo(data,length,to); - - } else if(_ptrRtcpSocket) - { - return _ptrRtcpSocket->SendTo(data,length,to); - } - return -1; -} - -int32_t UdpTransportImpl::SendRTPPacketTo(const int8_t* data, - size_t length, - const uint16_t rtpPort) -{ - CriticalSectionScoped cs(_crit); - // Use the current SocketAdress but update it with rtpPort. - SocketAddress to; - memcpy(&to, &_remoteRTPAddr, sizeof(SocketAddress)); - - if(_ipV6Enabled) - { - to._sockaddr_in6.sin6_port = Htons(rtpPort); - } else - { - to._sockaddr_in.sin_port = Htons(rtpPort); - } - - if(_ptrSendRtpSocket) - { - return _ptrSendRtpSocket->SendTo(data,length,to); - - } else if(_ptrRtpSocket) - { - return _ptrRtpSocket->SendTo(data,length,to); - } - return -1; -} - -int32_t UdpTransportImpl::SendRTCPPacketTo(const int8_t* data, - size_t length, - const uint16_t rtcpPort) -{ - CriticalSectionScoped cs(_crit); - - // Use the current SocketAdress but update it with rtcpPort. - SocketAddress to; - memcpy(&to, &_remoteRTCPAddr, sizeof(SocketAddress)); - - if(_ipV6Enabled) - { - to._sockaddr_in6.sin6_port = Htons(rtcpPort); - } else - { - to._sockaddr_in.sin_port = Htons(rtcpPort); - } - - if(_ptrSendRtcpSocket) - { - return _ptrSendRtcpSocket->SendTo(data,length,to); - - } else if(_ptrRtcpSocket) - { - return _ptrRtcpSocket->SendTo(data,length,to); - } - return -1; -} - -bool UdpTransportImpl::SendRtp(const uint8_t* data, - size_t length, - const PacketOptions& packet_options) { - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, "%s", __FUNCTION__); - - CriticalSectionScoped cs(_crit); - - if(_destIP[0] == 0) - { - return false; - } - if(_destPort == 0) - { - return false; - } - - // Create socket if it hasn't been set up already. - // TODO (hellner): why not fail here instead. Sockets not being initialized - // indicates that there is a problem somewhere. - if( _ptrSendRtpSocket == NULL && - _ptrRtpSocket == NULL) - { - WEBRTC_TRACE( - kTraceStateInfo, - kTraceTransport, - _id, - "Creating RTP socket since no receive or source socket is\ - configured"); - - _ptrRtpSocket = _socket_creator->CreateSocket(_id, _mgr, this, - IncomingRTPCallback, - IpV6Enabled(), false); - - // Don't bind to a specific IP address. - if(! IpV6Enabled()) - { - strncpy(_localIP, "0.0.0.0",16); - } else - { - strncpy(_localIP, "0000:0000:0000:0000:0000:0000:0000:0000", - kIpAddressVersion6Length); - } - _localPort = _destPort; - - ErrorCode retVal = BindLocalRTPSocket(); - if(retVal != kNoSocketError) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "SendPacket() failed to bind RTP socket"); - _lastError = retVal; - CloseReceiveSockets(); - return false; - } - } - - if(_ptrSendRtpSocket) - { - return _ptrSendRtpSocket->SendTo((const int8_t*)data, length, - _remoteRTPAddr) >= 0; - - } else if(_ptrRtpSocket) - { - return _ptrRtpSocket->SendTo((const int8_t*)data, length, - _remoteRTPAddr) >= 0; - } - return false; -} - -bool UdpTransportImpl::SendRtcp(const uint8_t* data, size_t length) { - CriticalSectionScoped cs(_crit); - if(_destIP[0] == 0) - { - return false; - } - if(_destPortRTCP == 0) - { - return false; - } - - // Create socket if it hasn't been set up already. - // TODO (hellner): why not fail here instead. Sockets not being initialized - // indicates that there is a problem somewhere. - if( _ptrSendRtcpSocket == NULL && - _ptrRtcpSocket == NULL) - { - WEBRTC_TRACE( - kTraceStateInfo, - kTraceTransport, - _id, - "Creating RTCP socket since no receive or source socket is\ - configured"); - - _ptrRtcpSocket = _socket_creator->CreateSocket(_id, _mgr, this, - IncomingRTCPCallback, - IpV6Enabled(), false); - - // Don't bind to a specific IP address. - if(! IpV6Enabled()) - { - strncpy(_localIP, "0.0.0.0",16); - } else - { - strncpy(_localIP, "0000:0000:0000:0000:0000:0000:0000:0000", - kIpAddressVersion6Length); - } - _localPortRTCP = _destPortRTCP; - - ErrorCode retVal = BindLocalRTCPSocket(); - if(retVal != kNoSocketError) - { - _lastError = retVal; - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "SendRtcp() failed to bind RTCP socket"); - CloseReceiveSockets(); - return false; - } - } - - if(_ptrSendRtcpSocket) - { - return _ptrSendRtcpSocket->SendTo((const int8_t*)data, length, - _remoteRTCPAddr) >= 0; - } else if(_ptrRtcpSocket) - { - return _ptrRtcpSocket->SendTo((const int8_t*)data, length, - _remoteRTCPAddr) >= 0; - } - return false; -} - -int32_t UdpTransportImpl::SetSendIP(const char* ipaddr) -{ - if(!IsIpAddressValid(ipaddr,IpV6Enabled())) - { - return kIpAddressInvalid; - } - CriticalSectionScoped cs(_crit); - strncpy(_destIP, ipaddr,kIpAddressVersion6Length); - BuildRemoteRTPAddr(); - BuildRemoteRTCPAddr(); - return 0; -} - -int32_t UdpTransportImpl::SetSendPorts(uint16_t rtpPort, uint16_t rtcpPort) -{ - CriticalSectionScoped cs(_crit); - _destPort = rtpPort; - if(rtcpPort == 0) - { - _destPortRTCP = _destPort+1; - } else - { - _destPortRTCP = rtcpPort; - } - BuildRemoteRTPAddr(); - BuildRemoteRTCPAddr(); - return 0; -} - -void UdpTransportImpl::IncomingRTPCallback(CallbackObj obj, - const int8_t* rtpPacket, - size_t rtpPacketLength, - const SocketAddress* from) -{ - if (rtpPacket && rtpPacketLength > 0) - { - UdpTransportImpl* socketTransport = (UdpTransportImpl*) obj; - socketTransport->IncomingRTPFunction(rtpPacket, rtpPacketLength, from); - } -} - -void UdpTransportImpl::IncomingRTCPCallback(CallbackObj obj, - const int8_t* rtcpPacket, - size_t rtcpPacketLength, - const SocketAddress* from) -{ - if (rtcpPacket && rtcpPacketLength > 0) - { - UdpTransportImpl* socketTransport = (UdpTransportImpl*) obj; - socketTransport->IncomingRTCPFunction(rtcpPacket, rtcpPacketLength, - from); - } -} - -void UdpTransportImpl::IncomingRTPFunction(const int8_t* rtpPacket, - size_t rtpPacketLength, - const SocketAddress* fromSocket) -{ - char ipAddress[kIpAddressVersion6Length]; - uint32_t ipAddressLength = kIpAddressVersion6Length; - uint16_t portNr = 0; - - { - CriticalSectionScoped cs(_critFilter); - if (FilterIPAddress(fromSocket) == false) - { - // Packet should be filtered out. Drop it. - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, - "Incoming RTP packet blocked by IP filter"); - return; - } - - if (IPAddressCached(*fromSocket, ipAddress, ipAddressLength, portNr) < - 0) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpTransportImpl::IncomingRTPFunction - Cannot get sender\ - information"); - }else - { - // Make sure ipAddress is null terminated. - ipAddress[kIpAddressVersion6Length - 1] = 0; - strncpy(_fromIP, ipAddress, kIpAddressVersion6Length - 1); - } - - // Filter based on port. - if (_rtpFilterPort != 0 && - _rtpFilterPort != portNr) - { - // Drop packet. - memset(_fromIP, 0, sizeof(_fromIP)); - WEBRTC_TRACE( - kTraceStream, - kTraceTransport, - _id, - "Incoming RTP packet blocked by filter incoming from port:%d\ - allowed port:%d", - portNr, - _rtpFilterPort); - return; - } - _fromPort = portNr; - } - - CriticalSectionScoped cs(_critPacketCallback); - if (_packetCallback) - { - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, - "Incoming RTP packet from ip:%s port:%d", ipAddress, portNr); - _packetCallback->IncomingRTPPacket(rtpPacket, rtpPacketLength, - ipAddress, portNr); - } -} - -void UdpTransportImpl::IncomingRTCPFunction(const int8_t* rtcpPacket, - size_t rtcpPacketLength, - const SocketAddress* fromSocket) -{ - char ipAddress[kIpAddressVersion6Length]; - uint32_t ipAddressLength = kIpAddressVersion6Length; - uint16_t portNr = 0; - - { - CriticalSectionScoped cs(_critFilter); - if (FilterIPAddress(fromSocket) == false) - { - // Packet should be filtered out. Drop it. - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, - "Incoming RTCP packet blocked by IP filter"); - return; - } - if (IPAddress(*fromSocket, ipAddress, ipAddressLength, portNr) < 0) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpTransportImpl::IncomingRTCPFunction - Cannot get sender\ - information"); - }else { - // Make sure ipAddress is null terminated. - ipAddress[kIpAddressVersion6Length - 1] = 0; - strncpy(_fromIP, ipAddress, kIpAddressVersion6Length - 1); - } - - // Filter based on port. - if (_rtcpFilterPort != 0 && - _rtcpFilterPort != portNr) - { - // Drop packet. - WEBRTC_TRACE( - kTraceStream, - kTraceTransport, - _id, - "Incoming RTCP packet blocked by filter incoming from port:%d\ - allowed port:%d", - portNr, - _rtpFilterPort); - return; - } - _fromPortRTCP = portNr; - } - - CriticalSectionScoped cs(_critPacketCallback); - if (_packetCallback) - { - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, - "Incoming RTCP packet from ip:%s port:%d", ipAddress, - portNr); - _packetCallback->IncomingRTCPPacket(rtcpPacket, rtcpPacketLength, - ipAddress, portNr); - } -} - -bool UdpTransportImpl::FilterIPAddress(const SocketAddress* fromAddress) -{ - if(fromAddress->_sockaddr_storage.sin_family == AF_INET) - { - if (_filterIPAddress._sockaddr_storage.sin_family == AF_INET) - { - // IP is stored in sin_addr. - if (_filterIPAddress._sockaddr_in.sin_addr != 0 && - (_filterIPAddress._sockaddr_in.sin_addr != - fromAddress->_sockaddr_in.sin_addr)) - { - return false; - } - } - } - else if(fromAddress->_sockaddr_storage.sin_family == AF_INET6) - { - if (_filterIPAddress._sockaddr_storage.sin_family == AF_INET6) - { - // IP is stored in sin_6addr. - for (int32_t i = 0; i < 4; i++) - { - if (_filterIPAddress._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[i] != 0 && - _filterIPAddress._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[i] != fromAddress->_sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[i]) - { - return false; - } - } - } - } - else - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpTransportImpl::FilterIPAddress() unknown address family"); - return false; - } - return true; -} - -void UdpTransportImpl::CloseReceiveSockets() -{ - if(_ptrRtpSocket) - { - _ptrRtpSocket->CloseBlocking(); - _ptrRtpSocket = NULL; - } - if(_ptrRtcpSocket) - { - _ptrRtcpSocket->CloseBlocking(); - _ptrRtcpSocket = NULL; - } - _receiving = false; -} - -void UdpTransportImpl::CloseSendSockets() -{ - if(_ptrSendRtpSocket) - { - _ptrSendRtpSocket->CloseBlocking(); - _ptrSendRtpSocket = 0; - } - if(_ptrSendRtcpSocket) - { - _ptrSendRtcpSocket->CloseBlocking(); - _ptrSendRtcpSocket = 0; - } -} - -uint16_t UdpTransport::Htons(const uint16_t port) -{ - return htons(port); -} - -uint32_t UdpTransport::Htonl(const uint32_t a) -{ - return htonl(a); -} - -uint32_t UdpTransport::InetAddrIPV4(const char* ip) -{ - return ::inet_addr(ip); -} - -int32_t UdpTransport::InetPresentationToNumeric(int32_t af, - const char* src, - void* dst) -{ -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - const int32_t result = inet_pton(af, src, dst); - return result > 0 ? 0 : -1; - -#elif defined(_WIN32) - SocketAddress temp; - int length=sizeof(SocketAddress); - - if(af == AF_INET) - { - int32_t result = WSAStringToAddressA( - (const LPSTR)src, - af, - 0, - reinterpret_cast(&temp), - &length); - if(result != 0) - { - return -1; - } - memcpy(dst,&(temp._sockaddr_in.sin_addr), - sizeof(temp._sockaddr_in.sin_addr)); - return 0; - } - else if(af == AF_INET6) - { - int32_t result = WSAStringToAddressA( - (const LPSTR)src, - af, - 0, - reinterpret_cast(&temp), - &length); - if(result !=0) - { - return -1; - } - memcpy(dst,&(temp._sockaddr_in6.sin6_addr), - sizeof(temp._sockaddr_in6.sin6_addr)); - return 0; - - }else - { - return -1; - } -#else - return -1; -#endif -} - -int32_t UdpTransport::LocalHostAddressIPV6(char n_localIP[16]) -{ - -#if defined(_WIN32) - struct addrinfo *result = NULL; - struct addrinfo *ptr = NULL; - struct addrinfo hints; - - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET6; - - char szHostName[256] = ""; - if(::gethostname(szHostName, sizeof(szHostName) - 1)) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, "gethostname failed"); - return -1; - } - - DWORD dwRetval = getaddrinfo(szHostName, NULL, &hints, &result); - if ( dwRetval != 0 ) - { - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, - "getaddrinfo failed, error:%d", dwRetval); - return -1; - } - for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) - { - switch (ptr->ai_family) - { - case AF_INET6: - { - for(int i = 0; i< 16; i++) - { - n_localIP[i] = (*(SocketAddress*)ptr->ai_addr). - _sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u8[i]; - } - bool islocalIP = true; - - for(int n = 0; n< 15; n++) - { - if(n_localIP[n] != 0) - { - islocalIP = false; - break; - } - } - - if(islocalIP && n_localIP[15] != 1) - { - islocalIP = false; - } - - if(islocalIP && ptr->ai_next) - { - continue; - } - if(n_localIP[0] == 0xfe && - n_localIP[1] == 0x80 && ptr->ai_next) - { - continue; - } - freeaddrinfo(result); - } - return 0; - default: - break; - }; - } - freeaddrinfo(result); - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, - "getaddrinfo failed to find address"); - return -1; - -#elif defined(WEBRTC_MAC) - struct ifaddrs* ptrIfAddrs = NULL; - struct ifaddrs* ptrIfAddrsStart = NULL; - - getifaddrs(&ptrIfAddrsStart); - ptrIfAddrs = ptrIfAddrsStart; - while(ptrIfAddrs) - { - if(ptrIfAddrs->ifa_addr->sa_family == AF_INET6) - { - const struct sockaddr_in6* sock_in6 = - reinterpret_cast(ptrIfAddrs->ifa_addr); - const struct in6_addr* sin6_addr = &sock_in6->sin6_addr; - - if (IN6_IS_ADDR_LOOPBACK(sin6_addr) || - IN6_IS_ADDR_LINKLOCAL(sin6_addr)) { - ptrIfAddrs = ptrIfAddrs->ifa_next; - continue; - } - memcpy(n_localIP, sin6_addr->s6_addr, sizeof(sin6_addr->s6_addr)); - freeifaddrs(ptrIfAddrsStart); - return 0; - } - ptrIfAddrs = ptrIfAddrs->ifa_next; - } - freeifaddrs(ptrIfAddrsStart); - return -1; -#elif defined(WEBRTC_ANDROID) - return -1; -#else // WEBRTC_LINUX - struct - { - struct nlmsghdr n; - struct ifaddrmsg r; - } req; - - struct rtattr* rta = NULL; - int status; - char buf[16384]; // = 16 * 1024 (16 kB) - struct nlmsghdr* nlmp; - struct ifaddrmsg* rtmp; - struct rtattr* rtatp; - int rtattrlen; - struct in6_addr* in6p; - - int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); - if (fd == -1) - { - return -1; - } - - // RTM_GETADDR is used to fetch the ip address from the kernel interface - // table. Populate the msg structure (req) the size of the message buffer - // is specified to netlinkmessage header, and flags values are set as - // NLM_F_ROOT | NLM_F_REQUEST. - // The request flag must be set for all messages requesting the data from - // kernel. The root flag is used to notify the kernel to return the full - // tabel. Another flag (not used) is NLM_F_MATCH. This is used to get only - // specified entries in the table. At the time of writing this program this - // flag is not implemented in kernel - - memset(&req, 0, sizeof(req)); - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; - req.n.nlmsg_type = RTM_GETADDR; - req.r.ifa_family = AF_INET6; - - // Fill up all the attributes for the rtnetlink header. - // The lenght is very important. 16 signifies the ipv6 address. - rta = (struct rtattr*)(((char*)&req) + NLMSG_ALIGN(req.n.nlmsg_len)); - rta->rta_len = RTA_LENGTH(16); - - status = send(fd, &req, req.n.nlmsg_len, 0); - if (status < 0) - { - close(fd); - return -1; - } - status = recv(fd, buf, sizeof(buf), 0); - if (status < 0) - { - close(fd); - return -1; - } - if(status == 0) - { - close(fd); - return -1; - } - close(fd); - - // The message is stored in buff. Parse the message to get the requested - // data. - { - nlmp = (struct nlmsghdr*)buf; - int len = nlmp->nlmsg_len; - int req_len = len - sizeof(*nlmp); - - if (req_len < 0 || len > status) - { - return -1; - } - if (!NLMSG_OK_NO_WARNING(nlmp, status)) - { - return -1; - } - rtmp = (struct ifaddrmsg*)NLMSG_DATA(nlmp); - rtatp = (struct rtattr*)IFA_RTA(rtmp); - - rtattrlen = IFA_PAYLOAD(nlmp); - - for (; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen)) - { - - // Here we hit the fist chunk of the message. Time to validate the - // type. For more info on the different types see - // "man(7) rtnetlink" The table below is taken from man pages. - // Attributes - // rta_type value type description - // ------------------------------------------------------------- - // IFA_UNSPEC - unspecified. - // IFA_ADDRESS raw protocol address interface address - // IFA_LOCAL raw protocol address local address - // IFA_LABEL asciiz string name of the interface - // IFA_BROADCAST raw protocol address broadcast address. - // IFA_ANYCAST raw protocol address anycast address - // IFA_CACHEINFO struct ifa_cacheinfo Address information. - - if(rtatp->rta_type == IFA_ADDRESS) - { - bool islocalIP = true; - in6p = (struct in6_addr*)RTA_DATA(rtatp); - for(int n = 0; n< 15; n++) - { - if(in6p->s6_addr[n] != 0) - { - islocalIP = false; - break; - } - } - if(islocalIP && in6p->s6_addr[15] != 1) - { - islocalIP = false; - } - if(!islocalIP) - { - for(int i = 0; i< 16; i++) - { - n_localIP[i] = in6p->s6_addr[i]; - } - if(n_localIP[0] == static_cast (0xfe) - && n_localIP[1] == static_cast(0x80) ) - { - // Auto configured IP. - continue; - } - break; - } - } - } - } - return 0; -#endif -} - -int32_t UdpTransport::LocalHostAddress(uint32_t& localIP) -{ - #if defined(_WIN32) - hostent* localHost; - localHost = gethostbyname( "" ); - if(localHost) - { - if(localHost->h_addrtype != AF_INET) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - -1, - "LocalHostAddress can only get local IP for IP Version 4"); - return -1; - } - localIP= Htonl( - (*(struct in_addr *)localHost->h_addr_list[0]).S_un.S_addr); - return 0; - } - else - { - int32_t error = WSAGetLastError(); - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, - "gethostbyname failed, error:%d", error); - return -1; - } -#elif (defined(WEBRTC_MAC)) - char localname[255]; - if (gethostname(localname, 255) != -1) - { - hostent* localHost; - localHost = gethostbyname(localname); - if(localHost) - { - if(localHost->h_addrtype != AF_INET) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - -1, - "LocalHostAddress can only get local IP for IP Version 4"); - return -1; - } - localIP = Htonl((*(struct in_addr*)*localHost->h_addr_list).s_addr); - return 0; - } - } - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, "gethostname failed"); - return -1; -#else // WEBRTC_LINUX - int sockfd, size = 1; - struct ifreq* ifr; - struct ifconf ifc; - - if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) - { - return -1; - } - ifc.ifc_len = IFRSIZE; - ifc.ifc_req = NULL; - do - { - ++size; - // Buffer size needed is unknown. Try increasing it until no overflow - // occurs. - if (NULL == (ifc.ifc_req = (ifreq*)realloc(ifc.ifc_req, IFRSIZE))) { - fprintf(stderr, "Out of memory.\n"); - exit(EXIT_FAILURE); - } - ifc.ifc_len = IFRSIZE; - if (ioctl(sockfd, SIOCGIFCONF, &ifc)) - { - free(ifc.ifc_req); - close(sockfd); - return -1; - } - } while (IFRSIZE <= ifc.ifc_len); - - ifr = ifc.ifc_req; - for (;(char *) ifr < (char *) ifc.ifc_req + ifc.ifc_len; ++ifr) - { - if (ifr->ifr_addr.sa_data == (ifr+1)->ifr_addr.sa_data) - { - continue; // duplicate, skip it - } - if (ioctl(sockfd, SIOCGIFFLAGS, ifr)) - { - continue; // failed to get flags, skip it - } - if(strncmp(ifr->ifr_name, "lo",3) == 0) - { - continue; - }else - { - struct sockaddr* saddr = &(ifr->ifr_addr); - SocketAddress* socket_addess = reinterpret_cast( - saddr); - localIP = Htonl(socket_addess->_sockaddr_in.sin_addr); - close(sockfd); - free(ifc.ifc_req); - return 0; - } - } - free(ifc.ifc_req); - close(sockfd); - return -1; -#endif -} - -int32_t UdpTransport::IPAddress(const SocketAddress& address, - char* ip, - uint32_t& ipSize, - uint16_t& sourcePort) -{ - #if defined(_WIN32) - DWORD dwIPSize = ipSize; - int32_t returnvalue = WSAAddressToStringA((LPSOCKADDR)(&address), - sizeof(SocketAddress), - NULL, - ip, - &dwIPSize); - if(returnvalue == -1) - { - return -1; - } - - uint16_t source_port = 0; - if(address._sockaddr_storage.sin_family == AF_INET) - { - // Parse IP assuming format "a.b.c.d:port". - char* ipEnd = strchr(ip,':'); - if(ipEnd != NULL) - { - *ipEnd = '\0'; - } - ipSize = (int32_t)strlen(ip); - if(ipSize == 0) - { - return -1; - } - source_port = address._sockaddr_in.sin_port; - } - else - { - // Parse IP assuming format "[address]:port". - char* ipEnd = strchr(ip,']'); - if(ipEnd != NULL) - { - // Calculate length - int32_t adrSize = int32_t(ipEnd - ip) - 1; - memmove(ip, &ip[1], adrSize); // Remove '[' - *(ipEnd - 1) = '\0'; - } - ipSize = (int32_t)strlen(ip); - if(ipSize == 0) - { - return -1; - } - - source_port = address._sockaddr_in6.sin6_port; - } - // Convert port number to network byte order. - sourcePort = htons(source_port); - return 0; - - #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - int32_t ipFamily = address._sockaddr_storage.sin_family; - const void* ptrNumericIP = NULL; - - if(ipFamily == AF_INET) - { - ptrNumericIP = &(address._sockaddr_in.sin_addr); - } - else if(ipFamily == AF_INET6) - { - ptrNumericIP = &(address._sockaddr_in6.sin6_addr); - } - else - { - return -1; - } - if(inet_ntop(ipFamily, ptrNumericIP, ip, ipSize) == NULL) - { - return -1; - } - uint16_t source_port; - if(ipFamily == AF_INET) - { - source_port = address._sockaddr_in.sin_port; - } else - { - source_port = address._sockaddr_in6.sin6_port; - } - // Convert port number to network byte order. - sourcePort = htons(source_port); - return 0; - #else - return -1; - #endif -} - -bool UdpTransport::IsIpAddressValid(const char* ipadr, const bool ipV6) -{ - if(ipV6) - { - int32_t len = (int32_t)strlen(ipadr); - if( len>39 || len == 0) - { - return false; - } - - int32_t i; - int32_t colonPos[7] = {0,0,0,0,0,0,0}; - int32_t lastColonPos = -2; - int32_t nColons = 0; - int32_t nDubbleColons = 0; - int32_t nDots = 0; - int32_t error = 0; - char c; - for(i = 0; i < len ; i++) - { - c=ipadr[i]; - if(isxdigit(c)) - ; - else if(c == ':') - { - if(nColons < 7) - colonPos[nColons] = i; - if((i-lastColonPos)==1) - nDubbleColons++; - lastColonPos=i; - if(nDots != 0) - { - error = 1; - } - nColons++; - } - else if(c == '.') - { - nDots++; - } - else - { - error = 1; - } - - } - if(error) - { - return false; - } - if(nDubbleColons > 1) - { - return false; - } - if(nColons > 7 || nColons < 2) - { - return false; - } - if(nColons < 7 && nDubbleColons == 0) - { - return false; - } - if(!(nDots == 3 || nDots == 0)) - { - return false; - } - lastColonPos = -1; - int32_t charsBeforeColon = 0; - for(i = 0; i < nColons; i++) - { - charsBeforeColon=colonPos[i]-lastColonPos-1; - if(charsBeforeColon > 4) - { - return false; - } - lastColonPos=colonPos[i]; - } - int32_t lengthAfterLastColon = len - lastColonPos - 1; - if(nDots == 0) - { - if(lengthAfterLastColon > 4) - return false; - } - if(nDots == 3 && lengthAfterLastColon > 0) - { - return IsIpAddressValid((ipadr+lastColonPos+1),false); - } - - } - else - { - int32_t len = (int32_t)strlen(ipadr); - if((len>15)||(len==0)) - { - return false; - } - - // IPv4 should be [0-255].[0-255].[0-255].[0-255] - int32_t i; - int32_t nDots = 0; - int32_t iDotPos[4] = {0,0,0,0}; - - for (i = 0; (i < len) && (nDots < 4); i++) - { - if (ipadr[i] == (char)'.') - { - // Store index of dots and count number of dots. - iDotPos[nDots++] = i; - } - else if (isdigit(ipadr[i]) == 0) - { - return false; - } - } - - bool allUnder256 = false; - // TODO (hellner): while loop seems to be abused here to get - // label like functionality. Fix later to avoid introducing bugs now. - - // Check that all numbers are smaller than 256. - do - { - if (nDots != 3 ) - { - break; - } - - if (iDotPos[0] <= 3) - { - char nr[4]; - memset(nr,0,4); - strncpy(nr,&ipadr[0],iDotPos[0]); - int32_t num = atoi(nr); - if (num > 255 || num < 0) - { - break; - } - } else { - break; - } - - if (iDotPos[1] - iDotPos[0] <= 4) - { - char nr[4]; - memset(nr,0,4); - strncpy(nr,&ipadr[iDotPos[0]+1], iDotPos[1] - iDotPos[0] - 1); - int32_t num = atoi(nr); - if (num > 255 || num < 0) - break; - } else { - break; - } - - if (iDotPos[2] - iDotPos[1] <= 4) - { - char nr[4]; - memset(nr,0,4); - strncpy(nr,&ipadr[iDotPos[1]+1], iDotPos[2] - iDotPos[1] - 1); - int32_t num = atoi(nr); - if (num > 255 || num < 0) - break; - } else { - break; - } - - if (len - iDotPos[2] <= 4) - { - char nr[4]; - memset(nr,0,4); - strncpy(nr,&ipadr[iDotPos[2]+1], len - iDotPos[2] -1); - int32_t num = atoi(nr); - if (num > 255 || num < 0) - break; - else - allUnder256 = true; - } else { - break; - } - } while(false); - - if (nDots != 3 || !allUnder256) - { - return false; - } - } - return true; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/voice_engine/test/channel_transport/udp_transport_impl.h b/webrtc/voice_engine/test/channel_transport/udp_transport_impl.h deleted file mode 100644 index 236ff53f5f..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_transport_impl.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2012 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. - */ - -#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_IMPL_H_ -#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_IMPL_H_ - -#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h" -#include "webrtc/voice_engine/test/channel_transport/udp_transport.h" - -namespace webrtc { - -class CriticalSectionWrapper; -class RWLockWrapper; - -namespace test { - -class UdpSocketManager; - -class UdpTransportImpl : public UdpTransport -{ -public: - // A factory that returns a wrapped UDP socket or equivalent. - class SocketFactoryInterface { - public: - virtual ~SocketFactoryInterface() {} - virtual UdpSocketWrapper* CreateSocket(const int32_t id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable, - bool disableGQOS) = 0; - }; - - // Constructor, only called by UdpTransport::Create and tests. - // The constructor takes ownership of the "maker". - // The constructor does not take ownership of socket_manager. - UdpTransportImpl(const int32_t id, - SocketFactoryInterface* maker, - UdpSocketManager* socket_manager); - virtual ~UdpTransportImpl(); - - // UdpTransport functions - int32_t InitializeSendSockets(const char* ipAddr, - const uint16_t rtpPort, - const uint16_t rtcpPort = 0) override; - int32_t InitializeReceiveSockets(UdpTransportData* const packetCallback, - const uint16_t rtpPort, - const char* ipAddr = NULL, - const char* multicastIpAddr = NULL, - const uint16_t rtcpPort = 0) override; - int32_t InitializeSourcePorts(const uint16_t rtpPort, - const uint16_t rtcpPort = 0) override; - int32_t SourcePorts(uint16_t& rtpPort, uint16_t& rtcpPort) const override; - int32_t ReceiveSocketInformation( - char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort, - char multicastIpAddr[kIpAddressVersion6Length]) const override; - int32_t SendSocketInformation(char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort) const override; - int32_t RemoteSocketInformation(char ipAddr[kIpAddressVersion6Length], - uint16_t& rtpPort, - uint16_t& rtcpPort) const override; - int32_t SetQoS(const bool QoS, - const int32_t serviceType, - const uint32_t maxBitrate = 0, - const int32_t overrideDSCP = 0, - const bool audio = false) override; - int32_t QoS(bool& QoS, - int32_t& serviceType, - int32_t& overrideDSCP) const override; - int32_t SetToS(const int32_t DSCP, - const bool useSetSockOpt = false) override; - int32_t ToS(int32_t& DSCP, bool& useSetSockOpt) const override; - int32_t SetPCP(const int32_t PCP) override; - int32_t PCP(int32_t& PCP) const override; - int32_t EnableIpV6() override; - bool IpV6Enabled() const override; - int32_t SetFilterIP( - const char filterIPAddress[kIpAddressVersion6Length]) override; - int32_t FilterIP( - char filterIPAddress[kIpAddressVersion6Length]) const override; - int32_t SetFilterPorts(const uint16_t rtpFilterPort, - const uint16_t rtcpFilterPort) override; - int32_t FilterPorts(uint16_t& rtpFilterPort, - uint16_t& rtcpFilterPort) const override; - int32_t StartReceiving(const uint32_t numberOfSocketBuffers) override; - int32_t StopReceiving() override; - bool Receiving() const override; - bool SendSocketsInitialized() const override; - bool SourcePortsInitialized() const override; - bool ReceiveSocketsInitialized() const override; - int32_t SendRaw(const int8_t* data, - size_t length, - int32_t isRTCP, - uint16_t portnr = 0, - const char* ip = NULL) override; - int32_t SendRTPPacketTo(const int8_t* data, - size_t length, - const SocketAddress& to) override; - int32_t SendRTCPPacketTo(const int8_t* data, - size_t length, - const SocketAddress& to) override; - int32_t SendRTPPacketTo(const int8_t* data, - size_t length, - uint16_t rtpPort) override; - int32_t SendRTCPPacketTo(const int8_t* data, - size_t length, - uint16_t rtcpPort) override; - // Transport functions - bool SendRtp(const uint8_t* data, - size_t length, - const PacketOptions& packet_options) override; - bool SendRtcp(const uint8_t* data, size_t length) override; - - // UdpTransport functions continue. - int32_t SetSendIP(const char* ipaddr) override; - int32_t SetSendPorts(const uint16_t rtpPort, - const uint16_t rtcpPort = 0) override; - - ErrorCode LastError() const override; - - int32_t IPAddressCached(const SocketAddress& address, - char* ip, - uint32_t& ipSize, - uint16_t& sourcePort) override; - - int32_t Id() const {return _id;} -protected: - // IncomingSocketCallback signature functions for receiving callbacks from - // UdpSocketWrapper. - static void IncomingRTPCallback(CallbackObj obj, - const int8_t* rtpPacket, - size_t rtpPacketLength, - const SocketAddress* from); - static void IncomingRTCPCallback(CallbackObj obj, - const int8_t* rtcpPacket, - size_t rtcpPacketLength, - const SocketAddress* from); - - void CloseSendSockets(); - void CloseReceiveSockets(); - - // Update _remoteRTPAddr according to _destPort and _destIP - void BuildRemoteRTPAddr(); - // Update _remoteRTCPAddr according to _destPortRTCP and _destIP - void BuildRemoteRTCPAddr(); - - void BuildSockaddrIn(uint16_t portnr, const char* ip, - SocketAddress& remoteAddr) const; - - ErrorCode BindLocalRTPSocket(); - ErrorCode BindLocalRTCPSocket(); - - ErrorCode BindRTPSendSocket(); - ErrorCode BindRTCPSendSocket(); - - void IncomingRTPFunction(const int8_t* rtpPacket, - size_t rtpPacketLength, - const SocketAddress* from); - void IncomingRTCPFunction(const int8_t* rtcpPacket, - size_t rtcpPacketLength, - const SocketAddress* from); - - bool FilterIPAddress(const SocketAddress* fromAddress); - - bool SetSockOptUsed(); - - int32_t EnableQoS(int32_t serviceType, bool audio, - uint32_t maxBitrate, int32_t overrideDSCP); - - int32_t DisableQoS(); - -private: - void GetCachedAddress(char* ip, uint32_t& ipSize, - uint16_t& sourcePort); - - int32_t _id; - SocketFactoryInterface* _socket_creator; - // Protects the sockets from being re-configured while receiving packets. - CriticalSectionWrapper* _crit; - CriticalSectionWrapper* _critFilter; - // _packetCallback's critical section. - CriticalSectionWrapper* _critPacketCallback; - UdpSocketManager* _mgr; - ErrorCode _lastError; - - // Remote RTP and RTCP ports. - uint16_t _destPort; - uint16_t _destPortRTCP; - - // Local RTP and RTCP ports. - uint16_t _localPort; - uint16_t _localPortRTCP; - - // Local port number when the local port for receiving and local port number - // for sending are not the same. - uint16_t _srcPort; - uint16_t _srcPortRTCP; - - // Remote port from which last received packet was sent. - uint16_t _fromPort; - uint16_t _fromPortRTCP; - - char _fromIP[kIpAddressVersion6Length]; - char _destIP[kIpAddressVersion6Length]; - char _localIP[kIpAddressVersion6Length]; - char _localMulticastIP[kIpAddressVersion6Length]; - - UdpSocketWrapper* _ptrRtpSocket; - UdpSocketWrapper* _ptrRtcpSocket; - - // Local port when the local port for receiving and local port for sending - // are not the same. - UdpSocketWrapper* _ptrSendRtpSocket; - UdpSocketWrapper* _ptrSendRtcpSocket; - - SocketAddress _remoteRTPAddr; - SocketAddress _remoteRTCPAddr; - - SocketAddress _localRTPAddr; - SocketAddress _localRTCPAddr; - - int32_t _tos; - bool _receiving; - bool _useSetSockOpt; - bool _qos; - int32_t _pcp; - bool _ipV6Enabled; - int32_t _serviceType; - int32_t _overrideDSCP; - uint32_t _maxBitrate; - - // Cache used by GetCachedAddress(..). - RWLockWrapper* _cachLock; - SocketAddress _previousAddress; - char _previousIP[kIpAddressVersion6Length]; - uint32_t _previousIPSize; - uint16_t _previousSourcePort; - - SocketAddress _filterIPAddress; - uint16_t _rtpFilterPort; - uint16_t _rtcpFilterPort; - - UdpTransportData* _packetCallback; -}; - -} // namespace test -} // namespace webrtc - -#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_IMPL_H_ diff --git a/webrtc/voice_engine/test/channel_transport/udp_transport_unittest.cc b/webrtc/voice_engine/test/channel_transport/udp_transport_unittest.cc deleted file mode 100644 index 2938b411e4..0000000000 --- a/webrtc/voice_engine/test/channel_transport/udp_transport_unittest.cc +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2012 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 "webrtc/test/gmock.h" -#include "webrtc/test/gtest.h" -#include "webrtc/voice_engine/test/channel_transport/udp_transport.h" - -// We include the implementation header file to get at the dependency-injecting -// constructor. -#include "webrtc/voice_engine/test/channel_transport/udp_transport_impl.h" - -// We must mock the socket manager, for which we need its definition. -#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h" - -using ::testing::_; -using ::testing::Return; - -namespace webrtc { -namespace test { - -class MockUdpSocketWrapper : public UdpSocketWrapper { - public: - // The following methods have to be mocked because they are pure. - MOCK_METHOD2(SetCallback, bool(CallbackObj, IncomingSocketCallback)); - MOCK_METHOD1(Bind, bool(const SocketAddress&)); - MOCK_METHOD0(ValidHandle, bool()); - MOCK_METHOD4(SetSockopt, bool(int32_t, int32_t, - const int8_t*, - int32_t)); - MOCK_METHOD1(SetTOS, int32_t(int32_t)); - MOCK_METHOD3(SendTo, int32_t(const int8_t*, size_t, const SocketAddress&)); - MOCK_METHOD8(SetQos, bool(int32_t, int32_t, - int32_t, int32_t, - int32_t, int32_t, - const SocketAddress &, - int32_t)); -}; - -class MockUdpSocketManager : public UdpSocketManager { - public: - // Access to protected destructor. - void Destroy() { - delete this; - } - MOCK_METHOD2(Init, bool(int32_t, uint8_t&)); - MOCK_METHOD0(Start, bool()); - MOCK_METHOD0(Stop, bool()); - MOCK_METHOD1(AddSocket, bool(UdpSocketWrapper*)); - MOCK_METHOD1(RemoveSocket, bool(UdpSocketWrapper*)); -}; - -class MockSocketFactory : - public UdpTransportImpl::SocketFactoryInterface { - public: - MockSocketFactory(std::vector* socket_counter) - : socket_counter_(socket_counter) { - } - UdpSocketWrapper* CreateSocket(const int32_t id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable, - bool disableGQOS) { - MockUdpSocketWrapper* socket = new MockUdpSocketWrapper(); - // We instrument the socket with calls that are expected, but do - // not matter for any specific test, in order to avoid warning messages. - EXPECT_CALL(*socket, ValidHandle()).WillRepeatedly(Return(true)); - EXPECT_CALL(*socket, Bind(_)).WillOnce(Return(true)); - socket_counter_->push_back(socket); - return socket; - } - std::vector* socket_counter_; -}; - -class UDPTransportTest : public ::testing::Test { - public: - UDPTransportTest() - : sockets_created_(0) { - } - - ~UDPTransportTest() { - // In production, sockets register themselves at creation time with - // an UdpSocketManager, and the UdpSocketManager is responsible for - // deleting them. In this test, we just delete them after the test. - while (!sockets_created_.empty()) { - delete sockets_created_.back(); - sockets_created_.pop_back(); - } - } - - size_t NumSocketsCreated() { - return sockets_created_.size(); - } - - std::vector* sockets_created() { - return &sockets_created_; - } -private: - std::vector sockets_created_; -}; - -TEST_F(UDPTransportTest, CreateTransport) { - int32_t id = 0; - uint8_t threads = 1; - UdpTransport* transport = UdpTransport::Create(id, threads); - UdpTransport::Destroy(transport); -} - -// This test verifies that the mock_socket is not called from the constructor. -TEST_F(UDPTransportTest, ConstructorDoesNotCreateSocket) { - int32_t id = 0; - UdpTransportImpl::SocketFactoryInterface* null_maker = NULL; - UdpSocketManager* null_manager = NULL; - UdpTransport* transport = new UdpTransportImpl(id, - null_maker, - null_manager); - delete transport; -} - -TEST_F(UDPTransportTest, InitializeSourcePorts) { - int32_t id = 0; - UdpTransportImpl::SocketFactoryInterface* mock_maker - = new MockSocketFactory(sockets_created()); - MockUdpSocketManager* mock_manager = new MockUdpSocketManager(); - UdpTransport* transport = new UdpTransportImpl(id, - mock_maker, - mock_manager); - EXPECT_EQ(0, transport->InitializeSourcePorts(4711, 4712)); - EXPECT_EQ(2u, NumSocketsCreated()); - - delete transport; - mock_manager->Destroy(); -} - -} // namespace test -} // namespace webrtc