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 |