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
31namespace webrtc {
32namespace test {
33
34struct 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
47struct 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
55struct 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
73struct 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
86struct 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.
95class 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
110class 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