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