387 lines
16 KiB
C
387 lines
16 KiB
C
|
/*
|
||
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#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"
|
||
|
|
||
|
#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 WebRtc_Word8* fromIP,
|
||
|
const WebRtc_UWord16 fromPort) = 0;
|
||
|
|
||
|
virtual void IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket,
|
||
|
const WebRtc_Word32 rtcpPacketLength,
|
||
|
const WebRtc_Word8* 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 WebRtc_Word8* 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 WebRtc_Word8* ipAddr = NULL,
|
||
|
const WebRtc_Word8* 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(
|
||
|
WebRtc_Word8 ipAddr[kIpAddressVersion6Length],
|
||
|
WebRtc_UWord16& rtpPort,
|
||
|
WebRtc_UWord16& rtcpPort,
|
||
|
WebRtc_Word8 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(
|
||
|
WebRtc_Word8 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(
|
||
|
WebRtc_Word8 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 WebRtc_Word8 filterIPAddress[kIpAddressVersion6Length]) = 0;
|
||
|
|
||
|
// Write the filter IP address (if any) to filterIPAddress.
|
||
|
virtual WebRtc_Word32 FilterIP(
|
||
|
WebRtc_Word8 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 WebRtc_Word8* 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 WebRtc_Word8 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(WebRtc_UWord8 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 WebRtc_Word8* 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 WebRtc_Word8* 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,
|
||
|
WebRtc_Word8* 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,
|
||
|
WebRtc_Word8* 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 WebRtc_Word8* ipaddr, const bool ipV6);
|
||
|
};
|
||
|
} // namespace webrtc
|
||
|
|
||
|
#endif // WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
|