OLD | NEW |
(Empty) | |
| 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: |
| 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_ |
OLD | NEW |