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