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