Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / common tools sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #ifndef GPAC_DISABLE_CORE_TOOLS
27 :
28 : #if defined(WIN32) || defined(_WIN32_WCE)
29 :
30 : #define _WINSOCK_DEPRECATED_NO_WARNINGS
31 :
32 : #ifdef _WIN32_WCE
33 : #include <winsock.h>
34 :
35 : #if !defined(__GNUC__)
36 : #pragma comment(lib, "winsock")
37 : #endif
38 :
39 : #else
40 :
41 : #include <sys/timeb.h>
42 : #include <winsock2.h>
43 : #include <ws2tcpip.h>
44 :
45 : #if !defined(__GNUC__)
46 : #pragma comment(lib, "ws2_32")
47 : #endif
48 :
49 : #endif
50 :
51 : #include <windows.h>
52 :
53 : #if !defined(__GNUC__)
54 :
55 : #if defined(IPV6_MULTICAST_IF)
56 : #define GPAC_HAS_IPV6 1
57 : #pragma message("Using WinSock IPV6")
58 : #else
59 : #undef GPAC_HAS_IPV6
60 : #pragma message("Using WinSock IPV4")
61 : #endif
62 :
63 : #endif
64 :
65 : #include <errno.h>
66 :
67 : #ifndef EISCONN
68 : /*common win32 redefs*/
69 : #undef EAGAIN
70 : #define EAGAIN WSAEWOULDBLOCK
71 : #define EISCONN WSAEISCONN
72 : #define ENOTCONN WSAENOTCONN
73 : #define ECONNRESET WSAECONNRESET
74 : #define EMSGSIZE WSAEMSGSIZE
75 : #define ECONNABORTED WSAECONNABORTED
76 : #define ENETDOWN WSAENETDOWN
77 : #undef EINTR
78 : #define EINTR WSAEINTR
79 : #undef EBADF
80 : #define EBADF WSAEBADF
81 : #endif
82 :
83 :
84 : #define LASTSOCKERROR WSAGetLastError()
85 :
86 : /*the number of sockets used. This because the WinSock lib needs init*/
87 : static int wsa_init = 0;
88 :
89 :
90 : #include <gpac/network.h>
91 :
92 :
93 : /*end-win32*/
94 :
95 : #else
96 : /*non-win32*/
97 : #include <unistd.h>
98 : #include <fcntl.h>
99 : #include <netdb.h>
100 :
101 : #ifndef __BEOS__
102 : #include <errno.h>
103 : #endif
104 :
105 : #ifndef __DARWIN__
106 : #include <sys/time.h>
107 : #endif
108 :
109 : #include <netinet/in.h>
110 : #include <netinet/tcp.h>
111 : #include <sys/socket.h>
112 : #include <sys/types.h>
113 : #include <arpa/inet.h>
114 :
115 : #include <gpac/network.h>
116 :
117 : /*not defined on solaris*/
118 : #if !defined(INADDR_NONE)
119 : # if (defined(sun) && defined(__SVR4))
120 : # define INADDR_NONE -1
121 : # else
122 : # define INADDR_NONE ((unsigned long)-1)
123 : # endif
124 : #endif
125 :
126 :
127 : #define INVALID_SOCKET -1
128 : #define SOCKET_ERROR -1
129 : #define LASTSOCKERROR errno
130 :
131 : typedef s32 SOCKET;
132 : #define closesocket(v) close(v)
133 :
134 : #endif /*WIN32||_WIN32_WCE*/
135 :
136 :
137 : #ifdef GPAC_HAS_IPV6
138 : # ifndef IPV6_ADD_MEMBERSHIP
139 : # define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
140 : # endif
141 : # ifndef IPV6_DROP_MEMBERSHIP
142 : # define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
143 : # endif
144 : #endif
145 :
146 :
147 : #ifdef __SYMBIAN32__
148 : #define SSO_CAST
149 : #else
150 : #define SSO_CAST (const char *)
151 : #endif
152 :
153 :
154 : #ifdef GPAC_HAS_IPV6
155 : static u32 ipv6_check_state = 0;
156 : #endif
157 :
158 : #ifdef _LP64
159 : #define NULL_SOCKET 0
160 : #else
161 : #define NULL_SOCKET (SOCKET)NULL
162 : #endif
163 :
164 : #ifdef GPAC_HAS_SOCK_UN
165 : #include <sys/un.h>
166 : #endif
167 :
168 : GF_EXPORT
169 1 : const char *gf_errno_str(int errnoval)
170 : {
171 1 : return strerror(errnoval);
172 : }
173 :
174 :
175 : /*internal flags*/
176 : enum
177 : {
178 : GF_SOCK_IS_TCP = 1<<9,
179 : GF_SOCK_IS_IPV6 = 1<<10,
180 : GF_SOCK_NON_BLOCKING = 1<<11,
181 : GF_SOCK_IS_MULTICAST = 1<<12,
182 : GF_SOCK_IS_LISTENING = 1<<13,
183 : /*socket is bound to a specific dest (server) or source (client) */
184 : GF_SOCK_HAS_PEER = 1<<14,
185 : GF_SOCK_IS_UN = 1<<15,
186 : };
187 :
188 : struct __tag_socket
189 : {
190 : u32 flags;
191 : SOCKET socket;
192 : /*destination address for sendto/recvfrom*/
193 : #ifdef GPAC_HAS_IPV6
194 : struct sockaddr_storage dest_addr;
195 : #else
196 : struct sockaddr_in dest_addr;
197 : #endif
198 : u32 dest_addr_len;
199 :
200 : u32 usec_wait;
201 : };
202 :
203 :
204 :
205 : GF_EXPORT
206 179 : u32 gf_net_has_ipv6()
207 : {
208 : #ifdef GPAC_HAS_IPV6
209 179 : if (!ipv6_check_state) {
210 : SOCKET s;
211 : #ifdef WIN32
212 : if (!wsa_init) {
213 : WSADATA Data;
214 : if (WSAStartup(0x0202, &Data)!=0) {
215 : ipv6_check_state = 1;
216 : return 0;
217 : }
218 : }
219 : #endif
220 88 : s = socket(PF_INET6, SOCK_STREAM, 0);
221 88 : if (!s) ipv6_check_state = 1;
222 : else {
223 88 : ipv6_check_state = 2;
224 88 : closesocket(s);
225 : }
226 : #ifdef WIN32
227 : if (!wsa_init) WSACleanup();
228 : #endif
229 : }
230 179 : return (ipv6_check_state==2);
231 : #else
232 : return 0;
233 : #endif
234 : }
235 :
236 : GF_EXPORT
237 115 : Bool gf_net_is_ipv6(const char *address)
238 : {
239 : char *sep;
240 115 : if (!address) return GF_FALSE;
241 90 : sep = strchr(address, ':');
242 : if (sep) sep = strchr(address, ':');
243 90 : return sep ? GF_TRUE : GF_FALSE;
244 : }
245 :
246 : #ifdef GPAC_HAS_IPV6
247 : #define MAX_PEER_NAME_LEN 1024
248 683 : static struct addrinfo *gf_sk_get_ipv6_addr(const char *PeerName, u16 PortNumber, int family, int flags, int sock_type)
249 : {
250 683 : struct addrinfo *res=NULL;
251 : struct addrinfo hints;
252 : char node[MAX_PEER_NAME_LEN], portstring[20];
253 : char *service, *dest;
254 : service = dest = NULL;
255 : #ifdef WIN32
256 : if (!wsa_init) {
257 : WSADATA Data;
258 : if (WSAStartup(0x0202, &Data)!=0) return NULL;
259 : wsa_init = 1;
260 : }
261 : #endif
262 :
263 : service = dest = NULL;
264 : memset(&hints, 0, sizeof(hints));
265 683 : hints.ai_socktype = sock_type;
266 683 : hints.ai_family = family;
267 683 : hints.ai_flags = flags;
268 :
269 683 : if (PortNumber) {
270 683 : sprintf (portstring, "%d", PortNumber);
271 : service = (char *)portstring;
272 : }
273 683 : if (PeerName) {
274 : strncpy(node, PeerName, MAX_PEER_NAME_LEN-1);
275 504 : if (node[0]=='[') {
276 0 : node[strlen(node)-1] = 0;
277 : memmove(node, &node[1], MAX_PEER_NAME_LEN-1);
278 : }
279 504 : node[MAX_PEER_NAME_LEN - 1] = 0;
280 : dest = (char *) node;
281 : }
282 683 : if (getaddrinfo((const char *)dest, (const char *)service, &hints, &res) != 0) return NULL;
283 683 : return res;
284 : }
285 :
286 :
287 : #endif
288 :
289 :
290 : GF_EXPORT
291 29 : GF_Err gf_sk_get_host_name(char *buffer)
292 : {
293 : s32 ret = gethostname(buffer, GF_MAX_IP_NAME_LEN);
294 29 : return (ret == SOCKET_ERROR) ? GF_IP_ADDRESS_NOT_FOUND : GF_OK;
295 : }
296 :
297 : GF_EXPORT
298 79 : GF_Err gf_sk_get_local_ip(GF_Socket *sock, char *buffer)
299 : {
300 : #ifdef GPAC_HAS_IPV6
301 : char clienthost[NI_MAXHOST];
302 79 : if (sock->flags & GF_SOCK_HAS_PEER) {
303 74 : if (getnameinfo((struct sockaddr *)&sock->dest_addr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST))
304 : return GF_IP_NETWORK_FAILURE;
305 : } else {
306 : struct sockaddr_storage clientaddr;
307 5 : socklen_t addrlen = sizeof(clientaddr);
308 5 : if (getsockname(sock->socket, (struct sockaddr *)&clientaddr, &addrlen)) return GF_IP_NETWORK_FAILURE;
309 :
310 5 : if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST))
311 : return GF_IP_NETWORK_FAILURE;
312 : }
313 : strcpy(buffer, clienthost);
314 : #else
315 : char *ip;
316 : if (sock->flags & GF_SOCK_HAS_PEER) {
317 : ip = inet_ntoa(sock->dest_addr.sin_addr);
318 : } else {
319 : struct sockaddr_in name;
320 : u32 len = sizeof(struct sockaddr_in);
321 : if (getsockname(sock->socket, (struct sockaddr*) &name, &len)) return GF_IP_NETWORK_FAILURE;
322 : ip = inet_ntoa(name.sin_addr);
323 : }
324 : if (!ip) return GF_IP_NETWORK_FAILURE;
325 : strcpy(buffer, ip);
326 : #endif
327 79 : return GF_OK;
328 : }
329 :
330 :
331 : GF_EXPORT
332 396 : GF_Socket *gf_sk_new(u32 SocketType)
333 : {
334 : GF_Socket *tmp;
335 :
336 : /*init WinSock*/
337 : #ifdef WIN32
338 : WSADATA Data;
339 : if (!wsa_init && (WSAStartup(0x0202, &Data)!=0) ) return NULL;
340 : #endif
341 396 : switch (SocketType) {
342 : case GF_SOCK_TYPE_UDP:
343 : case GF_SOCK_TYPE_TCP:
344 : #ifdef GPAC_HAS_SOCK_UN
345 : case GF_SOCK_TYPE_UDP_UN:
346 : case GF_SOCK_TYPE_TCP_UN:
347 : #endif
348 : break;
349 0 : default:
350 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] unsupported socket type %d\n", SocketType));
351 : return NULL;
352 : }
353 :
354 396 : GF_SAFEALLOC(tmp, GF_Socket);
355 396 : if (!tmp) return NULL;
356 396 : if (SocketType == GF_SOCK_TYPE_TCP) tmp->flags |= GF_SOCK_IS_TCP;
357 : #ifdef GPAC_HAS_SOCK_UN
358 170 : else if (SocketType == GF_SOCK_TYPE_TCP_UN) tmp->flags |= GF_SOCK_IS_TCP | GF_SOCK_IS_UN;
359 170 : else if (SocketType == GF_SOCK_TYPE_UDP_UN) tmp->flags |= GF_SOCK_IS_UN;
360 : #endif
361 :
362 : #ifdef GPAC_HAS_IPV6
363 396 : memset(&tmp->dest_addr, 0, sizeof(struct sockaddr_storage));
364 : #else
365 : memset(&tmp->dest_addr, 0, sizeof(struct sockaddr_in));
366 : tmp->dest_addr_len = sizeof(struct sockaddr);
367 : #endif
368 :
369 396 : tmp->usec_wait = 500;
370 : #ifdef WIN32
371 : wsa_init ++;
372 : #endif
373 396 : return tmp;
374 : }
375 :
376 : GF_EXPORT
377 165 : GF_Err gf_sk_set_buffer_size(GF_Socket *sock, Bool SendBuffer, u32 NewSize)
378 : {
379 165 : u32 nsize=0, psize;
380 : s32 res;
381 165 : if (!sock || !sock->socket) return GF_BAD_PARAM;
382 :
383 165 : if (SendBuffer) {
384 47 : res = setsockopt(sock->socket, SOL_SOCKET, SO_SNDBUF, (char *) &NewSize, sizeof(u32) );
385 : } else {
386 118 : res = setsockopt(sock->socket, SOL_SOCKET, SO_RCVBUF, (char *) &NewSize, sizeof(u32) );
387 : }
388 165 : if (res<0) {
389 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Couldn't set socket %s buffer size to %d: %d\n", SendBuffer ? "send" : "receive", NewSize, res));
390 : } else {
391 165 : GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[Socket] Set socket %s buffer size to %d\n", SendBuffer ? "send" : "receive", NewSize));
392 : }
393 165 : psize = sizeof(u32);
394 165 : if (SendBuffer) {
395 47 : res = getsockopt(sock->socket, SOL_SOCKET, SO_SNDBUF, (char *) &nsize, &psize );
396 : } else {
397 118 : res = getsockopt(sock->socket, SOL_SOCKET, SO_RCVBUF, (char *) &nsize, &psize );
398 : }
399 165 : if ((res>=0) && (nsize=!NewSize)) {
400 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[Socket] Asked to set socket %s buffer size to %d but system used %d\n", SendBuffer ? "send" : "receive", NewSize, nsize));
401 : }
402 :
403 : return GF_OK;
404 : }
405 :
406 : GF_EXPORT
407 37 : GF_Err gf_sk_set_block_mode(GF_Socket *sock, Bool NonBlockingOn)
408 : {
409 : s32 res;
410 : #ifdef WIN32
411 : long val = NonBlockingOn;
412 : if (sock->socket) {
413 : res = ioctlsocket(sock->socket, FIONBIO, &val);
414 : if (res) return GF_SERVICE_ERROR;
415 : }
416 : #else
417 37 : if (sock->socket) {
418 37 : s32 flags = fcntl(sock->socket, F_GETFL, 0);
419 37 : if (NonBlockingOn)
420 37 : flags |= O_NONBLOCK;
421 : else
422 0 : flags &= ~O_NONBLOCK;
423 :
424 37 : res = fcntl(sock->socket, F_SETFL, flags);
425 37 : if (res) return GF_SERVICE_ERROR;
426 : }
427 : #endif
428 37 : if (NonBlockingOn) {
429 37 : sock->flags |= GF_SOCK_NON_BLOCKING;
430 : } else {
431 0 : sock->flags &= ~GF_SOCK_NON_BLOCKING;
432 : }
433 : return GF_OK;
434 : }
435 :
436 : #include <assert.h>
437 :
438 474 : static void gf_sk_free(GF_Socket *sock)
439 : {
440 : assert( sock );
441 474 : if (!sock->socket) return;
442 :
443 : /*leave multicast*/
444 474 : if (sock->flags & GF_SOCK_IS_MULTICAST) {
445 : struct ip_mreq mreq;
446 : #ifdef GPAC_HAS_IPV6
447 : struct sockaddr *addr = (struct sockaddr *)&sock->dest_addr;
448 25 : if (addr->sa_family==AF_INET6) {
449 : struct ipv6_mreq mreq6;
450 : memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
451 0 : mreq6.ipv6mr_interface= 0;
452 0 : setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &mreq6, sizeof(mreq6));
453 : } else {
454 25 : mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
455 25 : mreq.imr_interface.s_addr = INADDR_ANY;
456 25 : setsockopt(sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
457 : }
458 : #else
459 : mreq.imr_multiaddr.s_addr = sock->dest_addr.sin_addr.s_addr;
460 : mreq.imr_interface.s_addr = INADDR_ANY;
461 : setsockopt(sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
462 : #endif
463 : }
464 474 : closesocket(sock->socket);
465 474 : sock->socket = (SOCKET) 0L;
466 : }
467 :
468 :
469 : GF_EXPORT
470 474 : void gf_sk_del(GF_Socket *sock)
471 : {
472 : assert( sock );
473 474 : gf_sk_free(sock);
474 : #ifdef WIN32
475 : wsa_init --;
476 : if (!wsa_init) WSACleanup();
477 : #endif
478 474 : gf_free(sock);
479 474 : }
480 :
481 : GF_EXPORT
482 58 : void gf_sk_reset(GF_Socket *sock)
483 : {
484 : u32 clear;
485 58 : if (sock) setsockopt(sock->socket, SOL_SOCKET, SO_ERROR, (char *) &clear, sizeof(u32) );
486 58 : }
487 :
488 : GF_EXPORT
489 31 : s32 gf_sk_get_handle(GF_Socket *sock)
490 : {
491 31 : return (s32) sock->socket;
492 : }
493 :
494 : GF_EXPORT
495 9 : void gf_sk_set_usec_wait(GF_Socket *sock, u32 usec_wait)
496 : {
497 9 : if (!sock) return;
498 8 : sock->usec_wait = (usec_wait>=1000000) ? 500 : usec_wait;
499 : }
500 :
501 : #ifdef GPAC_STATIC_BUILD
502 : struct hostent *gf_gethostbyname(const char *PeerName)
503 : {
504 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("Static GPAC build has no DNS support, cannot resolve host %s !\n", PeerName));
505 : return NULL;
506 : }
507 : #else
508 : #define gf_gethostbyname gethostbyname
509 : #endif
510 :
511 :
512 : //connects a socket to a remote peer on a given port
513 : GF_EXPORT
514 194 : GF_Err gf_sk_connect(GF_Socket *sock, const char *PeerName, u16 PortNumber, const char *local_ip)
515 : {
516 : s32 ret;
517 : #ifdef GPAC_HAS_IPV6
518 : u32 type;
519 : struct addrinfo *res, *aip, *lip;
520 : #else
521 : struct hostent *Host = NULL;
522 : #endif
523 :
524 194 : if (sock->flags & GF_SOCK_IS_UN) {
525 : #ifdef GPAC_HAS_SOCK_UN
526 : struct sockaddr_un server_add;
527 0 : if (!sock->socket) {
528 0 : sock->socket = socket(AF_UNIX, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
529 0 : if (sock->flags & GF_SOCK_NON_BLOCKING)
530 0 : gf_sk_set_block_mode(sock, GF_TRUE);
531 : }
532 0 : server_add.sun_family = AF_UNIX;
533 : strcpy(server_add.sun_path, PeerName);
534 0 : if (connect(sock->socket, (struct sockaddr *) &server_add, sizeof(struct sockaddr_un)) < 0) {
535 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Failed to connect unix domain socket to %s\n", PeerName));
536 : return GF_IP_CONNECTION_FAILURE;
537 : }
538 : return GF_OK;
539 : #else
540 : return GF_NOT_SUPPORTED;
541 : #endif
542 : }
543 :
544 : #ifdef GPAC_HAS_IPV6
545 194 : type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;
546 :
547 194 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV6] Solving %s address\n", PeerName));
548 194 : res = gf_sk_get_ipv6_addr(PeerName, PortNumber, AF_UNSPEC, AI_PASSIVE, type);
549 194 : if (!res) return GF_IP_CONNECTION_FAILURE;
550 194 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV6] Host %s found\n", PeerName));
551 :
552 : lip = NULL;
553 194 : if (local_ip) {
554 0 : lip = gf_sk_get_ipv6_addr(local_ip, PortNumber, AF_UNSPEC, AI_PASSIVE, type);
555 0 : if (!lip && local_ip) {
556 0 : lip = gf_sk_get_ipv6_addr(NULL, PortNumber, AF_UNSPEC, AI_PASSIVE, type);
557 : local_ip = NULL;
558 : }
559 : }
560 :
561 : /*for all interfaces*/
562 194 : for (aip=res; aip!=NULL; aip=aip->ai_next) {
563 194 : if (type != (u32) aip->ai_socktype) continue;
564 194 : if (!sock->socket) {
565 192 : sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
566 192 : if (sock->socket == INVALID_SOCKET) {
567 0 : sock->socket = NULL_SOCKET;
568 0 : continue;
569 : }
570 192 : if (sock->flags & GF_SOCK_IS_TCP) {
571 192 : if (sock->flags & GF_SOCK_NON_BLOCKING)
572 0 : gf_sk_set_block_mode(sock, GF_TRUE);
573 : }
574 :
575 192 : if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;
576 192 : else sock->flags &= ~GF_SOCK_IS_IPV6;
577 :
578 192 : if (lip) {
579 0 : ret = bind(sock->socket, lip->ai_addr, (int) lip->ai_addrlen);
580 0 : if (ret == SOCKET_ERROR) {
581 0 : closesocket(sock->socket);
582 0 : sock->socket = NULL_SOCKET;
583 0 : continue;
584 : }
585 : }
586 : }
587 :
588 194 : if (sock->flags & GF_SOCK_IS_TCP) {
589 192 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV6] Connecting to %s:%d\n", PeerName, PortNumber));
590 192 : ret = connect(sock->socket, aip->ai_addr, (int) aip->ai_addrlen);
591 192 : if (ret == SOCKET_ERROR) {
592 0 : closesocket(sock->socket);
593 0 : sock->socket = NULL_SOCKET;
594 0 : GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[Sock_IPV4] Failed to connect to host %s: %s - retrying\n", PeerName, gf_errno_str(LASTSOCKERROR) ));
595 0 : continue;
596 : }
597 192 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV6] Connected to %s:%d\n", PeerName, PortNumber));
598 :
599 : #ifdef SO_NOSIGPIPE
600 : int value = 1;
601 : setsockopt(sock->socket, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));
602 : #endif
603 : }
604 194 : memcpy(&sock->dest_addr, aip->ai_addr, aip->ai_addrlen);
605 194 : sock->dest_addr_len = (u32) aip->ai_addrlen;
606 194 : freeaddrinfo(res);
607 194 : if (lip) freeaddrinfo(lip);
608 : return GF_OK;
609 : }
610 0 : freeaddrinfo(res);
611 0 : if (lip) freeaddrinfo(lip);
612 : return GF_IP_CONNECTION_FAILURE;
613 :
614 : #else
615 : if (local_ip) {
616 : GF_Err e = gf_sk_bind(sock, local_ip, PortNumber, PeerName, PortNumber, GF_SOCK_REUSE_PORT);
617 : if (e) return e;
618 : }
619 : if (!sock->socket) {
620 : sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
621 : if (sock->flags & GF_SOCK_NON_BLOCKING)
622 : gf_sk_set_block_mode(sock, GF_TRUE);
623 : }
624 :
625 : /*setup the address*/
626 : sock->dest_addr.sin_family = AF_INET;
627 : sock->dest_addr.sin_port = htons(PortNumber);
628 : /*get the server IP*/
629 : sock->dest_addr.sin_addr.s_addr = inet_addr(PeerName);
630 : if (sock->dest_addr.sin_addr.s_addr==INADDR_NONE) {
631 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV4] Solving %s address\n", PeerName));
632 : Host = gf_gethostbyname(PeerName);
633 : if (Host == NULL) {
634 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV4] Failed to retrieve host %s address: %s\n", PeerName, gf_errno_str(LASTSOCKERROR) ));
635 : switch (LASTSOCKERROR) {
636 : #ifndef __SYMBIAN32__
637 : case ENETDOWN:
638 : return GF_IP_NETWORK_FAILURE;
639 : //case ENOHOST: return GF_IP_ADDRESS_NOT_FOUND;
640 : #endif
641 : default:
642 : return GF_IP_NETWORK_FAILURE;
643 : }
644 : }
645 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV4] Host %s found\n", PeerName));
646 : memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32));
647 : }
648 :
649 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV4] Connecting to %s:%d\n", PeerName, PortNumber));
650 : ret = connect(sock->socket, (struct sockaddr *) &sock->dest_addr, sizeof(struct sockaddr));
651 : if (ret == SOCKET_ERROR) {
652 : u32 res = LASTSOCKERROR;
653 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Sock_IPV4] Couldn't connect socket: %s\n", gf_errno_str(res) ));
654 : switch (res) {
655 : case EAGAIN:
656 : return GF_IP_SOCK_WOULD_BLOCK;
657 : #ifdef WIN32
658 : case WSAEINVAL:
659 : if (sock->flags & GF_SOCK_NON_BLOCKING)
660 : return GF_IP_SOCK_WOULD_BLOCK;
661 : #endif
662 : case EISCONN:
663 : return GF_OK;
664 : case ENOTCONN:
665 : return GF_IP_CONNECTION_FAILURE;
666 : case ECONNRESET:
667 : return GF_IP_CONNECTION_FAILURE;
668 : case EMSGSIZE:
669 : return GF_IP_CONNECTION_FAILURE;
670 : case ECONNABORTED:
671 : return GF_IP_CONNECTION_FAILURE;
672 : case ENETDOWN:
673 : return GF_IP_CONNECTION_FAILURE;
674 : default:
675 : return GF_IP_CONNECTION_FAILURE;
676 : }
677 : }
678 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Sock_IPV4] Connected to %s:%d\n", PeerName, PortNumber));
679 : #endif
680 : return GF_OK;
681 : }
682 :
683 :
684 : //binds the given socket to the specified port. If ReUse is true
685 : //this will enable reuse of ports on a single machine
686 : GF_EXPORT
687 179 : GF_Err gf_sk_bind(GF_Socket *sock, const char *local_ip, u16 port, const char *peer_name, u16 peer_port, u32 options)
688 : {
689 : #ifdef GPAC_HAS_IPV6
690 : struct addrinfo *res, *aip;
691 : int af;
692 : u32 type;
693 : #else
694 : u32 ip_add;
695 : size_t addrlen;
696 : struct sockaddr_in LocalAdd;
697 : struct hostent *Host = NULL;
698 : #endif
699 : s32 ret = 0;
700 : s32 optval;
701 :
702 179 : if (!sock || sock->socket) return GF_BAD_PARAM;
703 179 : if (local_ip && !strcmp(local_ip, "127.0.0.1"))
704 : local_ip = NULL;
705 :
706 179 : if (sock->flags & GF_SOCK_IS_UN) {
707 : #ifdef GPAC_HAS_SOCK_UN
708 : struct sockaddr_un server_un;
709 : if (!sock->socket) {
710 0 : sock->socket = socket(AF_UNIX, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
711 0 : if (sock->flags & GF_SOCK_NON_BLOCKING)
712 0 : gf_sk_set_block_mode(sock, GF_TRUE);
713 : }
714 0 : server_un.sun_family = AF_UNIX;
715 : strcpy(server_un.sun_path, peer_name);
716 0 : ret = bind(sock->socket, (struct sockaddr *) &server_un, (int) sizeof(struct sockaddr_un));
717 0 : if (ret == SOCKET_ERROR) {
718 0 : if (LASTSOCKERROR == EADDRINUSE) {
719 0 : return gf_sk_connect(sock, peer_name, peer_port, NULL);
720 : }
721 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] cannot bind socket: %s\n", gf_errno_str(LASTSOCKERROR) ));
722 : return GF_IP_CONNECTION_FAILURE;
723 : }
724 0 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] socket bound to unix domain %s\n", peer_name));
725 : return GF_OK;
726 : #else
727 : return GF_NOT_SUPPORTED;
728 : #endif
729 : }
730 :
731 :
732 : #ifndef WIN32
733 179 : if(!local_ip) {
734 179 : if(!peer_name || !strcmp(peer_name,"localhost")) {
735 : peer_name="127.0.0.1";
736 : }
737 : }
738 : #endif
739 :
740 : #ifdef GPAC_HAS_IPV6
741 179 : type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;
742 179 : af = (options & GF_SOCK_FORCE_IPV6) ? PF_INET6 : PF_UNSPEC;
743 179 : if (!gf_net_has_ipv6()) af = PF_INET;
744 : /*probe way to peer: is it V4 or V6? */
745 179 : if (peer_name && peer_port) {
746 109 : res = gf_sk_get_ipv6_addr(peer_name, peer_port, af, AI_PASSIVE, type);
747 109 : if (!res) {
748 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Cannot get IPV6 host name for %s:%d\n", peer_name, peer_port));
749 : return GF_IP_ADDRESS_NOT_FOUND;
750 : }
751 : #ifdef WIN32
752 : /*win32 has troubles redirecting IPV4 datagrams to IPV6 sockets, so override
753 : local family type to avoid IPV4(S)->IPV6(C) UDP*/
754 : af = res->ai_family;
755 : #endif
756 109 : memcpy(&sock->dest_addr, res->ai_addr, res->ai_addrlen);
757 109 : sock->dest_addr_len = (u32) res->ai_addrlen;
758 109 : freeaddrinfo(res);
759 : }
760 :
761 179 : res = gf_sk_get_ipv6_addr(local_ip, port, af, AI_PASSIVE, type);
762 179 : if (!res) {
763 0 : if (local_ip) {
764 0 : res = gf_sk_get_ipv6_addr(NULL, port, af, AI_PASSIVE, type);
765 : local_ip = NULL;
766 : }
767 0 : if (!res) {
768 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Cannot get IPV6 host name for %s:%d\n", local_ip, port));
769 : return GF_IP_ADDRESS_NOT_FOUND;
770 : }
771 : }
772 :
773 : /*for all interfaces*/
774 179 : for (aip=res; aip!=NULL; aip=aip->ai_next) {
775 179 : if (type != (u32) aip->ai_socktype) continue;
776 :
777 179 : if (aip->ai_next && (aip->ai_next->ai_family==PF_INET) && !gf_net_is_ipv6(peer_name)) continue;
778 :
779 179 : sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
780 179 : if (sock->socket == INVALID_SOCKET) {
781 0 : sock->socket = NULL_SOCKET;
782 0 : continue;
783 : }
784 179 : if (options & GF_SOCK_REUSE_PORT) {
785 143 : optval = 1;
786 143 : setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));
787 : #ifdef SO_REUSEPORT
788 143 : optval = 1;
789 143 : setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
790 : #endif
791 : }
792 :
793 179 : if (sock->flags & GF_SOCK_NON_BLOCKING)
794 0 : gf_sk_set_block_mode(sock, GF_TRUE);
795 :
796 179 : if (peer_name && peer_port)
797 109 : sock->flags |= GF_SOCK_HAS_PEER;
798 :
799 179 : if (! (options & GF_SOCK_FAKE_BIND) ) {
800 108 : ret = bind(sock->socket, aip->ai_addr, (int) aip->ai_addrlen);
801 108 : if (ret == SOCKET_ERROR) {
802 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] cannot bind: %s\n", gf_errno_str(LASTSOCKERROR) ));
803 0 : closesocket(sock->socket);
804 0 : sock->socket = NULL_SOCKET;
805 0 : continue;
806 : }
807 : }
808 179 : if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;
809 179 : else sock->flags &= ~GF_SOCK_IS_IPV6;
810 :
811 179 : freeaddrinfo(res);
812 179 : return GF_OK;
813 : }
814 0 : freeaddrinfo(res);
815 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Cannot bind to host %s port %d\n", local_ip, port));
816 : return GF_IP_CONNECTION_FAILURE;
817 :
818 : #else
819 :
820 : sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
821 : if (sock->flags & GF_SOCK_NON_BLOCKING)
822 : gf_sk_set_block_mode(sock, GF_TRUE);
823 : sock->flags &= ~GF_SOCK_IS_IPV6;
824 :
825 : memset((void *) &LocalAdd, 0, sizeof(LocalAdd));
826 :
827 : /*setup the address*/
828 : ip_add = 0;
829 : if (local_ip) ip_add = inet_addr(local_ip);
830 :
831 : if (!ip_add) {
832 : #if 0
833 : char buf[GF_MAX_IP_NAME_LEN];
834 : buf[0] = 0;
835 : ret = gethostname(buf, GF_MAX_IP_NAME_LEN);
836 : /*get the IP address*/
837 : Host = gf_gethostbyname(buf);
838 : if (Host != NULL) {
839 : memcpy((char *) &LocalAdd.sin_addr, Host->h_addr_list[0], sizeof(LocalAdd.sin_addr));
840 : ip_add = LocalAdd.sin_addr.s_addr;
841 : } else {
842 : ip_add = INADDR_ANY;
843 : }
844 : #else
845 : ip_add = INADDR_ANY;
846 : #endif
847 : }
848 : if (peer_name && peer_port) {
849 : #ifdef WIN32
850 : if ((inet_addr(peer_name)== ip_add) || !strcmp(peer_name, "127.0.0.1") ) {
851 : optval = 1;
852 : setsockopt(sock->socket, SOL_SOCKET, SO_USELOOPBACK, SSO_CAST &optval, sizeof(optval));
853 : }
854 : #endif
855 : }
856 :
857 : LocalAdd.sin_family = AF_INET;
858 : LocalAdd.sin_port = htons(port);
859 : LocalAdd.sin_addr.s_addr = ip_add;
860 : addrlen = sizeof(struct sockaddr_in);
861 :
862 :
863 : if (options & GF_SOCK_REUSE_PORT) {
864 : optval = 1;
865 : setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval));
866 : #ifdef SO_REUSEPORT
867 : optval = 1;
868 : setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
869 : #endif
870 : }
871 :
872 : if (! (options & GF_SOCK_FAKE_BIND) ) {
873 : /*bind the socket*/
874 : ret = bind(sock->socket, (struct sockaddr *) &LocalAdd, (int) addrlen);
875 : if (ret == SOCKET_ERROR) {
876 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] cannot bind socket: %s\n", gf_errno_str(LASTSOCKERROR) ));
877 : ret = GF_IP_CONNECTION_FAILURE;
878 : }
879 : }
880 :
881 : if (peer_name && peer_port) {
882 : sock->dest_addr.sin_port = htons(peer_port);
883 : sock->dest_addr.sin_family = AF_INET;
884 : sock->dest_addr.sin_addr.s_addr = inet_addr(peer_name);
885 : if (sock->dest_addr.sin_addr.s_addr == INADDR_NONE) {
886 : Host = gf_gethostbyname(peer_name);
887 : if (Host == NULL) ret = GF_IP_ADDRESS_NOT_FOUND;
888 : else memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32));
889 : }
890 : sock->flags |= GF_SOCK_HAS_PEER;
891 : }
892 : if (sock->flags & GF_SOCK_HAS_PEER) {
893 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] socket bound to %08X - port %d - remote peer: %s:%d\n", ip_add, port, peer_name, peer_port));
894 : } else {
895 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] socket bound to %08X - port %d\n", ip_add, port));
896 : }
897 : return ret;
898 : #endif
899 : }
900 :
901 : //send length bytes of a buffer
902 : GF_EXPORT
903 8232 : GF_Err gf_sk_send(GF_Socket *sock, const u8 *buffer, u32 length)
904 : {
905 : u32 count;
906 : s32 res;
907 : Bool not_ready = GF_FALSE;
908 : #ifndef __SYMBIAN32__
909 : int ready;
910 : struct timeval timeout;
911 : fd_set Group;
912 : #endif
913 :
914 : //the socket must be bound or connected
915 8232 : if (!sock || !sock->socket)
916 : return GF_BAD_PARAM;
917 :
918 : #ifndef __SYMBIAN32__
919 : //can we write?
920 8232 : FD_ZERO(&Group);
921 8232 : FD_SET(sock->socket, &Group);
922 8232 : timeout.tv_sec = 0;
923 8232 : timeout.tv_usec = sock->usec_wait;
924 :
925 : //TODO CHECK IF THIS IS CORRECT
926 8232 : ready = select((int) sock->socket+1, NULL, &Group, NULL, &timeout);
927 8232 : if (ready == SOCKET_ERROR) {
928 0 : switch (LASTSOCKERROR) {
929 : case EAGAIN:
930 : return GF_IP_SOCK_WOULD_BLOCK;
931 0 : default:
932 0 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] select failure: %s\n", gf_errno_str(LASTSOCKERROR)));
933 : return GF_IP_NETWORK_FAILURE;
934 : }
935 : }
936 :
937 : //should never happen (to check: is writeability is guaranteed for not-connected sockets)
938 8232 : if (!ready || !FD_ISSET(sock->socket, &Group)) {
939 : not_ready = GF_TRUE;
940 : }
941 : #endif
942 :
943 : //direct writing
944 : count = 0;
945 24694 : while (count < length) {
946 8232 : if (sock->flags & GF_SOCK_HAS_PEER) {
947 5690 : res = (s32) sendto(sock->socket, (char *) buffer+count, length - count, 0, (struct sockaddr *) &sock->dest_addr, sock->dest_addr_len);
948 : } else {
949 : int sflags = 0;
950 : #ifdef MSG_NOSIGNAL
951 : sflags = MSG_NOSIGNAL;
952 : #endif
953 2542 : res = (s32) send(sock->socket, (char *) buffer+count, length - count, sflags);
954 : }
955 8232 : if (res == SOCKET_ERROR) {
956 2 : if (not_ready)
957 : return GF_IP_NETWORK_EMPTY;
958 :
959 2 : switch (res = LASTSOCKERROR) {
960 : case EAGAIN:
961 : return GF_IP_SOCK_WOULD_BLOCK;
962 : #ifndef __SYMBIAN32__
963 2 : case ENOTCONN:
964 : case ECONNRESET:
965 : case EPIPE:
966 2 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] send failure: %s\n", gf_errno_str(LASTSOCKERROR)));
967 : return GF_IP_CONNECTION_CLOSED;
968 : #endif
969 :
970 : #ifndef __DARWIN__
971 : case EPROTOTYPE:
972 : return GF_IP_SOCK_WOULD_BLOCK;
973 : #endif
974 0 : case ENOBUFS:
975 0 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] send failure: %s\n", gf_errno_str(LASTSOCKERROR)));
976 : return GF_BUFFER_TOO_SMALL;
977 0 : default:
978 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] send failure: %s\n", gf_errno_str(LASTSOCKERROR)));
979 : return GF_IP_NETWORK_FAILURE;
980 : }
981 : }
982 8230 : count += res;
983 : }
984 : return GF_OK;
985 : }
986 :
987 300 : GF_Err gf_sk_select(GF_Socket *sock, u32 mode)
988 : {
989 : #ifndef __SYMBIAN32__
990 : int ready;
991 : struct timeval timeout;
992 : fd_set RGroup;
993 : fd_set WGroup;
994 : #endif
995 :
996 : //the socket must be bound or connected
997 300 : if (!sock || !sock->socket)
998 : return GF_BAD_PARAM;
999 :
1000 : #ifndef __SYMBIAN32__
1001 : //can we write?
1002 300 : FD_ZERO(&RGroup);
1003 300 : FD_ZERO(&WGroup);
1004 300 : if (mode != GF_SK_SELECT_WRITE)
1005 0 : FD_SET(sock->socket, &RGroup);
1006 300 : if (mode != GF_SK_SELECT_READ)
1007 300 : FD_SET(sock->socket, &WGroup);
1008 300 : timeout.tv_sec = 0;
1009 300 : timeout.tv_usec = sock->usec_wait;
1010 :
1011 : //TODO CHECK IF THIS IS CORRECT
1012 300 : ready = select((int) sock->socket+1, &RGroup, &WGroup, NULL, &timeout);
1013 300 : if (ready == SOCKET_ERROR) {
1014 0 : switch (LASTSOCKERROR) {
1015 : case EAGAIN:
1016 : return GF_IP_SOCK_WOULD_BLOCK;
1017 0 : default:
1018 0 : GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] select failure: %s\n", gf_errno_str(LASTSOCKERROR)));
1019 : return GF_IP_NETWORK_FAILURE;
1020 : }
1021 : }
1022 :
1023 : //should never happen (to check: is writeability is guaranteed for not-connected sockets)
1024 300 : if (!ready)
1025 : return GF_IP_SOCK_WOULD_BLOCK;
1026 297 : if ((mode != GF_SK_SELECT_WRITE) && !FD_ISSET(sock->socket, &RGroup))
1027 : return GF_IP_SOCK_WOULD_BLOCK;
1028 297 : if ((mode != GF_SK_SELECT_READ) && !FD_ISSET(sock->socket, &WGroup))
1029 : return GF_IP_SOCK_WOULD_BLOCK;
1030 : return GF_OK;
1031 : #else
1032 : return GF_IP_SOCK_WOULD_BLOCK;
1033 : #endif
1034 : }
1035 :
1036 :
1037 : GF_EXPORT
1038 201 : u32 gf_sk_is_multicast_address(const char *multi_IPAdd)
1039 : {
1040 : #ifdef GPAC_HAS_IPV6
1041 : u32 val;
1042 : char *sep;
1043 : struct addrinfo *res;
1044 201 : if (!multi_IPAdd) return 0;
1045 : /*IPV6 multicast address*/
1046 201 : sep = strchr(multi_IPAdd, ':');
1047 : if (sep) sep = strchr(multi_IPAdd, ':');
1048 201 : if (sep && !strnicmp(multi_IPAdd, "ff", 2)) return 1;
1049 : /*ipv4 multicast address*/
1050 201 : res = gf_sk_get_ipv6_addr((char*)multi_IPAdd, 7000, AF_UNSPEC, AI_PASSIVE, SOCK_DGRAM);
1051 201 : if (!res) return 0;
1052 : val = 0;
1053 201 : if (res->ai_addr->sa_family == AF_INET) {
1054 402 : val = IN_MULTICAST(ntohl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr));
1055 0 : } else if (res->ai_addr->sa_family == AF_INET6) {
1056 0 : val = IN6_IS_ADDR_MULTICAST(& ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr);
1057 : }
1058 201 : freeaddrinfo(res);
1059 201 : return val;
1060 : #else
1061 : if (!multi_IPAdd) return 0;
1062 : return ((htonl(inet_addr(multi_IPAdd)) >> 8) & 0x00f00000) == 0x00e00000;
1063 : #endif
1064 : }
1065 :
1066 : GF_EXPORT
1067 25 : GF_Err gf_sk_setup_multicast(GF_Socket *sock, const char *multi_IPAdd, u16 MultiPortNumber, u32 TTL, Bool NoBind, char *local_interface_ip)
1068 : {
1069 : s32 ret;
1070 : u32 flag;
1071 : struct ip_mreq M_req;
1072 : u32 optval;
1073 : #ifdef GPAC_HAS_IPV6
1074 : struct sockaddr *addr;
1075 : struct addrinfo *res, *aip;
1076 : Bool is_ipv6 = GF_FALSE;
1077 : u32 type;
1078 : #endif
1079 : u32 local_add_id;
1080 :
1081 25 : if (!sock || sock->socket) return GF_BAD_PARAM;
1082 :
1083 25 : if (TTL > 255) TTL = 255;
1084 :
1085 : /*check the address*/
1086 25 : if (!gf_sk_is_multicast_address(multi_IPAdd)) return GF_BAD_PARAM;
1087 :
1088 :
1089 : #ifdef GPAC_HAS_IPV6
1090 25 : is_ipv6 = gf_net_is_ipv6(multi_IPAdd) || gf_net_is_ipv6(local_interface_ip) ? GF_TRUE : GF_FALSE;
1091 25 : type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;
1092 :
1093 25 : if (is_ipv6) {
1094 :
1095 0 : res = gf_sk_get_ipv6_addr(local_interface_ip, MultiPortNumber, AF_UNSPEC, AI_PASSIVE, type);
1096 0 : if (!res) {
1097 0 : if (local_interface_ip) {
1098 0 : res = gf_sk_get_ipv6_addr(NULL, MultiPortNumber, AF_UNSPEC, AI_PASSIVE, type);
1099 : local_interface_ip = NULL;
1100 : }
1101 0 : if (!res) return GF_IP_CONNECTION_FAILURE;
1102 : }
1103 :
1104 : /*for all interfaces*/
1105 0 : for (aip=res; aip!=NULL; aip=aip->ai_next) {
1106 0 : if (type != (u32) aip->ai_socktype) continue;
1107 0 : sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
1108 0 : if (sock->socket == INVALID_SOCKET) {
1109 0 : sock->socket = NULL_SOCKET;
1110 0 : continue;
1111 : }
1112 :
1113 0 : if ((aip->ai_family!=PF_INET) && aip->ai_next && (aip->ai_next->ai_family==PF_INET) && !gf_net_is_ipv6(multi_IPAdd)) continue;
1114 :
1115 : /*enable address reuse*/
1116 0 : optval = 1;
1117 0 : setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));
1118 : #ifdef SO_REUSEPORT
1119 0 : optval = 1;
1120 0 : setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
1121 : #endif
1122 :
1123 : /*TODO: copy over other properties (recption buffer size & co)*/
1124 0 : if (sock->flags & GF_SOCK_NON_BLOCKING)
1125 0 : gf_sk_set_block_mode(sock, GF_TRUE);
1126 :
1127 0 : memcpy(&sock->dest_addr, aip->ai_addr, aip->ai_addrlen);
1128 0 : sock->dest_addr_len = (u32) aip->ai_addrlen;
1129 :
1130 0 : if (!NoBind) {
1131 0 : ret = bind(sock->socket, aip->ai_addr, (int) aip->ai_addrlen);
1132 0 : if (ret == SOCKET_ERROR) {
1133 0 : closesocket(sock->socket);
1134 0 : sock->socket = NULL_SOCKET;
1135 0 : continue;
1136 : }
1137 : }
1138 0 : if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;
1139 0 : else sock->flags &= ~GF_SOCK_IS_IPV6;
1140 : break;
1141 : }
1142 0 : freeaddrinfo(res);
1143 0 : if (!sock->socket) return GF_IP_CONNECTION_FAILURE;
1144 :
1145 0 : struct addrinfo *_res = gf_sk_get_ipv6_addr(multi_IPAdd, MultiPortNumber, AF_UNSPEC, 0, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM);
1146 0 : if (!_res) return GF_IP_CONNECTION_FAILURE;
1147 0 : memcpy(&sock->dest_addr, _res->ai_addr, res->ai_addrlen);
1148 0 : sock->dest_addr_len = (u32) _res->ai_addrlen;
1149 0 : freeaddrinfo(_res);
1150 :
1151 : addr = (struct sockaddr *)&sock->dest_addr;
1152 0 : if (addr->sa_family == AF_INET) {
1153 0 : M_req.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
1154 0 : M_req.imr_interface.s_addr = INADDR_ANY;
1155 0 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req));
1156 0 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1157 : /*set TTL*/
1158 0 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &TTL, sizeof(TTL));
1159 0 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1160 : /*Disable loopback*/
1161 0 : flag = 1;
1162 0 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag));
1163 0 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1164 : }
1165 :
1166 0 : if (addr->sa_family == AF_INET6) {
1167 : struct ipv6_mreq M_reqV6;
1168 :
1169 : memcpy(&M_reqV6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
1170 0 : M_reqV6.ipv6mr_interface = 0;
1171 :
1172 : /*set TTL*/
1173 0 : ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &TTL, sizeof(TTL));
1174 0 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1175 : /*enable loopback*/
1176 0 : flag = 1;
1177 0 : ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &flag, sizeof(flag));
1178 0 : if (ret == SOCKET_ERROR) {
1179 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[Socket] Cannot disale multicast loop: %s\n", gf_errno_str(LASTSOCKERROR) ));
1180 : }
1181 :
1182 0 : ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &M_reqV6, sizeof(M_reqV6));
1183 0 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1184 : }
1185 0 : sock->flags |= GF_SOCK_IS_MULTICAST | GF_SOCK_HAS_PEER;
1186 0 : return GF_OK;
1187 : }
1188 : #endif
1189 :
1190 : //IPv4 setup
1191 25 : sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
1192 25 : if (sock->flags & GF_SOCK_NON_BLOCKING)
1193 0 : gf_sk_set_block_mode(sock, GF_TRUE);
1194 25 : sock->flags &= ~GF_SOCK_IS_IPV6;
1195 :
1196 : /*enable address reuse*/
1197 25 : optval = 1;
1198 25 : ret = setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval));
1199 25 : if (ret == SOCKET_ERROR) {
1200 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[core] Failed to set SO_REUSEADDR: %s\n", gf_errno_str(LASTSOCKERROR) ));
1201 : }
1202 : #ifdef SO_REUSEPORT
1203 25 : optval = 1;
1204 25 : ret = setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
1205 25 : if (ret == SOCKET_ERROR) {
1206 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[core] Failed to set SO_REUSEPORT: %s\n", gf_errno_str(LASTSOCKERROR) ));
1207 : }
1208 : #endif
1209 :
1210 25 : if (local_interface_ip) local_add_id = inet_addr(local_interface_ip);
1211 25 : else local_add_id = htonl(INADDR_ANY);
1212 :
1213 25 : if (!NoBind) {
1214 : struct sockaddr_in local_address;
1215 :
1216 : memset(&local_address, 0, sizeof(struct sockaddr_in ));
1217 24 : local_address.sin_family = AF_INET;
1218 : // local_address.sin_addr.s_addr = local_add_id;
1219 : local_address.sin_addr.s_addr = htonl(INADDR_ANY);
1220 24 : local_address.sin_port = htons( MultiPortNumber);
1221 :
1222 24 : ret = bind(sock->socket, (struct sockaddr *) &local_address, sizeof(local_address));
1223 24 : if (ret == SOCKET_ERROR) {
1224 : /*retry without specifying the local add*/
1225 0 : local_address.sin_addr.s_addr = local_add_id = htonl(INADDR_ANY);
1226 : local_interface_ip = NULL;
1227 0 : ret = bind(sock->socket, (struct sockaddr *) &local_address, sizeof(local_address));
1228 0 : if (ret == SOCKET_ERROR) {
1229 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[core] Failed to bind socket: %s\n", gf_errno_str(LASTSOCKERROR) ));
1230 0 : return GF_IP_CONNECTION_FAILURE;
1231 : }
1232 : }
1233 : /*setup local interface*/
1234 24 : if (local_interface_ip) {
1235 0 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_IF, (void *) &local_add_id, sizeof(local_add_id));
1236 0 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1237 : }
1238 : }
1239 :
1240 : /*now join the multicast*/
1241 25 : M_req.imr_multiaddr.s_addr = inet_addr(multi_IPAdd);
1242 25 : M_req.imr_interface.s_addr = local_add_id;
1243 :
1244 25 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req));
1245 25 : if (ret == SOCKET_ERROR) {
1246 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[core] cannot join multicast: %s\n", gf_errno_str(LASTSOCKERROR)));
1247 : return GF_IP_CONNECTION_FAILURE;
1248 : }
1249 : /*set the Time To Live*/
1250 25 : if (TTL) {
1251 8 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&TTL, sizeof(TTL));
1252 8 : if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
1253 : }
1254 :
1255 : /*enable loopback*/
1256 25 : flag = 1;
1257 25 : ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag));
1258 25 : if (ret == SOCKET_ERROR) {
1259 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[Socket] Cannot disable multicast loop: %s\n", gf_errno_str(LASTSOCKERROR) ));
1260 : }
1261 :
1262 : #ifdef GPAC_HAS_IPV6
1263 25 : ((struct sockaddr_in *) &sock->dest_addr)->sin_family = AF_INET;
1264 25 : ((struct sockaddr_in *) &sock->dest_addr)->sin_addr.s_addr = M_req.imr_multiaddr.s_addr;
1265 25 : ((struct sockaddr_in *) &sock->dest_addr)->sin_port = htons( MultiPortNumber);
1266 25 : sock->dest_addr_len = sizeof(struct sockaddr);
1267 : #else
1268 : sock->dest_addr.sin_family = AF_INET;
1269 : sock->dest_addr.sin_addr.s_addr = M_req.imr_multiaddr.s_addr;
1270 : sock->dest_addr.sin_port = htons( MultiPortNumber);
1271 : #endif
1272 :
1273 25 : sock->flags |= GF_SOCK_IS_MULTICAST | GF_SOCK_HAS_PEER;
1274 25 : return GF_OK;
1275 : }
1276 :
1277 : #include <gpac/list.h>
1278 : struct __tag_sock_group
1279 : {
1280 : GF_List *sockets;
1281 : fd_set rgroup, wgroup;
1282 : };
1283 :
1284 64 : GF_SockGroup *gf_sk_group_new()
1285 : {
1286 : GF_SockGroup *tmp;
1287 64 : GF_SAFEALLOC(tmp, GF_SockGroup);
1288 64 : if (!tmp) return NULL;
1289 64 : tmp->sockets = gf_list_new();
1290 64 : FD_ZERO(&tmp->rgroup);
1291 64 : FD_ZERO(&tmp->wgroup);
1292 64 : return tmp;
1293 : }
1294 :
1295 64 : void gf_sk_group_del(GF_SockGroup *sg)
1296 : {
1297 64 : gf_list_del(sg->sockets);
1298 64 : gf_free(sg);
1299 64 : }
1300 :
1301 128 : void gf_sk_group_register(GF_SockGroup *sg, GF_Socket *sk)
1302 : {
1303 128 : if (sg && sk) {
1304 128 : if (gf_list_find(sg->sockets, sk)<0)
1305 128 : gf_list_add(sg->sockets, sk);
1306 : }
1307 128 : }
1308 91 : void gf_sk_group_unregister(GF_SockGroup *sg, GF_Socket *sk)
1309 : {
1310 91 : if (sg && sk) {
1311 91 : gf_list_del_item(sg->sockets, sk);
1312 : }
1313 91 : }
1314 :
1315 6300756 : GF_Err gf_sk_group_select(GF_SockGroup *sg, u32 usec_wait, GF_SockSelectMode mode)
1316 : {
1317 : s32 ready;
1318 6300756 : u32 i=0;
1319 : struct timeval timeout;
1320 : u32 max_fd=0;
1321 : GF_Socket *sock;
1322 : fd_set *rgroup=NULL, *wgroup=NULL;
1323 :
1324 6300756 : if (!gf_list_count(sg->sockets))
1325 : return GF_IP_NETWORK_EMPTY;
1326 :
1327 5794158 : FD_ZERO(&sg->rgroup);
1328 5794158 : FD_ZERO(&sg->wgroup);
1329 :
1330 5794158 : switch (mode) {
1331 5734943 : case GF_SK_SELECT_BOTH:
1332 5734943 : rgroup = &sg->rgroup;
1333 5734943 : wgroup = &sg->wgroup;
1334 5734943 : break;
1335 59215 : case GF_SK_SELECT_READ:
1336 59215 : rgroup = &sg->rgroup;
1337 59215 : break;
1338 0 : case GF_SK_SELECT_WRITE:
1339 0 : wgroup = &sg->wgroup;
1340 0 : break;
1341 : }
1342 17465644 : while ((sock = gf_list_enum(sg->sockets, &i))) {
1343 11671486 : if (rgroup)
1344 11671486 : FD_SET(sock->socket, rgroup);
1345 :
1346 11671486 : if (wgroup)
1347 11594390 : FD_SET(sock->socket, wgroup);
1348 :
1349 11671486 : if (max_fd < (u32) sock->socket) max_fd = (u32) sock->socket;
1350 : }
1351 5794158 : if (usec_wait>=1000000) {
1352 0 : timeout.tv_sec = usec_wait/1000000;
1353 0 : timeout.tv_usec = (u32) (usec_wait - (timeout.tv_sec*1000000));
1354 : } else {
1355 5794158 : timeout.tv_sec = 0;
1356 5794158 : timeout.tv_usec = usec_wait;
1357 : }
1358 5794158 : ready = select((int) max_fd+1, rgroup, wgroup, NULL, &timeout);
1359 :
1360 5794158 : if (ready == SOCKET_ERROR) {
1361 0 : switch (LASTSOCKERROR) {
1362 0 : case EBADF:
1363 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] cannot select, BAD descriptor\n"));
1364 : return GF_IP_CONNECTION_CLOSED;
1365 : case EAGAIN:
1366 : return GF_IP_SOCK_WOULD_BLOCK;
1367 0 : case EINTR:
1368 : /* Interrupted system call, not really important... */
1369 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] network is lost\n"));
1370 : return GF_IP_NETWORK_EMPTY;
1371 0 : default:
1372 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] cannot select: %s\n", gf_errno_str(LASTSOCKERROR) ));
1373 : return GF_IP_NETWORK_FAILURE;
1374 : }
1375 : }
1376 5794158 : if (!ready) {
1377 59187 : GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[socket] nothing to be read - ready %d\n", ready));
1378 : return GF_IP_NETWORK_EMPTY;
1379 : }
1380 : return GF_OK;
1381 : }
1382 :
1383 11593010 : Bool gf_sk_group_sock_is_set(GF_SockGroup *sg, GF_Socket *sk, GF_SockSelectMode mode)
1384 : {
1385 11593010 : if (sg && sk) {
1386 11593010 : if ((mode!=GF_SK_SELECT_WRITE) && FD_ISSET(sk->socket, &sg->rgroup))
1387 : return GF_TRUE;
1388 11590088 : if ((mode!=GF_SK_SELECT_READ) && FD_ISSET(sk->socket, &sg->wgroup))
1389 : return GF_TRUE;
1390 : }
1391 : return GF_FALSE;
1392 : }
1393 :
1394 :
1395 : //fetch nb bytes on a socket and fill the buffer from startFrom
1396 : //length is the allocated size of the receiving buffer
1397 : //BytesRead is the number of bytes read from the network
1398 152872 : GF_Err gf_sk_receive_internal(GF_Socket *sock, char *buffer, u32 length, u32 *BytesRead, Bool do_select)
1399 : {
1400 : s32 res;
1401 : #ifndef __SYMBIAN32__
1402 : s32 ready;
1403 : struct timeval timeout;
1404 : fd_set Group;
1405 : #endif
1406 :
1407 152872 : if (BytesRead) *BytesRead = 0;
1408 152872 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1409 :
1410 : #ifndef __SYMBIAN32__
1411 152872 : if (do_select) {
1412 : //can we read?
1413 151035 : timeout.tv_sec = 0;
1414 151035 : timeout.tv_usec = sock->usec_wait;
1415 151035 : FD_ZERO(&Group);
1416 151035 : FD_SET(sock->socket, &Group);
1417 151035 : ready = select((int) sock->socket+1, &Group, NULL, NULL, &timeout);
1418 :
1419 151035 : if (ready == SOCKET_ERROR) {
1420 0 : switch (LASTSOCKERROR) {
1421 0 : case EBADF:
1422 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] cannot select, BAD descriptor\n"));
1423 : return GF_IP_CONNECTION_CLOSED;
1424 : case EAGAIN:
1425 : return GF_IP_SOCK_WOULD_BLOCK;
1426 0 : case EINTR:
1427 : /* Interrupted system call, not really important... */
1428 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] network is lost\n"));
1429 : return GF_IP_NETWORK_EMPTY;
1430 0 : default:
1431 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] cannot select: %s\n", gf_errno_str(LASTSOCKERROR) ));
1432 : return GF_IP_NETWORK_FAILURE;
1433 : }
1434 : }
1435 151035 : if (!ready || !FD_ISSET(sock->socket, &Group)) {
1436 141025 : GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[socket] nothing to be read - ready %d\n", ready));
1437 : return GF_IP_NETWORK_EMPTY;
1438 : }
1439 : }
1440 : #endif
1441 11847 : if (!buffer) return GF_OK;
1442 :
1443 9521 : if (sock->flags & GF_SOCK_HAS_PEER)
1444 4652 : res = (s32) recvfrom(sock->socket, (char *) buffer, length, 0, (struct sockaddr *)&sock->dest_addr, &sock->dest_addr_len);
1445 : else {
1446 14390 : res = (s32) recv(sock->socket, (char *) buffer, length, 0);
1447 7195 : if (!do_select && (res == 0))
1448 : return GF_IP_CONNECTION_CLOSED;
1449 : }
1450 :
1451 9515 : if (res == SOCKET_ERROR) {
1452 0 : res = LASTSOCKERROR;
1453 0 : switch (res) {
1454 : case EAGAIN:
1455 : return GF_IP_SOCK_WOULD_BLOCK;
1456 : #ifndef __SYMBIAN32__
1457 0 : case EMSGSIZE:
1458 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] error reading: %s\n", gf_errno_str(LASTSOCKERROR)));
1459 : return GF_OUT_OF_MEM;
1460 0 : case ENOTCONN:
1461 : case ECONNRESET:
1462 : case ECONNABORTED:
1463 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] error reading: %s\n", gf_errno_str(LASTSOCKERROR)));
1464 : return GF_IP_CONNECTION_CLOSED;
1465 : #endif
1466 0 : default:
1467 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] error reading: %s\n", gf_errno_str(LASTSOCKERROR) ));
1468 : return GF_IP_NETWORK_FAILURE;
1469 : }
1470 : }
1471 9515 : if (!res) return GF_IP_NETWORK_EMPTY;
1472 9476 : if (BytesRead)
1473 9476 : *BytesRead = res;
1474 : return GF_OK;
1475 : }
1476 :
1477 : GF_EXPORT
1478 151035 : GF_Err gf_sk_receive(GF_Socket *sock, u8 *buffer, u32 length, u32 *BytesRead)
1479 : {
1480 151035 : return gf_sk_receive_internal(sock, buffer, length, BytesRead, GF_TRUE);
1481 : }
1482 :
1483 : GF_EXPORT
1484 1837 : GF_Err gf_sk_receive_no_select(GF_Socket *sock, u8 *buffer, u32 length, u32 *BytesRead)
1485 : {
1486 1837 : return gf_sk_receive_internal(sock, buffer, length, BytesRead, GF_FALSE);
1487 : }
1488 :
1489 : GF_EXPORT
1490 34 : GF_Err gf_sk_listen(GF_Socket *sock, u32 MaxConnection)
1491 : {
1492 : s32 i;
1493 34 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1494 34 : if (MaxConnection >= SOMAXCONN) MaxConnection = SOMAXCONN;
1495 34 : i = listen(sock->socket, MaxConnection);
1496 34 : if (i == SOCKET_ERROR) return GF_IP_NETWORK_FAILURE;
1497 34 : sock->flags |= GF_SOCK_IS_LISTENING;
1498 34 : return GF_OK;
1499 : }
1500 :
1501 : GF_EXPORT
1502 3789 : GF_Err gf_sk_accept(GF_Socket *sock, GF_Socket **newConnection)
1503 : {
1504 : u32 client_address_size;
1505 : SOCKET sk;
1506 : #ifndef __SYMBIAN32__
1507 : s32 ready;
1508 : struct timeval timeout;
1509 : fd_set Group;
1510 : #endif
1511 3789 : *newConnection = NULL;
1512 3789 : if (!sock || !(sock->flags & GF_SOCK_IS_LISTENING) ) return GF_BAD_PARAM;
1513 :
1514 : #ifndef __SYMBIAN32__
1515 : //can we read?
1516 3789 : FD_ZERO(&Group);
1517 3789 : FD_SET(sock->socket, &Group);
1518 3789 : timeout.tv_sec = 0;
1519 3789 : timeout.tv_usec = sock->usec_wait;
1520 :
1521 : //TODO - check if this is correct
1522 3789 : ready = select((int) sock->socket+1, &Group, NULL, NULL, &timeout);
1523 3789 : if (ready == SOCKET_ERROR) {
1524 0 : switch (LASTSOCKERROR) {
1525 : case EAGAIN:
1526 : return GF_IP_SOCK_WOULD_BLOCK;
1527 0 : default:
1528 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] select error: %s\n", gf_errno_str(LASTSOCKERROR)));
1529 : return GF_IP_NETWORK_FAILURE;
1530 : }
1531 : }
1532 3789 : if (!ready || !FD_ISSET(sock->socket, &Group)) return GF_IP_NETWORK_EMPTY;
1533 : #endif
1534 :
1535 : #ifdef GPAC_HAS_IPV6
1536 78 : client_address_size = sizeof(struct sockaddr_in6);
1537 : #else
1538 : client_address_size = sizeof(struct sockaddr_in);
1539 : #endif
1540 78 : sk = accept(sock->socket, (struct sockaddr *) &sock->dest_addr, &client_address_size);
1541 :
1542 : //we either have an error or we have no connections
1543 78 : if (sk == INVALID_SOCKET) {
1544 : // if (sock->flags & GF_SOCK_NON_BLOCKING) return GF_IP_NETWORK_FAILURE;
1545 0 : switch (LASTSOCKERROR) {
1546 : case EAGAIN:
1547 : return GF_IP_SOCK_WOULD_BLOCK;
1548 0 : default:
1549 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] accept error: %s\n", gf_errno_str(LASTSOCKERROR)));
1550 : return GF_IP_NETWORK_FAILURE;
1551 : }
1552 : }
1553 :
1554 78 : (*newConnection) = (GF_Socket *) gf_malloc(sizeof(GF_Socket));
1555 78 : (*newConnection)->socket = sk;
1556 78 : (*newConnection)->flags = sock->flags & ~GF_SOCK_IS_LISTENING;
1557 78 : (*newConnection)->usec_wait = sock->usec_wait;
1558 : #ifdef GPAC_HAS_IPV6
1559 78 : memcpy( &(*newConnection)->dest_addr, &sock->dest_addr, client_address_size);
1560 : memset(&sock->dest_addr, 0, sizeof(struct sockaddr_in6));
1561 : #else
1562 : memcpy( &(*newConnection)->dest_addr, &sock->dest_addr, client_address_size);
1563 : memset(&sock->dest_addr, 0, sizeof(struct sockaddr_in));
1564 : #endif
1565 :
1566 : #ifdef SO_NOSIGPIPE
1567 : int value = 1;
1568 : setsockopt((*newConnection)->socket, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));
1569 : #endif
1570 :
1571 : #if defined(WIN32) || defined(_WIN32_WCE)
1572 : wsa_init++;
1573 : #endif
1574 :
1575 78 : (*newConnection)->dest_addr_len = client_address_size;
1576 78 : return GF_OK;
1577 : }
1578 :
1579 : GF_EXPORT
1580 26 : GF_Err gf_sk_get_local_info(GF_Socket *sock, u16 *Port, u32 *Familly)
1581 : {
1582 : #ifdef GPAC_HAS_IPV6
1583 : struct sockaddr_in6 the_add;
1584 : #else
1585 : struct sockaddr_in the_add;
1586 : #endif
1587 : u32 size;
1588 :
1589 26 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1590 :
1591 25 : if (Port) {
1592 : #ifdef GPAC_HAS_IPV6
1593 25 : size = sizeof(struct sockaddr_in6);
1594 25 : if (getsockname(sock->socket, (struct sockaddr *) &the_add, &size) == SOCKET_ERROR) return GF_IP_NETWORK_FAILURE;
1595 25 : *Port = (u32) ntohs(the_add.sin6_port);
1596 : #else
1597 : size = sizeof(struct sockaddr_in);
1598 : if (getsockname(sock->socket, (struct sockaddr *) &the_add, &size) == SOCKET_ERROR) return GF_IP_NETWORK_FAILURE;
1599 : *Port = (u32) ntohs(the_add.sin_port);
1600 : #endif
1601 : }
1602 25 : if (Familly) {
1603 : /* size = 4;
1604 : if (getsockopt(sock->socket, SOL_SOCKET, SO_TYPE, (char *) &fam, &size) == SOCKET_ERROR)
1605 : return GF_IP_NETWORK_FAILURE;
1606 : *Familly = fam;
1607 : */
1608 25 : if (sock->flags & GF_SOCK_IS_TCP) *Familly = GF_SOCK_TYPE_TCP;
1609 0 : else *Familly = GF_SOCK_TYPE_UDP;
1610 : }
1611 : return GF_OK;
1612 : }
1613 :
1614 : //we have to do this for the server sockets as we use only one thread
1615 : GF_EXPORT
1616 59 : GF_Err gf_sk_server_mode(GF_Socket *sock, Bool serverOn)
1617 : {
1618 : u32 one;
1619 :
1620 59 : if (!sock || !(sock->flags & GF_SOCK_IS_TCP) || !sock->socket)
1621 : return GF_BAD_PARAM;
1622 :
1623 59 : one = serverOn ? 1 : 0;
1624 59 : setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, SSO_CAST &one, sizeof(u32));
1625 : #ifndef __SYMBIAN32__
1626 59 : setsockopt(sock->socket, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(u32));
1627 : #endif
1628 59 : return GF_OK;
1629 : }
1630 :
1631 : GF_EXPORT
1632 78 : GF_Err gf_sk_get_remote_address(GF_Socket *sock, char *buf)
1633 : {
1634 : #ifdef GPAC_HAS_IPV6
1635 : char clienthost[NI_MAXHOST];
1636 : char servname[NI_MAXHOST];
1637 78 : struct sockaddr_in6 * addrptr = (struct sockaddr_in6 *)(&sock->dest_addr);
1638 78 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1639 78 : inet_ntop(AF_INET, addrptr, clienthost, NI_MAXHOST);
1640 : strcpy(buf, clienthost);
1641 78 : if (getnameinfo((struct sockaddr *)addrptr, sock->dest_addr_len, clienthost, NI_MAXHOST, servname, NI_MAXHOST, NI_NUMERICHOST) == 0) {
1642 : strcpy(buf, clienthost);
1643 : }
1644 : #else
1645 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1646 : strcpy(buf, inet_ntoa(sock->dest_addr.sin_addr));
1647 : #endif
1648 : return GF_OK;
1649 : }
1650 :
1651 :
1652 :
1653 : #if 0 //unused
1654 :
1655 : //send length bytes of a buffer
1656 : GF_Err gf_sk_send_to(GF_Socket *sock, const char *buffer, u32 length, char *remoteHost, u16 remotePort)
1657 : {
1658 : u32 count, remote_add_len;
1659 : s32 res;
1660 : #ifdef GPAC_HAS_IPV6
1661 : struct sockaddr_storage remote_add;
1662 : #else
1663 : struct sockaddr_in remote_add;
1664 : struct hostent *Host;
1665 : #endif
1666 : #ifndef __SYMBIAN32__
1667 : s32 ready;
1668 : struct timeval timeout;
1669 : fd_set Group;
1670 : #endif
1671 :
1672 : //the socket must be bound or connected
1673 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1674 : if (remoteHost && !remotePort) return GF_BAD_PARAM;
1675 :
1676 : #ifndef __SYMBIAN32__
1677 : //can we write?
1678 : FD_ZERO(&Group);
1679 : FD_SET(sock->socket, &Group);
1680 : timeout.tv_sec = 0;
1681 : timeout.tv_usec = sock->usec_wait;
1682 :
1683 : //TODO - check if this is correct
1684 : ready = select((int) sock->socket+1, NULL, &Group, NULL, &timeout);
1685 : if (ready == SOCKET_ERROR) {
1686 : switch (LASTSOCKERROR) {
1687 : case EAGAIN:
1688 : return GF_IP_SOCK_WOULD_BLOCK;
1689 : default:
1690 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] select error: %s\n", gf_errno_str(LASTSOCKERROR)));
1691 : return GF_IP_NETWORK_FAILURE;
1692 : }
1693 : }
1694 : if (!ready || !FD_ISSET(sock->socket, &Group)) return GF_IP_NETWORK_EMPTY;
1695 : #endif
1696 :
1697 :
1698 : /*setup the address*/
1699 : #ifdef GPAC_HAS_IPV6
1700 : remote_add.ss_family = AF_INET6;
1701 : //if a remote host is specified, use it. Otherwise use the default host
1702 : if (remoteHost) {
1703 : //setup the address
1704 : struct addrinfo *res = gf_sk_get_ipv6_addr(remoteHost, remotePort, AF_UNSPEC, 0, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM);
1705 : if (!res) return GF_IP_ADDRESS_NOT_FOUND;
1706 : memcpy(&remote_add, res->ai_addr, res->ai_addrlen);
1707 : remote_add_len = (u32) res->ai_addrlen;
1708 : freeaddrinfo(res);
1709 : } else {
1710 : struct sockaddr_in6 *remotePtr = (struct sockaddr_in6 *)&remote_add;
1711 : struct sockaddr_in6 * addrptr = (struct sockaddr_in6 *)(&sock->dest_addr);
1712 : remotePtr->sin6_port = addrptr->sin6_port;
1713 : remotePtr->sin6_addr = addrptr->sin6_addr;
1714 : remote_add_len = sock->dest_addr_len;
1715 : }
1716 : #else
1717 : remote_add_len = sizeof(struct sockaddr_in);
1718 : remote_add.sin_family = AF_INET;
1719 : //if a remote host is specified, use it. Otherwise use the default host
1720 : if (remoteHost) {
1721 : //setup the address
1722 : remote_add.sin_port = htons(remotePort);
1723 : //get the server IP
1724 : Host = gf_gethostbyname(remoteHost);
1725 : if (Host == NULL) return GF_IP_ADDRESS_NOT_FOUND;
1726 : memcpy((char *) &remote_add.sin_addr, Host->h_addr_list[0], sizeof(u32));
1727 : } else {
1728 : remote_add.sin_port = sock->dest_addr.sin_port;
1729 : remote_add.sin_addr.s_addr = sock->dest_addr.sin_addr.s_addr;
1730 : }
1731 : #endif
1732 : count = 0;
1733 : while (count < length) {
1734 : res = (s32) sendto(sock->socket, (char *) buffer+count, length - count, 0, (struct sockaddr *) &remote_add, remote_add_len);
1735 : if (res == SOCKET_ERROR) {
1736 : switch (LASTSOCKERROR) {
1737 : case EAGAIN:
1738 : return GF_IP_SOCK_WOULD_BLOCK;
1739 : default:
1740 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] sendto error: %s\n", gf_errno_str(LASTSOCKERROR)));
1741 : return GF_IP_NETWORK_FAILURE;
1742 : }
1743 : }
1744 : count += res;
1745 : }
1746 : return GF_OK;
1747 : }
1748 : #endif
1749 :
1750 : GF_EXPORT
1751 135216 : GF_Err gf_sk_probe(GF_Socket *sock)
1752 : {
1753 : #ifndef __SYMBIAN32__
1754 : s32 ready;
1755 : struct timeval timeout;
1756 : fd_set Group;
1757 : #endif
1758 : s32 res;
1759 : u8 buffer[1];
1760 135216 : if (!sock) return GF_BAD_PARAM;
1761 :
1762 : #ifndef __SYMBIAN32__
1763 : //can we read?
1764 135216 : FD_ZERO(&Group);
1765 135216 : FD_SET(sock->socket, &Group);
1766 135216 : timeout.tv_sec = 0;
1767 135216 : timeout.tv_usec = 100;
1768 :
1769 135216 : ready = select((int) sock->socket+1, &Group, NULL, NULL, &timeout);
1770 135216 : if (ready == SOCKET_ERROR) {
1771 0 : switch (LASTSOCKERROR) {
1772 : case EAGAIN:
1773 : return GF_IP_SOCK_WOULD_BLOCK;
1774 0 : default:
1775 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] select error: %s\n", gf_errno_str(LASTSOCKERROR)));
1776 : return GF_IP_CONNECTION_CLOSED;
1777 : }
1778 : }
1779 135216 : if (!FD_ISSET(sock->socket, &Group)) {
1780 : return GF_IP_NETWORK_EMPTY;
1781 : }
1782 : #endif
1783 270 : res = (s32) recv(sock->socket, buffer, 1, MSG_PEEK);
1784 270 : if (res > 0) return GF_OK;
1785 : #if 0
1786 : res = LASTSOCKERROR;
1787 : switch (res) {
1788 : case 0:
1789 : case EAGAIN:
1790 : return GF_IP_NETWORK_EMPTY;
1791 : default:
1792 : GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[socket] probe error: %s\n", gf_errno_str(res)));
1793 : return GF_IP_CONNECTION_CLOSED;
1794 : }
1795 : #else
1796 39 : return GF_IP_CONNECTION_CLOSED;
1797 : #endif
1798 :
1799 : return GF_OK;
1800 : }
1801 :
1802 : GF_EXPORT
1803 1 : GF_Err gf_sk_receive_wait(GF_Socket *sock, u8 *buffer, u32 length, u32 *BytesRead, u32 Second )
1804 : {
1805 : s32 res;
1806 : #ifndef __SYMBIAN32__
1807 : s32 ready;
1808 : struct timeval timeout;
1809 : fd_set Group;
1810 : #endif
1811 :
1812 1 : if (!sock || !sock->socket || !buffer || !BytesRead) return GF_BAD_PARAM;
1813 0 : *BytesRead = 0;
1814 :
1815 : #ifndef __SYMBIAN32__
1816 : //can we read?
1817 0 : FD_ZERO(&Group);
1818 0 : FD_SET(sock->socket, &Group);
1819 0 : timeout.tv_sec = Second;
1820 0 : timeout.tv_usec = sock->usec_wait;
1821 :
1822 0 : ready = select((int) sock->socket+1, &Group, NULL, NULL, &timeout);
1823 0 : if (ready == SOCKET_ERROR) {
1824 0 : switch (LASTSOCKERROR) {
1825 : case EAGAIN:
1826 : return GF_IP_SOCK_WOULD_BLOCK;
1827 0 : default:
1828 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] select error: %s\n", gf_errno_str(LASTSOCKERROR)));
1829 : return GF_IP_NETWORK_FAILURE;
1830 : }
1831 : }
1832 0 : if (!FD_ISSET(sock->socket, &Group)) {
1833 : return GF_IP_NETWORK_EMPTY;
1834 : }
1835 : #endif
1836 :
1837 0 : res = (s32) recv(sock->socket, (char *) buffer, length, 0);
1838 0 : if (res == SOCKET_ERROR) {
1839 0 : switch (LASTSOCKERROR) {
1840 : case EAGAIN:
1841 : return GF_IP_SOCK_WOULD_BLOCK;
1842 0 : default:
1843 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] recv error: %s\n", gf_errno_str(LASTSOCKERROR)));
1844 : return GF_IP_NETWORK_FAILURE;
1845 : }
1846 : }
1847 0 : *BytesRead = res;
1848 0 : return GF_OK;
1849 : }
1850 :
1851 :
1852 : //send length bytes of a buffer
1853 : GF_EXPORT
1854 29 : GF_Err gf_sk_send_wait(GF_Socket *sock, const u8 *buffer, u32 length, u32 Second )
1855 : {
1856 : u32 count;
1857 : s32 res;
1858 : #ifndef __SYMBIAN32__
1859 : s32 ready;
1860 : struct timeval timeout;
1861 : fd_set Group;
1862 : #endif
1863 :
1864 : //the socket must be bound or connected
1865 29 : if (!sock || !sock->socket) return GF_BAD_PARAM;
1866 :
1867 : #ifndef __SYMBIAN32__
1868 : //can we write?
1869 28 : FD_ZERO(&Group);
1870 28 : FD_SET(sock->socket, &Group);
1871 28 : timeout.tv_sec = Second;
1872 28 : timeout.tv_usec = sock->usec_wait;
1873 :
1874 : //TODO - check if this is correct
1875 28 : ready = select((int) sock->socket+1, NULL, &Group, NULL, &timeout);
1876 28 : if (ready == SOCKET_ERROR) {
1877 0 : switch (LASTSOCKERROR) {
1878 : case EAGAIN:
1879 : return GF_IP_SOCK_WOULD_BLOCK;
1880 0 : default:
1881 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] select error: %s\n", gf_errno_str(LASTSOCKERROR)));
1882 : return GF_IP_NETWORK_FAILURE;
1883 : }
1884 : }
1885 : //should never happen (to check: is writeability is guaranteed for not-connected sockets)
1886 28 : if (!ready || !FD_ISSET(sock->socket, &Group)) {
1887 : return GF_IP_NETWORK_EMPTY;
1888 : }
1889 : #endif
1890 :
1891 : //direct writing
1892 : count = 0;
1893 56 : while (count < length) {
1894 28 : res = (s32) send(sock->socket, (char *) buffer+count, length - count, 0);
1895 28 : if (res == SOCKET_ERROR) {
1896 0 : switch (LASTSOCKERROR) {
1897 : case EAGAIN:
1898 : return GF_IP_SOCK_WOULD_BLOCK;
1899 : #ifndef __SYMBIAN32__
1900 0 : case ECONNRESET:
1901 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] send error: %s\n", gf_errno_str(LASTSOCKERROR)));
1902 : return GF_IP_CONNECTION_CLOSED;
1903 : #endif
1904 0 : default:
1905 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] send error: %s\n", gf_errno_str(LASTSOCKERROR)));
1906 : return GF_IP_NETWORK_FAILURE;
1907 : }
1908 : }
1909 28 : count += res;
1910 : }
1911 : return GF_OK;
1912 : }
1913 :
1914 : GF_EXPORT
1915 11 : u32 gf_htonl(u32 val)
1916 : {
1917 11 : return htonl(val);
1918 : }
1919 :
1920 :
1921 : GF_EXPORT
1922 2 : u32 gf_ntohl(u32 val)
1923 : {
1924 2 : return ntohl(val);
1925 : }
1926 :
1927 : GF_EXPORT
1928 2 : u16 gf_htons(u16 val)
1929 : {
1930 2 : return htons(val);
1931 : }
1932 :
1933 :
1934 : GF_EXPORT
1935 2 : u16 gf_ntohs(u16 val)
1936 : {
1937 2 : return ntohs(val);
1938 : }
1939 :
1940 : #endif /*GPAC_DISABLE_CORE_TOOLS*/
|