• 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/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:
~UdpTransportData()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