Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Unified Diff: webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc

Issue 2336123002: Revert of Moved webrtc/test/channel_transport/ into webrtc/voice_engine/test/ (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc
diff --git a/webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc b/webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc
deleted file mode 100644
index e265c1e84c3aeea6bf09d74f46309e9b5ac3e7f2..0000000000000000000000000000000000000000
--- a/webrtc/voice_engine/test/channel_transport/udp_transport_impl.cc
+++ /dev/null
@@ -1,3005 +0,0 @@
-/*
- * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/voice_engine/test/channel_transport/udp_transport_impl.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#if defined(_WIN32)
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <unistd.h>
-#ifndef WEBRTC_IOS
-#include <net/if_arp.h>
-#endif
-#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
-
-#if defined(WEBRTC_MAC)
-#include <ifaddrs.h>
-#include <machine/types.h>
-#endif
-#if defined(WEBRTC_LINUX)
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#endif
-
-#include "webrtc/common_types.h"
-#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
-#include "webrtc/system_wrappers/include/trace.h"
-#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
-#include "webrtc/typedefs.h"
-
-#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
-#define GetLastError() errno
-
-#define IFRSIZE ((int)(size * sizeof (struct ifreq)))
-
-#define NLMSG_OK_NO_WARNING(nlh,len) \
- ((len) >= (int)sizeof(struct nlmsghdr) && \
- (int)(nlh)->nlmsg_len >= (int)sizeof(struct nlmsghdr) && \
- (int)(nlh)->nlmsg_len <= (len))
-
-#endif // defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
-
-namespace webrtc {
-namespace test {
-
-class SocketFactory : public UdpTransportImpl::SocketFactoryInterface {
- public:
- UdpSocketWrapper* CreateSocket(const int32_t id,
- UdpSocketManager* mgr,
- CallbackObj obj,
- IncomingSocketCallback cb,
- bool ipV6Enable,
- bool disableGQOS) override {
- return UdpSocketWrapper::CreateSocket(id, mgr, obj, cb, ipV6Enable,
- disableGQOS);
- }
-};
-
-// Creates an UdpTransport using the definition of SocketFactory above,
-// and passes (creating if needed) a pointer to the static singleton
-// UdpSocketManager.
-UdpTransport* UdpTransport::Create(const int32_t id,
- uint8_t& numSocketThreads)
-{
- return new UdpTransportImpl(id,
- new SocketFactory(),
- UdpSocketManager::Create(id, numSocketThreads));
-}
-
-// Deletes the UdpTransport and decrements the refcount of the
-// static singleton UdpSocketManager, possibly destroying it.
-// Should only be used on UdpTransports that are created using Create.
-void UdpTransport::Destroy(UdpTransport* module)
-{
- if(module)
- {
- delete module;
- UdpSocketManager::Return();
- }
-}
-
-UdpTransportImpl::UdpTransportImpl(const int32_t id,
- SocketFactoryInterface* maker,
- UdpSocketManager* socket_manager)
- : _id(id),
- _socket_creator(maker),
- _crit(CriticalSectionWrapper::CreateCriticalSection()),
- _critFilter(CriticalSectionWrapper::CreateCriticalSection()),
- _critPacketCallback(CriticalSectionWrapper::CreateCriticalSection()),
- _mgr(socket_manager),
- _lastError(kNoSocketError),
- _destPort(0),
- _destPortRTCP(0),
- _localPort(0),
- _localPortRTCP(0),
- _srcPort(0),
- _srcPortRTCP(0),
- _fromPort(0),
- _fromPortRTCP(0),
- _fromIP(),
- _destIP(),
- _localIP(),
- _localMulticastIP(),
- _ptrRtpSocket(NULL),
- _ptrRtcpSocket(NULL),
- _ptrSendRtpSocket(NULL),
- _ptrSendRtcpSocket(NULL),
- _remoteRTPAddr(),
- _remoteRTCPAddr(),
- _localRTPAddr(),
- _localRTCPAddr(),
- _tos(0),
- _receiving(false),
- _useSetSockOpt(false),
- _qos(false),
- _pcp(0),
- _ipV6Enabled(false),
- _serviceType(0),
- _overrideDSCP(0),
- _maxBitrate(0),
- _cachLock(RWLockWrapper::CreateRWLock()),
- _previousAddress(),
- _previousIP(),
- _previousIPSize(0),
- _previousSourcePort(0),
- _filterIPAddress(),
- _rtpFilterPort(0),
- _rtcpFilterPort(0),
- _packetCallback(0)
-{
- memset(&_remoteRTPAddr, 0, sizeof(_remoteRTPAddr));
- memset(&_remoteRTCPAddr, 0, sizeof(_remoteRTCPAddr));
- memset(&_localRTPAddr, 0, sizeof(_localRTPAddr));
- memset(&_localRTCPAddr, 0, sizeof(_localRTCPAddr));
-
- memset(_fromIP, 0, sizeof(_fromIP));
- memset(_destIP, 0, sizeof(_destIP));
- memset(_localIP, 0, sizeof(_localIP));
- memset(_localMulticastIP, 0, sizeof(_localMulticastIP));
-
- memset(&_filterIPAddress, 0, sizeof(_filterIPAddress));
-
- WEBRTC_TRACE(kTraceMemory, kTraceTransport, id, "%s created", __FUNCTION__);
-}
-
-UdpTransportImpl::~UdpTransportImpl()
-{
- CloseSendSockets();
- CloseReceiveSockets();
- delete _crit;
- delete _critFilter;
- delete _critPacketCallback;
- delete _cachLock;
- delete _socket_creator;
-
- WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id, "%s deleted",
- __FUNCTION__);
-}
-
-UdpTransport::ErrorCode UdpTransportImpl::LastError() const
-{
- return _lastError;
-}
-
-bool SameAddress(const SocketAddress& address1, const SocketAddress& address2)
-{
- return (memcmp(&address1,&address2,sizeof(address1)) == 0);
-}
-
-void UdpTransportImpl::GetCachedAddress(char* ip,
- uint32_t& ipSize,
- uint16_t& sourcePort)
-{
- const uint32_t originalIPSize = ipSize;
- // If the incoming string is too small, fill it as much as there is room
- // for. Make sure that there is room for the '\0' character.
- ipSize = (ipSize - 1 < _previousIPSize) ? ipSize - 1 : _previousIPSize;
- memcpy(ip,_previousIP,sizeof(int8_t)*(ipSize + 1));
- ip[originalIPSize - 1] = '\0';
- sourcePort = _previousSourcePort;
-}
-
-int32_t UdpTransportImpl::IPAddressCached(const SocketAddress& address,
- char* ip,
- uint32_t& ipSize,
- uint16_t& sourcePort)
-{
- {
- ReadLockScoped rl(*_cachLock);
- // Check if the old address can be re-used (is the same).
- if(SameAddress(address,_previousAddress))
- {
- GetCachedAddress(ip,ipSize,sourcePort);
- return 0;
- }
- }
- // Get the new address and store it.
- WriteLockScoped wl(*_cachLock);
- ipSize = kIpAddressVersion6Length;
- if(IPAddress(address,_previousIP,ipSize,_previousSourcePort) != 0)
- {
- return -1;
- }
- _previousIPSize = ipSize;
- memcpy(&_previousAddress, &address, sizeof(address));
- // Address has been cached at this point.
- GetCachedAddress(ip,ipSize,sourcePort);
- return 0;
-}
-
-int32_t UdpTransportImpl::InitializeReceiveSockets(
- UdpTransportData* const packetCallback,
- const uint16_t portnr,
- const char* ip,
- const char* multicastIpAddr,
- const uint16_t rtcpPort)
-{
- {
- CriticalSectionScoped cs(_critPacketCallback);
- _packetCallback = packetCallback;
-
- if(packetCallback == NULL)
- {
- WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id,
- "Closing down receive sockets");
- return 0;
- }
- }
-
- CriticalSectionScoped cs(_crit);
- CloseReceiveSockets();
-
- if(portnr == 0)
- {
- // TODO (hellner): why not just fail here?
- if(_destPort == 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeReceiveSockets port 0 not allowed");
- _lastError = kPortInvalid;
- return -1;
- }
- _localPort = _destPort;
- } else {
- _localPort = portnr;
- }
- if(rtcpPort)
- {
- _localPortRTCP = rtcpPort;
- }else {
- _localPortRTCP = _localPort + 1;
- WEBRTC_TRACE(
- kTraceStateInfo,
- kTraceTransport,
- _id,
- "InitializeReceiveSockets RTCP port not configured using RTP\
- port+1=%d",
- _localPortRTCP);
- }
-
- if(ip)
- {
- if(IsIpAddressValid(ip,IpV6Enabled()))
- {
- strncpy(_localIP, ip,kIpAddressVersion6Length);
- } else
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeReceiveSockets invalid IP address");
- _lastError = kIpAddressInvalid;
- return -1;
- }
- }else
- {
- // Don't bind to a specific IP address.
- if(! IpV6Enabled())
- {
- strncpy(_localIP, "0.0.0.0",16);
- } else
- {
- strncpy(_localIP, "0000:0000:0000:0000:0000:0000:0000:0000",
- kIpAddressVersion6Length);
- }
- }
- if(multicastIpAddr && !IpV6Enabled())
- {
- if(IsIpAddressValid(multicastIpAddr,IpV6Enabled()))
- {
- strncpy(_localMulticastIP, multicastIpAddr,
- kIpAddressVersion6Length);
- } else
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeReceiveSockets invalid IP address");
- _lastError = kIpAddressInvalid;
- return -1;
- }
- }
- if(_mgr == NULL)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeReceiveSockets no socket manager");
- return -1;
- }
-
- _useSetSockOpt=false;
- _tos=0;
- _pcp=0;
-
- _ptrRtpSocket = _socket_creator->CreateSocket(_id, _mgr, this,
- IncomingRTPCallback,
- IpV6Enabled(), false);
-
- _ptrRtcpSocket = _socket_creator->CreateSocket(_id, _mgr, this,
- IncomingRTCPCallback,
- IpV6Enabled(), false);
-
- ErrorCode retVal = BindLocalRTPSocket();
- if(retVal != kNoSocketError)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeReceiveSockets faild to bind RTP socket");
- _lastError = retVal;
- CloseReceiveSockets();
- return -1;
- }
- retVal = BindLocalRTCPSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeReceiveSockets faild to bind RTCP socket");
- CloseReceiveSockets();
- return -1;
- }
- return 0;
-}
-
-int32_t UdpTransportImpl::ReceiveSocketInformation(
- char ipAddr[kIpAddressVersion6Length],
- uint16_t& rtpPort,
- uint16_t& rtcpPort,
- char multicastIpAddr[kIpAddressVersion6Length]) const
-{
- CriticalSectionScoped cs(_crit);
- rtpPort = _localPort;
- rtcpPort = _localPortRTCP;
- if (ipAddr)
- {
- strncpy(ipAddr, _localIP, IpV6Enabled() ?
- UdpTransport::kIpAddressVersion6Length :
- UdpTransport::kIpAddressVersion4Length);
- }
- if (multicastIpAddr)
- {
- strncpy(multicastIpAddr, _localMulticastIP, IpV6Enabled() ?
- UdpTransport::kIpAddressVersion6Length :
- UdpTransport::kIpAddressVersion4Length);
- }
- return 0;
-}
-
-int32_t UdpTransportImpl::SendSocketInformation(
- char ipAddr[kIpAddressVersion6Length],
- uint16_t& rtpPort,
- uint16_t& rtcpPort) const
-{
- CriticalSectionScoped cs(_crit);
- rtpPort = _destPort;
- rtcpPort = _destPortRTCP;
- strncpy(ipAddr, _destIP, IpV6Enabled() ?
- UdpTransport::kIpAddressVersion6Length :
- UdpTransport::kIpAddressVersion4Length);
- return 0;
-}
-
-int32_t UdpTransportImpl::RemoteSocketInformation(
- char ipAddr[kIpAddressVersion6Length],
- uint16_t& rtpPort,
- uint16_t& rtcpPort) const
-{
- CriticalSectionScoped cs(_crit);
- rtpPort = _fromPort;
- rtcpPort = _fromPortRTCP;
- if(ipAddr)
- {
- strncpy(ipAddr, _fromIP, IpV6Enabled() ?
- kIpAddressVersion6Length :
- kIpAddressVersion4Length);
- }
- return 0;
-}
-
-int32_t UdpTransportImpl::FilterPorts(
- uint16_t& rtpFilterPort,
- uint16_t& rtcpFilterPort) const
-{
- CriticalSectionScoped cs(_critFilter);
- rtpFilterPort = _rtpFilterPort;
- rtcpFilterPort = _rtcpFilterPort;
- return 0;
-}
-
-int32_t UdpTransportImpl::SetQoS(bool QoS, int32_t serviceType,
- uint32_t maxBitrate,
- int32_t overrideDSCP, bool audio)
-{
- if(QoS)
- {
- return EnableQoS(serviceType, audio, maxBitrate, overrideDSCP);
- }else
- {
- return DisableQoS();
- }
-}
-
-int32_t UdpTransportImpl::EnableQoS(int32_t serviceType,
- bool audio, uint32_t maxBitrate,
- int32_t overrideDSCP)
-{
- if (_ipV6Enabled)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is enabled but will be ignored since IPv6 is enabled");
- _lastError = kQosError;
- return -1;
- }
- if (_tos)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "TOS already enabled, can't use TOS and QoS at the same time");
- _lastError = kQosError;
- return -1;
- }
- if (_pcp)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "PCP already enabled, can't use PCP and QoS at the same time");
- _lastError = kQosError;
- return -1;
- }
- if(_destPort == 0)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is enabled but not started since we have not yet configured\
- the send destination");
- return -1;
- }
- if(_qos)
- {
- if(_overrideDSCP == 0 && overrideDSCP != 0)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is already enabled and overrideDSCP differs, not allowed");
- return -1;
- }
- }
- CriticalSectionScoped cs(_crit);
-
- UdpSocketWrapper* rtpSock = _ptrSendRtpSocket ?
- _ptrSendRtpSocket :
- _ptrRtpSocket;
- if (!rtpSock || !rtpSock->ValidHandle())
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is enabled but not started since we have not yet created the\
- RTP socket");
- return -1;
- }
- UdpSocketWrapper* rtcpSock = _ptrSendRtcpSocket ?
- _ptrSendRtcpSocket :
- _ptrRtcpSocket;
- if (!rtcpSock || !rtcpSock->ValidHandle())
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is enabled but not started since we have not yet created the\
- RTCP socket");
- return -1;
- }
-
- // Minimum packet size in bytes for which the requested quality of service
- // will be provided. The smallest RTP header is 12 byte.
- const int32_t min_policed_size = 12;
- // Max SDU, maximum packet size permitted or used in the traffic flow, in
- // bytes.
- const int32_t max_sdu_size = 1500;
-
- // Enable QoS for RTP sockets.
- if(maxBitrate)
- {
- // Note: 1 kbit is 125 bytes.
- // Token Rate is typically set to the average bit rate from peak to
- // peak.
- // Bucket size is normally set to the largest average frame size.
- if(audio)
- {
- WEBRTC_TRACE(kTraceStateInfo,
- kTraceTransport,
- _id,
- "Enable QOS for audio with max bitrate:%d",
- maxBitrate);
-
- const int32_t token_rate = maxBitrate*125;
- // The largest audio packets are 60ms frames. This is a fraction
- // more than 16 packets/second. These 16 frames are sent, at max,
- // at a bitrate of maxBitrate*125 -> 1 frame is maxBitrate*125/16 ~
- // maxBitrate * 8.
- const int32_t bucket_size = maxBitrate * 8;
- const int32_t peek_bandwith = maxBitrate * 125;
- if (!rtpSock->SetQos(serviceType, token_rate, bucket_size,
- peek_bandwith, min_policed_size,
- max_sdu_size, _remoteRTPAddr, overrideDSCP))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "QOS failed on the RTP socket");
- _lastError = kQosError;
- return -1;
- }
- }else
- {
- WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id,
- "Enable QOS for video with max bitrate:%d",
- maxBitrate);
-
- // Allow for a token rate that is twice that of the maximum bitrate
- // (in bytes).
- const int32_t token_rate = maxBitrate*250;
- // largest average frame size (key frame size). Assuming that a
- // keyframe is 25% of the bitrate during the second its sent
- // Assume that a key frame is 25% of the bitrate the second that it
- // is sent. The largest frame size is then maxBitrate* 125 * 0.25 ~
- // 31.
- const int32_t bucket_size = maxBitrate*31;
- const int32_t peek_bandwith = maxBitrate*125;
- if (!rtpSock->SetQos(serviceType, token_rate, bucket_size,
- peek_bandwith, min_policed_size, max_sdu_size,
- _remoteRTPAddr, overrideDSCP))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "QOS failed on the RTP socket");
- _lastError = kQosError;
- return -1;
- }
- }
- } else if(audio)
- {
- // No max bitrate set. Audio.
- WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id,
- "Enable QOS for audio with default max bitrate");
-
- // Let max bitrate be 240kbit/s.
- const int32_t token_rate = 30000;
- const int32_t bucket_size = 2000;
- const int32_t peek_bandwith = 30000;
- if (!rtpSock->SetQos(serviceType, token_rate, bucket_size,
- peek_bandwith, min_policed_size, max_sdu_size,
- _remoteRTPAddr, overrideDSCP))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "QOS failed on the RTP socket");
- _lastError = kQosError;
- return -1;
- }
- }else
- {
- // No max bitrate set. Video.
- WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, _id,
- "Enable QOS for video with default max bitrate");
-
- // Let max bitrate be 10mbit/s.
- const int32_t token_rate = 128000*10;
- const int32_t bucket_size = 32000;
- const int32_t peek_bandwith = 256000;
- if (!rtpSock->SetQos(serviceType, token_rate, bucket_size,
- peek_bandwith, min_policed_size, max_sdu_size,
- _remoteRTPAddr, overrideDSCP))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "QOS failed on the RTP socket");
- _lastError = kQosError;
- return -1;
- }
- }
-
- // Enable QoS for RTCP sockets.
- // TODO (hellner): shouldn't RTCP be based on 5% of the maximum bandwidth?
- if(audio)
- {
- const int32_t token_rate = 200;
- const int32_t bucket_size = 200;
- const int32_t peek_bandwith = 400;
- if (!rtcpSock->SetQos(serviceType, token_rate, bucket_size,
- peek_bandwith, min_policed_size, max_sdu_size,
- _remoteRTCPAddr, overrideDSCP))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "QOS failed on the RTCP socket");
- _lastError = kQosError;
- }
- }else
- {
- const int32_t token_rate = 5000;
- const int32_t bucket_size = 100;
- const int32_t peek_bandwith = 10000;
- if (!rtcpSock->SetQos(serviceType, token_rate, bucket_size,
- peek_bandwith, min_policed_size, max_sdu_size,
- _remoteRTCPAddr, _overrideDSCP))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "QOS failed on the RTCP socket");
- _lastError = kQosError;
- }
- }
- _qos = true;
- _serviceType = serviceType;
- _maxBitrate = maxBitrate;
- _overrideDSCP = overrideDSCP;
- return 0;
-}
-
-int32_t UdpTransportImpl::DisableQoS()
-{
- if(_qos == false)
- {
- return 0;
- }
- CriticalSectionScoped cs(_crit);
-
- UdpSocketWrapper* rtpSock = (_ptrSendRtpSocket ?
- _ptrSendRtpSocket : _ptrRtpSocket);
- if (!rtpSock || !rtpSock->ValidHandle())
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is enabled but not started since we have not yet created the\
- RTP socket");
- return -1;
- }
- UdpSocketWrapper* rtcpSock = (_ptrSendRtcpSocket ?
- _ptrSendRtcpSocket : _ptrRtcpSocket);
- if (!rtcpSock || !rtcpSock->ValidHandle())
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "QOS is enabled but not started since we have not yet created the\
- RTCP socket");
- return -1;
- }
-
- const int32_t service_type = 0; // = SERVICETYPE_NOTRAFFIC
- const int32_t not_specified = -1;
- if (!rtpSock->SetQos(service_type, not_specified, not_specified,
- not_specified, not_specified, not_specified,
- _remoteRTPAddr, _overrideDSCP))
- {
- _lastError = kQosError;
- return -1;
- }
- if (!rtcpSock->SetQos(service_type, not_specified, not_specified,
- not_specified, not_specified, not_specified,
- _remoteRTCPAddr,_overrideDSCP))
- {
- _lastError = kQosError;
- }
- _qos = false;
- return 0;
-}
-
-int32_t UdpTransportImpl::QoS(bool& QoS, int32_t& serviceType,
- int32_t& overrideDSCP) const
-{
- CriticalSectionScoped cs(_crit);
- QoS = _qos;
- serviceType = _serviceType;
- overrideDSCP = _overrideDSCP;
- return 0;
-}
-
-int32_t UdpTransportImpl::SetToS(int32_t DSCP, bool useSetSockOpt)
-{
- if (_qos)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "QoS already enabled");
- _lastError = kQosError;
- return -1;
- }
- if (DSCP < 0 || DSCP > 63)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "Invalid DSCP");
- _lastError = kTosInvalid;
- return -1;
- }
- if(_tos)
- {
- if(useSetSockOpt != _useSetSockOpt)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "Can't switch SetSockOpt method without disabling TOS first");
- _lastError = kTosInvalid;
- return -1;
- }
- }
- CriticalSectionScoped cs(_crit);
- UdpSocketWrapper* rtpSock = NULL;
- UdpSocketWrapper* rtcpSock = NULL;
- if(_ptrSendRtpSocket)
- {
- rtpSock = _ptrSendRtpSocket;
- }else
- {
- rtpSock = _ptrRtpSocket;
- }
- if (rtpSock == NULL)
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- if(!rtpSock->ValidHandle())
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- if(_ptrSendRtcpSocket)
- {
- rtcpSock = _ptrSendRtcpSocket;
- }else
- {
- rtcpSock = _ptrRtcpSocket;
- }
- if (rtcpSock == NULL)
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- if(!rtcpSock->ValidHandle())
- {
- _lastError = kSocketInvalid;
- return -1;
- }
-
- if (useSetSockOpt)
- {
-#ifdef _WIN32
- OSVERSIONINFO OsVersion;
- OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&OsVersion);
- // Disable QoS before setting ToS on Windows XP. This is done by closing
- // and re-opening the sockets.
- // TODO (hellner): why not just fail here and force the user to
- // re-initialize sockets? Doing this may trick the user
- // into thinking that the sockets are in a state which
- // they aren't.
- if (OsVersion.dwMajorVersion == 5 &&
- OsVersion.dwMinorVersion == 1)
- {
- if(!_useSetSockOpt)
- {
- if(_ptrSendRtpSocket)
- {
- CloseSendSockets();
- _ptrSendRtpSocket =
- _socket_creator->CreateSocket(_id, _mgr, NULL,
- NULL, IpV6Enabled(),
- true);
- _ptrSendRtcpSocket =
- _socket_creator->CreateSocket(_id, _mgr, NULL,
- NULL, IpV6Enabled(),
- true);
- rtpSock=_ptrSendRtpSocket;
- rtcpSock=_ptrSendRtcpSocket;
- ErrorCode retVal = BindRTPSendSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- return -1;
- }
- retVal = BindRTCPSendSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- return -1;
- }
- }
- else
- {
- bool receiving=_receiving;
- uint32_t noOfReceiveBuffers = 0;
- if(receiving)
- {
- noOfReceiveBuffers=_ptrRtpSocket->ReceiveBuffers();
- if(StopReceiving()!=0)
- {
- return -1;
- }
- }
- CloseReceiveSockets();
- _ptrRtpSocket = _socket_creator->CreateSocket(
- _id, _mgr, this, IncomingRTPCallback, IpV6Enabled(),
- true);
- _ptrRtcpSocket = _socket_creator->CreateSocket(
- _id, _mgr, this, IncomingRTCPCallback, IpV6Enabled(),
- true);
- rtpSock=_ptrRtpSocket;
- rtcpSock=_ptrRtcpSocket;
- ErrorCode retVal = BindLocalRTPSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- return -1;
- }
- retVal = BindLocalRTCPSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- return -1;
- }
- if(receiving)
- {
- if(StartReceiving(noOfReceiveBuffers) !=
- kNoSocketError)
- {
- return -1;
- }
- }
- }
- }
- }
-#endif // #ifdef _WIN32
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
- "Setting TOS using SetSockopt");
- int32_t TOSShifted = DSCP << 2;
- if (!rtpSock->SetSockopt(IPPROTO_IP, IP_TOS,
- (int8_t*) &TOSShifted, 4))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not SetSockopt tos value on RTP socket");
- _lastError = kTosInvalid;
- return -1;
- }
- if (!rtcpSock->SetSockopt(IPPROTO_IP, IP_TOS,
- (int8_t*) &TOSShifted, 4))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not sSetSockopt tos value on RTCP socket");
- _lastError = kTosInvalid;
- return -1;
- }
- } else
- {
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
- "Setting TOS NOT using SetSockopt");
- if (rtpSock->SetTOS(DSCP) != 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not set tos value on RTP socket");
- _lastError = kTosError;
- return -1;
- }
- if (rtcpSock->SetTOS(DSCP) != 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not set tos value on RTCP socket");
- _lastError = kTosError;
- return -1;
- }
- }
- _useSetSockOpt = useSetSockOpt;
- _tos = DSCP;
- return 0;
-}
-
-int32_t UdpTransportImpl::ToS(int32_t& DSCP,
- bool& useSetSockOpt) const
-{
- CriticalSectionScoped cs(_crit);
- DSCP = _tos;
- useSetSockOpt = _useSetSockOpt;
- return 0;
-}
-
-int32_t UdpTransportImpl::SetPCP(int32_t PCP)
-{
-
- if (_qos)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "QoS already enabled");
- _lastError = kQosError;
- return -1;
- }
- if ((PCP < 0) || (PCP > 7))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "Invalid PCP");
- _lastError = kPcpError;
- return -1;
- }
-
- CriticalSectionScoped cs(_crit);
- UdpSocketWrapper* rtpSock = NULL;
- UdpSocketWrapper* rtcpSock = NULL;
- if(_ptrSendRtpSocket)
- {
- rtpSock = _ptrSendRtpSocket;
- }else
- {
- rtpSock = _ptrRtpSocket;
- }
- if (rtpSock == NULL)
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- if(!rtpSock->ValidHandle())
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- if(_ptrSendRtcpSocket)
- {
- rtcpSock = _ptrSendRtcpSocket;
- }else
- {
- rtcpSock = _ptrRtcpSocket;
- }
- if (rtcpSock == NULL)
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- if(!rtcpSock->ValidHandle())
- {
- _lastError = kSocketInvalid;
- return -1;
- }
-
-#if defined(_WIN32)
- if (rtpSock->SetPCP(PCP) != 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not set PCP value on RTP socket");
- _lastError = kPcpError;
- return -1;
- }
- if (rtcpSock->SetPCP(PCP) != 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not set PCP value on RTCP socket");
- _lastError = kPcpError;
- return -1;
- }
-
-#elif defined(WEBRTC_LINUX)
- if (!rtpSock->SetSockopt(SOL_SOCKET, SO_PRIORITY, (int8_t*) &PCP,
- sizeof(PCP)))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not SetSockopt PCP value on RTP socket");
- _lastError = kPcpError;
- return -1;
- }
- if (!rtcpSock->SetSockopt(SOL_SOCKET, SO_PRIORITY, (int8_t*) &PCP,
- sizeof(PCP)))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Could not SetSockopt PCP value on RTCP socket");
- _lastError = kPcpError;
- return -1;
- }
-#else
- // Not supported on other platforms (WEBRTC_MAC)
- _lastError = kPcpError;
- return -1;
-#endif
- _pcp = PCP;
- return 0;
-}
-
-int32_t UdpTransportImpl::PCP(int32_t& PCP) const
-{
- CriticalSectionScoped cs(_crit);
- PCP = _pcp;
- return 0;
-}
-
-bool UdpTransportImpl::SetSockOptUsed()
-{
- return _useSetSockOpt;
-}
-
-int32_t UdpTransportImpl::EnableIpV6() {
-
- CriticalSectionScoped cs(_crit);
- const bool initialized = (_ptrSendRtpSocket || _ptrRtpSocket);
-
- if (_ipV6Enabled) {
- return 0;
- }
- if (initialized) {
- _lastError = kIpVersion6Error;
- return -1;
- }
- _ipV6Enabled = true;
- return 0;
-}
-
-int32_t UdpTransportImpl::FilterIP(
- char filterIPAddress[kIpAddressVersion6Length]) const
-{
-
- if(filterIPAddress == NULL)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "FilterIP: Invalid argument");
- return -1;
- }
- if(_filterIPAddress._sockaddr_storage.sin_family == 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "No Filter configured");
- return -1;
- }
- CriticalSectionScoped cs(_critFilter);
- uint32_t ipSize = kIpAddressVersion6Length;
- uint16_t sourcePort;
- return IPAddress(_filterIPAddress, filterIPAddress, ipSize, sourcePort);
-}
-
-int32_t UdpTransportImpl::SetFilterIP(
- const char filterIPAddress[kIpAddressVersion6Length])
-{
- if(filterIPAddress == NULL)
- {
- memset(&_filterIPAddress, 0, sizeof(_filterIPAddress));
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, "Filter IP reset");
- return 0;
- }
- CriticalSectionScoped cs(_critFilter);
- if (_ipV6Enabled)
- {
- _filterIPAddress._sockaddr_storage.sin_family = AF_INET6;
-
- if (InetPresentationToNumeric(
- AF_INET6,
- filterIPAddress,
- &_filterIPAddress._sockaddr_in6.sin6_addr) < 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id, "Failed to set\
- filter IP for IPv6");
- _lastError = FILTER_ERROR;
- return -1;
- }
- }
- else
- {
- _filterIPAddress._sockaddr_storage.sin_family = AF_INET;
-
- if(InetPresentationToNumeric(
- AF_INET,
- filterIPAddress,
- &_filterIPAddress._sockaddr_in.sin_addr) < 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Failed to set filter IP for IPv4");
- _lastError = FILTER_ERROR;
- return -1;
- }
- }
- WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id, "Filter IP set");
- return 0;
-}
-
-int32_t UdpTransportImpl::SetFilterPorts(uint16_t rtpFilterPort,
- uint16_t rtcpFilterPort)
-{
- CriticalSectionScoped cs(_critFilter);
- _rtpFilterPort = rtpFilterPort;
- _rtcpFilterPort = rtcpFilterPort;
- return 0;
-}
-
-bool UdpTransportImpl::SendSocketsInitialized() const
-{
- CriticalSectionScoped cs(_crit);
- if(_ptrSendRtpSocket)
- {
- return true;
- }
- if(_destPort !=0)
- {
- return true;
- }
- return false;
-}
-
-bool UdpTransportImpl::ReceiveSocketsInitialized() const
-{
- if(_ptrRtpSocket)
- {
- return true;
- }
- return false;
-}
-
-bool UdpTransportImpl::SourcePortsInitialized() const
-{
- if(_ptrSendRtpSocket)
- {
- return true;
- }
- return false;
-}
-
-bool UdpTransportImpl::IpV6Enabled() const
-{
- WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, "%s", __FUNCTION__);
- return _ipV6Enabled;
-}
-
-void UdpTransportImpl::BuildRemoteRTPAddr()
-{
- if(_ipV6Enabled)
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _remoteRTPAddr.sin_length = 0;
- _remoteRTPAddr.sin_family = PF_INET6;
-#else
- _remoteRTPAddr._sockaddr_storage.sin_family = PF_INET6;
-#endif
-
- _remoteRTPAddr._sockaddr_in6.sin6_flowinfo=0;
- _remoteRTPAddr._sockaddr_in6.sin6_scope_id=0;
- _remoteRTPAddr._sockaddr_in6.sin6_port = Htons(_destPort);
- InetPresentationToNumeric(AF_INET6,_destIP,
- &_remoteRTPAddr._sockaddr_in6.sin6_addr);
- } else
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _remoteRTPAddr.sin_length = 0;
- _remoteRTPAddr.sin_family = PF_INET;
-#else
- _remoteRTPAddr._sockaddr_storage.sin_family = PF_INET;
-#endif
- _remoteRTPAddr._sockaddr_in.sin_port = Htons(_destPort);
- _remoteRTPAddr._sockaddr_in.sin_addr = InetAddrIPV4(_destIP);
- }
-}
-
-void UdpTransportImpl::BuildRemoteRTCPAddr()
-{
- if(_ipV6Enabled)
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _remoteRTCPAddr.sin_length = 0;
- _remoteRTCPAddr.sin_family = PF_INET6;
-#else
- _remoteRTCPAddr._sockaddr_storage.sin_family = PF_INET6;
-#endif
-
- _remoteRTCPAddr._sockaddr_in6.sin6_flowinfo=0;
- _remoteRTCPAddr._sockaddr_in6.sin6_scope_id=0;
- _remoteRTCPAddr._sockaddr_in6.sin6_port = Htons(_destPortRTCP);
- InetPresentationToNumeric(AF_INET6,_destIP,
- &_remoteRTCPAddr._sockaddr_in6.sin6_addr);
-
- } else
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _remoteRTCPAddr.sin_length = 0;
- _remoteRTCPAddr.sin_family = PF_INET;
-#else
- _remoteRTCPAddr._sockaddr_storage.sin_family = PF_INET;
-#endif
- _remoteRTCPAddr._sockaddr_in.sin_port = Htons(_destPortRTCP);
- _remoteRTCPAddr._sockaddr_in.sin_addr= InetAddrIPV4(_destIP);
- }
-}
-
-UdpTransportImpl::ErrorCode UdpTransportImpl::BindRTPSendSocket()
-{
- if(!_ptrSendRtpSocket)
- {
- return kSocketInvalid;
- }
- if(!_ptrSendRtpSocket->ValidHandle())
- {
- return kIpAddressInvalid;
- }
- if(_ipV6Enabled)
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _localRTPAddr.sin_length = 0;
- _localRTPAddr.sin_family = PF_INET6;
-#else
- _localRTPAddr._sockaddr_storage.sin_family = PF_INET6;
-#endif
- _localRTPAddr._sockaddr_in6.sin6_flowinfo=0;
- _localRTPAddr._sockaddr_in6.sin6_scope_id=0;
- _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[0] =
- 0; // = INADDR_ANY
- _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[1] =
- 0;
- _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[2] =
- 0;
- _localRTPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[3] =
- 0;
- _localRTPAddr._sockaddr_in6.sin6_port = Htons(_srcPort);
- if(_ptrSendRtpSocket->Bind(_localRTPAddr) == false)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _srcPort);
- return kFailedToBindPort;
- }
-
- } else {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _localRTPAddr.sin_length = 0;
- _localRTPAddr.sin_family = PF_INET;
-#else
- _localRTPAddr._sockaddr_storage.sin_family = PF_INET;
-#endif
- _localRTPAddr._sockaddr_in.sin_addr = 0;
- _localRTPAddr._sockaddr_in.sin_port = Htons(_srcPort);
- if(_ptrSendRtpSocket->Bind(_localRTPAddr) == false)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _srcPort);
- return kFailedToBindPort;
- }
- }
- return kNoSocketError;
-}
-
-UdpTransportImpl::ErrorCode UdpTransportImpl::BindRTCPSendSocket()
-{
- if(!_ptrSendRtcpSocket)
- {
- return kSocketInvalid;
- }
-
- if(_ipV6Enabled)
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _localRTCPAddr.sin_length = 0;
- _localRTCPAddr.sin_family = PF_INET6;
-#else
- _localRTCPAddr._sockaddr_storage.sin_family = PF_INET6;
-#endif
- _localRTCPAddr._sockaddr_in6.sin6_flowinfo=0;
- _localRTCPAddr._sockaddr_in6.sin6_scope_id=0;
- _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[0] =
- 0; // = INADDR_ANY
- _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[1] =
- 0;
- _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[2] =
- 0;
- _localRTCPAddr._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[3] =
- 0;
- _localRTCPAddr._sockaddr_in6.sin6_port = Htons(_srcPortRTCP);
- if(_ptrSendRtcpSocket->Bind(_localRTCPAddr) == false)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _srcPortRTCP);
- return kFailedToBindPort;
- }
- } else {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- _localRTCPAddr.sin_length = 0;
- _localRTCPAddr.sin_family = PF_INET;
-#else
- _localRTCPAddr._sockaddr_storage.sin_family = PF_INET;
-#endif
- _localRTCPAddr._sockaddr_in.sin_addr= 0;
- _localRTCPAddr._sockaddr_in.sin_port = Htons(_srcPortRTCP);
- if(_ptrSendRtcpSocket->Bind(_localRTCPAddr) == false)
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _srcPortRTCP);
- return kFailedToBindPort;
- }
- }
- return kNoSocketError;
-}
-
-UdpTransportImpl::ErrorCode UdpTransportImpl::BindLocalRTPSocket()
-{
- if(!_ptrRtpSocket)
- {
- return kSocketInvalid;
- }
- if(!IpV6Enabled())
- {
- SocketAddress recAddr;
- memset(&recAddr, 0, sizeof(SocketAddress));
- recAddr._sockaddr_storage.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- recAddr.sin_length = 0;
- recAddr.sin_family = PF_INET;
-#else
- recAddr._sockaddr_storage.sin_family = PF_INET;
-#endif
- recAddr._sockaddr_in.sin_addr = InetAddrIPV4(_localIP);
- recAddr._sockaddr_in.sin_port = Htons(_localPort);
-
- if (!_ptrRtpSocket->Bind(recAddr))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _localPort);
- return kFailedToBindPort;
- }
- }
- else
- {
- SocketAddress stLclName;
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- stLclName.sin_lenght = 0;
- stLclName.sin_family = PF_INET6;
-#else
- stLclName._sockaddr_storage.sin_family = PF_INET6;
-#endif
- InetPresentationToNumeric(AF_INET6,_localIP,
- &stLclName._sockaddr_in6.sin6_addr);
- stLclName._sockaddr_in6.sin6_port = Htons(_localPort);
- stLclName._sockaddr_in6.sin6_flowinfo = 0;
- stLclName._sockaddr_in6.sin6_scope_id = 0;
-
- if (!_ptrRtpSocket->Bind(stLclName))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _localPort);
- return kFailedToBindPort;
- }
- }
-
- if(_localMulticastIP[0] != 0)
- {
- // Join the multicast group from which to receive datagrams.
- struct ip_mreq mreq;
- mreq.imr_multiaddr.s_addr = InetAddrIPV4(_localMulticastIP);
- mreq.imr_interface.s_addr = INADDR_ANY;
-
- if (!_ptrRtpSocket->SetSockopt(IPPROTO_IP,IP_ADD_MEMBERSHIP,
- (int8_t*)&mreq,sizeof (mreq)))
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "setsockopt() for multicast failed, not closing socket");
- }else
- {
- WEBRTC_TRACE(kTraceInfo, kTraceTransport, _id,
- "multicast group successfully joined");
- }
- }
- return kNoSocketError;
-}
-
-UdpTransportImpl::ErrorCode UdpTransportImpl::BindLocalRTCPSocket()
-{
- if(!_ptrRtcpSocket)
- {
- return kSocketInvalid;
- }
- if(! IpV6Enabled())
- {
- SocketAddress recAddr;
- memset(&recAddr, 0, sizeof(SocketAddress));
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- recAddr.sin_length = 0;
- recAddr.sin_family = AF_INET;
-#else
- recAddr._sockaddr_storage.sin_family = AF_INET;
-#endif
- recAddr._sockaddr_in.sin_addr = InetAddrIPV4(_localIP);
- recAddr._sockaddr_in.sin_port = Htons(_localPortRTCP);
-
- if (!_ptrRtcpSocket->Bind(recAddr))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _localPortRTCP);
- return kFailedToBindPort;
- }
- }
- else
- {
- SocketAddress stLclName;
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- stLclName.sin_length = 0;
- stLclName.sin_family = PF_INET6;
-#else
- stLclName._sockaddr_storage.sin_family = PF_INET6;
-#endif
- stLclName._sockaddr_in6.sin6_flowinfo = 0;
- stLclName._sockaddr_in6.sin6_scope_id = 0;
- stLclName._sockaddr_in6.sin6_port = Htons(_localPortRTCP);
-
- InetPresentationToNumeric(AF_INET6,_localIP,
- &stLclName._sockaddr_in6.sin6_addr);
- if (!_ptrRtcpSocket->Bind(stLclName))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, _id,
- "Failed to bind to port:%d ", _localPortRTCP);
- return kFailedToBindPort;
- }
- }
- if(_localMulticastIP[0] != 0)
- {
- // Join the multicast group from which to receive datagrams.
- struct ip_mreq mreq;
- mreq.imr_multiaddr.s_addr = InetAddrIPV4(_localMulticastIP);
- mreq.imr_interface.s_addr = INADDR_ANY;
-
- if (!_ptrRtcpSocket->SetSockopt(IPPROTO_IP,IP_ADD_MEMBERSHIP,
- (int8_t*)&mreq,sizeof (mreq)))
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "setsockopt() for multicast failed, not closing socket");
- }else
- {
- WEBRTC_TRACE(kTraceInfo, kTraceTransport, _id,
- "multicast group successfully joined");
- }
- }
- return kNoSocketError;
-}
-
-int32_t UdpTransportImpl::InitializeSourcePorts(uint16_t rtpPort,
- uint16_t rtcpPort)
-{
-
- if(rtpPort == 0)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "InitializeSourcePorts port 0 not allowed");
- _lastError = kPortInvalid;
- return -1;
- }
-
- CriticalSectionScoped cs(_crit);
-
- CloseSendSockets();
-
- if(_mgr == NULL)
- {
- return -1;
- }
-
- _srcPort = rtpPort;
- if(rtcpPort == 0)
- {
- _srcPortRTCP = rtpPort+1;
- } else
- {
- _srcPortRTCP = rtcpPort;
- }
- _useSetSockOpt =false;
- _tos=0;
- _pcp=0;
-
- _ptrSendRtpSocket = _socket_creator->CreateSocket(_id, _mgr, NULL, NULL,
- IpV6Enabled(), false);
- _ptrSendRtcpSocket = _socket_creator->CreateSocket(_id, _mgr, NULL, NULL,
- IpV6Enabled(), false);
-
- ErrorCode retVal = BindRTPSendSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- return -1;
- }
- retVal = BindRTCPSendSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- return -1;
- }
- return 0;
-}
-
-int32_t UdpTransportImpl::SourcePorts(uint16_t& rtpPort,
- uint16_t& rtcpPort) const
-{
- CriticalSectionScoped cs(_crit);
-
- rtpPort = (_srcPort != 0) ? _srcPort : _localPort;
- rtcpPort = (_srcPortRTCP != 0) ? _srcPortRTCP : _localPortRTCP;
- return 0;
-}
-
-
-#ifdef _WIN32
-int32_t UdpTransportImpl::StartReceiving(uint32_t numberOfSocketBuffers)
-#else
-int32_t UdpTransportImpl::StartReceiving(uint32_t /*numberOfSocketBuffers*/)
-#endif
-{
- CriticalSectionScoped cs(_crit);
- if(_receiving)
- {
- return 0;
- }
- if(_ptrRtpSocket)
- {
-#ifdef _WIN32
- if(!_ptrRtpSocket->StartReceiving(numberOfSocketBuffers))
-#else
- if(!_ptrRtpSocket->StartReceiving())
-#endif
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Failed to start receive on RTP socket");
- _lastError = kStartReceiveError;
- return -1;
- }
- }
- if(_ptrRtcpSocket)
- {
- if(!_ptrRtcpSocket->StartReceiving())
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Failed to start receive on RTCP socket");
- _lastError = kStartReceiveError;
- return -1;
- }
- }
- if( _ptrRtpSocket == NULL &&
- _ptrRtcpSocket == NULL)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Failed to StartReceiving, no socket initialized");
- _lastError = kStartReceiveError;
- return -1;
- }
- _receiving = true;
- return 0;
-}
-
-bool UdpTransportImpl::Receiving() const
-{
- return _receiving;
-}
-
-int32_t UdpTransportImpl::StopReceiving()
-{
-
- CriticalSectionScoped cs(_crit);
-
- _receiving = false;
-
- if (_ptrRtpSocket)
- {
- if (!_ptrRtpSocket->StopReceiving())
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Failed to stop receiving on RTP socket");
- _lastError = kStopReceiveError;
- return -1;
- }
- }
- if (_ptrRtcpSocket)
- {
- if (!_ptrRtcpSocket->StopReceiving())
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "Failed to stop receiving on RTCP socket");
- _lastError = kStopReceiveError;
- return -1;
- }
- }
- return 0;
-}
-
-int32_t UdpTransportImpl::InitializeSendSockets(
- const char* ipaddr,
- const uint16_t rtpPort,
- const uint16_t rtcpPort)
-{
- {
- CriticalSectionScoped cs(_crit);
- _destPort = rtpPort;
- if(rtcpPort == 0)
- {
- _destPortRTCP = _destPort+1;
- } else
- {
- _destPortRTCP = rtcpPort;
- }
-
- if(ipaddr == NULL)
- {
- if (!IsIpAddressValid(_destIP, IpV6Enabled()))
- {
- _destPort = 0;
- _destPortRTCP = 0;
- _lastError = kIpAddressInvalid;
- return -1;
- }
- } else
- {
- if (IsIpAddressValid(ipaddr, IpV6Enabled()))
- {
- strncpy(
- _destIP,
- ipaddr,
- IpV6Enabled() ? kIpAddressVersion6Length :
- kIpAddressVersion4Length);
- } else {
- _destPort = 0;
- _destPortRTCP = 0;
- _lastError = kIpAddressInvalid;
- return -1;
- }
- }
- BuildRemoteRTPAddr();
- BuildRemoteRTCPAddr();
- }
-
- if (_ipV6Enabled)
- {
- if (_qos)
- {
- WEBRTC_TRACE(
- kTraceWarning,
- kTraceTransport,
- _id,
- "QOS is enabled but will be ignored since IPv6 is enabled");
- }
- }else
- {
- // TODO (grunell): Multicast support is experimantal.
-
- // Put the first digit of the remote address in val.
- int32_t val = ntohl(_remoteRTPAddr._sockaddr_in.sin_addr)>> 24;
-
- if((val > 223) && (val < 240))
- {
- // Multicast address.
- CriticalSectionScoped cs(_crit);
-
- UdpSocketWrapper* rtpSock = (_ptrSendRtpSocket ?
- _ptrSendRtpSocket : _ptrRtpSocket);
- if (!rtpSock || !rtpSock->ValidHandle())
- {
- _lastError = kSocketInvalid;
- return -1;
- }
- UdpSocketWrapper* rtcpSock = (_ptrSendRtcpSocket ?
- _ptrSendRtcpSocket : _ptrRtcpSocket);
- if (!rtcpSock || !rtcpSock->ValidHandle())
- {
- _lastError = kSocketInvalid;
- return -1;
- }
-
- // Set Time To Live to same region
- int32_t iOptVal = 64;
- if (!rtpSock->SetSockopt(IPPROTO_IP, IP_MULTICAST_TTL,
- (int8_t*)&iOptVal,
- sizeof (int32_t)))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "setsockopt for multicast error on RTP socket");
- _ptrRtpSocket->CloseBlocking();
- _ptrRtpSocket = NULL;
- _lastError = kMulticastAddressInvalid;
- return -1;
- }
- if (!rtcpSock->SetSockopt(IPPROTO_IP, IP_MULTICAST_TTL,
- (int8_t*)&iOptVal,
- sizeof (int32_t)))
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "setsockopt for multicast error on RTCP socket");
- _ptrRtpSocket->CloseBlocking();
- _ptrRtpSocket = NULL;
- _lastError = kMulticastAddressInvalid;
- return -1;
- }
- }
- }
- return 0;
-}
-
-void UdpTransportImpl::BuildSockaddrIn(uint16_t portnr,
- const char* ip,
- SocketAddress& remoteAddr) const
-{
- if(_ipV6Enabled)
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- remoteAddr.sin_length = 0;
- remoteAddr.sin_family = PF_INET6;
-#else
- remoteAddr._sockaddr_storage.sin_family = PF_INET6;
-#endif
- remoteAddr._sockaddr_in6.sin6_port = Htons(portnr);
- InetPresentationToNumeric(AF_INET6, ip,
- &remoteAddr._sockaddr_in6.sin6_addr);
- remoteAddr._sockaddr_in6.sin6_flowinfo=0;
- remoteAddr._sockaddr_in6.sin6_scope_id=0;
- } else
- {
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- remoteAddr.sin_length = 0;
- remoteAddr.sin_family = PF_INET;
-#else
- remoteAddr._sockaddr_storage.sin_family = PF_INET;
-#endif
- remoteAddr._sockaddr_in.sin_port = Htons(portnr);
- remoteAddr._sockaddr_in.sin_addr= InetAddrIPV4(
- const_cast<char*>(ip));
- }
-}
-
-int32_t UdpTransportImpl::SendRaw(const int8_t *data,
- size_t length,
- int32_t isRTCP,
- uint16_t portnr,
- const char* ip)
-{
- CriticalSectionScoped cs(_crit);
- if(isRTCP)
- {
- UdpSocketWrapper* rtcpSock = NULL;
- if(_ptrSendRtcpSocket)
- {
- rtcpSock = _ptrSendRtcpSocket;
- } else if(_ptrRtcpSocket)
- {
- rtcpSock = _ptrRtcpSocket;
- } else
- {
- return -1;
- }
- if(portnr == 0 && ip == NULL)
- {
- return rtcpSock->SendTo(data,length,_remoteRTCPAddr);
-
- } else if(portnr != 0 && ip != NULL)
- {
- SocketAddress remoteAddr;
- BuildSockaddrIn(portnr, ip, remoteAddr);
- return rtcpSock->SendTo(data,length,remoteAddr);
- } else if(ip != NULL)
- {
- SocketAddress remoteAddr;
- BuildSockaddrIn(_destPortRTCP, ip, remoteAddr);
- return rtcpSock->SendTo(data,length,remoteAddr);
- } else
- {
- SocketAddress remoteAddr;
- BuildSockaddrIn(portnr, _destIP, remoteAddr);
- return rtcpSock->SendTo(data,length,remoteAddr);
- }
- } else {
- UdpSocketWrapper* rtpSock = NULL;
- if(_ptrSendRtpSocket)
- {
- rtpSock = _ptrSendRtpSocket;
-
- } else if(_ptrRtpSocket)
- {
- rtpSock = _ptrRtpSocket;
- } else
- {
- return -1;
- }
- if(portnr == 0 && ip == NULL)
- {
- return rtpSock->SendTo(data,length,_remoteRTPAddr);
-
- } else if(portnr != 0 && ip != NULL)
- {
- SocketAddress remoteAddr;
- BuildSockaddrIn(portnr, ip, remoteAddr);
- return rtpSock->SendTo(data,length,remoteAddr);
- } else if(ip != NULL)
- {
- SocketAddress remoteAddr;
- BuildSockaddrIn(_destPort, ip, remoteAddr);
- return rtpSock->SendTo(data,length,remoteAddr);
- } else
- {
- SocketAddress remoteAddr;
- BuildSockaddrIn(portnr, _destIP, remoteAddr);
- return rtpSock->SendTo(data,length,remoteAddr);
- }
- }
-}
-
-int32_t UdpTransportImpl::SendRTPPacketTo(const int8_t* data,
- size_t length,
- const SocketAddress& to)
-{
- CriticalSectionScoped cs(_crit);
- if(_ptrSendRtpSocket)
- {
- return _ptrSendRtpSocket->SendTo(data,length,to);
-
- } else if(_ptrRtpSocket)
- {
- return _ptrRtpSocket->SendTo(data,length,to);
- }
- return -1;
-}
-
-int32_t UdpTransportImpl::SendRTCPPacketTo(const int8_t* data,
- size_t length,
- const SocketAddress& to)
-{
-
- CriticalSectionScoped cs(_crit);
-
- if(_ptrSendRtcpSocket)
- {
- return _ptrSendRtcpSocket->SendTo(data,length,to);
-
- } else if(_ptrRtcpSocket)
- {
- return _ptrRtcpSocket->SendTo(data,length,to);
- }
- return -1;
-}
-
-int32_t UdpTransportImpl::SendRTPPacketTo(const int8_t* data,
- size_t length,
- const uint16_t rtpPort)
-{
- CriticalSectionScoped cs(_crit);
- // Use the current SocketAdress but update it with rtpPort.
- SocketAddress to;
- memcpy(&to, &_remoteRTPAddr, sizeof(SocketAddress));
-
- if(_ipV6Enabled)
- {
- to._sockaddr_in6.sin6_port = Htons(rtpPort);
- } else
- {
- to._sockaddr_in.sin_port = Htons(rtpPort);
- }
-
- if(_ptrSendRtpSocket)
- {
- return _ptrSendRtpSocket->SendTo(data,length,to);
-
- } else if(_ptrRtpSocket)
- {
- return _ptrRtpSocket->SendTo(data,length,to);
- }
- return -1;
-}
-
-int32_t UdpTransportImpl::SendRTCPPacketTo(const int8_t* data,
- size_t length,
- const uint16_t rtcpPort)
-{
- CriticalSectionScoped cs(_crit);
-
- // Use the current SocketAdress but update it with rtcpPort.
- SocketAddress to;
- memcpy(&to, &_remoteRTCPAddr, sizeof(SocketAddress));
-
- if(_ipV6Enabled)
- {
- to._sockaddr_in6.sin6_port = Htons(rtcpPort);
- } else
- {
- to._sockaddr_in.sin_port = Htons(rtcpPort);
- }
-
- if(_ptrSendRtcpSocket)
- {
- return _ptrSendRtcpSocket->SendTo(data,length,to);
-
- } else if(_ptrRtcpSocket)
- {
- return _ptrRtcpSocket->SendTo(data,length,to);
- }
- return -1;
-}
-
-bool UdpTransportImpl::SendRtp(const uint8_t* data,
- size_t length,
- const PacketOptions& packet_options) {
- WEBRTC_TRACE(kTraceStream, kTraceTransport, _id, "%s", __FUNCTION__);
-
- CriticalSectionScoped cs(_crit);
-
- if(_destIP[0] == 0)
- {
- return false;
- }
- if(_destPort == 0)
- {
- return false;
- }
-
- // Create socket if it hasn't been set up already.
- // TODO (hellner): why not fail here instead. Sockets not being initialized
- // indicates that there is a problem somewhere.
- if( _ptrSendRtpSocket == NULL &&
- _ptrRtpSocket == NULL)
- {
- WEBRTC_TRACE(
- kTraceStateInfo,
- kTraceTransport,
- _id,
- "Creating RTP socket since no receive or source socket is\
- configured");
-
- _ptrRtpSocket = _socket_creator->CreateSocket(_id, _mgr, this,
- IncomingRTPCallback,
- IpV6Enabled(), false);
-
- // Don't bind to a specific IP address.
- if(! IpV6Enabled())
- {
- strncpy(_localIP, "0.0.0.0",16);
- } else
- {
- strncpy(_localIP, "0000:0000:0000:0000:0000:0000:0000:0000",
- kIpAddressVersion6Length);
- }
- _localPort = _destPort;
-
- ErrorCode retVal = BindLocalRTPSocket();
- if(retVal != kNoSocketError)
- {
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "SendPacket() failed to bind RTP socket");
- _lastError = retVal;
- CloseReceiveSockets();
- return false;
- }
- }
-
- if(_ptrSendRtpSocket)
- {
- return _ptrSendRtpSocket->SendTo((const int8_t*)data, length,
- _remoteRTPAddr) >= 0;
-
- } else if(_ptrRtpSocket)
- {
- return _ptrRtpSocket->SendTo((const int8_t*)data, length,
- _remoteRTPAddr) >= 0;
- }
- return false;
-}
-
-bool UdpTransportImpl::SendRtcp(const uint8_t* data, size_t length) {
- CriticalSectionScoped cs(_crit);
- if(_destIP[0] == 0)
- {
- return false;
- }
- if(_destPortRTCP == 0)
- {
- return false;
- }
-
- // Create socket if it hasn't been set up already.
- // TODO (hellner): why not fail here instead. Sockets not being initialized
- // indicates that there is a problem somewhere.
- if( _ptrSendRtcpSocket == NULL &&
- _ptrRtcpSocket == NULL)
- {
- WEBRTC_TRACE(
- kTraceStateInfo,
- kTraceTransport,
- _id,
- "Creating RTCP socket since no receive or source socket is\
- configured");
-
- _ptrRtcpSocket = _socket_creator->CreateSocket(_id, _mgr, this,
- IncomingRTCPCallback,
- IpV6Enabled(), false);
-
- // Don't bind to a specific IP address.
- if(! IpV6Enabled())
- {
- strncpy(_localIP, "0.0.0.0",16);
- } else
- {
- strncpy(_localIP, "0000:0000:0000:0000:0000:0000:0000:0000",
- kIpAddressVersion6Length);
- }
- _localPortRTCP = _destPortRTCP;
-
- ErrorCode retVal = BindLocalRTCPSocket();
- if(retVal != kNoSocketError)
- {
- _lastError = retVal;
- WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
- "SendRtcp() failed to bind RTCP socket");
- CloseReceiveSockets();
- return false;
- }
- }
-
- if(_ptrSendRtcpSocket)
- {
- return _ptrSendRtcpSocket->SendTo((const int8_t*)data, length,
- _remoteRTCPAddr) >= 0;
- } else if(_ptrRtcpSocket)
- {
- return _ptrRtcpSocket->SendTo((const int8_t*)data, length,
- _remoteRTCPAddr) >= 0;
- }
- return false;
-}
-
-int32_t UdpTransportImpl::SetSendIP(const char* ipaddr)
-{
- if(!IsIpAddressValid(ipaddr,IpV6Enabled()))
- {
- return kIpAddressInvalid;
- }
- CriticalSectionScoped cs(_crit);
- strncpy(_destIP, ipaddr,kIpAddressVersion6Length);
- BuildRemoteRTPAddr();
- BuildRemoteRTCPAddr();
- return 0;
-}
-
-int32_t UdpTransportImpl::SetSendPorts(uint16_t rtpPort, uint16_t rtcpPort)
-{
- CriticalSectionScoped cs(_crit);
- _destPort = rtpPort;
- if(rtcpPort == 0)
- {
- _destPortRTCP = _destPort+1;
- } else
- {
- _destPortRTCP = rtcpPort;
- }
- BuildRemoteRTPAddr();
- BuildRemoteRTCPAddr();
- return 0;
-}
-
-void UdpTransportImpl::IncomingRTPCallback(CallbackObj obj,
- const int8_t* rtpPacket,
- size_t rtpPacketLength,
- const SocketAddress* from)
-{
- if (rtpPacket && rtpPacketLength > 0)
- {
- UdpTransportImpl* socketTransport = (UdpTransportImpl*) obj;
- socketTransport->IncomingRTPFunction(rtpPacket, rtpPacketLength, from);
- }
-}
-
-void UdpTransportImpl::IncomingRTCPCallback(CallbackObj obj,
- const int8_t* rtcpPacket,
- size_t rtcpPacketLength,
- const SocketAddress* from)
-{
- if (rtcpPacket && rtcpPacketLength > 0)
- {
- UdpTransportImpl* socketTransport = (UdpTransportImpl*) obj;
- socketTransport->IncomingRTCPFunction(rtcpPacket, rtcpPacketLength,
- from);
- }
-}
-
-void UdpTransportImpl::IncomingRTPFunction(const int8_t* rtpPacket,
- size_t rtpPacketLength,
- const SocketAddress* fromSocket)
-{
- char ipAddress[kIpAddressVersion6Length];
- uint32_t ipAddressLength = kIpAddressVersion6Length;
- uint16_t portNr = 0;
-
- {
- CriticalSectionScoped cs(_critFilter);
- if (FilterIPAddress(fromSocket) == false)
- {
- // Packet should be filtered out. Drop it.
- WEBRTC_TRACE(kTraceStream, kTraceTransport, _id,
- "Incoming RTP packet blocked by IP filter");
- return;
- }
-
- if (IPAddressCached(*fromSocket, ipAddress, ipAddressLength, portNr) <
- 0)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "UdpTransportImpl::IncomingRTPFunction - Cannot get sender\
- information");
- }else
- {
- // Make sure ipAddress is null terminated.
- ipAddress[kIpAddressVersion6Length - 1] = 0;
- strncpy(_fromIP, ipAddress, kIpAddressVersion6Length - 1);
- }
-
- // Filter based on port.
- if (_rtpFilterPort != 0 &&
- _rtpFilterPort != portNr)
- {
- // Drop packet.
- memset(_fromIP, 0, sizeof(_fromIP));
- WEBRTC_TRACE(
- kTraceStream,
- kTraceTransport,
- _id,
- "Incoming RTP packet blocked by filter incoming from port:%d\
- allowed port:%d",
- portNr,
- _rtpFilterPort);
- return;
- }
- _fromPort = portNr;
- }
-
- CriticalSectionScoped cs(_critPacketCallback);
- if (_packetCallback)
- {
- WEBRTC_TRACE(kTraceStream, kTraceTransport, _id,
- "Incoming RTP packet from ip:%s port:%d", ipAddress, portNr);
- _packetCallback->IncomingRTPPacket(rtpPacket, rtpPacketLength,
- ipAddress, portNr);
- }
-}
-
-void UdpTransportImpl::IncomingRTCPFunction(const int8_t* rtcpPacket,
- size_t rtcpPacketLength,
- const SocketAddress* fromSocket)
-{
- char ipAddress[kIpAddressVersion6Length];
- uint32_t ipAddressLength = kIpAddressVersion6Length;
- uint16_t portNr = 0;
-
- {
- CriticalSectionScoped cs(_critFilter);
- if (FilterIPAddress(fromSocket) == false)
- {
- // Packet should be filtered out. Drop it.
- WEBRTC_TRACE(kTraceStream, kTraceTransport, _id,
- "Incoming RTCP packet blocked by IP filter");
- return;
- }
- if (IPAddress(*fromSocket, ipAddress, ipAddressLength, portNr) < 0)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "UdpTransportImpl::IncomingRTCPFunction - Cannot get sender\
- information");
- }else {
- // Make sure ipAddress is null terminated.
- ipAddress[kIpAddressVersion6Length - 1] = 0;
- strncpy(_fromIP, ipAddress, kIpAddressVersion6Length - 1);
- }
-
- // Filter based on port.
- if (_rtcpFilterPort != 0 &&
- _rtcpFilterPort != portNr)
- {
- // Drop packet.
- WEBRTC_TRACE(
- kTraceStream,
- kTraceTransport,
- _id,
- "Incoming RTCP packet blocked by filter incoming from port:%d\
- allowed port:%d",
- portNr,
- _rtpFilterPort);
- return;
- }
- _fromPortRTCP = portNr;
- }
-
- CriticalSectionScoped cs(_critPacketCallback);
- if (_packetCallback)
- {
- WEBRTC_TRACE(kTraceStream, kTraceTransport, _id,
- "Incoming RTCP packet from ip:%s port:%d", ipAddress,
- portNr);
- _packetCallback->IncomingRTCPPacket(rtcpPacket, rtcpPacketLength,
- ipAddress, portNr);
- }
-}
-
-bool UdpTransportImpl::FilterIPAddress(const SocketAddress* fromAddress)
-{
- if(fromAddress->_sockaddr_storage.sin_family == AF_INET)
- {
- if (_filterIPAddress._sockaddr_storage.sin_family == AF_INET)
- {
- // IP is stored in sin_addr.
- if (_filterIPAddress._sockaddr_in.sin_addr != 0 &&
- (_filterIPAddress._sockaddr_in.sin_addr !=
- fromAddress->_sockaddr_in.sin_addr))
- {
- return false;
- }
- }
- }
- else if(fromAddress->_sockaddr_storage.sin_family == AF_INET6)
- {
- if (_filterIPAddress._sockaddr_storage.sin_family == AF_INET6)
- {
- // IP is stored in sin_6addr.
- for (int32_t i = 0; i < 4; i++)
- {
- if (_filterIPAddress._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[i] != 0 &&
- _filterIPAddress._sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[i] != fromAddress->_sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u32[i])
- {
- return false;
- }
- }
- }
- }
- else
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- _id,
- "UdpTransportImpl::FilterIPAddress() unknown address family");
- return false;
- }
- return true;
-}
-
-void UdpTransportImpl::CloseReceiveSockets()
-{
- if(_ptrRtpSocket)
- {
- _ptrRtpSocket->CloseBlocking();
- _ptrRtpSocket = NULL;
- }
- if(_ptrRtcpSocket)
- {
- _ptrRtcpSocket->CloseBlocking();
- _ptrRtcpSocket = NULL;
- }
- _receiving = false;
-}
-
-void UdpTransportImpl::CloseSendSockets()
-{
- if(_ptrSendRtpSocket)
- {
- _ptrSendRtpSocket->CloseBlocking();
- _ptrSendRtpSocket = 0;
- }
- if(_ptrSendRtcpSocket)
- {
- _ptrSendRtcpSocket->CloseBlocking();
- _ptrSendRtcpSocket = 0;
- }
-}
-
-uint16_t UdpTransport::Htons(const uint16_t port)
-{
- return htons(port);
-}
-
-uint32_t UdpTransport::Htonl(const uint32_t a)
-{
- return htonl(a);
-}
-
-uint32_t UdpTransport::InetAddrIPV4(const char* ip)
-{
- return ::inet_addr(ip);
-}
-
-int32_t UdpTransport::InetPresentationToNumeric(int32_t af,
- const char* src,
- void* dst)
-{
-#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
- const int32_t result = inet_pton(af, src, dst);
- return result > 0 ? 0 : -1;
-
-#elif defined(_WIN32)
- SocketAddress temp;
- int length=sizeof(SocketAddress);
-
- if(af == AF_INET)
- {
- int32_t result = WSAStringToAddressA(
- (const LPSTR)src,
- af,
- 0,
- reinterpret_cast<struct sockaddr*>(&temp),
- &length);
- if(result != 0)
- {
- return -1;
- }
- memcpy(dst,&(temp._sockaddr_in.sin_addr),
- sizeof(temp._sockaddr_in.sin_addr));
- return 0;
- }
- else if(af == AF_INET6)
- {
- int32_t result = WSAStringToAddressA(
- (const LPSTR)src,
- af,
- 0,
- reinterpret_cast<struct sockaddr*>(&temp),
- &length);
- if(result !=0)
- {
- return -1;
- }
- memcpy(dst,&(temp._sockaddr_in6.sin6_addr),
- sizeof(temp._sockaddr_in6.sin6_addr));
- return 0;
-
- }else
- {
- return -1;
- }
-#else
- return -1;
-#endif
-}
-
-int32_t UdpTransport::LocalHostAddressIPV6(char n_localIP[16])
-{
-
-#if defined(_WIN32)
- struct addrinfo *result = NULL;
- struct addrinfo *ptr = NULL;
- struct addrinfo hints;
-
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_family = AF_INET6;
-
- char szHostName[256] = "";
- if(::gethostname(szHostName, sizeof(szHostName) - 1))
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, "gethostname failed");
- return -1;
- }
-
- DWORD dwRetval = getaddrinfo(szHostName, NULL, &hints, &result);
- if ( dwRetval != 0 )
- {
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1,
- "getaddrinfo failed, error:%d", dwRetval);
- return -1;
- }
- for(ptr=result; ptr != NULL ;ptr=ptr->ai_next)
- {
- switch (ptr->ai_family)
- {
- case AF_INET6:
- {
- for(int i = 0; i< 16; i++)
- {
- n_localIP[i] = (*(SocketAddress*)ptr->ai_addr).
- _sockaddr_in6.sin6_addr.Version6AddressUnion._s6_u8[i];
- }
- bool islocalIP = true;
-
- for(int n = 0; n< 15; n++)
- {
- if(n_localIP[n] != 0)
- {
- islocalIP = false;
- break;
- }
- }
-
- if(islocalIP && n_localIP[15] != 1)
- {
- islocalIP = false;
- }
-
- if(islocalIP && ptr->ai_next)
- {
- continue;
- }
- if(n_localIP[0] == 0xfe &&
- n_localIP[1] == 0x80 && ptr->ai_next)
- {
- continue;
- }
- freeaddrinfo(result);
- }
- return 0;
- default:
- break;
- };
- }
- freeaddrinfo(result);
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1,
- "getaddrinfo failed to find address");
- return -1;
-
-#elif defined(WEBRTC_MAC)
- struct ifaddrs* ptrIfAddrs = NULL;
- struct ifaddrs* ptrIfAddrsStart = NULL;
-
- getifaddrs(&ptrIfAddrsStart);
- ptrIfAddrs = ptrIfAddrsStart;
- while(ptrIfAddrs)
- {
- if(ptrIfAddrs->ifa_addr->sa_family == AF_INET6)
- {
- const struct sockaddr_in6* sock_in6 =
- reinterpret_cast<struct sockaddr_in6*>(ptrIfAddrs->ifa_addr);
- const struct in6_addr* sin6_addr = &sock_in6->sin6_addr;
-
- if (IN6_IS_ADDR_LOOPBACK(sin6_addr) ||
- IN6_IS_ADDR_LINKLOCAL(sin6_addr)) {
- ptrIfAddrs = ptrIfAddrs->ifa_next;
- continue;
- }
- memcpy(n_localIP, sin6_addr->s6_addr, sizeof(sin6_addr->s6_addr));
- freeifaddrs(ptrIfAddrsStart);
- return 0;
- }
- ptrIfAddrs = ptrIfAddrs->ifa_next;
- }
- freeifaddrs(ptrIfAddrsStart);
- return -1;
-#elif defined(WEBRTC_ANDROID)
- return -1;
-#else // WEBRTC_LINUX
- struct
- {
- struct nlmsghdr n;
- struct ifaddrmsg r;
- } req;
-
- struct rtattr* rta = NULL;
- int status;
- char buf[16384]; // = 16 * 1024 (16 kB)
- struct nlmsghdr* nlmp;
- struct ifaddrmsg* rtmp;
- struct rtattr* rtatp;
- int rtattrlen;
- struct in6_addr* in6p;
-
- int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
- if (fd == -1)
- {
- return -1;
- }
-
- // RTM_GETADDR is used to fetch the ip address from the kernel interface
- // table. Populate the msg structure (req) the size of the message buffer
- // is specified to netlinkmessage header, and flags values are set as
- // NLM_F_ROOT | NLM_F_REQUEST.
- // The request flag must be set for all messages requesting the data from
- // kernel. The root flag is used to notify the kernel to return the full
- // tabel. Another flag (not used) is NLM_F_MATCH. This is used to get only
- // specified entries in the table. At the time of writing this program this
- // flag is not implemented in kernel
-
- memset(&req, 0, sizeof(req));
- req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
- req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
- req.n.nlmsg_type = RTM_GETADDR;
- req.r.ifa_family = AF_INET6;
-
- // Fill up all the attributes for the rtnetlink header.
- // The lenght is very important. 16 signifies the ipv6 address.
- rta = (struct rtattr*)(((char*)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
- rta->rta_len = RTA_LENGTH(16);
-
- status = send(fd, &req, req.n.nlmsg_len, 0);
- if (status < 0)
- {
- close(fd);
- return -1;
- }
- status = recv(fd, buf, sizeof(buf), 0);
- if (status < 0)
- {
- close(fd);
- return -1;
- }
- if(status == 0)
- {
- close(fd);
- return -1;
- }
- close(fd);
-
- // The message is stored in buff. Parse the message to get the requested
- // data.
- {
- nlmp = (struct nlmsghdr*)buf;
- int len = nlmp->nlmsg_len;
- int req_len = len - sizeof(*nlmp);
-
- if (req_len < 0 || len > status)
- {
- return -1;
- }
- if (!NLMSG_OK_NO_WARNING(nlmp, status))
- {
- return -1;
- }
- rtmp = (struct ifaddrmsg*)NLMSG_DATA(nlmp);
- rtatp = (struct rtattr*)IFA_RTA(rtmp);
-
- rtattrlen = IFA_PAYLOAD(nlmp);
-
- for (; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen))
- {
-
- // Here we hit the fist chunk of the message. Time to validate the
- // type. For more info on the different types see
- // "man(7) rtnetlink" The table below is taken from man pages.
- // Attributes
- // rta_type value type description
- // -------------------------------------------------------------
- // IFA_UNSPEC - unspecified.
- // IFA_ADDRESS raw protocol address interface address
- // IFA_LOCAL raw protocol address local address
- // IFA_LABEL asciiz string name of the interface
- // IFA_BROADCAST raw protocol address broadcast address.
- // IFA_ANYCAST raw protocol address anycast address
- // IFA_CACHEINFO struct ifa_cacheinfo Address information.
-
- if(rtatp->rta_type == IFA_ADDRESS)
- {
- bool islocalIP = true;
- in6p = (struct in6_addr*)RTA_DATA(rtatp);
- for(int n = 0; n< 15; n++)
- {
- if(in6p->s6_addr[n] != 0)
- {
- islocalIP = false;
- break;
- }
- }
- if(islocalIP && in6p->s6_addr[15] != 1)
- {
- islocalIP = false;
- }
- if(!islocalIP)
- {
- for(int i = 0; i< 16; i++)
- {
- n_localIP[i] = in6p->s6_addr[i];
- }
- if(n_localIP[0] == static_cast<char> (0xfe)
- && n_localIP[1] == static_cast<char>(0x80) )
- {
- // Auto configured IP.
- continue;
- }
- break;
- }
- }
- }
- }
- return 0;
-#endif
-}
-
-int32_t UdpTransport::LocalHostAddress(uint32_t& localIP)
-{
- #if defined(_WIN32)
- hostent* localHost;
- localHost = gethostbyname( "" );
- if(localHost)
- {
- if(localHost->h_addrtype != AF_INET)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- -1,
- "LocalHostAddress can only get local IP for IP Version 4");
- return -1;
- }
- localIP= Htonl(
- (*(struct in_addr *)localHost->h_addr_list[0]).S_un.S_addr);
- return 0;
- }
- else
- {
- int32_t error = WSAGetLastError();
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1,
- "gethostbyname failed, error:%d", error);
- return -1;
- }
-#elif (defined(WEBRTC_MAC))
- char localname[255];
- if (gethostname(localname, 255) != -1)
- {
- hostent* localHost;
- localHost = gethostbyname(localname);
- if(localHost)
- {
- if(localHost->h_addrtype != AF_INET)
- {
- WEBRTC_TRACE(
- kTraceError,
- kTraceTransport,
- -1,
- "LocalHostAddress can only get local IP for IP Version 4");
- return -1;
- }
- localIP = Htonl((*(struct in_addr*)*localHost->h_addr_list).s_addr);
- return 0;
- }
- }
- WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1, "gethostname failed");
- return -1;
-#else // WEBRTC_LINUX
- int sockfd, size = 1;
- struct ifreq* ifr;
- struct ifconf ifc;
-
- if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
- {
- return -1;
- }
- ifc.ifc_len = IFRSIZE;
- ifc.ifc_req = NULL;
- do
- {
- ++size;
- // Buffer size needed is unknown. Try increasing it until no overflow
- // occurs.
- if (NULL == (ifc.ifc_req = (ifreq*)realloc(ifc.ifc_req, IFRSIZE))) {
- fprintf(stderr, "Out of memory.\n");
- exit(EXIT_FAILURE);
- }
- ifc.ifc_len = IFRSIZE;
- if (ioctl(sockfd, SIOCGIFCONF, &ifc))
- {
- free(ifc.ifc_req);
- close(sockfd);
- return -1;
- }
- } while (IFRSIZE <= ifc.ifc_len);
-
- ifr = ifc.ifc_req;
- for (;(char *) ifr < (char *) ifc.ifc_req + ifc.ifc_len; ++ifr)
- {
- if (ifr->ifr_addr.sa_data == (ifr+1)->ifr_addr.sa_data)
- {
- continue; // duplicate, skip it
- }
- if (ioctl(sockfd, SIOCGIFFLAGS, ifr))
- {
- continue; // failed to get flags, skip it
- }
- if(strncmp(ifr->ifr_name, "lo",3) == 0)
- {
- continue;
- }else
- {
- struct sockaddr* saddr = &(ifr->ifr_addr);
- SocketAddress* socket_addess = reinterpret_cast<SocketAddress*>(
- saddr);
- localIP = Htonl(socket_addess->_sockaddr_in.sin_addr);
- close(sockfd);
- free(ifc.ifc_req);
- return 0;
- }
- }
- free(ifc.ifc_req);
- close(sockfd);
- return -1;
-#endif
-}
-
-int32_t UdpTransport::IPAddress(const SocketAddress& address,
- char* ip,
- uint32_t& ipSize,
- uint16_t& sourcePort)
-{
- #if defined(_WIN32)
- DWORD dwIPSize = ipSize;
- int32_t returnvalue = WSAAddressToStringA((LPSOCKADDR)(&address),
- sizeof(SocketAddress),
- NULL,
- ip,
- &dwIPSize);
- if(returnvalue == -1)
- {
- return -1;
- }
-
- uint16_t source_port = 0;
- if(address._sockaddr_storage.sin_family == AF_INET)
- {
- // Parse IP assuming format "a.b.c.d:port".
- char* ipEnd = strchr(ip,':');
- if(ipEnd != NULL)
- {
- *ipEnd = '\0';
- }
- ipSize = (int32_t)strlen(ip);
- if(ipSize == 0)
- {
- return -1;
- }
- source_port = address._sockaddr_in.sin_port;
- }
- else
- {
- // Parse IP assuming format "[address]:port".
- char* ipEnd = strchr(ip,']');
- if(ipEnd != NULL)
- {
- // Calculate length
- int32_t adrSize = int32_t(ipEnd - ip) - 1;
- memmove(ip, &ip[1], adrSize); // Remove '['
- *(ipEnd - 1) = '\0';
- }
- ipSize = (int32_t)strlen(ip);
- if(ipSize == 0)
- {
- return -1;
- }
-
- source_port = address._sockaddr_in6.sin6_port;
- }
- // Convert port number to network byte order.
- sourcePort = htons(source_port);
- return 0;
-
- #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
- int32_t ipFamily = address._sockaddr_storage.sin_family;
- const void* ptrNumericIP = NULL;
-
- if(ipFamily == AF_INET)
- {
- ptrNumericIP = &(address._sockaddr_in.sin_addr);
- }
- else if(ipFamily == AF_INET6)
- {
- ptrNumericIP = &(address._sockaddr_in6.sin6_addr);
- }
- else
- {
- return -1;
- }
- if(inet_ntop(ipFamily, ptrNumericIP, ip, ipSize) == NULL)
- {
- return -1;
- }
- uint16_t source_port;
- if(ipFamily == AF_INET)
- {
- source_port = address._sockaddr_in.sin_port;
- } else
- {
- source_port = address._sockaddr_in6.sin6_port;
- }
- // Convert port number to network byte order.
- sourcePort = htons(source_port);
- return 0;
- #else
- return -1;
- #endif
-}
-
-bool UdpTransport::IsIpAddressValid(const char* ipadr, const bool ipV6)
-{
- if(ipV6)
- {
- int32_t len = (int32_t)strlen(ipadr);
- if( len>39 || len == 0)
- {
- return false;
- }
-
- int32_t i;
- int32_t colonPos[7] = {0,0,0,0,0,0,0};
- int32_t lastColonPos = -2;
- int32_t nColons = 0;
- int32_t nDubbleColons = 0;
- int32_t nDots = 0;
- int32_t error = 0;
- char c;
- for(i = 0; i < len ; i++)
- {
- c=ipadr[i];
- if(isxdigit(c))
- ;
- else if(c == ':')
- {
- if(nColons < 7)
- colonPos[nColons] = i;
- if((i-lastColonPos)==1)
- nDubbleColons++;
- lastColonPos=i;
- if(nDots != 0)
- {
- error = 1;
- }
- nColons++;
- }
- else if(c == '.')
- {
- nDots++;
- }
- else
- {
- error = 1;
- }
-
- }
- if(error)
- {
- return false;
- }
- if(nDubbleColons > 1)
- {
- return false;
- }
- if(nColons > 7 || nColons < 2)
- {
- return false;
- }
- if(!(nDots == 3 || nDots == 0))
- {
- return false;
- }
- lastColonPos = -1;
- int32_t charsBeforeColon = 0;
- for(i = 0; i < nColons; i++)
- {
- charsBeforeColon=colonPos[i]-lastColonPos-1;
- if(charsBeforeColon > 4)
- {
- return false;
- }
- lastColonPos=colonPos[i];
- }
- int32_t lengthAfterLastColon = len - lastColonPos - 1;
- if(nDots == 0)
- {
- if(lengthAfterLastColon > 4)
- return false;
- }
- if(nDots == 3 && lengthAfterLastColon > 0)
- {
- return IsIpAddressValid((ipadr+lastColonPos+1),false);
- }
-
- }
- else
- {
- int32_t len = (int32_t)strlen(ipadr);
- if((len>15)||(len==0))
- {
- return false;
- }
-
- // IPv4 should be [0-255].[0-255].[0-255].[0-255]
- int32_t i;
- int32_t nDots = 0;
- int32_t iDotPos[4] = {0,0,0,0};
-
- for (i = 0; (i < len) && (nDots < 4); i++)
- {
- if (ipadr[i] == (char)'.')
- {
- // Store index of dots and count number of dots.
- iDotPos[nDots++] = i;
- }
- else if (isdigit(ipadr[i]) == 0)
- {
- return false;
- }
- }
-
- bool allUnder256 = false;
- // TODO (hellner): while loop seems to be abused here to get
- // label like functionality. Fix later to avoid introducing bugs now.
-
- // Check that all numbers are smaller than 256.
- do
- {
- if (nDots != 3 )
- {
- break;
- }
-
- if (iDotPos[0] <= 3)
- {
- char nr[4];
- memset(nr,0,4);
- strncpy(nr,&ipadr[0],iDotPos[0]);
- int32_t num = atoi(nr);
- if (num > 255 || num < 0)
- {
- break;
- }
- } else {
- break;
- }
-
- if (iDotPos[1] - iDotPos[0] <= 4)
- {
- char nr[4];
- memset(nr,0,4);
- strncpy(nr,&ipadr[iDotPos[0]+1], iDotPos[1] - iDotPos[0] - 1);
- int32_t num = atoi(nr);
- if (num > 255 || num < 0)
- break;
- } else {
- break;
- }
-
- if (iDotPos[2] - iDotPos[1] <= 4)
- {
- char nr[4];
- memset(nr,0,4);
- strncpy(nr,&ipadr[iDotPos[1]+1], iDotPos[2] - iDotPos[1] - 1);
- int32_t num = atoi(nr);
- if (num > 255 || num < 0)
- break;
- } else {
- break;
- }
-
- if (len - iDotPos[2] <= 4)
- {
- char nr[4];
- memset(nr,0,4);
- strncpy(nr,&ipadr[iDotPos[2]+1], len - iDotPos[2] -1);
- int32_t num = atoi(nr);
- if (num > 255 || num < 0)
- break;
- else
- allUnder256 = true;
- } else {
- break;
- }
- } while(false);
-
- if (nDots != 3 || !allUnder256)
- {
- return false;
- }
- }
- return true;
-}
-
-} // namespace test
-} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698