1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ 12 #define WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ 13 14 #include "webrtc/common_types.h" 15 #include "webrtc/transport.h" 16 #include "webrtc/typedefs.h" 17 18 /* 19 * WARNING 20 * This code is not use in production/testing and might have security issues 21 * for example: http://code.google.com/p/webrtc/issues/detail?id=1028 22 * 23 */ 24 25 #define SS_MAXSIZE 128 26 #define SS_ALIGNSIZE (sizeof (uint64_t)) 27 #define SS_PAD1SIZE (SS_ALIGNSIZE - sizeof(int16_t)) 28 #define SS_PAD2SIZE (SS_MAXSIZE - (sizeof(int16_t) + SS_PAD1SIZE +\ 29 SS_ALIGNSIZE)) 30 31 // BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN 32 namespace webrtc { 33 namespace test { 34 35 struct SocketAddressIn { 36 // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) 37 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 38 int8_t sin_length; 39 int8_t sin_family; 40 #else 41 int16_t sin_family; 42 #endif 43 uint16_t sin_port; 44 uint32_t sin_addr; 45 int8_t sin_zero[8]; 46 }; 47 48 struct Version6InAddress { 49 union { 50 uint8_t _s6_u8[16]; 51 uint32_t _s6_u32[4]; 52 uint64_t _s6_u64[2]; 53 } Version6AddressUnion; 54 }; 55 56 struct SocketAddressInVersion6 { 57 // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) 58 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 59 int8_t sin_length; 60 int8_t sin_family; 61 #else 62 int16_t sin_family; 63 #endif 64 // Transport layer port number. 65 uint16_t sin6_port; 66 // IPv6 traffic class and flow info or ip4 address. 67 uint32_t sin6_flowinfo; 68 // IPv6 address 69 struct Version6InAddress sin6_addr; 70 // Set of interfaces for a scope. 71 uint32_t sin6_scope_id; 72 }; 73 74 struct SocketAddressStorage { 75 // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6) 76 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 77 int8_t sin_length; 78 int8_t sin_family; 79 #else 80 int16_t sin_family; 81 #endif 82 int8_t __ss_pad1[SS_PAD1SIZE]; 83 uint64_t __ss_align; 84 int8_t __ss_pad2[SS_PAD2SIZE]; 85 }; 86 87 struct SocketAddress { 88 union { 89 struct SocketAddressIn _sockaddr_in; 90 struct SocketAddressInVersion6 _sockaddr_in6; 91 struct SocketAddressStorage _sockaddr_storage; 92 }; 93 }; 94 95 // Callback class that receives packets from UdpTransport. 96 class UdpTransportData { 97 public: ~UdpTransportData()98 virtual ~UdpTransportData() {}; 99 100 virtual void IncomingRTPPacket(const int8_t* incomingRtpPacket, 101 const size_t rtpPacketLength, 102 const char* fromIP, 103 const uint16_t fromPort) = 0; 104 105 virtual void IncomingRTCPPacket(const int8_t* incomingRtcpPacket, 106 const size_t rtcpPacketLength, 107 const char* fromIP, 108 const uint16_t fromPort) = 0; 109 }; 110 111 class UdpTransport : public Transport { 112 public: 113 enum 114 { 115 kIpAddressVersion6Length = 64, 116 kIpAddressVersion4Length = 16 117 }; 118 enum ErrorCode 119 { 120 kNoSocketError = 0, 121 kFailedToBindPort = 1, 122 kIpAddressInvalid = 2, 123 kAddressInvalid = 3, 124 kSocketInvalid = 4, 125 kPortInvalid = 5, 126 kTosInvalid = 6, 127 kMulticastAddressInvalid = 7, 128 kQosError = 8, 129 kSocketAlreadyInitialized = 9, 130 kIpVersion6Error = 10, 131 FILTER_ERROR = 11, 132 kStartReceiveError = 12, 133 kStopReceiveError = 13, 134 kCannotFindLocalIp = 14, 135 kTosError = 16, 136 kNotInitialized = 17, 137 kPcpError = 18 138 }; 139 140 // Factory method. Constructor disabled. 141 static UdpTransport* Create(const int32_t id, uint8_t& numSocketThreads); 142 static void Destroy(UdpTransport* module); 143 144 // Prepares the class for sending RTP packets to ipAddr:rtpPort and RTCP 145 // packets to ipAddr:rtpPort+1 if rtcpPort is zero. Otherwise to 146 // ipAddr:rtcpPort. 147 virtual int32_t InitializeSendSockets(const char* ipAddr, 148 const uint16_t rtpPort, 149 const uint16_t rtcpPort = 0) = 0; 150 151 // Register packetCallback for receiving incoming packets. Set the local 152 // RTP port to rtpPort. Bind local IP address to ipAddr. If ipAddr is NULL 153 // bind to local IP ANY. Set the local rtcp port to rtcpPort or rtpPort + 1 154 // if rtcpPort is 0. 155 virtual int32_t InitializeReceiveSockets( 156 UdpTransportData* const packetCallback, 157 const uint16_t rtpPort, 158 const char* ipAddr = NULL, 159 const char* multicastIpAddr = NULL, 160 const uint16_t rtcpPort = 0) = 0; 161 162 // Set local RTP port to rtpPort and RTCP port to rtcpPort or rtpPort + 1 if 163 // rtcpPort is 0. These ports will be used for sending instead of the local 164 // ports set by InitializeReceiveSockets(..). 165 virtual int32_t InitializeSourcePorts(const uint16_t rtpPort, 166 const uint16_t rtcpPort = 0) = 0; 167 168 // Retrieve local ports used for sending if other than the ports specified 169 // by InitializeReceiveSockets(..). rtpPort is set to the RTP port. 170 // rtcpPort is set to the RTCP port. 171 virtual int32_t SourcePorts(uint16_t& rtpPort, 172 uint16_t& rtcpPort) const = 0; 173 174 // Set ipAddr to the IP address that is currently being listened on. rtpPort 175 // to the RTP port listened to. rtcpPort to the RTCP port listened on. 176 // multicastIpAddr to the multicast IP address group joined (the address 177 // is NULL terminated). 178 virtual int32_t ReceiveSocketInformation( 179 char ipAddr[kIpAddressVersion6Length], 180 uint16_t& rtpPort, 181 uint16_t& rtcpPort, 182 char multicastIpAddr[kIpAddressVersion6Length]) const = 0; 183 184 // Set ipAddr to the IP address being sent from. rtpPort to the local RTP 185 // port used for sending and rtcpPort to the local RTCP port used for 186 // sending. 187 virtual int32_t SendSocketInformation(char ipAddr[kIpAddressVersion6Length], 188 uint16_t& rtpPort, 189 uint16_t& rtcpPort) const = 0; 190 191 // Put the IP address, RTP port and RTCP port from the last received packet 192 // into ipAddr, rtpPort and rtcpPort respectively. 193 virtual int32_t RemoteSocketInformation( 194 char ipAddr[kIpAddressVersion6Length], 195 uint16_t& rtpPort, 196 uint16_t& rtcpPort) const = 0; 197 198 // Enable/disable quality of service if QoS is true or false respectively. 199 // Set the type of service to serviceType, max bitrate in kbit/s to 200 // maxBitrate and override DSCP if overrideDSCP is not 0. 201 // Note: Must be called both InitializeSendSockets() and 202 // InitializeReceiveSockets() has been called. 203 virtual int32_t SetQoS(const bool QoS, 204 const int32_t serviceType, 205 const uint32_t maxBitrate = 0, 206 const int32_t overrideDSCP = 0, 207 const bool audio = false) = 0; 208 209 // Set QoS to true if quality of service has been turned on. If QoS is true, 210 // also set serviceType to type of service and overrideDSCP to override 211 // DSCP. 212 virtual int32_t QoS(bool& QoS, 213 int32_t& serviceType, 214 int32_t& overrideDSCP) const = 0; 215 216 // Set type of service. 217 virtual int32_t SetToS(const int32_t DSCP, 218 const bool useSetSockOpt = false) = 0; 219 220 // Get type of service configuration. 221 virtual int32_t ToS(int32_t& DSCP, 222 bool& useSetSockOpt) const = 0; 223 224 // Set Priority Code Point (IEEE 802.1Q) 225 // Note: for Linux this function will set the priority for the socket, 226 // which then can be mapped to a PCP value with vconfig. 227 virtual int32_t SetPCP(const int32_t PCP) = 0; 228 229 // Get Priority Code Point 230 virtual int32_t PCP(int32_t& PCP) const = 0; 231 232 // Enable IPv6. 233 // Note: this API must be called before any call to 234 // InitializeReceiveSockets() or InitializeSendSockets(). It is not 235 // possible to go back to IPv4 (default) after this call. 236 virtual int32_t EnableIpV6() = 0; 237 238 // Return true if IPv6 has been enabled. 239 virtual bool IpV6Enabled() const = 0; 240 241 // Only allow packets received from filterIPAddress to be processed. 242 // Note: must be called after EnableIPv6(), if IPv6 is used. 243 virtual int32_t SetFilterIP( 244 const char filterIPAddress[kIpAddressVersion6Length]) = 0; 245 246 // Write the filter IP address (if any) to filterIPAddress. 247 virtual int32_t FilterIP( 248 char filterIPAddress[kIpAddressVersion6Length]) const = 0; 249 250 // Only allow RTP packets from rtpFilterPort and RTCP packets from 251 // rtcpFilterPort be processed. 252 // Note: must be called after EnableIPv6(), if IPv6 is used. 253 virtual int32_t SetFilterPorts(const uint16_t rtpFilterPort, 254 const uint16_t rtcpFilterPort) = 0; 255 256 // Set rtpFilterPort to the filter RTP port and rtcpFilterPort to the 257 // filter RTCP port (if filtering based on port is enabled). 258 virtual int32_t FilterPorts(uint16_t& rtpFilterPort, 259 uint16_t& rtcpFilterPort) const = 0; 260 261 // Set the number of buffers that the socket implementation may use for 262 // receiving packets to numberOfSocketBuffers. I.e. the number of packets 263 // that can be received in parallell. 264 // Note: this API only has effect on Windows. 265 virtual int32_t StartReceiving(const uint32_t numberOfSocketBuffers) = 0; 266 267 // Stop receive incoming packets. 268 virtual int32_t StopReceiving() = 0; 269 270 // Return true incoming packets are received. 271 virtual bool Receiving() const = 0; 272 273 // Return true if send sockets have been initialized. 274 virtual bool SendSocketsInitialized() const = 0; 275 276 // Return true if local ports for sending has been set. 277 virtual bool SourcePortsInitialized() const = 0; 278 279 // Return true if receive sockets have been initialized. 280 virtual bool ReceiveSocketsInitialized() const = 0; 281 282 // Send data with size length to ip:portnr. The same port as the set 283 // with InitializeSendSockets(..) is used if portnr is 0. The same IP 284 // address as set with InitializeSendSockets(..) is used if ip is NULL. 285 // If isRTCP is true the port used will be the RTCP port. 286 virtual int32_t SendRaw(const int8_t* data, 287 size_t length, 288 int32_t isRTCP, 289 uint16_t portnr = 0, 290 const char* ip = NULL) = 0; 291 292 // Send RTP data with size length to the address specified by to. 293 virtual int32_t SendRTPPacketTo(const int8_t* data, 294 size_t length, 295 const SocketAddress& to) = 0; 296 297 298 // Send RTCP data with size length to the address specified by to. 299 virtual int32_t SendRTCPPacketTo(const int8_t* data, 300 size_t length, 301 const SocketAddress& to) = 0; 302 303 // Send RTP data with size length to ip:rtpPort where ip is the ip set by 304 // the InitializeSendSockets(..) call. 305 virtual int32_t SendRTPPacketTo(const int8_t* data, 306 size_t length, 307 uint16_t rtpPort) = 0; 308 309 310 // Send RTCP data with size length to ip:rtcpPort where ip is the ip set by 311 // the InitializeSendSockets(..) call. 312 virtual int32_t SendRTCPPacketTo(const int8_t* data, 313 size_t length, 314 uint16_t rtcpPort) = 0; 315 316 // Set the IP address to which packets are sent to ipaddr. 317 virtual int32_t SetSendIP( 318 const char ipaddr[kIpAddressVersion6Length]) = 0; 319 320 // Set the send RTP and RTCP port to rtpPort and rtcpPort respectively. 321 virtual int32_t SetSendPorts(const uint16_t rtpPort, 322 const uint16_t rtcpPort = 0) = 0; 323 324 // Retreive the last registered error code. 325 virtual ErrorCode LastError() const = 0; 326 327 // Put the local IPv4 address in localIP. 328 // Note: this API is for IPv4 only. 329 static int32_t LocalHostAddress(uint32_t& localIP); 330 331 // Put the local IP6 address in localIP. 332 // Note: this API is for IPv6 only. 333 static int32_t LocalHostAddressIPV6(char localIP[16]); 334 335 // Return a copy of hostOrder (host order) in network order. 336 static uint16_t Htons(uint16_t hostOrder); 337 338 // Return a copy of hostOrder (host order) in network order. 339 static uint32_t Htonl(uint32_t hostOrder); 340 341 // Return IPv4 address in ip as 32 bit integer. 342 static uint32_t InetAddrIPV4(const char* ip); 343 344 // Convert the character string src into a network address structure in 345 // the af address family and put it in dst. 346 // Note: same functionality as inet_pton(..) 347 static int32_t InetPresentationToNumeric(int32_t af, 348 const char* src, 349 void* dst); 350 351 // Set ip and sourcePort according to address. As input parameter ipSize 352 // is the length of ip. As output parameter it's the number of characters 353 // written to ip (not counting the '\0' character). 354 // Note: this API is only implemented on Windows and Linux. 355 static int32_t IPAddress(const SocketAddress& address, 356 char* ip, 357 uint32_t& ipSize, 358 uint16_t& sourcePort); 359 360 // Set ip and sourcePort according to address. As input parameter ipSize 361 // is the length of ip. As output parameter it's the number of characters 362 // written to ip (not counting the '\0' character). 363 // Note: this API is only implemented on Windows and Linux. 364 // Additional note: this API caches the address of the last call to it. If 365 // address is likley to be the same for multiple calls it may be beneficial 366 // to call this API instead of IPAddress(). 367 virtual int32_t IPAddressCached(const SocketAddress& address, 368 char* ip, 369 uint32_t& ipSize, 370 uint16_t& sourcePort) = 0; 371 372 // Return true if ipaddr is a valid IP address. 373 // If ipV6 is false ipaddr is interpreted as an IPv4 address otherwise it 374 // is interptreted as IPv6. 375 static bool IsIpAddressValid(const char* ipaddr, const bool ipV6); 376 }; 377 378 } // namespace test 379 } // namespace webrtc 380 381 #endif // WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_ 382