PageRenderTime 349ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/ext/gpac/src/utils/os_net.c

https://github.com/paulcbetts/yikes
C | 1394 lines | 1112 code | 181 blank | 101 comment | 283 complexity | 622fa646d9bcd39bdb8adb456be3b16c MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception
  1. /*
  2. * GPAC - Multimedia Framework C SDK
  3. *
  4. * Copyright (c) Jean Le Feuvre 2000-2005
  5. * All rights reserved
  6. *
  7. * This file is part of GPAC / common tools sub-project
  8. *
  9. * GPAC is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published by
  11. * the Free Software Foundation; either version 2, or (at your option)
  12. * any later version.
  13. *
  14. * GPAC is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; see the file COPYING. If not, write to
  21. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22. *
  23. */
  24. #if defined(WIN32) || defined(_WIN32_WCE)
  25. #ifdef _WIN32_WCE
  26. #include <winsock.h>
  27. #else
  28. #include <sys/timeb.h>
  29. #include <winsock2.h>
  30. #include <ws2tcpip.h>
  31. #endif
  32. #include <windows.h>
  33. #if !defined(__GNUC__)
  34. #if 0 && defined(IPV6_MULTICAST_IF)
  35. #define GPAC_IPV6 1
  36. #pragma message("Using WinSock IPV6")
  37. #else
  38. #undef GPAC_IPV6
  39. #pragma message("Using WinSock IPV4")
  40. #endif
  41. #endif
  42. /*common win32 redefs*/
  43. #define EAGAIN WSAEWOULDBLOCK
  44. #define EISCONN WSAEISCONN
  45. #define ENOTCONN WSAENOTCONN
  46. #define ECONNRESET WSAECONNRESET
  47. #define EMSGSIZE WSAEMSGSIZE
  48. #define ECONNABORTED WSAECONNABORTED
  49. #define ENETDOWN WSAENETDOWN
  50. #define LASTSOCKERROR WSAGetLastError()
  51. /*the number of sockets used. This because the WinSock lib needs init*/
  52. static int wsa_init = 0;
  53. #include <gpac/network.h>
  54. /*end-win32*/
  55. #else
  56. /*non-win32*/
  57. #include <unistd.h>
  58. #include <fcntl.h>
  59. #include <netdb.h>
  60. #ifndef __BEOS__
  61. #include <errno.h>
  62. #endif
  63. #ifndef __DARWIN__
  64. #include <sys/time.h>
  65. #endif
  66. #include <netinet/in.h>
  67. #include <netinet/tcp.h>
  68. #include <sys/socket.h>
  69. #include <arpa/inet.h>
  70. #include <gpac/network.h>
  71. #define INVALID_SOCKET -1
  72. #define SOCKET_ERROR -1
  73. #define LASTSOCKERROR errno
  74. typedef s32 SOCKET;
  75. #define closesocket(v) close(v)
  76. #endif
  77. #ifdef __SYMBIAN32__
  78. #define SSO_CAST
  79. #else
  80. #define SSO_CAST (const char *)
  81. #endif
  82. #define SOCK_MICROSEC_WAIT 500
  83. #ifdef GPAC_IPV6
  84. static u32 ipv6_check_state = 0;
  85. #endif
  86. // XXX: Added by bettsp, not actually correct!
  87. #ifndef u_long
  88. #define u_long unsigned long
  89. #endif
  90. /*internal flags*/
  91. enum
  92. {
  93. GF_SOCK_IS_TCP = 1<<9,
  94. GF_SOCK_IS_IPV6 = 1<<10,
  95. GF_SOCK_NON_BLOCKING = 1<<11,
  96. GF_SOCK_IS_MULTICAST = 1<<12,
  97. GF_SOCK_IS_LISTENING = 1<<13,
  98. /*socket is bound to a specific dest (server) or source (client) */
  99. GF_SOCK_HAS_PEER = 1<<14
  100. };
  101. struct __tag_socket
  102. {
  103. u32 flags;
  104. SOCKET socket;
  105. /*destination address for sendto/recvfrom*/
  106. #ifdef GPAC_IPV6
  107. struct sockaddr_storage dest_addr;
  108. #else
  109. struct sockaddr_in dest_addr;
  110. #endif
  111. u32 dest_addr_len;
  112. };
  113. /*
  114. Some NTP tools
  115. */
  116. void gf_net_get_ntp(u32 *sec, u32 *frac)
  117. {
  118. struct timeval now;
  119. #ifdef WIN32
  120. s32 gettimeofday(struct timeval *tp, void *tz);
  121. #endif
  122. gettimeofday(&now, NULL);
  123. *sec = (u32) (now.tv_sec) + GF_NTP_SEC_1900_TO_1970;
  124. *frac = (u32) ( (now.tv_usec << 12) + (now.tv_usec << 8) - ((now.tv_usec * 3650) >> 6) );
  125. }
  126. u32 gf_net_has_ipv6()
  127. {
  128. #ifdef GPAC_IPV6
  129. if (!ipv6_check_state) {
  130. SOCKET s;
  131. #ifdef WIN32
  132. if (!wsa_init) {
  133. WSADATA Data;
  134. if (WSAStartup(0x0202, &Data)!=0) {
  135. ipv6_check_state = 1;
  136. return 0;
  137. }
  138. }
  139. #endif
  140. s = socket(PF_INET6, SOCK_STREAM, 0);
  141. if (!s) ipv6_check_state = 1;
  142. else {
  143. ipv6_check_state = 2;
  144. closesocket(s);
  145. }
  146. #ifdef WIN32
  147. if (!wsa_init) WSACleanup();
  148. #endif
  149. }
  150. return (ipv6_check_state==2);
  151. #else
  152. return 0;
  153. #endif
  154. }
  155. GF_EXPORT
  156. Bool gf_net_is_ipv6(char *address)
  157. {
  158. char *sep;
  159. if (!address) return 0;
  160. sep = strchr(address, ':');
  161. if (sep) sep = strchr(address, ':');
  162. return sep ? 1 : 0;
  163. }
  164. #ifdef GPAC_IPV6
  165. static struct addrinfo *gf_sk_get_ipv6_addr(char *PeerName, u16 PortNumber, int family, int flags, int sock_type)
  166. {
  167. struct addrinfo *res=NULL;
  168. struct addrinfo hints;
  169. char node[50], portstring[20], *service, *dest;
  170. #ifdef WIN32
  171. if (!wsa_init) {
  172. WSADATA Data;
  173. if (WSAStartup(0x0202, &Data)!=0) return NULL;
  174. wsa_init = 1;
  175. }
  176. #endif
  177. service = dest = NULL;
  178. memset(&hints, 0, sizeof(hints));
  179. hints.ai_socktype = sock_type;
  180. hints.ai_family = family;
  181. hints.ai_flags = flags;
  182. if (PortNumber) {
  183. sprintf (portstring, "%d", PortNumber);
  184. service = (char *)portstring;
  185. }
  186. if (PeerName) {
  187. strcpy(node, PeerName);
  188. if (node[0]=='[') {
  189. node[strlen(node)-1] = 0;
  190. strcpy(node, &node[1]);
  191. }
  192. dest = (char *) node;
  193. }
  194. if (getaddrinfo((const char *)dest, (const char *)service, &hints, &res) != 0) return NULL;
  195. return res;
  196. }
  197. static Bool gf_sk_ipv6_set_remote_address(GF_Socket *sock, char *address, u16 PortNumber)
  198. {
  199. struct addrinfo *res = gf_sk_get_ipv6_addr(address, PortNumber, AF_UNSPEC, 0, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM);
  200. if (!res) return 0;
  201. memcpy(&sock->dest_addr, res->ai_addr, res->ai_addrlen);
  202. sock->dest_addr_len = res->ai_addrlen;
  203. freeaddrinfo(res);
  204. return 1;
  205. }
  206. #endif
  207. GF_Err gf_sk_get_host_name(char *buffer)
  208. {
  209. s32 ret = gethostname(buffer, GF_MAX_IP_NAME_LEN);
  210. return (ret == SOCKET_ERROR) ? GF_IP_ADDRESS_NOT_FOUND : GF_OK;
  211. }
  212. GF_Err gf_sk_get_local_ip(GF_Socket *sock, char *buffer)
  213. {
  214. #ifdef GPAC_IPV6
  215. char clienthost[NI_MAXHOST];
  216. if (sock->flags & GF_SOCK_HAS_PEER) {
  217. if (getnameinfo((struct sockaddr *)&sock->dest_addr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST))
  218. return GF_IP_NETWORK_FAILURE;
  219. } else {
  220. struct sockaddr_storage clientaddr;
  221. socklen_t addrlen = sizeof(clientaddr);
  222. if (getsockname(sock->socket, (struct sockaddr *)&clientaddr, &addrlen)) return GF_IP_NETWORK_FAILURE;
  223. if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST))
  224. return GF_IP_NETWORK_FAILURE;
  225. }
  226. strcpy(buffer, clienthost);
  227. #else
  228. char *ip;
  229. if (sock->flags & GF_SOCK_HAS_PEER) {
  230. ip = inet_ntoa(sock->dest_addr.sin_addr);
  231. } else {
  232. struct sockaddr_in name;
  233. u32 len = sizeof(struct sockaddr_in);
  234. if (getsockname(sock->socket, (struct sockaddr*) &name, &len)) return GF_IP_NETWORK_FAILURE;
  235. ip = inet_ntoa(name.sin_addr);
  236. }
  237. if (!ip) return GF_IP_NETWORK_FAILURE;
  238. strcpy(buffer, ip);
  239. #endif
  240. return GF_OK;
  241. }
  242. GF_Socket *gf_sk_new(u32 SocketType)
  243. {
  244. GF_Socket *tmp;
  245. /*init WinSock*/
  246. #ifdef WIN32
  247. WSADATA Data;
  248. if (!wsa_init && (WSAStartup(0x0202, &Data)!=0) ) return NULL;
  249. #endif
  250. if ((SocketType != GF_SOCK_TYPE_UDP) && (SocketType != GF_SOCK_TYPE_TCP)) return NULL;
  251. GF_SAFEALLOC(tmp, GF_Socket);
  252. if (!tmp) return NULL;
  253. if (SocketType == GF_SOCK_TYPE_TCP) tmp->flags |= GF_SOCK_IS_TCP;
  254. #ifdef GPAC_IPV6
  255. memset(&tmp->dest_addr, 0, sizeof(struct sockaddr_storage));
  256. #else
  257. memset(&tmp->dest_addr, 0, sizeof(struct sockaddr_in));
  258. tmp->dest_addr_len = sizeof(struct sockaddr);
  259. #endif
  260. #ifdef WIN32
  261. wsa_init ++;
  262. #endif
  263. return tmp;
  264. }
  265. GF_Err gf_sk_set_buffer_size(GF_Socket *sock, Bool SendBuffer, u32 NewSize)
  266. {
  267. if (!sock || !sock->socket) return GF_BAD_PARAM;
  268. if (SendBuffer) {
  269. setsockopt(sock->socket, SOL_SOCKET, SO_SNDBUF, (char *) &NewSize, sizeof(u32) );
  270. } else {
  271. setsockopt(sock->socket, SOL_SOCKET, SO_RCVBUF, (char *) &NewSize, sizeof(u32) );
  272. }
  273. return GF_OK;
  274. }
  275. GF_Err gf_sk_set_block_mode(GF_Socket *sock, u32 NonBlockingOn)
  276. {
  277. s32 res;
  278. #ifdef WIN32
  279. u_long val = NonBlockingOn;
  280. res = ioctlsocket(sock->socket, FIONBIO, &val);
  281. if (res) return GF_SERVICE_ERROR;
  282. #else
  283. s32 flag = fcntl(sock->socket, F_GETFL, 0);
  284. res = fcntl(sock->socket, F_SETFL, flag | O_NONBLOCK);
  285. if (res) return GF_SERVICE_ERROR;
  286. #endif
  287. if (NonBlockingOn) {
  288. sock->flags |= GF_SOCK_NON_BLOCKING;
  289. } else {
  290. sock->flags &= ~GF_SOCK_NON_BLOCKING;
  291. }
  292. return GF_OK;
  293. }
  294. static void gf_sk_free(GF_Socket *sock)
  295. {
  296. /*leave multicast*/
  297. if (sock->socket && (sock->flags & GF_SOCK_IS_MULTICAST) ) {
  298. struct ip_mreq mreq;
  299. #ifdef GPAC_IPV6
  300. struct sockaddr *addr = (struct sockaddr *)&sock->dest_addr;
  301. if (addr->sa_family==AF_INET6) {
  302. struct ipv6_mreq mreq6;
  303. memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
  304. mreq6.ipv6mr_interface= 0;
  305. setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &mreq6, sizeof(mreq6));
  306. } else {
  307. mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
  308. mreq.imr_interface.s_addr = INADDR_ANY;
  309. setsockopt(sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
  310. }
  311. #else
  312. mreq.imr_multiaddr.s_addr = sock->dest_addr.sin_addr.s_addr;
  313. mreq.imr_interface.s_addr = INADDR_ANY;
  314. setsockopt(sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &mreq, sizeof(mreq));
  315. #endif
  316. }
  317. if (sock->socket) closesocket(sock->socket);
  318. sock->socket = (SOCKET) 0L;
  319. }
  320. void gf_sk_del(GF_Socket *sock)
  321. {
  322. gf_sk_free(sock);
  323. #ifdef WIN32
  324. wsa_init --;
  325. if (!wsa_init) WSACleanup();
  326. #endif
  327. free(sock);
  328. }
  329. void gf_sk_reset(GF_Socket *sock)
  330. {
  331. u32 clear;
  332. if (sock) setsockopt(sock->socket, SOL_SOCKET, SO_ERROR, (char *) &clear, sizeof(u32) );
  333. }
  334. s32 gf_sk_get_handle(GF_Socket *sock)
  335. {
  336. return sock->socket;
  337. }
  338. //connects a socket to a remote peer on a given port
  339. GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber)
  340. {
  341. s32 ret;
  342. #ifdef GPAC_IPV6
  343. u32 type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;
  344. struct addrinfo *res, *aip;
  345. gf_sk_free(sock);
  346. res = gf_sk_get_ipv6_addr(PeerName, PortNumber, AF_UNSPEC, AI_PASSIVE, type);
  347. if (!res) return GF_IP_CONNECTION_FAILURE;
  348. /*for all interfaces*/
  349. for (aip=res; aip!=NULL; aip=aip->ai_next) {
  350. if (type != (u32) aip->ai_socktype) continue;
  351. sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
  352. if (sock->socket == INVALID_SOCKET) {
  353. sock->socket = (SOCKET)NULL;
  354. continue;
  355. }
  356. if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);
  357. if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;
  358. else sock->flags &= ~GF_SOCK_IS_IPV6;
  359. ret = connect(sock->socket, aip->ai_addr, aip->ai_addrlen);
  360. if (ret == SOCKET_ERROR) {
  361. closesocket(sock->socket);
  362. sock->socket = (SOCKET)NULL;
  363. continue;
  364. }
  365. memcpy(&sock->dest_addr, aip->ai_addr, aip->ai_addrlen);
  366. sock->dest_addr_len = aip->ai_addrlen;
  367. freeaddrinfo(res);
  368. return GF_OK;
  369. }
  370. freeaddrinfo(res);
  371. return GF_IP_CONNECTION_FAILURE;
  372. #else
  373. struct hostent *Host;
  374. if (!sock->socket)
  375. sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
  376. /*setup the address*/
  377. sock->dest_addr.sin_family = AF_INET;
  378. sock->dest_addr.sin_port = htons(PortNumber);
  379. /*get the server IP*/
  380. sock->dest_addr.sin_addr.s_addr = inet_addr(PeerName);
  381. if (sock->dest_addr.sin_addr.s_addr==INADDR_NONE) {
  382. Host = gethostbyname(PeerName);
  383. if (Host == NULL) {
  384. switch (LASTSOCKERROR) {
  385. #ifndef __SYMBIAN32__
  386. case ENETDOWN: return GF_IP_NETWORK_FAILURE;
  387. //case ENOHOST: return GF_IP_ADDRESS_NOT_FOUND;
  388. #endif
  389. default: return GF_IP_NETWORK_FAILURE;
  390. }
  391. }
  392. memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32));
  393. }
  394. if (sock->flags & GF_SOCK_IS_TCP) {
  395. ret = connect(sock->socket, (struct sockaddr *) &sock->dest_addr, sizeof(struct sockaddr));
  396. if (ret == SOCKET_ERROR) {
  397. switch (LASTSOCKERROR) {
  398. case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK;
  399. case EISCONN: return GF_OK;
  400. default: return GF_IP_CONNECTION_FAILURE;
  401. }
  402. }
  403. }
  404. #endif
  405. return GF_OK;
  406. }
  407. //binds the given socket to the specified port. If ReUse is true
  408. //this will enable reuse of ports on a single machine
  409. GF_Err gf_sk_bind(GF_Socket *sock, u16 port, char *peer_name, u16 peer_port, u32 options)
  410. {
  411. #ifdef GPAC_IPV6
  412. struct addrinfo *res, *aip;
  413. int af;
  414. u32 type;
  415. #else
  416. size_t addrlen;
  417. struct sockaddr_in LocalAdd;
  418. struct hostent *Host;
  419. char buf[GF_MAX_IP_NAME_LEN];
  420. #endif
  421. s32 ret;
  422. s32 optval;
  423. if (!sock || sock->socket) return GF_BAD_PARAM;
  424. #ifdef GPAC_IPV6
  425. type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;
  426. af = (options & GF_SOCK_FORCE_IPV6) ? PF_INET6 : PF_UNSPEC;
  427. if (!gf_net_has_ipv6()) af = PF_INET;
  428. /*probe way to peer: is it V4 or V6? */
  429. if (peer_name && peer_port) {
  430. res = gf_sk_get_ipv6_addr(peer_name, peer_port, af, AI_PASSIVE, type);
  431. if (!res) return GF_IP_CONNECTION_FAILURE;
  432. #ifdef WIN32
  433. /*win32 has troubles redirecting IPV4 datagrams to IPV6 sockets, so override
  434. local family type to avoid IPV4(S)->IPV6(C) UDP*/
  435. af = res->ai_family;
  436. #endif
  437. memcpy(&sock->dest_addr, res->ai_addr, res->ai_addrlen);
  438. sock->dest_addr_len = res->ai_addrlen;
  439. freeaddrinfo(res);
  440. }
  441. res = gf_sk_get_ipv6_addr(NULL, port, af, AI_PASSIVE, type);
  442. if (!res) return GF_IP_CONNECTION_FAILURE;
  443. /*for all interfaces*/
  444. for (aip=res; aip!=NULL; aip=aip->ai_next) {
  445. if (type != (u32) aip->ai_socktype) continue;
  446. if (aip->ai_next && (aip->ai_next->ai_family==PF_INET) && !gf_net_is_ipv6(peer_name)) continue;
  447. sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
  448. if (sock->socket == INVALID_SOCKET) {
  449. sock->socket = (SOCKET)NULL;
  450. continue;
  451. }
  452. if (options & GF_SOCK_REUSE_PORT) {
  453. optval = 1;
  454. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));
  455. #ifdef SO_REUSEPORT
  456. optval = 1;
  457. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
  458. #endif
  459. }
  460. if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);
  461. ret = bind(sock->socket, aip->ai_addr, aip->ai_addrlen);
  462. if (ret == SOCKET_ERROR) {
  463. closesocket(sock->socket);
  464. sock->socket = (SOCKET)NULL;
  465. continue;
  466. }
  467. if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;
  468. else sock->flags &= ~GF_SOCK_IS_IPV6;
  469. if (peer_name && peer_port)
  470. sock->flags |= GF_SOCK_HAS_PEER;
  471. freeaddrinfo(res);
  472. return GF_OK;
  473. }
  474. freeaddrinfo(res);
  475. return GF_IP_CONNECTION_FAILURE;
  476. #else
  477. sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
  478. if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);
  479. sock->flags &= ~GF_SOCK_IS_IPV6;
  480. memset((void *) &LocalAdd, 0, sizeof(LocalAdd));
  481. ret = gethostname(buf, GF_MAX_IP_NAME_LEN);
  482. if (ret == SOCKET_ERROR) {
  483. GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot get localhost name - socket error %x\n", LASTSOCKERROR));
  484. return GF_IP_ADDRESS_NOT_FOUND;
  485. }
  486. /*get the IP address*/
  487. Host = gethostbyname(buf);
  488. if (Host == NULL) {
  489. GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot resolve localhost name - socket error %x\n", LASTSOCKERROR));
  490. return GF_IP_ADDRESS_NOT_FOUND;
  491. }
  492. /*setup the address*/
  493. memcpy((char *) &LocalAdd.sin_addr, Host->h_addr_list[0], sizeof(LocalAdd.sin_addr));
  494. LocalAdd.sin_family = AF_INET;
  495. LocalAdd.sin_addr.s_addr = INADDR_ANY;
  496. LocalAdd.sin_port = htons(port);
  497. addrlen = sizeof(struct sockaddr_in);
  498. if (options & GF_SOCK_REUSE_PORT) {
  499. optval = 1;
  500. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval));
  501. #ifdef SO_REUSEPORT
  502. optval = 1;
  503. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
  504. #endif
  505. }
  506. /*bind the socket*/
  507. ret = bind(sock->socket, (struct sockaddr *) &LocalAdd, addrlen);
  508. if (ret == SOCKET_ERROR) {
  509. GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot bind socket - socket error %x\n", LASTSOCKERROR));
  510. return GF_IP_CONNECTION_FAILURE;
  511. }
  512. if (peer_name && peer_port) {
  513. sock->dest_addr.sin_port = htons(peer_port);
  514. sock->dest_addr.sin_family = AF_INET;
  515. sock->dest_addr.sin_addr.s_addr = inet_addr(peer_name);
  516. if (sock->dest_addr.sin_addr.s_addr == INADDR_NONE) {
  517. Host = gethostbyname(peer_name);
  518. if (Host == NULL) return GF_IP_ADDRESS_NOT_FOUND;
  519. memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32));
  520. }
  521. sock->flags |= GF_SOCK_HAS_PEER;
  522. }
  523. #endif
  524. if (sock->flags & GF_SOCK_HAS_PEER) {
  525. GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] socket bound to port %d - remote peer: %s:%d\n", port, peer_name, peer_port));
  526. } else {
  527. GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] socket bound to port %d\n", port));
  528. }
  529. return GF_OK;
  530. }
  531. //send length bytes of a buffer
  532. GF_Err gf_sk_send(GF_Socket *sock, char *buffer, u32 length)
  533. {
  534. GF_Err e;
  535. u32 Count, Res;
  536. #ifndef __SYMBIAN32__
  537. u32 ready;
  538. struct timeval timeout;
  539. fd_set Group;
  540. #endif
  541. e = GF_OK;
  542. //the socket must be bound or connected
  543. if (!sock || !sock->socket) return GF_BAD_PARAM;
  544. #ifndef __SYMBIAN32__
  545. //can we write?
  546. FD_ZERO(&Group);
  547. FD_SET(sock->socket, &Group);
  548. timeout.tv_sec = 0;
  549. timeout.tv_usec = SOCK_MICROSEC_WAIT;
  550. ready = select(sock->socket+1, NULL, &Group, NULL, &timeout);
  551. if (ready == SOCKET_ERROR) {
  552. switch (LASTSOCKERROR) {
  553. case EAGAIN:
  554. return GF_IP_SOCK_WOULD_BLOCK;
  555. default:
  556. return GF_IP_NETWORK_FAILURE;
  557. }
  558. }
  559. //should never happen (to check: is writeability is guaranteed for not-connected sockets)
  560. if (!ready || !FD_ISSET(sock->socket, &Group)) {
  561. return GF_IP_NETWORK_EMPTY;
  562. }
  563. #endif
  564. //direct writing
  565. Count = 0;
  566. while (Count < length) {
  567. if (sock->flags & GF_SOCK_HAS_PEER) {
  568. Res = sendto(sock->socket, (char *) &buffer[Count], length - Count, 0, (struct sockaddr *) &sock->dest_addr, sock->dest_addr_len);
  569. } else {
  570. Res = send(sock->socket, (char *) &buffer[Count], length - Count, 0);
  571. }
  572. if (Res == SOCKET_ERROR) {
  573. switch (Res = LASTSOCKERROR) {
  574. case EAGAIN:
  575. return GF_IP_SOCK_WOULD_BLOCK;
  576. #ifndef __SYMBIAN32__
  577. case ENOTCONN:
  578. case ECONNRESET:
  579. return GF_IP_CONNECTION_CLOSED;
  580. #endif
  581. default:
  582. return GF_IP_NETWORK_FAILURE;
  583. }
  584. }
  585. Count += Res;
  586. }
  587. return GF_OK;
  588. }
  589. u32 gf_sk_is_multicast_address(char *multi_IPAdd)
  590. {
  591. #ifdef GPAC_IPV6
  592. u32 val;
  593. char *sep;
  594. struct addrinfo *res;
  595. if (!multi_IPAdd) return 0;
  596. /*IPV6 multicast address*/
  597. sep = strchr(multi_IPAdd, ':');
  598. if (sep) sep = strchr(multi_IPAdd, ':');
  599. if (sep && !strnicmp(multi_IPAdd, "ff", 2)) return 1;
  600. /*ipv4 multicast address*/
  601. res = gf_sk_get_ipv6_addr(multi_IPAdd, 7000, AF_UNSPEC, AI_PASSIVE, SOCK_DGRAM);
  602. if (!res) return 0;
  603. val = 0;
  604. if (res->ai_addr->sa_family == AF_INET) {
  605. val = IN_MULTICAST(ntohl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr));
  606. } else if (res->ai_addr->sa_family == AF_INET6) {
  607. val = IN6_IS_ADDR_MULTICAST(& ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr);
  608. }
  609. freeaddrinfo(res);
  610. return val;
  611. #else
  612. if (!multi_IPAdd) return 0;
  613. return ((htonl(inet_addr(multi_IPAdd)) >> 8) & 0x00f00000) == 0x00e00000;
  614. #endif
  615. }
  616. GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNumber, u32 TTL, Bool NoBind, char *local_interface_ip)
  617. {
  618. s32 ret;
  619. u32 flag;
  620. struct ip_mreq M_req;
  621. u32 optval;
  622. #ifdef GPAC_IPV6
  623. struct sockaddr *addr;
  624. struct addrinfo *res, *aip;
  625. u32 type;
  626. #else
  627. u_long local_add_id;
  628. #endif
  629. if (!sock || sock->socket) return GF_BAD_PARAM;
  630. if (TTL > 255) TTL = 255;
  631. /*check the address*/
  632. if (!gf_sk_is_multicast_address(multi_IPAdd)) return GF_BAD_PARAM;
  633. #ifdef GPAC_IPV6
  634. type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM;
  635. res = gf_sk_get_ipv6_addr(local_interface_ip, MultiPortNumber, AF_UNSPEC, AI_PASSIVE, type);
  636. if (!res) {
  637. if (local_interface_ip) {
  638. res = gf_sk_get_ipv6_addr(NULL, MultiPortNumber, AF_UNSPEC, AI_PASSIVE, type);
  639. local_interface_ip = NULL;
  640. }
  641. if (!res) return GF_IP_CONNECTION_FAILURE;
  642. }
  643. /*for all interfaces*/
  644. for (aip=res; aip!=NULL; aip=aip->ai_next) {
  645. if (type != (u32) aip->ai_socktype) continue;
  646. sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
  647. if (sock->socket == INVALID_SOCKET) {
  648. sock->socket = (SOCKET)NULL;
  649. continue;
  650. }
  651. if (aip->ai_next && (aip->ai_next->ai_family==PF_INET) && !gf_net_is_ipv6(multi_IPAdd)) continue;
  652. /*enable address reuse*/
  653. optval = 1;
  654. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));
  655. #ifdef SO_REUSEPORT
  656. optval = 1;
  657. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
  658. #endif
  659. /*TODO: copy over other properties (recption buffer size & co)*/
  660. if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);
  661. memcpy(&sock->dest_addr, aip->ai_addr, aip->ai_addrlen);
  662. sock->dest_addr_len = aip->ai_addrlen;
  663. if (!NoBind) {
  664. ret = bind(sock->socket, aip->ai_addr, aip->ai_addrlen);
  665. if (ret == SOCKET_ERROR) {
  666. closesocket(sock->socket);
  667. sock->socket = (SOCKET)NULL;
  668. continue;
  669. }
  670. }
  671. if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6;
  672. else sock->flags &= ~GF_SOCK_IS_IPV6;
  673. break;
  674. }
  675. freeaddrinfo(res);
  676. if (!sock->socket) return GF_IP_CONNECTION_FAILURE;
  677. if (!gf_sk_ipv6_set_remote_address(sock, multi_IPAdd, MultiPortNumber))
  678. return GF_IP_CONNECTION_FAILURE;
  679. addr = (struct sockaddr *)&sock->dest_addr;
  680. if (addr->sa_family == AF_INET) {
  681. M_req.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
  682. M_req.imr_interface.s_addr = INADDR_ANY;
  683. ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req));
  684. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  685. /*set TTL*/
  686. ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &TTL, sizeof(TTL));
  687. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  688. /*Disable loopback*/
  689. flag = 1;
  690. ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag));
  691. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  692. }
  693. if (addr->sa_family == AF_INET6) {
  694. struct ipv6_mreq M_reqV6;
  695. memcpy(&M_reqV6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
  696. M_reqV6.ipv6mr_interface = 0;
  697. /*set TTL*/
  698. ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &TTL, sizeof(TTL));
  699. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  700. /*Disable loopback*/
  701. flag = 1;
  702. ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &flag, sizeof(flag));
  703. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  704. ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &M_reqV6, sizeof(M_reqV6));
  705. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  706. }
  707. #else
  708. sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0);
  709. if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1);
  710. sock->flags &= ~GF_SOCK_IS_IPV6;
  711. /*enable address reuse*/
  712. optval = 1;
  713. ret = setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval));
  714. #ifdef SO_REUSEPORT
  715. optval = 1;
  716. setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval));
  717. #endif
  718. if (local_interface_ip) local_add_id = inet_addr(local_interface_ip);
  719. else local_add_id = htonl(INADDR_ANY);
  720. if (!NoBind) {
  721. struct sockaddr_in local_address;
  722. local_address.sin_family = AF_INET;
  723. local_address.sin_addr.s_addr = local_add_id;
  724. local_address.sin_port = htons( MultiPortNumber);
  725. ret = bind(sock->socket, (struct sockaddr *) &local_address, sizeof(local_address));
  726. if (ret == SOCKET_ERROR) {
  727. /*retry without specifying the local add*/
  728. local_address.sin_addr.s_addr = local_add_id = htonl(INADDR_ANY);
  729. local_interface_ip = NULL;
  730. ret = bind(sock->socket, (struct sockaddr *) &local_address, sizeof(local_address));
  731. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  732. }
  733. /*setup local interface*/
  734. if (local_interface_ip) {
  735. ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_IF, (char *) &local_add_id, sizeof(local_add_id));
  736. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  737. }
  738. }
  739. /*now join the multicast*/
  740. M_req.imr_multiaddr.s_addr = inet_addr(multi_IPAdd);
  741. M_req.imr_interface.s_addr = local_add_id;
  742. ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req));
  743. if (ret == SOCKET_ERROR) {
  744. GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] cannot join multicast: error %d\n", LASTSOCKERROR));
  745. return GF_IP_CONNECTION_FAILURE;
  746. }
  747. /*set the Time To Live*/
  748. ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&TTL, sizeof(TTL));
  749. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  750. /*Disable loopback*/
  751. flag = 1;
  752. ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag));
  753. if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE;
  754. sock->dest_addr.sin_family = AF_INET;
  755. sock->dest_addr.sin_addr.s_addr = M_req.imr_multiaddr.s_addr;
  756. sock->dest_addr.sin_port = htons( MultiPortNumber);
  757. #endif
  758. sock->flags |= GF_SOCK_IS_MULTICAST | GF_SOCK_HAS_PEER;
  759. return GF_OK;
  760. }
  761. //fetch nb bytes on a socket and fill the buffer from startFrom
  762. //length is the allocated size of the receiving buffer
  763. //BytesRead is the number of bytes read from the network
  764. GF_Err gf_sk_receive(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u32 *BytesRead)
  765. {
  766. GF_Err e;
  767. u32 res;
  768. #ifndef __SYMBIAN32__
  769. u32 ready;
  770. struct timeval timeout;
  771. fd_set Group;
  772. #endif
  773. e = GF_OK;
  774. *BytesRead = 0;
  775. if (!sock->socket) {
  776. assert(0);
  777. return GF_BAD_PARAM;
  778. }
  779. if (startFrom >= length) {
  780. assert(0);
  781. return GF_IO_ERR;
  782. }
  783. #ifndef __SYMBIAN32__
  784. //can we read?
  785. FD_ZERO(&Group);
  786. FD_SET(sock->socket, &Group);
  787. timeout.tv_sec = 0;
  788. timeout.tv_usec = SOCK_MICROSEC_WAIT;
  789. res = 0;
  790. ready = select(sock->socket+1, &Group, NULL, NULL, &timeout);
  791. if (ready == SOCKET_ERROR) {
  792. switch (LASTSOCKERROR) {
  793. case EAGAIN:
  794. return GF_IP_SOCK_WOULD_BLOCK;
  795. default:
  796. GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot select (error %d)\n", LASTSOCKERROR));
  797. return GF_IP_NETWORK_FAILURE;
  798. }
  799. }
  800. if (!FD_ISSET(sock->socket, &Group)) {
  801. GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] nothing to be read\n"));
  802. return GF_IP_NETWORK_EMPTY;
  803. }
  804. #endif
  805. if (sock->flags & GF_SOCK_HAS_PEER)
  806. res = recvfrom(sock->socket, (char *) buffer + startFrom, length - startFrom, 0, (struct sockaddr *)&sock->dest_addr, &sock->dest_addr_len);
  807. else
  808. res = recv(sock->socket, (char *) buffer + startFrom, length - startFrom, 0);
  809. if (res == SOCKET_ERROR) {
  810. res = LASTSOCKERROR;
  811. GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] error reading - socket error %d\n", res));
  812. switch (res) {
  813. case EAGAIN:
  814. return GF_IP_SOCK_WOULD_BLOCK;
  815. #ifndef __SYMBIAN32__
  816. case EMSGSIZE:
  817. return GF_OUT_OF_MEM;
  818. case ENOTCONN:
  819. case ECONNRESET:
  820. case ECONNABORTED:
  821. return GF_IP_CONNECTION_CLOSED;
  822. #endif
  823. default:
  824. return GF_IP_NETWORK_FAILURE;
  825. }
  826. }
  827. if (!res) return GF_IP_NETWORK_EMPTY;
  828. *BytesRead = res;
  829. return GF_OK;
  830. }
  831. GF_Err gf_sk_listen(GF_Socket *sock, u32 MaxConnection)
  832. {
  833. s32 i;
  834. if (!sock || !sock->socket) return GF_BAD_PARAM;
  835. if (MaxConnection >= SOMAXCONN) MaxConnection = SOMAXCONN;
  836. i = listen(sock->socket, MaxConnection);
  837. if (i == SOCKET_ERROR) return GF_IP_NETWORK_FAILURE;
  838. sock->flags |= GF_SOCK_IS_LISTENING;
  839. return GF_OK;
  840. }
  841. GF_Err gf_sk_accept(GF_Socket *sock, GF_Socket **newConnection)
  842. {
  843. u32 client_address_size, res;
  844. SOCKET sk;
  845. #ifndef __SYMBIAN32__
  846. u32 ready;
  847. struct timeval timeout;
  848. fd_set Group;
  849. #endif
  850. *newConnection = NULL;
  851. if (!sock || !(sock->flags & GF_SOCK_IS_LISTENING) ) return GF_BAD_PARAM;
  852. #ifndef __SYMBIAN32__
  853. //can we read?
  854. FD_ZERO(&Group);
  855. FD_SET(sock->socket, &Group);
  856. timeout.tv_sec = 0;
  857. timeout.tv_usec = SOCK_MICROSEC_WAIT;
  858. res = 0;
  859. ready = select(sock->socket, &Group, NULL, NULL, &timeout);
  860. if (ready == SOCKET_ERROR) {
  861. switch (LASTSOCKERROR) {
  862. case EAGAIN:
  863. return GF_IP_SOCK_WOULD_BLOCK;
  864. default:
  865. return GF_IP_NETWORK_FAILURE;
  866. }
  867. }
  868. if (!ready || !FD_ISSET(sock->socket, &Group)) return GF_IP_NETWORK_EMPTY;
  869. #endif
  870. #ifdef GPAC_IPV6
  871. client_address_size = sizeof(struct sockaddr_in6);
  872. #else
  873. client_address_size = sizeof(struct sockaddr_in);
  874. #endif
  875. sk = accept(sock->socket, (struct sockaddr *) &sock->dest_addr, &client_address_size);
  876. //we either have an error or we have no connections
  877. if (sk == INVALID_SOCKET) {
  878. // if (sock->flags & GF_SOCK_NON_BLOCKING) return GF_IP_NETWORK_FAILURE;
  879. switch (LASTSOCKERROR) {
  880. case EAGAIN:
  881. return GF_IP_SOCK_WOULD_BLOCK;
  882. default:
  883. return GF_IP_NETWORK_FAILURE;
  884. }
  885. }
  886. (*newConnection) = (GF_Socket *) malloc(sizeof(GF_Socket));
  887. (*newConnection)->socket = sk;
  888. (*newConnection)->flags = sock->flags & ~GF_SOCK_IS_LISTENING;
  889. #ifdef GPAC_IPV6
  890. memcpy( &(*newConnection)->dest_addr, &sock->dest_addr, client_address_size);
  891. memset(&sock->dest_addr, 0, sizeof(struct sockaddr_in6));
  892. #else
  893. memcpy( &(*newConnection)->dest_addr, &sock->dest_addr, client_address_size);
  894. memset(&sock->dest_addr, 0, sizeof(struct sockaddr_in));
  895. #endif
  896. (*newConnection)->dest_addr_len = client_address_size;
  897. return GF_OK;
  898. }
  899. GF_Err gf_sk_get_local_info(GF_Socket *sock, u16 *Port, u32 *Familly)
  900. {
  901. #ifdef GPAC_IPV6
  902. struct sockaddr_in6 the_add;
  903. #else
  904. struct sockaddr_in the_add;
  905. #endif
  906. u32 size;
  907. if (!sock || !sock->socket) return GF_BAD_PARAM;
  908. if (Port) {
  909. #ifdef GPAC_IPV6
  910. size = sizeof(struct sockaddr_in6);
  911. if (getsockname(sock->socket, (struct sockaddr *) &the_add, &size) == SOCKET_ERROR) return GF_IP_NETWORK_FAILURE;
  912. *Port = (u32) ntohs(the_add.sin6_port);
  913. #else
  914. size = sizeof(struct sockaddr_in);
  915. if (getsockname(sock->socket, (struct sockaddr *) &the_add, &size) == SOCKET_ERROR) return GF_IP_NETWORK_FAILURE;
  916. *Port = (u32) ntohs(the_add.sin_port);
  917. #endif
  918. }
  919. if (Familly) {
  920. /* size = 4;
  921. if (getsockopt(sock->socket, SOL_SOCKET, SO_TYPE, (char *) &fam, &size) == SOCKET_ERROR)
  922. return GF_IP_NETWORK_FAILURE;
  923. *Familly = fam;
  924. */
  925. if (sock->flags & GF_SOCK_IS_TCP) *Familly = GF_SOCK_TYPE_TCP;
  926. else *Familly = GF_SOCK_TYPE_UDP;
  927. }
  928. return GF_OK;
  929. }
  930. //we have to do this for the server sockets as we use only one thread
  931. GF_Err gf_sk_server_mode(GF_Socket *sock, Bool serverOn)
  932. {
  933. u32 one;
  934. if (!sock || !(sock->flags & GF_SOCK_IS_TCP) || !sock->socket)
  935. return GF_BAD_PARAM;
  936. one = serverOn ? 1 : 0;
  937. setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, SSO_CAST &one, sizeof(u32));
  938. #ifndef __SYMBIAN32__
  939. setsockopt(sock->socket, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(u32));
  940. #endif
  941. return GF_OK;
  942. }
  943. GF_Err gf_sk_get_remote_address(GF_Socket *sock, char *buf)
  944. {
  945. #ifdef GPAC_IPV6
  946. char clienthost[NI_MAXHOST];
  947. struct sockaddr_in6 * addrptr = (struct sockaddr_in6 *)(&sock->dest_addr_len);
  948. if (!sock || sock->socket) return GF_BAD_PARAM;
  949. if (getnameinfo((struct sockaddr *)addrptr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST))
  950. return GF_IP_ADDRESS_NOT_FOUND;
  951. strcpy(buf, clienthost);
  952. #else
  953. if (!sock || !sock->socket) return GF_BAD_PARAM;
  954. strcpy(buf, inet_ntoa(sock->dest_addr.sin_addr));
  955. #endif
  956. return GF_OK;
  957. }
  958. //send length bytes of a buffer
  959. GF_Err gf_sk_send_to(GF_Socket *sock, char *buffer, u32 length, char *remoteHost, u16 remotePort)
  960. {
  961. u32 Count, Res, remote_add_len;
  962. #ifdef GPAC_IPV6
  963. struct sockaddr_storage remote_add;
  964. #else
  965. struct sockaddr_in remote_add;
  966. struct hostent *Host;
  967. #endif
  968. #ifndef __SYMBIAN32__
  969. u32 ready;
  970. struct timeval timeout;
  971. fd_set Group;
  972. #endif
  973. //the socket must be bound or connected
  974. if (!sock || !sock->socket) return GF_BAD_PARAM;
  975. if (remoteHost && !remotePort) return GF_BAD_PARAM;
  976. #ifndef __SYMBIAN32__
  977. //can we write?
  978. FD_ZERO(&Group);
  979. FD_SET(sock->socket, &Group);
  980. timeout.tv_sec = 0;
  981. timeout.tv_usec = SOCK_MICROSEC_WAIT;
  982. ready = select(sock->socket+1, NULL, &Group, NULL, &timeout);
  983. if (ready == SOCKET_ERROR) {
  984. switch (LASTSOCKERROR) {
  985. case EAGAIN:
  986. return GF_IP_SOCK_WOULD_BLOCK;
  987. default:
  988. return GF_IP_NETWORK_FAILURE;
  989. }
  990. }
  991. if (!ready || !FD_ISSET(sock->socket, &Group)) return GF_IP_NETWORK_EMPTY;
  992. #endif
  993. /*setup the address*/
  994. #ifdef GPAC_IPV6
  995. remote_add.ss_family = AF_INET6;
  996. //if a remote host is specified, use it. Otherwise use the default host
  997. if (remoteHost) {
  998. //setup the address
  999. struct addrinfo *res = gf_sk_get_ipv6_addr(remoteHost, remotePort, AF_UNSPEC, 0, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM);
  1000. if (!res) return GF_IP_ADDRESS_NOT_FOUND;
  1001. memcpy(&remote_add, res->ai_addr, res->ai_addrlen);
  1002. remote_add_len = res->ai_addrlen;
  1003. freeaddrinfo(res);
  1004. } else {
  1005. struct sockaddr_in6 *remotePtr = (struct sockaddr_in6 *)&remote_add;
  1006. struct sockaddr_in6 * addrptr = (struct sockaddr_in6 *)(&sock->dest_addr);
  1007. remotePtr->sin6_port = addrptr->sin6_port;
  1008. remotePtr->sin6_addr = addrptr->sin6_addr;
  1009. remote_add_len = sock->dest_addr_len;
  1010. }
  1011. #else
  1012. remote_add_len = sizeof(struct sockaddr_in);
  1013. remote_add.sin_family = AF_INET;
  1014. //if a remote host is specified, use it. Otherwise use the default host
  1015. if (remoteHost) {
  1016. //setup the address
  1017. remote_add.sin_port = htons(remotePort);
  1018. //get the server IP
  1019. Host = gethostbyname(remoteHost);
  1020. if (Host == NULL) return GF_IP_ADDRESS_NOT_FOUND;
  1021. memcpy((char *) &remote_add.sin_addr, Host->h_addr_list[0], sizeof(u32));
  1022. } else {
  1023. remote_add.sin_port = sock->dest_addr.sin_port;
  1024. remote_add.sin_addr.s_addr = sock->dest_addr.sin_addr.s_addr;
  1025. }
  1026. #endif
  1027. Count = 0;
  1028. while (Count < length) {
  1029. Res = sendto(sock->socket, (char *) &buffer[Count], length - Count, 0, (struct sockaddr *) &remote_add, remote_add_len);
  1030. if (Res == SOCKET_ERROR) {
  1031. switch (LASTSOCKERROR) {
  1032. case EAGAIN:
  1033. return GF_IP_SOCK_WOULD_BLOCK;
  1034. default:
  1035. return GF_IP_NETWORK_FAILURE;
  1036. }
  1037. }
  1038. Count += Res;
  1039. }
  1040. return GF_OK;
  1041. }
  1042. GF_Err gf_sk_receive_wait(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u32 *BytesRead, u32 Second )
  1043. {
  1044. GF_Err e;
  1045. u32 res;
  1046. #ifndef __SYMBIAN32__
  1047. u32 ready;
  1048. struct timeval timeout;
  1049. fd_set Group;
  1050. #endif
  1051. e = GF_OK;
  1052. *BytesRead = 0;
  1053. if (startFrom >= length) return GF_OK;
  1054. #ifndef __SYMBIAN32__
  1055. //can we read?
  1056. FD_ZERO(&Group);
  1057. FD_SET(sock->socket, &Group);
  1058. timeout.tv_sec = Second;
  1059. timeout.tv_usec = SOCK_MICROSEC_WAIT;
  1060. res = 0;
  1061. ready = select(sock->socket+1, &Group, NULL, NULL, &timeout);
  1062. if (ready == SOCKET_ERROR) {
  1063. switch (LASTSOCKERROR) {
  1064. case EAGAIN:
  1065. return GF_IP_SOCK_WOULD_BLOCK;
  1066. default:
  1067. return GF_IP_NETWORK_FAILURE;
  1068. }
  1069. }
  1070. if (!FD_ISSET(sock->socket, &Group)) {
  1071. return GF_IP_NETWORK_EMPTY;
  1072. }
  1073. #endif
  1074. res = recv(sock->socket, (char *) buffer + startFrom, length - startFrom, 0);
  1075. if (res == SOCKET_ERROR) {
  1076. switch (LASTSOCKERROR) {
  1077. case EAGAIN:
  1078. return GF_IP_SOCK_WOULD_BLOCK;
  1079. default:
  1080. return GF_IP_NETWORK_FAILURE;
  1081. }
  1082. }
  1083. *BytesRead = res;
  1084. return GF_OK;
  1085. }
  1086. //send length bytes of a buffer
  1087. GF_Err gf_sk_send_wait(GF_Socket *sock, char *buffer, u32 length, u32 Second )
  1088. {
  1089. GF_Err e;
  1090. u32 Count, Res;
  1091. #ifndef __SYMBIAN32__
  1092. u32 ready;
  1093. struct timeval timeout;
  1094. fd_set Group;
  1095. #endif
  1096. e = GF_OK;
  1097. //the socket must be bound or connected
  1098. if (!sock || !sock->socket) return GF_BAD_PARAM;
  1099. #ifndef __SYMBIAN32__
  1100. //can we write?
  1101. FD_ZERO(&Group);
  1102. FD_SET(sock->socket, &Group);
  1103. timeout.tv_sec = Second;
  1104. timeout.tv_usec = SOCK_MICROSEC_WAIT;
  1105. ready = select(sock->socket+1, NULL, &Group, NULL, &timeout);
  1106. if (ready == SOCKET_ERROR) {
  1107. switch (LASTSOCKERROR) {
  1108. case EAGAIN:
  1109. return GF_IP_SOCK_WOULD_BLOCK;
  1110. default:
  1111. return GF_IP_NETWORK_FAILURE;
  1112. }
  1113. }
  1114. //should never happen (to check: is writeability is guaranteed for not-connected sockets)
  1115. if (!ready || !FD_ISSET(sock->socket, &Group)) {
  1116. return GF_IP_NETWORK_EMPTY;
  1117. }
  1118. #endif
  1119. //direct writing
  1120. Count = 0;
  1121. while (Count < length) {
  1122. Res = send(sock->socket, (char *) &buffer[Count], length - Count, 0);
  1123. if (Res == SOCKET_ERROR) {
  1124. switch (LASTSOCKERROR) {
  1125. case EAGAIN:
  1126. return GF_IP_SOCK_WOULD_BLOCK;
  1127. #ifndef __SYMBIAN32__
  1128. case ECONNRESET:
  1129. return GF_IP_CONNECTION_CLOSED;
  1130. #endif
  1131. default:
  1132. return GF_IP_NETWORK_FAILURE;
  1133. }
  1134. }
  1135. Count += Res;
  1136. }
  1137. return GF_OK;
  1138. }
  1139. #if 0
  1140. //Socket Group for select(). The group is a collection of sockets ready for reading / writing
  1141. typedef struct __tag_sock_group
  1142. {
  1143. //the max time value before a select returns
  1144. struct timeval timeout;
  1145. fd_set ReadGroup;
  1146. fd_set WriteGroup;
  1147. } GF_SocketGroup;
  1148. #define GF_SOCK_GROUP_READ 0
  1149. #define GF_SOCK_GROUP_WRITE 1
  1150. GF_SocketGroup *NewSockGroup()
  1151. {
  1152. GF_SocketGroup *tmp = (GF_SocketGroup*)malloc(sizeof(GF_SocketGroup));
  1153. if (!tmp) return NULL;
  1154. FD_ZERO(&tmp->ReadGroup);
  1155. FD_ZERO(&tmp->WriteGroup);
  1156. return tmp;
  1157. }
  1158. void SKG_Delete(GF_SocketGroup *group)
  1159. {
  1160. free(group);
  1161. }
  1162. void SKG_SetWatchTime(GF_SocketGroup *group, u32 DelayInS, u32 DelayInMicroS)
  1163. {
  1164. group->timeout.tv_sec = DelayInS;
  1165. group->timeout.tv_usec = DelayInMicroS;
  1166. }
  1167. void SKG_AddSocket(GF_SocketGroup *group, GF_Socket *sock, u32 GroupType)
  1168. {
  1169. switch (GroupType) {
  1170. case GF_SOCK_GROUP_READ:
  1171. FD_SET(sock->socket, &group->ReadGroup);
  1172. return;
  1173. case GF_SOCK_GROUP_WRITE:
  1174. FD_SET(sock->socket, &group->WriteGroup);
  1175. return;
  1176. default:
  1177. return;
  1178. }
  1179. }
  1180. void SKG_RemoveSocket(GF_SocketGroup *group, GF_Socket *sock, u32 GroupType)
  1181. {
  1182. switch (GroupType) {
  1183. case GF_SOCK_GROUP_READ:
  1184. FD_CLR(sock->socket, &group->ReadGroup);
  1185. return;
  1186. case GF_SOCK_GROUP_WRITE:
  1187. FD_CLR(sock->socket, &group->WriteGroup);
  1188. return;
  1189. default:
  1190. return;
  1191. }
  1192. }
  1193. Bool SKG_IsSocketIN(GF_SocketGroup *group, GF_Socket *sock, u32 GroupType)
  1194. {
  1195. switch (GroupType) {
  1196. case GF_SOCK_GROUP_READ:
  1197. if (FD_ISSET(sock->socket, &group->ReadGroup)) return 1;
  1198. return 0;
  1199. case GF_SOCK_GROUP_WRITE:
  1200. if (FD_ISSET(sock->socket, &group->WriteGroup)) return 1;
  1201. return 0;
  1202. default:
  1203. return 0;
  1204. }
  1205. }
  1206. u32 SKG_Select(GF_SocketGroup *group)
  1207. {
  1208. u32 ready, rien = 0;
  1209. ready = select(rien, &group->ReadGroup, &group->WriteGroup, NULL, &group->timeout);
  1210. if (ready == SOCKET_ERROR) return 0;
  1211. return ready;
  1212. }
  1213. #endif