• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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