| /* |
| * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ |
| #define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ |
| |
| #include "webrtc/common_types.h" |
| #include "webrtc/transport.h" |
| #include "webrtc/typedefs.h" |
| |
| /* |
| * WARNING |
| * This code is not use in production/testing and might have security issues |
| * for example: http://code.google.com/p/webrtc/issues/detail?id=1028 |
| * |
| */ |
| |
| #define SS_MAXSIZE 128 |
| #define SS_ALIGNSIZE (sizeof (uint64_t)) |
| #define SS_PAD1SIZE (SS_ALIGNSIZE - sizeof(int16_t)) |
| #define SS_PAD2SIZE (SS_MAXSIZE - (sizeof(int16_t) + SS_PAD1SIZE +\ |
| SS_ALIGNSIZE)) |
| |
| // BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN |
| namespace webrtc { |
| namespace test { |
| |
| struct SocketAddressIn { |
| // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) |
| #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN |
| int8_t sin_length; |
| int8_t sin_family; |
| #else |
| int16_t sin_family; |
| #endif |
| uint16_t sin_port; |
| uint32_t sin_addr; |
| int8_t sin_zero[8]; |
| }; |
| |
| struct Version6InAddress { |
| union { |
| uint8_t _s6_u8[16]; |
| uint32_t _s6_u32[4]; |
| uint64_t _s6_u64[2]; |
| } Version6AddressUnion; |
| }; |
| |
| struct SocketAddressInVersion6 { |
| // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) |
| #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN |
| int8_t sin_length; |
| int8_t sin_family; |
| #else |
| int16_t sin_family; |
| #endif |
| // Transport layer port number. |
| uint16_t sin6_port; |
| // IPv6 traffic class and flow info or ip4 address. |
| uint32_t sin6_flowinfo; |
| // IPv6 address |
| struct Version6InAddress sin6_addr; |
| // Set of interfaces for a scope. |
| uint32_t sin6_scope_id; |
| }; |
| |
| struct SocketAddressStorage { |
| // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) |
| #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN |
| int8_t sin_length; |
| int8_t sin_family; |
| #else |
| int16_t sin_family; |
| #endif |
| int8_t __ss_pad1[SS_PAD1SIZE]; |
| uint64_t __ss_align; |
| int8_t __ss_pad2[SS_PAD2SIZE]; |
| }; |
| |
| struct SocketAddress { |
| union { |
| struct SocketAddressIn _sockaddr_in; |
| struct SocketAddressInVersion6 _sockaddr_in6; |
| struct SocketAddressStorage _sockaddr_storage; |
| }; |
| }; |
| |
| // Callback class that receives packets from UdpTransport. |
| class UdpTransportData { |
| public: |
| virtual ~UdpTransportData() {}; |
| |
| virtual void IncomingRTPPacket(const int8_t* incomingRtpPacket, |
| const size_t rtpPacketLength, |
| const char* fromIP, |
| const uint16_t fromPort) = 0; |
| |
| virtual void IncomingRTCPPacket(const int8_t* incomingRtcpPacket, |
| const size_t rtcpPacketLength, |
| const char* fromIP, |
| const uint16_t fromPort) = 0; |
| }; |
| |
| class UdpTransport : public Transport { |
| public: |
| enum |
| { |
| kIpAddressVersion6Length = 64, |
| kIpAddressVersion4Length = 16 |
| }; |
| enum ErrorCode |
| { |
| kNoSocketError = 0, |
| kFailedToBindPort = 1, |
| kIpAddressInvalid = 2, |
| kAddressInvalid = 3, |
| kSocketInvalid = 4, |
| kPortInvalid = 5, |
| kTosInvalid = 6, |
| kMulticastAddressInvalid = 7, |
| kQosError = 8, |
| kSocketAlreadyInitialized = 9, |
| kIpVersion6Error = 10, |
| FILTER_ERROR = 11, |
| kStartReceiveError = 12, |
| kStopReceiveError = 13, |
| kCannotFindLocalIp = 14, |
| kTosError = 16, |
| kNotInitialized = 17, |
| kPcpError = 18 |
| }; |
| |
| // Factory method. Constructor disabled. |
| static UdpTransport* Create(const int32_t id, uint8_t& numSocketThreads); |
| static void Destroy(UdpTransport* module); |
| |
| // Prepares the class for sending RTP packets to ipAddr:rtpPort and RTCP |
| // packets to ipAddr:rtpPort+1 if rtcpPort is zero. Otherwise to |
| // ipAddr:rtcpPort. |
| virtual int32_t InitializeSendSockets(const char* ipAddr, |
| const uint16_t rtpPort, |
| const uint16_t rtcpPort = 0) = 0; |
| |
| // Register packetCallback for receiving incoming packets. Set the local |
| // RTP port to rtpPort. Bind local IP address to ipAddr. If ipAddr is NULL |
| // bind to local IP ANY. Set the local rtcp port to rtcpPort or rtpPort + 1 |
| // if rtcpPort is 0. |
| virtual int32_t InitializeReceiveSockets( |
| UdpTransportData* const packetCallback, |
| const uint16_t rtpPort, |
| const char* ipAddr = NULL, |
| const char* multicastIpAddr = NULL, |
| const uint16_t rtcpPort = 0) = 0; |
| |
| // Set local RTP port to rtpPort and RTCP port to rtcpPort or rtpPort + 1 if |
| // rtcpPort is 0. These ports will be used for sending instead of the local |
| // ports set by InitializeReceiveSockets(..). |
| virtual int32_t InitializeSourcePorts(const uint16_t rtpPort, |
| const uint16_t rtcpPort = 0) = 0; |
| |
| // Retrieve local ports used for sending if other than the ports specified |
| // by InitializeReceiveSockets(..). rtpPort is set to the RTP port. |
| // rtcpPort is set to the RTCP port. |
| virtual int32_t SourcePorts(uint16_t& rtpPort, |
| uint16_t& rtcpPort) const = 0; |
| |
| // Set ipAddr to the IP address that is currently being listened on. rtpPort |
| // to the RTP port listened to. rtcpPort to the RTCP port listened on. |
| // multicastIpAddr to the multicast IP address group joined (the address |
| // is NULL terminated). |
| virtual int32_t ReceiveSocketInformation( |
| char ipAddr[kIpAddressVersion6Length], |
| uint16_t& rtpPort, |
| uint16_t& rtcpPort, |
| char multicastIpAddr[kIpAddressVersion6Length]) const = 0; |
| |
| // Set ipAddr to the IP address being sent from. rtpPort to the local RTP |
| // port used for sending and rtcpPort to the local RTCP port used for |
| // sending. |
| virtual int32_t SendSocketInformation(char ipAddr[kIpAddressVersion6Length], |
| uint16_t& rtpPort, |
| uint16_t& rtcpPort) const = 0; |
| |
| // Put the IP address, RTP port and RTCP port from the last received packet |
| // into ipAddr, rtpPort and rtcpPort respectively. |
| virtual int32_t RemoteSocketInformation( |
| char ipAddr[kIpAddressVersion6Length], |
| uint16_t& rtpPort, |
| uint16_t& rtcpPort) const = 0; |
| |
| // Enable/disable quality of service if QoS is true or false respectively. |
| // Set the type of service to serviceType, max bitrate in kbit/s to |
| // maxBitrate and override DSCP if overrideDSCP is not 0. |
| // Note: Must be called both InitializeSendSockets() and |
| // InitializeReceiveSockets() has been called. |
| virtual int32_t SetQoS(const bool QoS, |
| const int32_t serviceType, |
| const uint32_t maxBitrate = 0, |
| const int32_t overrideDSCP = 0, |
| const bool audio = false) = 0; |
| |
| // Set QoS to true if quality of service has been turned on. If QoS is true, |
| // also set serviceType to type of service and overrideDSCP to override |
| // DSCP. |
| virtual int32_t QoS(bool& QoS, |
| int32_t& serviceType, |
| int32_t& overrideDSCP) const = 0; |
| |
| // Set type of service. |
| virtual int32_t SetToS(const int32_t DSCP, |
| const bool useSetSockOpt = false) = 0; |
| |
| // Get type of service configuration. |
| virtual int32_t ToS(int32_t& DSCP, |
| bool& useSetSockOpt) const = 0; |
| |
| // Set Priority Code Point (IEEE 802.1Q) |
| // Note: for Linux this function will set the priority for the socket, |
| // which then can be mapped to a PCP value with vconfig. |
| virtual int32_t SetPCP(const int32_t PCP) = 0; |
| |
| // Get Priority Code Point |
| virtual int32_t PCP(int32_t& PCP) const = 0; |
| |
| // Enable IPv6. |
| // Note: this API must be called before any call to |
| // InitializeReceiveSockets() or InitializeSendSockets(). It is not |
| // possible to go back to IPv4 (default) after this call. |
| virtual int32_t EnableIpV6() = 0; |
| |
| // Return true if IPv6 has been enabled. |
| virtual bool IpV6Enabled() const = 0; |
| |
| // Only allow packets received from filterIPAddress to be processed. |
| // Note: must be called after EnableIPv6(), if IPv6 is used. |
| virtual int32_t SetFilterIP( |
| const char filterIPAddress[kIpAddressVersion6Length]) = 0; |
| |
| // Write the filter IP address (if any) to filterIPAddress. |
| virtual int32_t FilterIP( |
| char filterIPAddress[kIpAddressVersion6Length]) const = 0; |
| |
| // Only allow RTP packets from rtpFilterPort and RTCP packets from |
| // rtcpFilterPort be processed. |
| // Note: must be called after EnableIPv6(), if IPv6 is used. |
| virtual int32_t SetFilterPorts(const uint16_t rtpFilterPort, |
| const uint16_t rtcpFilterPort) = 0; |
| |
| // Set rtpFilterPort to the filter RTP port and rtcpFilterPort to the |
| // filter RTCP port (if filtering based on port is enabled). |
| virtual int32_t FilterPorts(uint16_t& rtpFilterPort, |
| uint16_t& rtcpFilterPort) const = 0; |
| |
| // Set the number of buffers that the socket implementation may use for |
| // receiving packets to numberOfSocketBuffers. I.e. the number of packets |
| // that can be received in parallell. |
| // Note: this API only has effect on Windows. |
| virtual int32_t StartReceiving(const uint32_t numberOfSocketBuffers) = 0; |
| |
| // Stop receive incoming packets. |
| virtual int32_t StopReceiving() = 0; |
| |
| // Return true incoming packets are received. |
| virtual bool Receiving() const = 0; |
| |
| // Return true if send sockets have been initialized. |
| virtual bool SendSocketsInitialized() const = 0; |
| |
| // Return true if local ports for sending has been set. |
| virtual bool SourcePortsInitialized() const = 0; |
| |
| // Return true if receive sockets have been initialized. |
| virtual bool ReceiveSocketsInitialized() const = 0; |
| |
| // Send data with size length to ip:portnr. The same port as the set |
| // with InitializeSendSockets(..) is used if portnr is 0. The same IP |
| // address as set with InitializeSendSockets(..) is used if ip is NULL. |
| // If isRTCP is true the port used will be the RTCP port. |
| virtual int32_t SendRaw(const int8_t* data, |
| size_t length, |
| int32_t isRTCP, |
| uint16_t portnr = 0, |
| const char* ip = NULL) = 0; |
| |
| // Send RTP data with size length to the address specified by to. |
| virtual int32_t SendRTPPacketTo(const int8_t* data, |
| size_t length, |
| const SocketAddress& to) = 0; |
| |
| |
| // Send RTCP data with size length to the address specified by to. |
| virtual int32_t SendRTCPPacketTo(const int8_t* data, |
| size_t length, |
| const SocketAddress& to) = 0; |
| |
| // Send RTP data with size length to ip:rtpPort where ip is the ip set by |
| // the InitializeSendSockets(..) call. |
| virtual int32_t SendRTPPacketTo(const int8_t* data, |
| size_t length, |
| uint16_t rtpPort) = 0; |
| |
| |
| // Send RTCP data with size length to ip:rtcpPort where ip is the ip set by |
| // the InitializeSendSockets(..) call. |
| virtual int32_t SendRTCPPacketTo(const int8_t* data, |
| size_t length, |
| uint16_t rtcpPort) = 0; |
| |
| // Set the IP address to which packets are sent to ipaddr. |
| virtual int32_t SetSendIP( |
| const char ipaddr[kIpAddressVersion6Length]) = 0; |
| |
| // Set the send RTP and RTCP port to rtpPort and rtcpPort respectively. |
| virtual int32_t SetSendPorts(const uint16_t rtpPort, |
| const uint16_t rtcpPort = 0) = 0; |
| |
| // Retreive the last registered error code. |
| virtual ErrorCode LastError() const = 0; |
| |
| // Put the local IPv4 address in localIP. |
| // Note: this API is for IPv4 only. |
| static int32_t LocalHostAddress(uint32_t& localIP); |
| |
| // Put the local IP6 address in localIP. |
| // Note: this API is for IPv6 only. |
| static int32_t LocalHostAddressIPV6(char localIP[16]); |
| |
| // Return a copy of hostOrder (host order) in network order. |
| static uint16_t Htons(uint16_t hostOrder); |
| |
| // Return a copy of hostOrder (host order) in network order. |
| static uint32_t Htonl(uint32_t hostOrder); |
| |
| // Return IPv4 address in ip as 32 bit integer. |
| static uint32_t InetAddrIPV4(const char* ip); |
| |
| // Convert the character string src into a network address structure in |
| // the af address family and put it in dst. |
| // Note: same functionality as inet_pton(..) |
| static int32_t InetPresentationToNumeric(int32_t af, |
| const char* src, |
| void* dst); |
| |
| // Set ip and sourcePort according to address. As input parameter ipSize |
| // is the length of ip. As output parameter it's the number of characters |
| // written to ip (not counting the '\0' character). |
| // Note: this API is only implemented on Windows and Linux. |
| static int32_t IPAddress(const SocketAddress& address, |
| char* ip, |
| uint32_t& ipSize, |
| uint16_t& sourcePort); |
| |
| // Set ip and sourcePort according to address. As input parameter ipSize |
| // is the length of ip. As output parameter it's the number of characters |
| // written to ip (not counting the '\0' character). |
| // Note: this API is only implemented on Windows and Linux. |
| // Additional note: this API caches the address of the last call to it. If |
| // address is likley to be the same for multiple calls it may be beneficial |
| // to call this API instead of IPAddress(). |
| virtual int32_t IPAddressCached(const SocketAddress& address, |
| char* ip, |
| uint32_t& ipSize, |
| uint16_t& sourcePort) = 0; |
| |
| // Return true if ipaddr is a valid IP address. |
| // If ipV6 is false ipaddr is interpreted as an IPv4 address otherwise it |
| // is interptreted as IPv6. |
| static bool IsIpAddressValid(const char* ipaddr, const bool ipV6); |
| }; |
| |
| } // namespace test |
| } // namespace webrtc |
| |
| #endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ |