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