diff --git a/webrtc/modules/modules.gyp b/webrtc/modules/modules.gyp index 837d551898..1671c139f6 100644 --- a/webrtc/modules/modules.gyp +++ b/webrtc/modules/modules.gyp @@ -27,7 +27,6 @@ 'pacing/pacing.gypi', 'remote_bitrate_estimator/remote_bitrate_estimator.gypi', 'rtp_rtcp/source/rtp_rtcp.gypi', - 'udp_transport/source/udp_transport.gypi', 'utility/source/utility.gypi', 'video_coding/codecs/i420/main/source/i420.gypi', 'video_coding/main/source/video_coding.gypi', diff --git a/webrtc/modules/udp_transport/OWNERS b/webrtc/modules/udp_transport/OWNERS deleted file mode 100644 index 3b2a44459d..0000000000 --- a/webrtc/modules/udp_transport/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -pwestin@webrtc.org -henrikg@webrtc.org -mallinath@webrtc.org -tomasl@webrtc.org \ No newline at end of file diff --git a/webrtc/modules/udp_transport/interface/udp_transport.h b/webrtc/modules/udp_transport/interface/udp_transport.h deleted file mode 100644 index 2ca4eb8182..0000000000 --- a/webrtc/modules/udp_transport/interface/udp_transport.h +++ /dev/null @@ -1,394 +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_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_ - -#include "common_types.h" -#include "module.h" -#include "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 (WebRtc_UWord64)) -#define SS_PAD1SIZE (SS_ALIGNSIZE - sizeof(WebRtc_Word16)) -#define SS_PAD2SIZE (SS_MAXSIZE - (sizeof(WebRtc_Word16) + SS_PAD1SIZE +\ - SS_ALIGNSIZE)) - -// BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN -namespace webrtc { -struct SocketAddressIn -{ - // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - WebRtc_Word8 sin_length; - WebRtc_Word8 sin_family; -#else - WebRtc_Word16 sin_family; -#endif - WebRtc_UWord16 sin_port; - WebRtc_UWord32 sin_addr; - WebRtc_Word8 sin_zero[8]; -}; - -struct Version6InAddress -{ - union - { - WebRtc_UWord8 _s6_u8[16]; - WebRtc_UWord32 _s6_u32[4]; - WebRtc_UWord64 _s6_u64[2]; - } Version6AddressUnion; -}; - -struct SocketAddressInVersion6 -{ - // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - WebRtc_Word8 sin_length; - WebRtc_Word8 sin_family; -#else - WebRtc_Word16 sin_family; -#endif - // Transport layer port number. - WebRtc_UWord16 sin6_port; - // IPv6 traffic class and flow info or ip4 address. - WebRtc_UWord32 sin6_flowinfo; - // IPv6 address - struct Version6InAddress sin6_addr; - // Set of interfaces for a scope. - WebRtc_UWord32 sin6_scope_id; -}; - -struct SocketAddressStorage -{ - // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - WebRtc_Word8 sin_length; - WebRtc_Word8 sin_family; -#else - WebRtc_Word16 sin_family; -#endif - WebRtc_Word8 __ss_pad1[SS_PAD1SIZE]; - WebRtc_UWord64 __ss_align; - WebRtc_Word8 __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 WebRtc_Word8* incomingRtpPacket, - const WebRtc_Word32 rtpPacketLength, - const char* fromIP, - const WebRtc_UWord16 fromPort) = 0; - - virtual void IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket, - const WebRtc_Word32 rtcpPacketLength, - const char* fromIP, - const WebRtc_UWord16 fromPort) = 0; -}; - - -class UdpTransport : public Module, 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 WebRtc_Word32 id, - WebRtc_UWord8& 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 WebRtc_Word32 InitializeSendSockets( - const char* ipAddr, - const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 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 WebRtc_Word32 InitializeReceiveSockets( - UdpTransportData* const packetCallback, - const WebRtc_UWord16 rtpPort, - const char* ipAddr = NULL, - const char* multicastIpAddr = NULL, - const WebRtc_UWord16 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 WebRtc_Word32 InitializeSourcePorts( - const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 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 WebRtc_Word32 SourcePorts(WebRtc_UWord16& rtpPort, - WebRtc_UWord16& 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 WebRtc_Word32 ReceiveSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& 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 WebRtc_Word32 SendSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const = 0; - - // Put the IP address, RTP port and RTCP port from the last received packet - // into ipAddr, rtpPort and rtcpPort respectively. - virtual WebRtc_Word32 RemoteSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& 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 WebRtc_Word32 SetQoS(const bool QoS, - const WebRtc_Word32 serviceType, - const WebRtc_UWord32 maxBitrate = 0, - const WebRtc_Word32 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 WebRtc_Word32 QoS(bool& QoS, - WebRtc_Word32& serviceType, - WebRtc_Word32& overrideDSCP) const = 0; - - // Set type of service. - virtual WebRtc_Word32 SetToS(const WebRtc_Word32 DSCP, - const bool useSetSockOpt = false) = 0; - - // Get type of service configuration. - virtual WebRtc_Word32 ToS(WebRtc_Word32& 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 WebRtc_Word32 SetPCP(const WebRtc_Word32 PCP) = 0; - - // Get Priority Code Point - virtual WebRtc_Word32 PCP(WebRtc_Word32& 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 WebRtc_Word32 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 WebRtc_Word32 SetFilterIP( - const char filterIPAddress[kIpAddressVersion6Length]) = 0; - - // Write the filter IP address (if any) to filterIPAddress. - virtual WebRtc_Word32 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 WebRtc_Word32 SetFilterPorts( - const WebRtc_UWord16 rtpFilterPort, - const WebRtc_UWord16 rtcpFilterPort) = 0; - - // Set rtpFilterPort to the filter RTP port and rtcpFilterPort to the - // filter RTCP port (if filtering based on port is enabled). - virtual WebRtc_Word32 FilterPorts(WebRtc_UWord16& rtpFilterPort, - WebRtc_UWord16& 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 WebRtc_Word32 StartReceiving( - const WebRtc_UWord32 numberOfSocketBuffers) = 0; - - // Stop receive incoming packets. - virtual WebRtc_Word32 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 WebRtc_Word32 SendRaw(const WebRtc_Word8* data, - WebRtc_UWord32 length, - WebRtc_Word32 isRTCP, - WebRtc_UWord16 portnr = 0, - const char* ip = NULL) = 0; - - // Send RTP data with size length to the address specified by to. - virtual WebRtc_Word32 SendRTPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 length, - const SocketAddress& to) = 0; - - - // Send RTCP data with size length to the address specified by to. - virtual WebRtc_Word32 SendRTCPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 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 WebRtc_Word32 SendRTPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 length, - WebRtc_UWord16 rtpPort) = 0; - - - // Send RTCP data with size length to ip:rtcpPort where ip is the ip set by - // the InitializeSendSockets(..) call. - virtual WebRtc_Word32 SendRTCPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 length, - WebRtc_UWord16 rtcpPort) = 0; - - // Set the IP address to which packets are sent to ipaddr. - virtual WebRtc_Word32 SetSendIP( - const char ipaddr[kIpAddressVersion6Length]) = 0; - - // Set the send RTP and RTCP port to rtpPort and rtcpPort respectively. - virtual WebRtc_Word32 SetSendPorts(const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 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 WebRtc_Word32 LocalHostAddress(WebRtc_UWord32& localIP); - - // Put the local IP6 address in localIP. - // Note: this API is for IPv6 only. - static WebRtc_Word32 LocalHostAddressIPV6(char localIP[16]); - - // Return a copy of hostOrder (host order) in network order. - static WebRtc_UWord16 Htons(WebRtc_UWord16 hostOrder); - - // Return a copy of hostOrder (host order) in network order. - static WebRtc_UWord32 Htonl(WebRtc_UWord32 hostOrder); - - // Return IPv4 address in ip as 32 bit integer. - static WebRtc_UWord32 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 WebRtc_Word32 InetPresentationToNumeric(WebRtc_Word32 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 WebRtc_Word32 IPAddress(const SocketAddress& address, - char* ip, - WebRtc_UWord32& ipSize, - WebRtc_UWord16& 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 WebRtc_Word32 IPAddressCached(const SocketAddress& address, - char* ip, - WebRtc_UWord32& ipSize, - WebRtc_UWord16& 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 webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_ diff --git a/webrtc/modules/udp_transport/source/Android.mk b/webrtc/modules/udp_transport/source/Android.mk deleted file mode 100644 index f3cb0e83f3..0000000000 --- a/webrtc/modules/udp_transport/source/Android.mk +++ /dev/null @@ -1,45 +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. - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -include $(LOCAL_PATH)/../../../../android-webrtc.mk - -LOCAL_ARM_MODE := arm -LOCAL_MODULE_CLASS := STATIC_LIBRARIES -LOCAL_MODULE := libwebrtc_udp_transport -LOCAL_MODULE_TAGS := optional -LOCAL_CPP_EXTENSION := .cc -LOCAL_SRC_FILES := \ - udp_transport_impl.cc \ - udp_socket_wrapper.cc \ - udp_socket_manager_wrapper.cc \ - udp_socket_manager_posix.cc \ - udp_socket_posix.cc - -# Flags passed to both C and C++ files. -LOCAL_CFLAGS := \ - $(MY_WEBRTC_COMMON_DEFS) - -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH)/../interface \ - $(LOCAL_PATH)/../../.. \ - $(LOCAL_PATH)/../../interface \ - $(LOCAL_PATH)/../../../system_wrappers/interface - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libdl \ - libstlport - -ifndef NDK_ROOT -include external/stlport/libstlport.mk -endif -include $(BUILD_STATIC_LIBRARY) diff --git a/webrtc/modules/udp_transport/source/traffic_control_windows.cc b/webrtc/modules/udp_transport/source/traffic_control_windows.cc deleted file mode 100644 index 09038c06fb..0000000000 --- a/webrtc/modules/udp_transport/source/traffic_control_windows.cc +++ /dev/null @@ -1,253 +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 "traffic_control_windows.h" - -#include - -#include "trace.h" - -namespace webrtc { -TrafficControlWindows* TrafficControlWindows::instance = NULL; -WebRtc_UWord32 TrafficControlWindows::refCounter = 0; - -TrafficControlWindows::TrafficControlWindows(const WebRtc_Word32 id) : _id(id) -{ -} - -TrafficControlWindows* TrafficControlWindows::GetInstance( - const WebRtc_Word32 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, gtc->_id, - "TrafficControlWindows - Releasing object"); - refCounter--; - if ((0 == refCounter) && instance) - { - WEBRTC_TRACE(kTraceMemory, kTraceTransport, gtc->_id, - "TrafficControlWindows - Deleting object"); - delete instance; - instance = NULL; - } -} -WebRtc_Word32 TrafficControlWindows::ChangeUniqueId(const WebRtc_Word32 id) -{ - _id = id; - return 0; -} - -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 MyClNotifyHandler(HANDLE ClRegCtx, HANDLE ClIfcCtx, ULONG Event, - HANDLE SubCode, ULONG BufSize, PVOID Buffer) -{ -} -} // namespace webrtc diff --git a/webrtc/modules/udp_transport/source/traffic_control_windows.h b/webrtc/modules/udp_transport/source/traffic_control_windows.h deleted file mode 100644 index cfa52ce18a..0000000000 --- a/webrtc/modules/udp_transport/source/traffic_control_windows.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_MODULES_UDP_TRANSPORT_SOURCE_TRAFFIC_CONTROL_WINDOWS_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_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 "trace.h" - -namespace webrtc { -void 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 WebRtc_Word32 id); - static void Release(TrafficControlWindows* gtc); - - WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); - - 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 WebRtc_Word32 id); - WebRtc_Word32 _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 WebRtc_UWord32 refCounter; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_TRAFFIC_CONTROL_WINDOWS_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket2_manager_windows.cc b/webrtc/modules/udp_transport/source/udp_socket2_manager_windows.cc deleted file mode 100644 index 32863d3068..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket2_manager_windows.cc +++ /dev/null @@ -1,657 +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 "udp_socket2_manager_windows.h" - -#include -#include - -#include "aligned_malloc.h" -#include "udp_socket2_windows.h" - -namespace webrtc { -WebRtc_UWord32 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(); - - // All threads are stopped. Safe to delete them. - ListItem* pItem = NULL; - while((pItem = _workerThreadsList.First()) != NULL) - { - delete static_cast(pItem->GetItem()); - _workerThreadsList.PopFront(); - } - - _ioContextPool.Free(); - - _numOfActiveManagers--; - if(_ioCompletionHandle) - { - CloseHandle(_ioCompletionHandle); - } - if (_numOfActiveManagers == 0) - { - if(_wsaInit) - { - WSACleanup(); - } - } - } - if(_pCrit) - { - delete _pCrit; - } - if(_event) - { - delete _event; - } -} - -bool UdpSocket2ManagerWindows::Init(WebRtc_Word32 id, - WebRtc_UWord8& numOfWorkThreads) { - CriticalSectionScoped cs(_pCrit); - if ((_id != -1) || (_numOfWorkThreads != 0)) { - assert(_id != -1); - assert(_numOfWorkThreads != 0); - return false; - } - _id = id; - _numOfWorkThreads = numOfWorkThreads; - return true; -} - -WebRtc_Word32 UdpSocket2ManagerWindows::ChangeUniqueId(const WebRtc_Word32 id) -{ - _id = id; - return 0; -} - -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; - WebRtc_Word32 error = 0; - ListItem* pItem = _workerThreadsList.First(); - UdpSocket2WorkerWindows* pWorker; - while(pItem != NULL && !error) - { - pWorker = (UdpSocket2WorkerWindows*)pItem->GetItem(); - if(!pWorker->Start()) - error = 1; - pItem = _workerThreadsList.Next(pItem); - } - 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) - { - WebRtc_Word32 error = GetLastError(); - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StartWorkerThreads()" - "_ioCompletioHandle == NULL: error:%d", - _managerNumber,error); - _pCrit->Leave(); - return false; - } - - // Create worker threads. - WebRtc_UWord32 i = 0; - bool error = false; - while(i < _numOfWorkThreads && !error) - { - UdpSocket2WorkerWindows* pWorker = - new UdpSocket2WorkerWindows(_ioCompletionHandle); - if(pWorker->Init() != 0) - { - error = true; - delete pWorker; - break; - } - _workerThreadsList.PushFront(pWorker); - i++; - } - if(error) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error " - "creating work threads", - _managerNumber); - // Delete worker threads. - ListItem* pItem = NULL; - while((pItem = _workerThreadsList.First()) != NULL) - { - delete static_cast(pItem->GetItem()); - _workerThreadsList.PopFront(); - } - _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() -{ - WebRtc_Word32 error = 0; - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - _id, - "UdpSocket2ManagerWindows(%d)::StopWorkerThreads() Worker\ - threadsStoped, numActicve Sockets=%d", - _managerNumber, - _numActiveSockets); - UdpSocket2WorkerWindows* pWorker; - ListItem* pItem = _workerThreadsList.First(); - - // Set worker threads to not alive so that they will stop calling - // UdpSocket2WorkerWindows::Run(). - while(pItem != NULL) - { - pWorker = (UdpSocket2WorkerWindows*)pItem->GetItem(); - pWorker->SetNotAlive(); - pItem = _workerThreadsList.Next(pItem); - } - // Release all threads waiting for GetQueuedCompletionStatus(..). - if(_ioCompletionHandle) - { - WebRtc_UWord32 i = 0; - for(i = 0; i < _workerThreadsList.GetSize(); i++) - { - PostQueuedCompletionStatus(_ioCompletionHandle, 0 ,0 , NULL); - } - } - pItem = _workerThreadsList.First(); - - while(pItem != NULL) - { - pWorker = (UdpSocket2WorkerWindows*)pItem->GetItem(); - if(pWorker->Stop() == false) - { - error = -1; - WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, - "failed to stop worker thread"); - } - pItem = _workerThreadsList.Next(pItem); - } - - 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, - (WebRtc_Word32)s->GetFd()); - _pCrit->Leave(); - return false; - - } - _ioCompletionHandle = CreateIoCompletionPort((HANDLE)s->GetFd(), - _ioCompletionHandle, - (ULONG_PTR)(s), 0); - if(_ioCompletionHandle == NULL) - { - WebRtc_Word32 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; -} - -WebRtc_Word32 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); -} - -WebRtc_Word32 IoContextPool::Init(WebRtc_UWord32 /*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; -} - -WebRtc_Word32 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 WebRtc_Word32 usedItems = --_inUse; - const WebRtc_Word32 totalItems = _size.Value(); - const WebRtc_Word32 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; -} - -WebRtc_Word32 IoContextPool::Free() -{ - if(!_init) - { - return 0; - } - - WebRtc_Word32 itemsFreed = 0; - PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead); - while(pListEntry != NULL) - { - IoContextPoolItem* item = ((IoContextPoolItem*)pListEntry); - AlignedFree(item); - --_size; - itemsFreed++; - pListEntry = InterlockedPopEntrySList(_pListHead); - } - return itemsFreed; -} - -WebRtc_Word32 UdpSocket2WorkerWindows::_numOfWorkers = 0; - -UdpSocket2WorkerWindows::UdpSocket2WorkerWindows(HANDLE ioCompletionHandle) - : _ioCompletionHandle(ioCompletionHandle), - _pThread(NULL), - _init(false) -{ - _workerNumber = _numOfWorkers++; - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocket2WorkerWindows created"); -} - -UdpSocket2WorkerWindows::~UdpSocket2WorkerWindows() -{ - if(_pThread) - { - delete _pThread; - } - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocket2WorkerWindows deleted"); -} - -bool UdpSocket2WorkerWindows::Start() -{ - unsigned int id = 0; - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Start UdpSocket2WorkerWindows"); - return _pThread->Start(id); -} - -bool UdpSocket2WorkerWindows::Stop() -{ - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Stop UdpSocket2WorkerWindows"); - return _pThread->Stop(); -} - -void UdpSocket2WorkerWindows::SetNotAlive() -{ - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "SetNotAlive UdpSocket2WorkerWindows"); - _pThread->SetNotAlive(); -} - -WebRtc_Word32 UdpSocket2WorkerWindows::Init() -{ - if(!_init) - { - const char* threadName = "UdpSocket2ManagerWindows_thread"; - _pThread = ThreadWrapper::CreateThread(Run, this, kRealtimePriority, - threadName); - if(_pThread == NULL) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - -1, - "UdpSocket2WorkerWindows(%d)::Init(), error creating thread!", - _workerNumber); - return -1; - } - _init = true; - } - return 0; -} - -bool UdpSocket2WorkerWindows::Run(ThreadObj 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() -{ - WebRtc_Word32 success = 0; - DWORD ioSize = 0; - UdpSocket2Windows* pSocket = NULL; - PerIoContext* pIOContext = 0; - OVERLAPPED* pOverlapped = 0; - success = GetQueuedCompletionStatus(_ioCompletionHandle, - &ioSize, - (ULONG_PTR*)&pSocket, &pOverlapped, 200); - - WebRtc_UWord32 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 webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket2_manager_windows.h b/webrtc/modules/udp_transport/source/udp_socket2_manager_windows.h deleted file mode 100644 index 782cb41cfe..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket2_manager_windows.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_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET2_MANAGER_WINDOWS_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET2_MANAGER_WINDOWS_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -#include "atomic32.h" -#include "critical_section_wrapper.h" -#include "event_wrapper.h" -#include "list_wrapper.h" -#include "thread_wrapper.h" -#include "udp_socket2_windows.h" -#include "udp_socket_manager_wrapper.h" - -#define MAX_IO_BUFF_SIZE 1600 - -namespace webrtc { -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; - int 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 ioInitiatedByThreadWrapper; - // 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 WebRtc_Word32 Init(WebRtc_UWord32 increaseSize = 128); - // Re-use an old unused IO context or create a new one. - virtual PerIoContext* PopIoContext(); - virtual WebRtc_Word32 PushIoContext(PerIoContext* pIoContext); - virtual inline WebRtc_Word32 GetSize(WebRtc_UWord32* inUse = 0) - {return _size.Value();} - virtual WebRtc_Word32 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 UdpSocket2ManagerWindows : public UdpSocketManager -{ -public: - UdpSocket2ManagerWindows(); - virtual ~UdpSocket2ManagerWindows(); - - virtual bool Init(WebRtc_Word32 id, WebRtc_UWord8& numOfWorkThreads); - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); - - 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); - WebRtc_Word32 PushIoContext(PerIoContext* pIoContext); - -private: - bool StopWorkerThreads(); - bool StartWorkerThreads(); - bool AddSocketPrv(UdpSocket2Windows* s); - bool RemoveSocketPrv(UdpSocket2Windows* s); - - static WebRtc_UWord32 _numOfActiveManagers; - static bool _wsaInit; - - WebRtc_Word32 _id; - CriticalSectionWrapper* _pCrit; - WebRtc_Word32 _managerNumber; - volatile bool _stopped; - bool _init; - WebRtc_Word32 _numActiveSockets; - ListWrapper _workerThreadsList; - EventWrapper* _event; - - HANDLE _ioCompletionHandle; - IoContextPool _ioContextPool; -}; - -class UdpSocket2WorkerWindows -{ -public: - UdpSocket2WorkerWindows(HANDLE ioCompletionHandle); - virtual ~UdpSocket2WorkerWindows(); - - virtual bool Start(); - virtual bool Stop(); - virtual WebRtc_Word32 Init(); - virtual void SetNotAlive(); -protected: - static bool Run(ThreadObj obj); - bool Process(); -private: - HANDLE _ioCompletionHandle; - ThreadWrapper*_pThread; - static WebRtc_Word32 _numOfWorkers; - WebRtc_Word32 _workerNumber; - volatile bool _stop; - bool _init; -}; -} // namespace webrtc -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET2_MANAGER_WINDOWS_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket2_windows.cc b/webrtc/modules/udp_transport/source/udp_socket2_windows.cc deleted file mode 100644 index d6bc32e1b2..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket2_windows.cc +++ /dev/null @@ -1,1387 +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 "modules/udp_transport/source/udp_socket2_windows.h" - -#include -#include -#include - -#include "modules/udp_transport/source/traffic_control_windows.h" -#include "modules/udp_transport/source/udp_socket2_manager_windows.h" -#include "system_wrappers/interface/sleep.h" - -#pragma warning(disable : 4311) - -namespace webrtc { -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 WebRtc_Word32 id, - UdpSocketManager* mgr, bool ipV6Enable, - bool disableGQOS) - : _id(id), - _qos(true), - _iProtocol(0), - _outstandingCalls(0), - _outstandingCallComplete(0), - _terminate(false), - _addedToMgr(false), - _safeTodelete(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; - _pCrit = CriticalSectionWrapper::CreateCriticalSection(); - _ptrCbRWLock = RWLockWrapper::CreateRWLock(); - _ptrDestRWLock = RWLockWrapper::CreateRWLock(); - _ptrSocketRWLock = RWLockWrapper::CreateRWLock(); - _ptrDeleteCrit = CriticalSectionWrapper::CreateCriticalSection(); - _ptrDeleteCond = ConditionVariableWrapper::CreateConditionVariable(); - - // 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. - WebRtc_Word32 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 (WebRtc_Word32 i=0; iTcDeleteFilter(_filterHandle); - } - if(_flowHandle) - { - _gtc->TcDeleteFlow(_flowHandle); - } - TrafficControlWindows::Release( _gtc); - } -} - -WebRtc_Word32 UdpSocket2Windows::ChangeUniqueId(const WebRtc_Word32 id) -{ - _id = id; - if (_gtc) - { - _gtc->ChangeUniqueId(id); - } - return 0; -} - -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 ",(WebRtc_Word32)this); - if(_addedToMgr) - { - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback alreadey added", - (WebRtc_Word32) this); - return false; - - } - if (_mgr->AddSocket(this)) - { - WEBRTC_TRACE( - kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback socket added to manager", - (WebRtc_Word32)this); - _addedToMgr = true; - return true; - } - - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SetCallback error adding me to mgr", - (WebRtc_Word32) this); - return false; -} - -bool UdpSocket2Windows::SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname, - const WebRtc_Word8* optval, - WebRtc_Word32 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(WebRtc_UWord32 receiveBuffers) -{ - WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, - "UdpSocket2Windows(%d)::StartReceiving(%d)", - (WebRtc_Word32)this, receiveBuffers); - - _wantsIncoming = true; - - WebRtc_Word32 numberOfReceiveBuffersToCreate = - receiveBuffers - _receiveBuffers.Value(); - numberOfReceiveBuffersToCreate = (numberOfReceiveBuffersToCreate < 0) ? - 0 : numberOfReceiveBuffersToCreate; - - WebRtc_Word32 error = 0; - for(WebRtc_Word32 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; -} - -WebRtc_Word32 UdpSocket2Windows::SendTo(const WebRtc_Word8* buf, - WebRtc_Word32 len, - const SocketAddress& to) -{ - WebRtc_Word32 retVal = 0; - WebRtc_Word32 error = 0; - if(len < 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SendTo(), len= %d < 0", - (WebRtc_Word32)this, len); - return -1; - } - - PerIoContext* pIoContext = _mgr->PopIoContext(); - if(pIoContext == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::SendTo(), pIoContext==0", - (WebRtc_Word32) this); - return -1; - } - // sizeof(pIoContext->buffer) is smaller than the highest number that - // can be represented by a WebRtc_Word32. - if(len >= (WebRtc_Word32) sizeof(pIoContext->buffer)) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::SendTo(), len= %d > buffer_size = %d", - (WebRtc_Word32) this, - len,sizeof(pIoContext->buffer)); - len = sizeof(pIoContext->buffer); - } - - memcpy(pIoContext->buffer,buf,len); - pIoContext->wsabuf.buf = pIoContext->buffer; - pIoContext->wsabuf.len = 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 len; - } - if((error = _mgr->PushIoContext(pIoContext))) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::SendTo(), error:%d pushing ioContext", - (WebRtc_Word32)this, error); - } - - // Roll back. - OutstandingCallCompleted(); - return -1; -} - -void UdpSocket2Windows::IOCompleted(PerIoContext* pIOContext, - WebRtc_UWord32 ioSize, WebRtc_UWord32 error) -{ - if(pIOContext == NULL || error == ERROR_OPERATION_ABORTED) - { - if ((pIOContext != NULL) && - !pIOContext->ioInitiatedByThreadWrapper && - (error == ERROR_OPERATION_ABORTED) && - (pIOContext->ioOperation == OP_READ) && - _outstandingCallsDisabled) - { - // !pIOContext->initiatedIOByThreadWrapper indicate that the I/O - // was not initiated by a ThreadWrapper 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", - (WebRtc_Word32)pIOContext, - ioSize, - error, - pIOContext ? (WebRtc_Word32)pIOContext->ioOperation : -1); - } else { - WEBRTC_TRACE( - kTraceDebug, - kTraceTransport, - _id, - "UdpSocket2Windows::IOCompleted() Operation aborted"); - } - if(pIOContext) - { - WebRtc_Word32 remainingReceiveBuffers = --_receiveBuffers; - if(remainingReceiveBuffers < 0) - { - assert(false); - } - WebRtc_Word32 err = 0; - if((err = _mgr->PushIoContext(pIOContext))) - { - 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(); - } - WebRtc_Word32 err = PostRecv(pIOContext); - if(err == 0) - { - // The PerIoContext was posted by a thread controlled by the socket - // implementation. - pIOContext->ioInitiatedByThreadWrapper = 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. -} - -WebRtc_Word32 UdpSocket2Windows::PostRecv() -{ - PerIoContext* pIoContext=_mgr->PopIoContext(); - if(pIoContext == 0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::PostRecv(), pIoContext == 0", - (WebRtc_Word32)this); - return -1; - } - // This function may have been called by thread not controlled by the socket - // implementation. - pIoContext->ioInitiatedByThreadWrapper = false; - return PostRecv(pIoContext); -} - -WebRtc_Word32 UdpSocket2Windows::PostRecv(PerIoContext* pIoContext) -{ - if(pIoContext==0) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows(%d)::PostRecv(?), pIoContext==0", - (WebRtc_Word32)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; - WebRtc_Word32 rxError = 0; - WebRtc_Word32 nRet = 0; - WebRtc_Word32 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(WebRtc_Word32 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", - (WebRtc_Word32)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; - } - WebRtc_Word32 remainingReceiveBuffers = --_receiveBuffers; - if(remainingReceiveBuffers < 0) - { - assert(false); - } - WebRtc_Word32 error = 0; - if((error = _mgr->PushIoContext(pIoContext))) - { - WEBRTC_TRACE( - kTraceError, - kTraceTransport, - _id, - "UdpSocket2Windows(%d)::PostRecv(?), error:%d when PushIoContext", - (WebRtc_Word32)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(); - WaitForOutstandingCalls(); - delete this; -} - -bool UdpSocket2Windows::SetQos(WebRtc_Word32 serviceType, - WebRtc_Word32 tokenRate, - WebRtc_Word32 bucketSize, - WebRtc_Word32 peekBandwith, - WebRtc_Word32 minPolicedSize, - WebRtc_Word32 maxSduSize, - const SocketAddress &stRemName, - WebRtc_Word32 overrideDSCP) -{ - if(_qos == false) - { - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocket2Windows::SetQos(), socket not capable of QOS"); - return false; - } - if(overrideDSCP != 0) - { - FLOWSPEC f; - WebRtc_Word32 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((WebRtc_Word8 *)&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. - WebRtc_Word32 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; -} - -WebRtc_Word32 UdpSocket2Windows::SetTOS(WebRtc_Word32 serviceType) -{ - SocketAddress socketName; - - struct sockaddr_in* name = - reinterpret_cast(&socketName); - int nameLength = sizeof(SocketAddress); - if(AquireSocket()) - { - getsockname(_socket, (struct sockaddr*)name, &nameLength); - ReleaseSocket(); - } - - WebRtc_Word32 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 , - (WebRtc_Word8*)&serviceType, 4) != 0) - { - return -1; - } - } - } - return res; -} - -WebRtc_Word32 UdpSocket2Windows::SetPCP(WebRtc_Word32 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); -} - -WebRtc_Word32 UdpSocket2Windows::SetTrafficControl( - WebRtc_Word32 dscp, - WebRtc_Word32 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) - (((WebRtc_Word8*)pInterfaceBuffer) + BufferSize); - oneinterface = (PTC_IFC_DESCRIPTOR) - ((WebRtc_Word8 *)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((WebRtc_Word8*)&filterPattern, sizeof(IP_PATTERN)); - ZeroMemory((WebRtc_Word8*)&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; -} - -WebRtc_Word32 UdpSocket2Windows::CreateFlowSpec(WebRtc_Word32 serviceType, - WebRtc_Word32 tokenRate, - WebRtc_Word32 bucketSize, - WebRtc_Word32 peekBandwith, - WebRtc_Word32 minPolicedSize, - WebRtc_Word32 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. - CriticalSectionScoped cs(_ptrDeleteCrit); - _safeTodelete = true; - _ptrDeleteCond->Wake(); - } -} - -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) - { - CriticalSectionScoped cs(_ptrDeleteCrit); - _safeTodelete = true; - _ptrDeleteCond->Wake(); - } -} - -void UdpSocket2Windows::WaitForOutstandingCalls() -{ - CriticalSectionScoped cs(_ptrDeleteCrit); - while(!_safeTodelete) - { - _ptrDeleteCond->SleepCS(*_ptrDeleteCrit); - } -} - -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", - (WebRtc_Word32)this, WSAGetLastError()); - } - _socket = INVALID_SOCKET; - _ptrSocketRWLock->ReleaseLockExclusive(); - return true; -} -} // namespace webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket2_windows.h b/webrtc/modules/udp_transport/source/udp_socket2_windows.h deleted file mode 100644 index 8cc46eefa7..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket2_windows.h +++ /dev/null @@ -1,171 +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_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET2_WINDOWS_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_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 "atomic32.h" -#include "condition_variable_wrapper.h" -#include "critical_section_wrapper.h" -#include "event_wrapper.h" -#include "list_wrapper.h" -#include "rw_lock_wrapper.h" -#include "trace.h" -#include "udp_socket_wrapper.h" -#include "udp_socket2_manager_windows.h" - -namespace webrtc { -class UdpSocket2ManagerWindows; -class TrafficControlWindows; -struct PerIoContext; - -class UdpSocket2Windows : public UdpSocketWrapper -{ -public: - UdpSocket2Windows(const WebRtc_Word32 id, UdpSocketManager* mgr, - bool ipV6Enable = false, bool disableGQOS = false); - virtual ~UdpSocket2Windows(); - - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); - - virtual bool ValidHandle(); - - virtual bool SetCallback(CallbackObj, IncomingSocketCallback); - - virtual bool Bind(const SocketAddress& name); - virtual bool SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname, - const WebRtc_Word8* optval, WebRtc_Word32 optlen); - - virtual bool StartReceiving(const WebRtc_UWord32 receiveBuffers); - virtual inline bool StartReceiving() {return StartReceiving(8);} - virtual bool StopReceiving(); - - virtual WebRtc_Word32 SendTo(const WebRtc_Word8* buf, WebRtc_Word32 len, - const SocketAddress& to); - - virtual void CloseBlocking(); - - virtual SOCKET GetFd() { return _socket;} - virtual bool SetQos(WebRtc_Word32 serviceType, WebRtc_Word32 tokenRate, - WebRtc_Word32 bucketSize, WebRtc_Word32 peekBandwith, - WebRtc_Word32 minPolicedSize, WebRtc_Word32 maxSduSize, - const SocketAddress &stRemName, - WebRtc_Word32 overrideDSCP = 0); - - virtual WebRtc_Word32 SetTOS(const WebRtc_Word32 serviceType); - virtual WebRtc_Word32 SetPCP(const WebRtc_Word32 pcp); - - virtual WebRtc_UWord32 ReceiveBuffers(){return _receiveBuffers.Value();} - -protected: - void IOCompleted(PerIoContext* pIOContext, WebRtc_UWord32 ioSize, - WebRtc_UWord32 error); - - WebRtc_Word32 PostRecv(); - // Use pIoContext to post a new WSARecvFrom(..). - WebRtc_Word32 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. - WebRtc_Word32 SetTrafficControl(WebRtc_Word32 dscp, WebRtc_Word32 pcp, - const struct sockaddr_in* name, - FLOWSPEC* send = NULL, - FLOWSPEC* recv = NULL); - WebRtc_Word32 CreateFlowSpec(WebRtc_Word32 serviceType, - WebRtc_Word32 tokenRate, - WebRtc_Word32 bucketSize, - WebRtc_Word32 peekBandwith, - WebRtc_Word32 minPolicedSize, - WebRtc_Word32 maxSduSize, FLOWSPEC *f); - - WebRtc_Word32 _id; - RWLockWrapper* _ptrCbRWLock; - IncomingSocketCallback _incomingCb; - CallbackObj _obj; - bool _qos; - - SocketAddress _remoteAddr; - SOCKET _socket; - WebRtc_Word32 _iProtocol; - UdpSocket2ManagerWindows* _mgr; - - CriticalSectionWrapper* _pCrit; - Atomic32 _outstandingCalls; - Atomic32 _outstandingCallComplete; - volatile bool _terminate; - volatile bool _addedToMgr; - - CriticalSectionWrapper* _ptrDeleteCrit; - ConditionVariableWrapper* _ptrDeleteCond; - bool _safeTodelete; - - RWLockWrapper* _ptrDestRWLock; - bool _outstandingCallsDisabled; - bool NewOutstandingCall(); - void OutstandingCallCompleted(); - void DisableNewOutstandingCalls(); - void WaitForOutstandingCalls(); - - 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 webrtc -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET2_WINDOWS_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket_manager_posix.cc b/webrtc/modules/udp_transport/source/udp_socket_manager_posix.cc deleted file mode 100644 index 1705aefcbf..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_manager_posix.cc +++ /dev/null @@ -1,424 +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 "udp_socket_manager_posix.h" - -#include -#include -#include -#include -#include - -#include "modules/udp_transport/source/udp_socket_posix.h" -#include "system_wrappers/interface/sleep.h" -#include "system_wrappers/interface/trace.h" - -namespace webrtc { -UdpSocketManagerPosix::UdpSocketManagerPosix() - : UdpSocketManager(), - _id(-1), - _critSect(CriticalSectionWrapper::CreateCriticalSection()), - _numberOfSocketMgr(-1), - _incSocketMgrNextTime(0), - _nextSocketMgrToAssign(0), - _socketMgr() -{ -} - -bool UdpSocketManagerPosix::Init(WebRtc_Word32 id, - WebRtc_UWord8& 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; -} - -WebRtc_Word32 UdpSocketManagerPosix::ChangeUniqueId(const WebRtc_Word32 id) -{ - _id = id; - return 0; -} - -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() -{ - _critSectList = CriticalSectionWrapper::CreateCriticalSection(); - _thread = ThreadWrapper::CreateThread(UdpSocketManagerPosixImpl::Run, this, - kRealtimePriority, - "UdpSocketManagerPosixImplThread"); - FD_ZERO(&_readFds); - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocketManagerPosix created"); -} - -UdpSocketManagerPosixImpl::~UdpSocketManagerPosixImpl() -{ - if(_thread != NULL) - { - delete _thread; - } - - if (_critSectList != NULL) - { - UpdateSocketMap(); - - _critSectList->Enter(); - - MapItem* item = _socketMap.First(); - while(item) - { - UdpSocketPosix* s = static_cast(item->GetItem()); - _socketMap.Erase(item); - item = _socketMap.First(); - delete s; - } - _critSectList->Leave(); - - delete _critSectList; - } - - WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1, - "UdpSocketManagerPosix deleted"); -} - -bool UdpSocketManagerPosixImpl::Start() -{ - unsigned int id = 0; - if (_thread == NULL) - { - return false; - } - - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Start UdpSocketManagerPosix"); - return _thread->Start(id); -} - -bool UdpSocketManagerPosixImpl::Stop() -{ - if (_thread == NULL) - { - return true; - } - - WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1, - "Stop UdpSocketManagerPosix"); - return _thread->Stop(); -} - -bool UdpSocketManagerPosixImpl::Process() -{ - bool doSelect = false; - // Timeout = 1 second. - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 10000; - MapItem* it; - - FD_ZERO(&_readFds); - - UpdateSocketMap(); - - unsigned int maxFd = 0; - for (it = _socketMap.First(); it != NULL; it=_socketMap.Next(it)) - { - doSelect = true; - maxFd = maxFd > it->GetUnsignedId() ? maxFd : it->GetUnsignedId(); - FD_SET(it->GetUnsignedId(), &_readFds); - - maxFd = maxFd > it->GetUnsignedId() ? maxFd : it->GetUnsignedId(); - doSelect = true; - } - - 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 (it = _socketMap.First(); it != NULL && num > 0; - it = _socketMap.Next(it)) - { - UdpSocketPosix* s = static_cast(it->GetItem()); - if (FD_ISSET(it->GetUnsignedId(), &_readFds)) - { - s->HasIncoming(); - num--; - } - } - return true; -} - -bool UdpSocketManagerPosixImpl::Run(ThreadObj 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.PushBack(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. - ListItem* addListItem = _addList.First(); - while(addListItem) - { - UdpSocketPosix* addSocket = (UdpSocketPosix*)addListItem->GetItem(); - unsigned int addFD = addSocket->GetFd(); - unsigned int removeFD = static_cast(s)->GetFd(); - if(removeFD == addFD) - { - _removeList.PushBack(removeFD); - _critSectList->Leave(); - return true; - } - addListItem = _addList.Next(addListItem); - } - - // 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()) != NULL) - { - _removeList.PushBack(static_cast(s)->GetFd()); - _critSectList->Leave(); - return true; - } - _critSectList->Leave(); - return false; -} - -void UdpSocketManagerPosixImpl::UpdateSocketMap() -{ - // Remove items in remove list. - _critSectList->Enter(); - while(!_removeList.Empty()) - { - UdpSocketPosix* deleteSocket = NULL; - unsigned int removeFD = _removeList.First()->GetUnsignedItem(); - - // 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. - ListItem* addListItem = _addList.First(); - while(addListItem) - { - UdpSocketPosix* addSocket = (UdpSocketPosix*)addListItem->GetItem(); - unsigned int addFD = addSocket->GetFd(); - if(removeFD == addFD) - { - deleteSocket = addSocket; - _addList.Erase(addListItem); - break; - } - addListItem = _addList.Next(addListItem); - } - - // Find and remove socket from _socketMap. - MapItem* it = _socketMap.Find(removeFD); - if(it != NULL) - { - UdpSocketPosix* socket = - static_cast(it->GetItem()); - if(socket) - { - deleteSocket = socket; - } - _socketMap.Erase(it); - } - if(deleteSocket) - { - deleteSocket->ReadyForDeletion(); - delete deleteSocket; - } - _removeList.PopFront(); - } - - // Add sockets from add list. - while(!_addList.Empty()) - { - UdpSocketPosix* s = - static_cast(_addList.First()->GetItem()); - if(s) - { - _socketMap.Insert(s->GetFd(), s); - } - _addList.PopFront(); - } - _critSectList->Leave(); -} -} // namespace webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket_manager_posix.h b/webrtc/modules/udp_transport/source/udp_socket_manager_posix.h deleted file mode 100644 index c89aa134f7..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_manager_posix.h +++ /dev/null @@ -1,85 +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_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_POSIX_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_POSIX_H_ - -#include -#include - -#include "critical_section_wrapper.h" -#include "list_wrapper.h" -#include "map_wrapper.h" -#include "thread_wrapper.h" -#include "udp_socket_manager_wrapper.h" -#include "udp_socket_wrapper.h" - -#define MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX 8 - -namespace webrtc { - -class ConditionVariableWrapper; -class UdpSocketManagerPosixImpl; - -class UdpSocketManagerPosix : public UdpSocketManager -{ -public: - UdpSocketManagerPosix(); - virtual ~UdpSocketManagerPosix(); - - virtual bool Init(WebRtc_Word32 id, - WebRtc_UWord8& numOfWorkThreads); - - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); - - virtual bool Start(); - virtual bool Stop(); - - virtual bool AddSocket(UdpSocketWrapper* s); - virtual bool RemoveSocket(UdpSocketWrapper* s); -private: - WebRtc_Word32 _id; - CriticalSectionWrapper* _critSect; - WebRtc_UWord8 _numberOfSocketMgr; - WebRtc_UWord8 _incSocketMgrNextTime; - WebRtc_UWord8 _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(ThreadObj obj); - bool Process(); - void UpdateSocketMap(); - -private: - ThreadWrapper* _thread; - CriticalSectionWrapper* _critSectList; - - fd_set _readFds; - - MapWrapper _socketMap; - ListWrapper _addList; - ListWrapper _removeList; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_POSIX_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket_manager_unittest.cc b/webrtc/modules/udp_transport/source/udp_socket_manager_unittest.cc deleted file mode 100644 index 6d94cbe8cf..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_manager_unittest.cc +++ /dev/null @@ -1,82 +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 "udp_socket_wrapper.h" -#include "udp_socket_manager_wrapper.h" -#include "gtest/gtest.h" -#include "system_wrappers/interface/trace.h" - -namespace webrtc { - -TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) { - WebRtc_Word32 id = 42; - WebRtc_UWord8 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) { - WebRtc_Word32 id = 42; - WebRtc_UWord8 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 - WebRtc_Word32 id = 42; - WebRtc_UWord8 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 webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket_manager_wrapper.cc b/webrtc/modules/udp_transport/source/udp_socket_manager_wrapper.cc deleted file mode 100644 index 37388be662..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_manager_wrapper.cc +++ /dev/null @@ -1,69 +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 "udp_socket_manager_wrapper.h" - -#include - -#ifdef _WIN32 -#include "fix_interlocked_exchange_pointer_win.h" -#include "udp_socket2_manager_windows.h" -#else -#include "udp_socket_manager_posix.h" -#endif - -namespace webrtc { -UdpSocketManager* UdpSocketManager::CreateInstance() -{ -#if defined(_WIN32) - return static_cast(new UdpSocket2ManagerWindows()); -#else - return new UdpSocketManagerPosix(); -#endif -} - -UdpSocketManager* UdpSocketManager::StaticInstance( - CountOperation count_operation, - const WebRtc_Word32 id, - WebRtc_UWord8& 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 WebRtc_Word32 id, - WebRtc_UWord8& numOfWorkThreads) -{ - return UdpSocketManager::StaticInstance(kAddRef, id, - numOfWorkThreads); -} - -void UdpSocketManager::Return() -{ - WebRtc_UWord8 numOfWorkThreads = 0; - UdpSocketManager::StaticInstance(kRelease, -1, - numOfWorkThreads); -} - -UdpSocketManager::UdpSocketManager() : _numOfWorkThreads(0) -{ -} - -WebRtc_UWord8 UdpSocketManager::WorkThreads() const -{ - return _numOfWorkThreads; -} -} // namespace webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket_manager_wrapper.h b/webrtc/modules/udp_transport/source/udp_socket_manager_wrapper.h deleted file mode 100644 index e7bd09e31b..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_manager_wrapper.h +++ /dev/null @@ -1,71 +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_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_WRAPPER_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_WRAPPER_H_ - -#include "system_wrappers/interface/static_instance.h" -#include "typedefs.h" - -namespace webrtc { - -class UdpSocketWrapper; - -class UdpSocketManager -{ -public: - static UdpSocketManager* Create(const WebRtc_Word32 id, - WebRtc_UWord8& numOfWorkThreads); - static void Return(); - - // Initializes the socket manager. Returns true if the manager wasn't - // already initialized. - virtual bool Init(WebRtc_Word32 id, - WebRtc_UWord8& numOfWorkThreads) = 0; - - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id) = 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 WebRtc_UWord8 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() {} - - WebRtc_UWord8 _numOfWorkThreads; - - // Factory method. - static UdpSocketManager* CreateInstance(); - -private: - // Friend function to allow the UDP destructor to be accessed from the - // instance template. - friend UdpSocketManager* - GetStaticInstance(CountOperation count_operation); - - static UdpSocketManager* StaticInstance( - CountOperation count_operation, - const WebRtc_Word32 id, - WebRtc_UWord8& numOfWorkThreads); -}; - -} // namespace webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_MANAGER_WRAPPER_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket_posix.cc b/webrtc/modules/udp_transport/source/udp_socket_posix.cc deleted file mode 100644 index 79b1600aa4..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_posix.cc +++ /dev/null @@ -1,277 +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 "udp_socket_posix.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "trace.h" -#include "udp_socket_manager_wrapper.h" -#include "udp_socket_wrapper.h" - -namespace webrtc { -UdpSocketPosix::UdpSocketPosix(const WebRtc_Word32 id, UdpSocketManager* mgr, - bool ipV6Enable) -{ - WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, - "UdpSocketPosix::UdpSocketPosix()"); - - _wantsIncoming = false; - _error = 0; - _mgr = mgr; - - _id = id; - _obj = NULL; - _incomingCb = NULL; - _readyForDeletionCond = ConditionVariableWrapper::CreateConditionVariable(); - _closeBlockingCompletedCond = - ConditionVariableWrapper::CreateConditionVariable(); - _cs = CriticalSectionWrapper::CreateCriticalSection(); - _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; - } - if(_readyForDeletionCond) - { - delete _readyForDeletionCond; - } - - if(_closeBlockingCompletedCond) - { - delete _closeBlockingCompletedCond; - } - - if(_cs) - { - delete _cs; - } -} - -WebRtc_Word32 UdpSocketPosix::ChangeUniqueId(const WebRtc_Word32 id) -{ - _id = id; - return 0; -} - -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(WebRtc_Word32 level, WebRtc_Word32 optname, - const WebRtc_Word8* optval, WebRtc_Word32 optlen) -{ - if(0 == setsockopt(_socket, level, optname, optval, optlen )) - { - return true; - } - - _error = errno; - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocketPosix::SetSockopt(), error:%d", _error); - return false; -} - -WebRtc_Word32 UdpSocketPosix::SetTOS(WebRtc_Word32 serviceType) -{ - if (SetSockopt(IPPROTO_IP, IP_TOS ,(WebRtc_Word8*)&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; - } - _error = errno; - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocketPosix::Bind() error: %d",_error); - return false; -} - -WebRtc_Word32 UdpSocketPosix::SendTo(const WebRtc_Word8* buf, WebRtc_Word32 len, - const SocketAddress& to) -{ - int size = sizeof(sockaddr); - int retVal = sendto(_socket,buf, len, 0, - reinterpret_cast(&to), size); - if(retVal == SOCKET_ERROR) - { - _error = errno; - WEBRTC_TRACE(kTraceError, kTraceTransport, _id, - "UdpSocketPosix::SendTo() error: %d", _error); - } - - return retVal; -} - -bool UdpSocketPosix::ValidHandle() -{ - return _socket != INVALID_SOCKET; -} - -void UdpSocketPosix::HasIncoming() -{ - // replace 2048 with a mcro define and figure out - // where 2048 comes from - WebRtc_Word8 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; - } -} - -void UdpSocketPosix::CloseBlocking() -{ - _cs->Enter(); - _closeBlockingActive = true; - if(!CleanUp()) - { - _closeBlockingActive = false; - _cs->Leave(); - return; - } - - while(!_readyForDeletion) - { - _readyForDeletionCond->SleepCS(*_cs); - } - _closeBlockingCompleted = true; - _closeBlockingCompletedCond->Wake(); - _cs->Leave(); -} - -void UdpSocketPosix::ReadyForDeletion() -{ - _cs->Enter(); - if(!_closeBlockingActive) - { - _cs->Leave(); - return; - } - close(_socket); - _socket = INVALID_SOCKET; - _readyForDeletion = true; - _readyForDeletionCond->Wake(); - while(!_closeBlockingCompleted) - { - _closeBlockingCompletedCond->SleepCS(*_cs); - } - _cs->Leave(); -} - -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 webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket_posix.h b/webrtc/modules/udp_transport/source/udp_socket_posix.h deleted file mode 100644 index ee76abb6fc..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_posix.h +++ /dev/null @@ -1,91 +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_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_POSIX_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_POSIX_H_ - -#include -#include -#include -#include - -#include "condition_variable_wrapper.h" -#include "critical_section_wrapper.h" -#include "udp_socket_wrapper.h" - -#define SOCKET_ERROR -1 - -namespace webrtc { -class UdpSocketPosix : public UdpSocketWrapper -{ -public: - UdpSocketPosix(const WebRtc_Word32 id, UdpSocketManager* mgr, - bool ipV6Enable = false); - - virtual ~UdpSocketPosix(); - - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); - - virtual bool SetCallback(CallbackObj obj, IncomingSocketCallback cb); - - virtual bool Bind(const SocketAddress& name); - - virtual bool SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname, - const WebRtc_Word8* optval, WebRtc_Word32 optlen); - - virtual WebRtc_Word32 SetTOS(const WebRtc_Word32 serviceType); - - virtual WebRtc_Word32 SendTo(const WebRtc_Word8* buf, WebRtc_Word32 len, - const SocketAddress& to); - - // Deletes socket in addition to closing it. - // TODO (hellner): make destructor protected. - virtual void CloseBlocking(); - - virtual SOCKET GetFd() {return _socket;} - virtual WebRtc_Word32 GetError() {return _error;} - - virtual bool ValidHandle(); - - virtual bool SetQos(WebRtc_Word32 /*serviceType*/, - WebRtc_Word32 /*tokenRate*/, - WebRtc_Word32 /*bucketSize*/, - WebRtc_Word32 /*peekBandwith*/, - WebRtc_Word32 /*minPolicedSize*/, - WebRtc_Word32 /*maxSduSize*/, - const SocketAddress& /*stRemName*/, - WebRtc_Word32 /*overrideDSCP*/) {return false;} - - bool CleanUp(); - void HasIncoming(); - bool WantsIncoming() {return _wantsIncoming;} - void ReadyForDeletion(); -private: - friend class UdpSocketManagerPosix; - - WebRtc_Word32 _id; - IncomingSocketCallback _incomingCb; - CallbackObj _obj; - WebRtc_Word32 _error; - - SOCKET _socket; - UdpSocketManager* _mgr; - ConditionVariableWrapper* _closeBlockingCompletedCond; - ConditionVariableWrapper* _readyForDeletionCond; - - bool _closeBlockingActive; - bool _closeBlockingCompleted; - bool _readyForDeletion; - - CriticalSectionWrapper* _cs; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_POSIX_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket_wrapper.cc b/webrtc/modules/udp_transport/source/udp_socket_wrapper.cc deleted file mode 100644 index 6445e76a52..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_wrapper.cc +++ /dev/null @@ -1,147 +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 "udp_socket_wrapper.h" - -#include -#include - -#include "event_wrapper.h" -#include "trace.h" -#include "udp_socket_manager_wrapper.h" - -#if defined(_WIN32) - #include "udp_socket2_windows.h" -#else - #include "udp_socket_posix.h" -#endif - - -namespace webrtc { -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 WebRtc_Word32 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 ); - WebRtc_Word32 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::StopReceiving() -{ - _wantsIncoming = false; - return true; -} -} // namespace webrtc diff --git a/webrtc/modules/udp_transport/source/udp_socket_wrapper.h b/webrtc/modules/udp_transport/source/udp_socket_wrapper.h deleted file mode 100644 index e5289cf649..0000000000 --- a/webrtc/modules/udp_transport/source/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_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_WRAPPER_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_WRAPPER_H_ - -#include "udp_transport.h" - -namespace webrtc { -class EventWrapper; -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 WebRtc_Word8* buf, - WebRtc_Word32 len, - const SocketAddress* from); - -class UdpSocketWrapper -{ -public: - static UdpSocketWrapper* CreateSocket(const WebRtc_Word32 id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable = false, - bool disableGQOS = false); - - // Set the unique identifier of this class to id. - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id) = 0; - - // 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 inline bool StartReceiving(const WebRtc_UWord32 /*receiveBuffers*/) - {return StartReceiving();} - // Stop receiving UDP data. - virtual bool StopReceiving(); - - virtual bool ValidHandle() = 0; - - // Set socket options. - virtual bool SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname, - const WebRtc_Word8* optval, - WebRtc_Word32 optlen) = 0; - - // Set TOS for outgoing packets. - virtual WebRtc_Word32 SetTOS(const WebRtc_Word32 serviceType) = 0; - - // Set 802.1Q PCP field (802.1p) for outgoing VLAN traffic. - virtual WebRtc_Word32 SetPCP(const WebRtc_Word32 /*pcp*/) {return -1;} - - // Send buf of length len to the address specified by to. - virtual WebRtc_Word32 SendTo(const WebRtc_Word8* buf, WebRtc_Word32 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(WebRtc_Word32 serviceType, WebRtc_Word32 tokenRate, - WebRtc_Word32 bucketSize, WebRtc_Word32 peekBandwith, - WebRtc_Word32 minPolicedSize, WebRtc_Word32 maxSduSize, - const SocketAddress &stRemName, - WebRtc_Word32 overrideDSCP = 0) = 0; - - virtual WebRtc_UWord32 ReceiveBuffers() {return 0;}; - -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; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_SOCKET_WRAPPER_H_ diff --git a/webrtc/modules/udp_transport/source/udp_socket_wrapper_unittest.cc b/webrtc/modules/udp_transport/source/udp_socket_wrapper_unittest.cc deleted file mode 100644 index 2489604d52..0000000000 --- a/webrtc/modules/udp_transport/source/udp_socket_wrapper_unittest.cc +++ /dev/null @@ -1,66 +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 "gtest/gtest.h" -#include "gmock/gmock.h" -#include "modules/udp_transport/source/udp_socket_wrapper.h" -#include "modules/udp_transport/source/udp_socket_manager_wrapper.h" - -using ::testing::_; -using ::testing::Return; - -namespace webrtc { - -class MockSocketManager : public UdpSocketManager { - public: - MockSocketManager() {} - // Access to protected destructor. - void Destroy() { - delete this; - } - MOCK_METHOD2(Init, bool(WebRtc_Word32, WebRtc_UWord8&)); - MOCK_METHOD1(ChangeUniqueId, WebRtc_Word32(const WebRtc_Word32)); - MOCK_METHOD0(Start, bool()); - MOCK_METHOD0(Stop, bool()); - MOCK_METHOD1(AddSocket, bool(webrtc::UdpSocketWrapper*)); - MOCK_METHOD1(RemoveSocket, bool(webrtc::UdpSocketWrapper*)); -}; - -// Creates a socket using the static constructor method and verifies that -// it's added to the socket manager. -TEST(UdpSocketWrapper, CreateSocket) { - WebRtc_Word32 id = 42; - // We can't test deletion of sockets without a socket manager. - WebRtc_UWord8 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 webrtc diff --git a/webrtc/modules/udp_transport/source/udp_transport.gypi b/webrtc/modules/udp_transport/source/udp_transport.gypi deleted file mode 100644 index a73a58735c..0000000000 --- a/webrtc/modules/udp_transport/source/udp_transport.gypi +++ /dev/null @@ -1,114 +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. - -{ - 'targets': [ - { - 'target_name': 'udp_transport', - 'type': 'static_library', - 'dependencies': [ - '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', - ], - 'include_dirs': [ - '../interface', - '../../interface', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../interface', - '../../interface', - ], - }, - 'sources': [ - # PLATFORM INDEPENDENT SOURCE FILES - '../interface/udp_transport.h', - 'udp_transport_impl.cc', - 'udp_socket_wrapper.cc', - 'udp_socket_manager_wrapper.cc', - 'udp_transport_impl.h', - 'udp_socket_wrapper.h', - 'udp_socket_manager_wrapper.h', - # PLATFORM SPECIFIC SOURCE FILES - Will be filtered below - # Posix (Linux/Mac) - 'udp_socket_posix.cc', - 'udp_socket_posix.h', - 'udp_socket_manager_posix.cc', - 'udp_socket_manager_posix.h', - # Windows - 'udp_socket2_manager_windows.cc', - 'udp_socket2_manager_windows.h', - 'udp_socket2_windows.cc', - 'udp_socket2_windows.h', - 'traffic_control_windows.cc', - 'traffic_control_windows.h', - ], # source - 'conditions': [ - # DEFINE PLATFORM SPECIFIC SOURCE FILES - ['os_posix==0', { - 'sources!': [ - 'udp_socket_posix.cc', - 'udp_socket_posix.h', - 'udp_socket_manager_posix.cc', - 'udp_socket_manager_posix.h', - ], - }], - ['OS!="win"', { - 'sources!': [ - 'udp_socket2_manager_windows.cc', - 'udp_socket2_manager_windows.h', - 'udp_socket2_windows.cc', - 'udp_socket2_windows.h', - 'traffic_control_windows.cc', - 'traffic_control_windows.h', - ], - }], - ['OS=="linux"', { - 'cflags': [ - '-fno-strict-aliasing', - ], - }], - ['OS=="mac"', { - 'xcode_settings': { - 'OTHER_CPLUSPLUSFLAGS': [ '-fno-strict-aliasing' ], - }, - }], - ] # conditions - }, - ], # targets - 'conditions': [ - ['include_tests==1', { - 'targets': [ - { - 'target_name': 'udp_transport_unittests', - 'type': 'executable', - 'dependencies': [ - 'udp_transport', - '<(DEPTH)/testing/gtest.gyp:gtest', - '<(DEPTH)/testing/gmock.gyp:gmock', - '<(webrtc_root)/test/test.gyp:test_support_main', - ], - 'sources': [ - 'udp_transport_unittest.cc', - 'udp_socket_manager_unittest.cc', - 'udp_socket_wrapper_unittest.cc', - ], - # Disable warnings to enable Win64 build, issue 1323. - 'msvs_disabled_warnings': [ - 4267, # size_t to int truncation. - ], - }, # udp_transport_unittests - ], # targets - }], # include_tests - ], # conditions -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/webrtc/modules/udp_transport/source/udp_transport_impl.cc b/webrtc/modules/udp_transport/source/udp_transport_impl.cc deleted file mode 100644 index b7ded87463..0000000000 --- a/webrtc/modules/udp_transport/source/udp_transport_impl.cc +++ /dev/null @@ -1,3035 +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 "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 "common_types.h" -#include "critical_section_wrapper.h" -#include "rw_lock_wrapper.h" -#include "trace.h" -#include "typedefs.h" -#include "udp_socket_manager_wrapper.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 { - -class SocketFactory : public UdpTransportImpl::SocketFactoryInterface { - public: - UdpSocketWrapper* CreateSocket(const WebRtc_Word32 id, - UdpSocketManager* mgr, - CallbackObj obj, - IncomingSocketCallback cb, - bool ipV6Enable, - bool disableGQOS) { - 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 WebRtc_Word32 id, - WebRtc_UWord8& 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 WebRtc_Word32 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__); -} - -WebRtc_Word32 UdpTransportImpl::ChangeUniqueId(const WebRtc_Word32 id) -{ - - CriticalSectionScoped cs(_crit); - _id = id; - if(_mgr) - { - _mgr->ChangeUniqueId(id); - } - if(_ptrRtpSocket) - { - _ptrRtpSocket->ChangeUniqueId(id); - } - if(_ptrRtcpSocket) - { - _ptrRtcpSocket->ChangeUniqueId(id); - } - if(_ptrSendRtpSocket) - { - _ptrSendRtpSocket->ChangeUniqueId(id); - } - if(_ptrSendRtcpSocket) - { - _ptrSendRtcpSocket->ChangeUniqueId(id); - } - return 0; -} - -WebRtc_Word32 UdpTransportImpl::TimeUntilNextProcess() -{ - return 100; -} - -WebRtc_Word32 UdpTransportImpl::Process() -{ - return 0; -} - -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, - WebRtc_UWord32& ipSize, - WebRtc_UWord16& sourcePort) -{ - const WebRtc_UWord32 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(WebRtc_Word8)*(ipSize + 1)); - ip[originalIPSize - 1] = '\0'; - sourcePort = _previousSourcePort; -} - -WebRtc_Word32 UdpTransportImpl::IPAddressCached(const SocketAddress& address, - char* ip, - WebRtc_UWord32& ipSize, - WebRtc_UWord16& 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; -} - -WebRtc_Word32 UdpTransportImpl::InitializeReceiveSockets( - UdpTransportData* const packetCallback, - const WebRtc_UWord16 portnr, - const char* ip, - const char* multicastIpAddr, - const WebRtc_UWord16 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; -} - -WebRtc_Word32 UdpTransportImpl::ReceiveSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& 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; -} - -WebRtc_Word32 UdpTransportImpl::SendSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const -{ - CriticalSectionScoped cs(_crit); - rtpPort = _destPort; - rtcpPort = _destPortRTCP; - strncpy(ipAddr, _destIP, IpV6Enabled() ? - UdpTransport::kIpAddressVersion6Length : - UdpTransport::kIpAddressVersion4Length); - return 0; -} - -WebRtc_Word32 UdpTransportImpl::RemoteSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const -{ - CriticalSectionScoped cs(_crit); - rtpPort = _fromPort; - rtcpPort = _fromPortRTCP; - if(ipAddr) - { - strncpy(ipAddr, _fromIP, IpV6Enabled() ? - kIpAddressVersion6Length : - kIpAddressVersion4Length); - } - return 0; -} - -WebRtc_Word32 UdpTransportImpl::FilterPorts( - WebRtc_UWord16& rtpFilterPort, - WebRtc_UWord16& rtcpFilterPort) const -{ - CriticalSectionScoped cs(_critFilter); - rtpFilterPort = _rtpFilterPort; - rtcpFilterPort = _rtcpFilterPort; - return 0; -} - -WebRtc_Word32 UdpTransportImpl::SetQoS(bool QoS, WebRtc_Word32 serviceType, - WebRtc_UWord32 maxBitrate, - WebRtc_Word32 overrideDSCP, bool audio) -{ - if(QoS) - { - return EnableQoS(serviceType, audio, maxBitrate, overrideDSCP); - }else - { - return DisableQoS(); - } -} - -WebRtc_Word32 UdpTransportImpl::EnableQoS(WebRtc_Word32 serviceType, - bool audio, WebRtc_UWord32 maxBitrate, - WebRtc_Word32 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 WebRtc_Word32 min_policed_size = 12; - // Max SDU, maximum packet size permitted or used in the traffic flow, in - // bytes. - const WebRtc_Word32 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 WebRtc_Word32 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 WebRtc_Word32 bucket_size = maxBitrate * 8; - const WebRtc_Word32 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 WebRtc_Word32 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 WebRtc_Word32 bucket_size = maxBitrate*31; - const WebRtc_Word32 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 WebRtc_Word32 token_rate = 30000; - const WebRtc_Word32 bucket_size = 2000; - const WebRtc_Word32 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 WebRtc_Word32 token_rate = 128000*10; - const WebRtc_Word32 bucket_size = 32000; - const WebRtc_Word32 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 WebRtc_Word32 token_rate = 200; - const WebRtc_Word32 bucket_size = 200; - const WebRtc_Word32 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 WebRtc_Word32 token_rate = 5000; - const WebRtc_Word32 bucket_size = 100; - const WebRtc_Word32 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; -} - -WebRtc_Word32 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 WebRtc_Word32 service_type = 0; // = SERVICETYPE_NOTRAFFIC - const WebRtc_Word32 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; -} - -WebRtc_Word32 UdpTransportImpl::QoS(bool& QoS, WebRtc_Word32& serviceType, - WebRtc_Word32& overrideDSCP) const -{ - CriticalSectionScoped cs(_crit); - QoS = _qos; - serviceType = _serviceType; - overrideDSCP = _overrideDSCP; - return 0; -} - -WebRtc_Word32 UdpTransportImpl::SetToS(WebRtc_Word32 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; - WebRtc_UWord32 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"); - WebRtc_Word32 TOSShifted = DSCP << 2; - if (!rtpSock->SetSockopt(IPPROTO_IP, IP_TOS, - (WebRtc_Word8*) &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, - (WebRtc_Word8*) &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; -} - -WebRtc_Word32 UdpTransportImpl::ToS(WebRtc_Word32& DSCP, - bool& useSetSockOpt) const -{ - CriticalSectionScoped cs(_crit); - DSCP = _tos; - useSetSockOpt = _useSetSockOpt; - return 0; -} - -WebRtc_Word32 UdpTransportImpl::SetPCP(WebRtc_Word32 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, (WebRtc_Word8*) &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, (WebRtc_Word8*) &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; -} - -WebRtc_Word32 UdpTransportImpl::PCP(WebRtc_Word32& PCP) const -{ - CriticalSectionScoped cs(_crit); - PCP = _pcp; - return 0; -} - -bool UdpTransportImpl::SetSockOptUsed() -{ - return _useSetSockOpt; -} - -WebRtc_Word32 UdpTransportImpl::EnableIpV6() { - - CriticalSectionScoped cs(_crit); - const bool initialized = (_ptrSendRtpSocket || _ptrRtpSocket); - - if (_ipV6Enabled) { - return 0; - } - if (initialized) { - _lastError = kIpVersion6Error; - return -1; - } - _ipV6Enabled = true; - return 0; -} - -WebRtc_Word32 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); - WebRtc_UWord32 ipSize = kIpAddressVersion6Length; - WebRtc_UWord16 sourcePort; - return IPAddress(_filterIPAddress, filterIPAddress, ipSize, sourcePort); -} - -WebRtc_Word32 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; -} - -WebRtc_Word32 UdpTransportImpl::SetFilterPorts(WebRtc_UWord16 rtpFilterPort, - WebRtc_UWord16 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_length = 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, - (WebRtc_Word8*)&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, - (WebRtc_Word8*)&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; -} - -WebRtc_Word32 UdpTransportImpl::InitializeSourcePorts(WebRtc_UWord16 rtpPort, - WebRtc_UWord16 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; -} - -WebRtc_Word32 UdpTransportImpl::SourcePorts(WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const -{ - CriticalSectionScoped cs(_crit); - - rtpPort = (_srcPort != 0) ? _srcPort : _localPort; - rtcpPort = (_srcPortRTCP != 0) ? _srcPortRTCP : _localPortRTCP; - return 0; -} - - -#ifdef _WIN32 -WebRtc_Word32 UdpTransportImpl::StartReceiving( - WebRtc_UWord32 numberOfSocketBuffers) -#else -WebRtc_Word32 UdpTransportImpl::StartReceiving( - WebRtc_UWord32 /*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; -} - -WebRtc_Word32 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; -} - -WebRtc_Word32 UdpTransportImpl::InitializeSendSockets( - const char* ipaddr, - const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 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. - WebRtc_Word32 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 - WebRtc_Word32 iOptVal = 64; - if (!rtpSock->SetSockopt(IPPROTO_IP, IP_MULTICAST_TTL, - (WebRtc_Word8*)&iOptVal, - sizeof (WebRtc_Word32))) - { - 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, - (WebRtc_Word8*)&iOptVal, - sizeof (WebRtc_Word32))) - { - 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(WebRtc_UWord16 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)); - } -} - -WebRtc_Word32 UdpTransportImpl::SendRaw(const WebRtc_Word8 *data, - WebRtc_UWord32 length, - WebRtc_Word32 isRTCP, - WebRtc_UWord16 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); - } - } -} - -WebRtc_Word32 UdpTransportImpl::SendRTPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 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; -} - -WebRtc_Word32 UdpTransportImpl::SendRTCPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 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; -} - -WebRtc_Word32 UdpTransportImpl::SendRTPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 length, - const WebRtc_UWord16 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; -} - -WebRtc_Word32 UdpTransportImpl::SendRTCPPacketTo(const WebRtc_Word8* data, - WebRtc_UWord32 length, - const WebRtc_UWord16 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; -} - -int UdpTransportImpl::SendPacket(int /*channel*/, const void* data, int length) -{ - WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, "%s", __FUNCTION__); - - CriticalSectionScoped cs(_crit); - - if(_destIP[0] == 0) - { - return -1; - } - if(_destPort == 0) - { - return -1; - } - - // 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 -1; - } - } - - if(_ptrSendRtpSocket) - { - return _ptrSendRtpSocket->SendTo((const WebRtc_Word8*)data, length, - _remoteRTPAddr); - - } else if(_ptrRtpSocket) - { - return _ptrRtpSocket->SendTo((const WebRtc_Word8*)data, length, - _remoteRTPAddr); - } - return -1; -} - -int UdpTransportImpl::SendRTCPPacket(int /*channel*/, const void* data, - int length) -{ - - CriticalSectionScoped cs(_crit); - if(_destIP[0] == 0) - { - return -1; - } - if(_destPortRTCP == 0) - { - return -1; - } - - // 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, - "SendRTCPPacket() failed to bind RTCP socket"); - CloseReceiveSockets(); - return -1; - } - } - - if(_ptrSendRtcpSocket) - { - return _ptrSendRtcpSocket->SendTo((const WebRtc_Word8*)data, length, - _remoteRTCPAddr); - } else if(_ptrRtcpSocket) - { - return _ptrRtcpSocket->SendTo((const WebRtc_Word8*)data, length, - _remoteRTCPAddr); - } - return -1; -} - -WebRtc_Word32 UdpTransportImpl::SetSendIP(const char* ipaddr) -{ - if(!IsIpAddressValid(ipaddr,IpV6Enabled())) - { - return kIpAddressInvalid; - } - CriticalSectionScoped cs(_crit); - strncpy(_destIP, ipaddr,kIpAddressVersion6Length); - BuildRemoteRTPAddr(); - BuildRemoteRTCPAddr(); - return 0; -} - -WebRtc_Word32 UdpTransportImpl::SetSendPorts(WebRtc_UWord16 rtpPort, - WebRtc_UWord16 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 WebRtc_Word8* rtpPacket, - WebRtc_Word32 rtpPacketLength, - const SocketAddress* from) -{ - if (rtpPacket && rtpPacketLength > 0) - { - UdpTransportImpl* socketTransport = (UdpTransportImpl*) obj; - socketTransport->IncomingRTPFunction(rtpPacket, rtpPacketLength, from); - } -} - -void UdpTransportImpl::IncomingRTCPCallback(CallbackObj obj, - const WebRtc_Word8* rtcpPacket, - WebRtc_Word32 rtcpPacketLength, - const SocketAddress* from) -{ - if (rtcpPacket && rtcpPacketLength > 0) - { - UdpTransportImpl* socketTransport = (UdpTransportImpl*) obj; - socketTransport->IncomingRTCPFunction(rtcpPacket, rtcpPacketLength, - from); - } -} - -void UdpTransportImpl::IncomingRTPFunction(const WebRtc_Word8* rtpPacket, - WebRtc_Word32 rtpPacketLength, - const SocketAddress* fromSocket) -{ - char ipAddress[kIpAddressVersion6Length]; - WebRtc_UWord32 ipAddressLength = kIpAddressVersion6Length; - WebRtc_UWord16 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 WebRtc_Word8* rtcpPacket, - WebRtc_Word32 rtcpPacketLength, - const SocketAddress* fromSocket) -{ - char ipAddress[kIpAddressVersion6Length]; - WebRtc_UWord32 ipAddressLength = kIpAddressVersion6Length; - WebRtc_UWord16 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 (WebRtc_Word32 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; - } -} - -WebRtc_UWord16 UdpTransport::Htons(const WebRtc_UWord16 port) -{ - return htons(port); -} - -WebRtc_UWord32 UdpTransport::Htonl(const WebRtc_UWord32 a) -{ - return htonl(a); -} - -WebRtc_UWord32 UdpTransport::InetAddrIPV4(const char* ip) -{ - return ::inet_addr(ip); -} - -WebRtc_Word32 UdpTransport::InetPresentationToNumeric(WebRtc_Word32 af, - const char* src, - void* dst) -{ -#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC) - const WebRtc_Word32 result = inet_pton(af, src, dst); - return result > 0 ? 0 : -1; - -#elif defined(_WIN32) - SocketAddress temp; - int length=sizeof(SocketAddress); - - if(af == AF_INET) - { - WebRtc_Word32 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) - { - WebRtc_Word32 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 -} - -WebRtc_Word32 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 length 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 -} - -WebRtc_Word32 UdpTransport::LocalHostAddress(WebRtc_UWord32& 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 - { - WebRtc_Word32 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 -} - -WebRtc_Word32 UdpTransport::IPAddress(const SocketAddress& address, - char* ip, - WebRtc_UWord32& ipSize, - WebRtc_UWord16& sourcePort) -{ - #if defined(_WIN32) - DWORD dwIPSize = ipSize; - WebRtc_Word32 returnvalue = WSAAddressToStringA((LPSOCKADDR)(&address), - sizeof(SocketAddress), - NULL, - ip, - &dwIPSize); - if(returnvalue == -1) - { - return -1; - } - - WebRtc_UWord16 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 = (WebRtc_Word32)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 - WebRtc_Word32 adrSize = WebRtc_Word32(ipEnd - ip) - 1; - memmove(ip, &ip[1], adrSize); // Remove '[' - *(ipEnd - 1) = '\0'; - } - ipSize = (WebRtc_Word32)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) - WebRtc_Word32 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; - } - WebRtc_UWord16 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) - { - WebRtc_Word32 len = (WebRtc_Word32)strlen(ipadr); - if( len>39 || len == 0) - { - return false; - } - - WebRtc_Word32 i; - WebRtc_Word32 colonPos[7] = {0,0,0,0,0,0,0}; - WebRtc_Word32 lastColonPos = -2; - WebRtc_Word32 nColons = 0; - WebRtc_Word32 nDubbleColons = 0; - WebRtc_Word32 nDots = 0; - WebRtc_Word32 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(!(nDots == 3 || nDots == 0)) - { - return false; - } - lastColonPos = -1; - WebRtc_Word32 charsBeforeColon = 0; - for(i = 0; i < nColons; i++) - { - charsBeforeColon=colonPos[i]-lastColonPos-1; - if(charsBeforeColon > 4) - { - return false; - } - lastColonPos=colonPos[i]; - } - WebRtc_Word32 lengthAfterLastColon = len - lastColonPos - 1; - if(nDots == 0) - { - if(lengthAfterLastColon > 4) - return false; - } - if(nDots == 3 && lengthAfterLastColon > 0) - { - return IsIpAddressValid((ipadr+lastColonPos+1),false); - } - - } - else - { - WebRtc_Word32 len = (WebRtc_Word32)strlen(ipadr); - if((len>15)||(len==0)) - { - return false; - } - - // IPv4 should be [0-255].[0-255].[0-255].[0-255] - WebRtc_Word32 i; - WebRtc_Word32 nDots = 0; - WebRtc_Word32 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; - } - } - - 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]); - WebRtc_Word32 num = atoi(nr); - if (num > 255) - { - 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); - WebRtc_Word32 num = atoi(nr); - if (num > 255) - break; - } else { - break; - } - - if (iDotPos[2] - iDotPos[1] <= 4) - { - char nr[4]; - memset(nr,0,4); - strncpy(nr,&ipadr[iDotPos[1]+1], iDotPos[1] - iDotPos[0] - 1); - WebRtc_Word32 num = atoi(nr); - if (num > 255) - break; - - memset(nr,0,4); - strncpy(nr,&ipadr[iDotPos[2]+1], len - iDotPos[2] -1); - num = atoi(nr); - if (num > 255) - break; - else - allUnder256 = true; - } else - break; - } while(false); - - if (nDots != 3 || !allUnder256) - { - return false; - } - } - return true; -} -} // namespace webrtc diff --git a/webrtc/modules/udp_transport/source/udp_transport_impl.h b/webrtc/modules/udp_transport/source/udp_transport_impl.h deleted file mode 100644 index 9f4fd9fb06..0000000000 --- a/webrtc/modules/udp_transport/source/udp_transport_impl.h +++ /dev/null @@ -1,263 +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_MODULES_UDP_TRANSPORT_SOURCE_UDP_TRANSPORT_IMPL_H_ -#define WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_TRANSPORT_IMPL_H_ - -#include "udp_transport.h" -#include "udp_socket_wrapper.h" - -namespace webrtc { -class CriticalSectionWrapper; -class RWLockWrapper; -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 WebRtc_Word32 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 WebRtc_Word32 id, - SocketFactoryInterface* maker, - UdpSocketManager* socket_manager); - virtual ~UdpTransportImpl(); - - // Module functions - virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id); - virtual WebRtc_Word32 TimeUntilNextProcess(); - virtual WebRtc_Word32 Process(); - - // UdpTransport functions - virtual WebRtc_Word32 InitializeSendSockets( - const char* ipAddr, - const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 rtcpPort = 0); - virtual WebRtc_Word32 InitializeReceiveSockets( - UdpTransportData* const packetCallback, - const WebRtc_UWord16 rtpPort, - const char* ipAddr = NULL, - const char* multicastIpAddr = NULL, - const WebRtc_UWord16 rtcpPort = 0); - virtual WebRtc_Word32 InitializeSourcePorts( - const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 rtcpPort = 0); - virtual WebRtc_Word32 SourcePorts(WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const; - virtual WebRtc_Word32 ReceiveSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort, - char multicastIpAddr[kIpAddressVersion6Length]) const; - virtual WebRtc_Word32 SendSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const; - virtual WebRtc_Word32 RemoteSocketInformation( - char ipAddr[kIpAddressVersion6Length], - WebRtc_UWord16& rtpPort, - WebRtc_UWord16& rtcpPort) const; - virtual WebRtc_Word32 SetQoS(const bool QoS, - const WebRtc_Word32 serviceType, - const WebRtc_UWord32 maxBitrate = 0, - const WebRtc_Word32 overrideDSCP = 0, - const bool audio = false); - virtual WebRtc_Word32 QoS(bool& QoS, WebRtc_Word32& serviceType, - WebRtc_Word32& overrideDSCP) const; - virtual WebRtc_Word32 SetToS(const WebRtc_Word32 DSCP, - const bool useSetSockOpt = false); - virtual WebRtc_Word32 ToS(WebRtc_Word32& DSCP, - bool& useSetSockOpt) const; - virtual WebRtc_Word32 SetPCP(const WebRtc_Word32 PCP); - virtual WebRtc_Word32 PCP(WebRtc_Word32& PCP) const; - virtual WebRtc_Word32 EnableIpV6(); - virtual bool IpV6Enabled() const; - virtual WebRtc_Word32 SetFilterIP( - const char filterIPAddress[kIpAddressVersion6Length]); - virtual WebRtc_Word32 FilterIP( - char filterIPAddress[kIpAddressVersion6Length]) const; - virtual WebRtc_Word32 SetFilterPorts(const WebRtc_UWord16 rtpFilterPort, - const WebRtc_UWord16 rtcpFilterPort); - virtual WebRtc_Word32 FilterPorts(WebRtc_UWord16& rtpFilterPort, - WebRtc_UWord16& rtcpFilterPort) const; - virtual WebRtc_Word32 StartReceiving( - const WebRtc_UWord32 numberOfSocketBuffers); - virtual WebRtc_Word32 StopReceiving(); - virtual bool Receiving() const; - virtual bool SendSocketsInitialized() const; - virtual bool SourcePortsInitialized() const; - virtual bool ReceiveSocketsInitialized() const; - virtual WebRtc_Word32 SendRaw(const WebRtc_Word8* data, - WebRtc_UWord32 length, WebRtc_Word32 isRTCP, - WebRtc_UWord16 portnr = 0, - const char* ip = NULL); - virtual WebRtc_Word32 SendRTPPacketTo(const WebRtc_Word8 *data, - WebRtc_UWord32 length, - const SocketAddress& to); - virtual WebRtc_Word32 SendRTCPPacketTo(const WebRtc_Word8 *data, - WebRtc_UWord32 length, - const SocketAddress& to); - virtual WebRtc_Word32 SendRTPPacketTo(const WebRtc_Word8 *data, - WebRtc_UWord32 length, - WebRtc_UWord16 rtpPort); - virtual WebRtc_Word32 SendRTCPPacketTo(const WebRtc_Word8 *data, - WebRtc_UWord32 length, - WebRtc_UWord16 rtcpPort); - // Transport functions - virtual int SendPacket(int channel, const void* data, int length); - virtual int SendRTCPPacket(int channel, const void* data, int length); - - // UdpTransport functions continue. - virtual WebRtc_Word32 SetSendIP(const char* ipaddr); - virtual WebRtc_Word32 SetSendPorts(const WebRtc_UWord16 rtpPort, - const WebRtc_UWord16 rtcpPort = 0); - - virtual ErrorCode LastError() const; - - virtual WebRtc_Word32 IPAddressCached(const SocketAddress& address, - char* ip, - WebRtc_UWord32& ipSize, - WebRtc_UWord16& sourcePort); - - WebRtc_Word32 Id() const {return _id;} -protected: - // IncomingSocketCallback signature functions for receiving callbacks from - // UdpSocketWrapper. - static void IncomingRTPCallback(CallbackObj obj, - const WebRtc_Word8* rtpPacket, - WebRtc_Word32 rtpPacketLength, - const SocketAddress* from); - static void IncomingRTCPCallback(CallbackObj obj, - const WebRtc_Word8* rtcpPacket, - WebRtc_Word32 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(WebRtc_UWord16 portnr, const char* ip, - SocketAddress& remoteAddr) const; - - ErrorCode BindLocalRTPSocket(); - ErrorCode BindLocalRTCPSocket(); - - ErrorCode BindRTPSendSocket(); - ErrorCode BindRTCPSendSocket(); - - void IncomingRTPFunction(const WebRtc_Word8* rtpPacket, - WebRtc_Word32 rtpPacketLength, - const SocketAddress* from); - void IncomingRTCPFunction(const WebRtc_Word8* rtcpPacket, - WebRtc_Word32 rtcpPacketLength, - const SocketAddress* from); - - bool FilterIPAddress(const SocketAddress* fromAddress); - - bool SetSockOptUsed(); - - WebRtc_Word32 EnableQoS(WebRtc_Word32 serviceType, bool audio, - WebRtc_UWord32 maxBitrate, - WebRtc_Word32 overrideDSCP); - - WebRtc_Word32 DisableQoS(); - -private: - void GetCachedAddress(char* ip, WebRtc_UWord32& ipSize, - WebRtc_UWord16& sourcePort); - - WebRtc_Word32 _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. - WebRtc_UWord16 _destPort; - WebRtc_UWord16 _destPortRTCP; - - // Local RTP and RTCP ports. - WebRtc_UWord16 _localPort; - WebRtc_UWord16 _localPortRTCP; - - // Local port number when the local port for receiving and local port number - // for sending are not the same. - WebRtc_UWord16 _srcPort; - WebRtc_UWord16 _srcPortRTCP; - - // Remote port from which last received packet was sent. - WebRtc_UWord16 _fromPort; - WebRtc_UWord16 _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; - - WebRtc_Word32 _tos; - bool _receiving; - bool _useSetSockOpt; - bool _qos; - WebRtc_Word32 _pcp; - bool _ipV6Enabled; - WebRtc_Word32 _serviceType; - WebRtc_Word32 _overrideDSCP; - WebRtc_UWord32 _maxBitrate; - - // Cache used by GetCachedAddress(..). - RWLockWrapper* _cachLock; - SocketAddress _previousAddress; - char _previousIP[kIpAddressVersion6Length]; - WebRtc_UWord32 _previousIPSize; - WebRtc_UWord16 _previousSourcePort; - - SocketAddress _filterIPAddress; - WebRtc_UWord16 _rtpFilterPort; - WebRtc_UWord16 _rtcpFilterPort; - - UdpTransportData* _packetCallback; -}; -} // namespace webrtc - -#endif // WEBRTC_MODULES_UDP_TRANSPORT_SOURCE_UDP_TRANSPORT_IMPL_H_ diff --git a/webrtc/modules/udp_transport/source/udp_transport_unittest.cc b/webrtc/modules/udp_transport/source/udp_transport_unittest.cc deleted file mode 100644 index 3125e2e5fb..0000000000 --- a/webrtc/modules/udp_transport/source/udp_transport_unittest.cc +++ /dev/null @@ -1,141 +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 "udp_transport.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -// We include the implementation header file to get at the dependency-injecting -// constructor. -#include "udp_transport_impl.h" -// We must mock the socket manager, for which we need its definition. -#include "udp_socket_manager_wrapper.h" - -using ::testing::_; -using ::testing::Return; - -class MockUdpSocketWrapper : public webrtc::UdpSocketWrapper { - public: - // The following methods have to be mocked because they are pure. - MOCK_METHOD1(ChangeUniqueId, WebRtc_Word32(WebRtc_Word32)); - MOCK_METHOD2(SetCallback, bool(webrtc::CallbackObj, - webrtc::IncomingSocketCallback)); - MOCK_METHOD1(Bind, bool(const webrtc::SocketAddress&)); - MOCK_METHOD0(ValidHandle, bool()); - MOCK_METHOD4(SetSockopt, bool(WebRtc_Word32, WebRtc_Word32, - const WebRtc_Word8*, - WebRtc_Word32)); - MOCK_METHOD1(SetTOS, WebRtc_Word32(WebRtc_Word32)); - MOCK_METHOD3(SendTo, WebRtc_Word32(const WebRtc_Word8*, WebRtc_Word32, - const webrtc::SocketAddress&)); - MOCK_METHOD8(SetQos, bool(WebRtc_Word32, WebRtc_Word32, - WebRtc_Word32, WebRtc_Word32, - WebRtc_Word32, WebRtc_Word32, - const webrtc::SocketAddress &, - WebRtc_Word32)); -}; - -class MockUdpSocketManager : public webrtc::UdpSocketManager { - public: - // Access to protected destructor. - void Destroy() { - delete this; - } - MOCK_METHOD2(Init, bool(WebRtc_Word32, WebRtc_UWord8&)); - MOCK_METHOD1(ChangeUniqueId, WebRtc_Word32(const WebRtc_Word32)); - MOCK_METHOD0(Start, bool()); - MOCK_METHOD0(Stop, bool()); - MOCK_METHOD1(AddSocket, bool(webrtc::UdpSocketWrapper*)); - MOCK_METHOD1(RemoveSocket, bool(webrtc::UdpSocketWrapper*)); -}; - -class MockSocketFactory : - public webrtc::UdpTransportImpl::SocketFactoryInterface { - public: - MockSocketFactory(std::vector* socket_counter) - : socket_counter_(socket_counter) { - } - webrtc::UdpSocketWrapper* CreateSocket(const WebRtc_Word32 id, - webrtc::UdpSocketManager* mgr, - webrtc::CallbackObj obj, - webrtc::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(); - } - } - - int NumSocketsCreated() { - return sockets_created_.size(); - } - - std::vector* sockets_created() { - return &sockets_created_; - } -private: - std::vector sockets_created_; -}; - -TEST_F(UDPTransportTest, CreateTransport) { - WebRtc_Word32 id = 0; - WebRtc_UWord8 threads = 1; - webrtc::UdpTransport* transport = webrtc::UdpTransport::Create(id, threads); - webrtc::UdpTransport::Destroy(transport); -} - -// This test verifies that the mock_socket is not called from the constructor. -TEST_F(UDPTransportTest, ConstructorDoesNotCreateSocket) { - WebRtc_Word32 id = 0; - webrtc::UdpTransportImpl::SocketFactoryInterface* null_maker = NULL; - webrtc::UdpSocketManager* null_manager = NULL; - webrtc::UdpTransport* transport = new webrtc::UdpTransportImpl(id, - null_maker, - null_manager); - delete transport; -} - -TEST_F(UDPTransportTest, InitializeSourcePorts) { - WebRtc_Word32 id = 0; - webrtc::UdpTransportImpl::SocketFactoryInterface* mock_maker - = new MockSocketFactory(sockets_created()); - MockUdpSocketManager* mock_manager = new MockUdpSocketManager(); - webrtc::UdpTransport* transport = new webrtc::UdpTransportImpl(id, - mock_maker, - mock_manager); - EXPECT_EQ(0, transport->InitializeSourcePorts(4711, 4712)); - EXPECT_EQ(2, NumSocketsCreated()); - - delete transport; - mock_manager->Destroy(); -} diff --git a/webrtc/modules/udp_transport/test/SocketManagerTest.cc b/webrtc/modules/udp_transport/test/SocketManagerTest.cc deleted file mode 100644 index 03119bec56..0000000000 --- a/webrtc/modules/udp_transport/test/SocketManagerTest.cc +++ /dev/null @@ -1,449 +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 - -#ifdef _WIN32 -#include -#include -#else -#include -#define Sleep(x) usleep(x*1000) -#endif - -#include "udp_transport.h" -#include "common_types.h" -#include "trace.h" - -//#define QOS_TEST -//#define QOS_TEST_WITH_OVERRIDE // require admin on Win7 -//#define TOS_TEST // require admin on Win7 -//#define TOS_TEST_USING_SETSOCKOPT -//#define PCP_TEST - -class UdpTransportDataA: public UdpTransportData -{ -public: - UdpTransportDataA() : - _counterRTP(0), - _counterRTCP(0) - { - }; - virtual void IncomingRTPPacket(const WebRtc_Word8* incommingRtpPacket, - const WebRtc_Word32 rtpPacketLength, - const char* fromIP, - const WebRtc_UWord16 fromPort) - { - _counterRTP++; - }; - - virtual void IncomingRTCPPacket(const WebRtc_Word8* incommingRtcpPacket, - const WebRtc_Word32 rtcpPacketLength, - const char* fromIP, - const WebRtc_UWord16 fromPort) - { - _counterRTCP++; - }; - WebRtc_UWord32 _counterRTP; - WebRtc_UWord32 _counterRTCP; -}; - -class UdpTransportDataB: public UdpTransportData -{ -public: - UdpTransportDataB() : - _counterRTP(0), - _counterRTCP(0) - { - }; - virtual void IncomingRTPPacket(const WebRtc_Word8* incommingRtpPacket, - const WebRtc_Word32 rtpPacketLength, - const char* fromIP, - const WebRtc_UWord16 fromPort) - { - _counterRTP++; - }; - - virtual void IncomingRTCPPacket(const WebRtc_Word8* incommingRtcpPacket, - const WebRtc_Word32 rtcpPacketLength, - const char* fromIP, - const WebRtc_UWord16 fromPort) - { - _counterRTCP++; - }; - WebRtc_UWord32 _counterRTP; - WebRtc_UWord32 _counterRTCP; -}; - -#ifdef _WIN32 -int _tmain(int argc, _TCHAR* argv[]) -#else -int main(int argc, char* argv[]) -#endif -{ - Trace::CreateTrace(); - Trace::SetTraceFile("testTrace.txt"); - Trace::SetEncryptedTraceFile("testTraceDebug.txt"); - Trace::SetLevelFilter(webrtc::kTraceAll); - - printf("Start UdpTransport test\n"); - - WebRtc_UWord8 numberOfSocketThreads = 5; - UdpTransport* client1 = UdpTransport::Create(1,numberOfSocketThreads,NULL); - numberOfSocketThreads = 0; - UdpTransport* client2 = UdpTransport::Create(2,numberOfSocketThreads,NULL); - assert(5 == numberOfSocketThreads); - - UdpTransportDataA* client1Callback = new UdpTransportDataA(); - UdpTransportDataB* client2Callback = new UdpTransportDataB(); - - WebRtc_UWord32 localIP = 0; - char localIPAddr[64]; - assert( 0 == client1->LocalHostAddress(localIP)); // network host order aka big-endian - - sprintf(localIPAddr,"%lu.%lu.%lu.%lu",(localIP>>24)& 0x0ff,(localIP>>16)& 0x0ff ,(localIP>>8)& 0x0ff, localIP & 0x0ff); - printf("\tLocal IP:%s\n", localIPAddr); - - char localIPV6[16]; - char localIPAddrV6[128]; - if( 0 == client1->LocalHostAddressIPV6(localIPV6)) - { - sprintf(localIPAddrV6,"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", localIPV6[0],localIPV6[1],localIPV6[2],localIPV6[3],localIPV6[4],localIPV6[5],localIPV6[6],localIPV6[7], localIPV6[8],localIPV6[9],localIPV6[10],localIPV6[11],localIPV6[12],localIPV6[13],localIPV6[14],localIPV6[15]); - printf("\tLocal IPV6:%s\n", localIPAddrV6); - } - - char test[9] = "testtest"; - assert( 0 == client1->InitializeReceiveSockets(client1Callback,1234, localIPAddr)); - -#if defined QOS_TEST_WITH_OVERRIDE || defined QOS_TEST || defined TOS_TEST || defined TOS_TEST_USING_SETSOCKOPT - assert( -1 == client1->SetQoS(true, 3, 1000)); // should fail - assert( 0 == client1->InitializeSendSockets("192.168.200.1", 1236,1237)); -#else - assert( 0 == client1->InitializeSendSockets(localIPAddr, 1236,1237)); -#endif - assert( 0 == client1->StartReceiving(20)); - - assert( 0 == client2->InitializeReceiveSockets(client2Callback,1236)); - assert( 0 == client2->InitializeSendSockets(localIPAddr, 1234,1235)); - assert( 0 == client2->StartReceiving(20)); - - Sleep(10); - -#ifdef TOS_TEST - // note: you need to have QOS installed on your interface for this test - // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 - assert( 0 == client1->SetToS(2)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetToS(3)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetToS(0)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - - printf("Tested TOS \n"); - Sleep(5000); - return 0; -#endif - -#ifdef TOS_TEST_USING_SETSOCKOPT - // note: you need to have QOS installed on your interface for this test - // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 - assert( 0 == client1->SetToS(2, true)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetToS(3, true)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetToS(0, true)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - - printf("Tested TOS using setsockopt \n"); - Sleep(5000); - return 0; -#endif - -#ifdef QOS_TEST - // note: you need to have QOS installed on your interface for this test - // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 - assert( 0 == client1->SetQoS(true, 2, 1000)); // SERVICETYPE_CONTROLLEDLOAD 2 - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetQoS(true, 3, 1000)); // SERVICETYPE_GUARANTEED 3 - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetQoS(false, 0)); // - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - - printf("Tested QOS \n"); - Sleep(5000); - return 0; -#endif - -#ifdef QOS_TEST_WITH_OVERRIDE - // note: you need to have QOS installed on your interface for this test - // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1 - assert( 0 == client1->SetQoS(true, 2, 1000, 1)); // SERVICETYPE_CONTROLLEDLOAD 2 - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetQoS(true, 2, 1000, 2)); // SERVICETYPE_GUARANTEED 3 - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - Sleep(10); - assert( 0 == client1->SetQoS(false, 0)); // - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - printf("Tested QOS with override \n"); - Sleep(5000); - return 0; -#endif - -#ifdef PCP_TEST - // Note: We currently don't know how to test that the bits are actually set in the frame, - // this test simply tests the API and that we can send a packet after setting PCP. - assert( -1 == client1->SetPCP(-1)); // should fail - assert( -1 == client1->SetPCP(8)); // should fail - printf("Setting PCP to 7 returned %d \n", client1->SetPCP(7)); - printf("(Failing is normal, requires the CAP_NET_ADMIN capability to succeed.) \n"); - Sleep(10); - for (int pcp = 6; pcp >= 0; --pcp) - { - assert( 0 == client1->SetPCP(pcp)); - Sleep(10); - assert( 9 == client1->SendPacket(-1, test, 9)); - } - printf("Tested PCP \n"); - Sleep(5000); - return 0; -#endif - - Sleep(10); - - assert( 9 == client1->SendPacket(-1, test, 9)); - - // test start rec after a socket has revceived data - // result: packets received before first startReceive is saved by the OS -/* - for(int i = 0; i < 100; i++) - { - assert( 9 == client1->SendPacket(-1, test, 9)); - } - Sleep(10); - assert( 0 == client2->StartReceiving(20)); - -// assert( 0 == client2->StopReceiving()); - - Sleep(10); - for(int i = 0; i < 100; i++) - { - assert( 9 == client1->SendPacket(-1, test, 9)); - } - - assert( 0 == client2->StartReceiving(20)); - - for(int i = 0; i < 100; i++) - { - assert( 9 == client1->SendPacket(-1, test, 9)); - } -*/ - Sleep(10); - - assert( 0 == client1Callback->_counterRTP); - assert( 1 == client2Callback->_counterRTP); - assert( 0 == client1Callback->_counterRTCP); - assert( 0 == client2Callback->_counterRTCP); - - printf("Sent 1 packet on one socket \n"); - - char ipAddr[64]; - char tempIpAddr[64]; - char ipMulticastAddr[64]; - WebRtc_UWord16 rtpPort = 0; - WebRtc_UWord16 rtcpPort = 0; - bool reusableSocket = true; - assert( 0 == client2->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort)); - assert( rtpPort == 1234); - assert( strncmp(ipAddr, localIPAddr, 16) == 0); - - assert( 0 == client2->ReceiveSocketInformation(ipAddr, rtpPort, rtcpPort, ipMulticastAddr, reusableSocket)); - assert( rtpPort == 1236); - assert( rtcpPort == 1237); - assert( strncmp(ipAddr, "0.0.0.0", 16) == 0); - assert( ipMulticastAddr[0] == 0); - assert( reusableSocket == false); - - assert( 0 == client2->SendSocketInformation(ipAddr, rtpPort, rtcpPort)); - assert( rtpPort == 1234); - assert( rtcpPort == 1235); - assert( strncmp(ipAddr,localIPAddr, 16) == 0); - - const int numberOfPackets = 1000; - int n = 0; - while(n < numberOfPackets) - { - assert( 9 == client1->SendPacket(-1, test, 9)); - assert( 9 == client2->SendPacket(-1, test, 9)); - assert( 9 == client1->SendRTCPPacket(-1, test, 9)); - assert( 9 == client2->SendRTCPPacket(-1, test, 9)); - n++; - } - int loops = 0; - for(; loops < 100 && - !(client1Callback->_counterRTP == numberOfPackets && - client1Callback->_counterRTCP == numberOfPackets && - client2Callback->_counterRTP == numberOfPackets+1 && - client2Callback->_counterRTCP == numberOfPackets); - loops++) - { - Sleep(10); - } - printf("\tSent %d packets on 4 sockets in:%d ms\n", numberOfPackets, loops*10); - - assert( numberOfPackets == client1Callback->_counterRTP); - assert( numberOfPackets+1 == client2Callback->_counterRTP); - assert( numberOfPackets == client1Callback->_counterRTCP); - assert( numberOfPackets == client2Callback->_counterRTCP); - - assert( 0 == client1->StopReceiving()); - assert( 0 == client2->StopReceiving()); - - printf("Tear down client 2\n"); - - // configure that fail - assert( -1 == client2->InitializeReceiveSockets(client2Callback,1234, localIPAddr)); // port in use - assert( !client2->ReceiveSocketsInitialized()); - assert( 0 == client2->InitializeReceiveSockets(client2Callback,1236)); - assert( 0 == client2->StartReceiving(20)); - - printf("Client 2 re-configured\n"); - - assert( client1->SendSocketsInitialized()); - assert( client1->ReceiveSocketsInitialized()); - assert( client2->SendSocketsInitialized()); - assert( client2->ReceiveSocketsInitialized()); - - assert( 9 == client1->SendPacket(-1, test, 9)); - - // this should not be received since we dont receive in client 1 - assert( 9 == client2->SendPacket(-1, test, 9)); - - Sleep(10); - - assert( numberOfPackets == client1Callback->_counterRTP); - assert( numberOfPackets+2 == client2Callback->_counterRTP); - assert( numberOfPackets == client1Callback->_counterRTCP); - assert( numberOfPackets == client2Callback->_counterRTCP); - printf("\tSent 1 packet on one socket \n"); - - printf("Start filter test\n"); - - assert( 0 == client1->StartReceiving(20)); - - assert( 0 == client1->SetFilterPorts(1234, 1235)); // should filter out what we send - assert( 0 == client1->SetFilterIP(localIPAddr)); - - assert( 0 == client1->FilterIP(tempIpAddr)); - assert( strncmp(tempIpAddr, localIPAddr, 16) == 0); - - assert( 9 == client2->SendPacket(-1, test, 9)); - assert( 9 == client2->SendRTCPPacket(-1, test, 9)); - - Sleep(10); - - assert( numberOfPackets == client1Callback->_counterRTP); - assert( numberOfPackets+2 == client2Callback->_counterRTP); - assert( numberOfPackets == client1Callback->_counterRTCP); - assert( numberOfPackets == client2Callback->_counterRTCP); - - assert( 0 == client1->SetFilterPorts(1236, 1237)); // should pass through - - assert( 9 == client2->SendPacket(-1, test, 9)); - assert( 9 == client2->SendRTCPPacket(-1, test, 9)); - printf("\tSent 1 packet on two sockets \n"); - - Sleep(10); - - assert( numberOfPackets+1 == client1Callback->_counterRTP); - assert( numberOfPackets+2 == client2Callback->_counterRTP); - assert( numberOfPackets+1 == client1Callback->_counterRTCP); - assert( numberOfPackets == client2Callback->_counterRTCP); - - assert( 0 == client1->SetFilterIP("127.0.0.2")); - - assert( 9 == client2->SendPacket(-1, test, 9)); - assert( 9 == client2->SendRTCPPacket(-1, test, 9)); - printf("\tSent 1 packet on two sockets \n"); - - Sleep(10); - - assert( numberOfPackets+1 == client1Callback->_counterRTP); - assert( numberOfPackets+2 == client2Callback->_counterRTP); - assert( numberOfPackets+1 == client1Callback->_counterRTCP); - assert( numberOfPackets == client2Callback->_counterRTCP); - - assert( 0 == client1->SetFilterIP(NULL)); - assert( 0 == client1->SetFilterPorts(0, 0)); - - printf("Tested filter \n"); - - assert( 0 == client2->InitializeSourcePorts(1238, 1239)); - assert( 9 == client2->SendPacket(-1, test, 9)); - assert( 9 == client2->SendRTCPPacket(-1, test, 9)); - printf("\tSent 1 packet on two sockets \n"); - - Sleep(10); - - assert( numberOfPackets+2 == client1Callback->_counterRTP); - assert( numberOfPackets+2 == client2Callback->_counterRTP); - assert( numberOfPackets+2 == client1Callback->_counterRTCP); - assert( numberOfPackets == client2Callback->_counterRTCP); - - assert( 0 == client1->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort)); - assert( rtpPort == 1238); - assert( rtcpPort == 1239); - assert( strncmp(ipAddr, localIPAddr, 16) == 0); - - printf("Tested source port \n"); - - assert( 0 == client2->InitializeSourcePorts(1240 )); - assert( 9 == client2->SendPacket(-1, test, 9)); - assert( 9 == client2->SendRTCPPacket(-1, test, 9)); - printf("\tSent 1 packet on two sockets \n"); - - Sleep(10); - - assert( 0 == client1->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort)); - assert( rtpPort == 1240); - assert( rtcpPort == 1241); - - printf("Tested SetSendPorts source port \n"); - - UdpTransport::Destroy(client1); - UdpTransport::Destroy(client2); - - printf("\n\nUdpTransport test done\n"); - - delete client1Callback; - delete client2Callback; - - Sleep(5000); - Trace::ReturnTrace(); -}; diff --git a/webrtc/video_engine/test/android/jni/Android.mk b/webrtc/video_engine/test/android/jni/Android.mk index 1b51044c8d..f72231c9bb 100644 --- a/webrtc/video_engine/test/android/jni/Android.mk +++ b/webrtc/video_engine/test/android/jni/Android.mk @@ -212,12 +212,6 @@ LOCAL_SRC_FILES := \ $(MY_LIBS_PATH)/libmedia_file.a include $(PREBUILT_STATIC_LIBRARY) -include $(CLEAR_VARS) -LOCAL_MODULE := libudp_transport -LOCAL_SRC_FILES := \ - $(MY_LIBS_PATH)/libudp_transport.a -include $(PREBUILT_STATIC_LIBRARY) - include $(CLEAR_VARS) LOCAL_MODULE := libchannel_transport LOCAL_SRC_FILES := \ diff --git a/webrtc/voice_engine/voice_engine_core.gypi b/webrtc/voice_engine/voice_engine_core.gypi index 1c28c0d4a1..21bfca41e0 100644 --- a/webrtc/voice_engine/voice_engine_core.gypi +++ b/webrtc/voice_engine/voice_engine_core.gypi @@ -20,7 +20,6 @@ '<(webrtc_root)/modules/modules.gyp:audio_processing', '<(webrtc_root)/modules/modules.gyp:media_file', '<(webrtc_root)/modules/modules.gyp:rtp_rtcp', - '<(webrtc_root)/modules/modules.gyp:udp_transport', '<(webrtc_root)/modules/modules.gyp:webrtc_utility', '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', ], @@ -134,7 +133,6 @@ '<(webrtc_root)/modules/modules.gyp:audio_conference_mixer', '<(webrtc_root)/modules/modules.gyp:media_file', '<(webrtc_root)/modules/modules.gyp:rtp_rtcp', - '<(webrtc_root)/modules/modules.gyp:udp_transport', '<(webrtc_root)/modules/modules.gyp:webrtc_utility', '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers', ],