/src/utils/os_net.c

https://github.com/svettom/gpac · C · 1536 lines · 1216 code · 202 blank · 118 comment · 330 complexity · c7265c06e0a263b9b80d685678a1330f MD5 · raw file

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