static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr, int *addr_len) { int udp_fd = -1; struct addrinfo *res0 = NULL, *res = NULL; int family = AF_UNSPEC; if (((struct sockaddr *) &s->dest_addr)->sa_family) family = ((struct sockaddr *) &s->dest_addr)->sa_family; res0 = udp_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); if (res0 == 0) goto fail; for (res = res0; res; res=res->ai_next) { udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); if (udp_fd > 0) break; av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno)); } if (udp_fd < 0) goto fail; memcpy(addr, res->ai_addr, res->ai_addrlen); *addr_len = res->ai_addrlen; freeaddrinfo(res0); return udp_fd; fail: if (udp_fd >= 0) closesocket(udp_fd); if(res0) freeaddrinfo(res0); return -1; }
static int udp_socket_create(int local_port, struct sockaddr_storage *addr, socklen_t *addr_len, const char *localaddr) { int udp_fd = -1; struct addrinfo *res0 = NULL, *res = NULL; int family = AF_UNSPEC; res0 = udp_resolve_host(localaddr[0] ? localaddr : NULL, local_port, SOCK_DGRAM, family, AI_PASSIVE); if (res0 == 0) goto fail; for (res = res0; res; res=res->ai_next) { udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); if (udp_fd != -1) break; log_net_error(NULL, AV_LOG_ERROR, "socket"); } if (udp_fd < 0) goto fail; memcpy(addr, res->ai_addr, res->ai_addrlen); *addr_len = res->ai_addrlen; freeaddrinfo(res0); return udp_fd; fail: if (udp_fd >= 0) closesocket(udp_fd); if(res0) freeaddrinfo(res0); return -1; }
static int udp_set_url(struct sockaddr_storage *addr, const char *hostname, int port) { struct addrinfo *res0; int addr_len; res0 = udp_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); if (res0 == 0) return AVERROR(EIO); memcpy(addr, res0->ai_addr, res0->ai_addrlen); addr_len = res0->ai_addrlen; freeaddrinfo(res0); return addr_len; }
static int udp_set_url(struct sockaddr_storage *addr, const char *hostname, int port) { struct addrinfo *res0; int addr_len; int family = AF_UNSPEC; if(am_getconfig_bool_def("media.libplayer.ipv4only",1)) family = AF_INET; res0 = udp_resolve_host(hostname, port, SOCK_DGRAM, family, 0); if (res0 == 0) return AVERROR(EIO); memcpy(addr, res0->ai_addr, res0->ai_addrlen); addr_len = res0->ai_addrlen; freeaddrinfo(res0); return addr_len; }
static int udp_socket_create(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len, const char *localaddr) { UDPContext *s = h->priv_data; int udp_fd = -1; struct addrinfo *res0, *res; int family = AF_UNSPEC; if (((struct sockaddr *) &s->dest_addr)->sa_family) family = ((struct sockaddr *) &s->dest_addr)->sa_family; res0 = udp_resolve_host(h, (localaddr && localaddr[0]) ? localaddr : NULL, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); if (!res0) goto fail; for (res = res0; res; res=res->ai_next) { if (s->udplite_coverage) udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, IPPROTO_UDPLITE); else udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0); if (udp_fd != -1) break; log_net_error(NULL, AV_LOG_ERROR, "socket"); } if (udp_fd < 0) goto fail; memcpy(addr, res->ai_addr, res->ai_addrlen); *addr_len = res->ai_addrlen; freeaddrinfo(res0); return udp_fd; fail: if (udp_fd >= 0) closesocket(udp_fd); if(res0) freeaddrinfo(res0); return -1; }
static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr, int addr_len, char **sources, int nb_sources, int include) { #if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32) /* These ones are available in the microsoft SDK, but don't seem to work * as on linux, so just prefer the v4-only approach there for now. */ int i; for (i = 0; i < nb_sources; i++) { struct group_source_req mreqs; int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0, SOCK_DGRAM, AF_UNSPEC, 0); if (!sourceaddr) return AVERROR(ENOENT); mreqs.gsr_interface = 0; memcpy(&mreqs.gsr_group, addr, addr_len); memcpy(&mreqs.gsr_source, sourceaddr->ai_addr, sourceaddr->ai_addrlen); freeaddrinfo(sourceaddr); if (setsockopt(sockfd, level, include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE, (const void *)&mreqs, sizeof(mreqs)) < 0) { if (include) log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)"); else log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)"); return ff_neterrno(); } } #elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE) int i; if (addr->sa_family != AF_INET) { av_log(NULL, AV_LOG_ERROR, "Setting multicast sources only supported for IPv4\n"); return AVERROR(EINVAL); } for (i = 0; i < nb_sources; i++) { struct ip_mreq_source mreqs; struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0, SOCK_DGRAM, AF_UNSPEC, 0); if (!sourceaddr) return AVERROR(ENOENT); if (sourceaddr->ai_addr->sa_family != AF_INET) { freeaddrinfo(sourceaddr); av_log(NULL, AV_LOG_ERROR, "%s is of incorrect protocol family\n", sources[i]); return AVERROR(EINVAL); } mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; mreqs.imr_interface.s_addr = INADDR_ANY; mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)sourceaddr->ai_addr)->sin_addr.s_addr; freeaddrinfo(sourceaddr); if (setsockopt(sockfd, IPPROTO_IP, include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE, (const void *)&mreqs, sizeof(mreqs)) < 0) { if (include) log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)"); else log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)"); return ff_neterrno(); } } #else return AVERROR(ENOSYS); #endif return 0; }
static int udp_set_multicast_opts( int sockfd, obe_udp_ctx *s ) { struct sockaddr *addr = (struct sockaddr *)&s->dest_addr; if( addr->sa_family == AF_INET ) { #ifdef IP_MULTICAST_TTL if( setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &s->ttl, sizeof(s->ttl) ) < 0 ) { fprintf( stderr, "[udp] Could not setup IPv4 multicast\n" ); return -1; } #endif #ifdef IP_MULTICAST_IF struct ip_mreqn req = { .imr_ifindex = s->miface }; if( setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_IF, &req, sizeof(req) ) < 0 ) { fprintf( stderr, "[udp] Could not setup multicast interface\n" ); return -1; } #endif } #ifdef IPPROTO_IPV6 if( addr->sa_family == AF_INET6 ) { #ifdef IPV6_MULTICAST_HOPS if( setsockopt( sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &s->ttl, sizeof(s->ttl) ) < 0 ) { fprintf( stderr, "[udp] Could not setup IPv6 multicast\n" ); return -1; } #endif #ifdef IPV6_MULTICAST_IF if( setsockopt( sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &s->miface, sizeof(s->miface) ) < 0 ) { fprintf( stderr, "[udp] Could not setup IPv6 multicast interface\n" ); return -1; } #endif } #endif return 0; } static struct addrinfo* udp_resolve_host( const char *hostname, int port, int type, int family, int flags ) { struct addrinfo hints, *res = 0; int error; char sport[16]; const char *node = 0, *service = "0"; if( port > 0 ) { snprintf( sport, sizeof(sport), "%d", port ); service = sport; } if( (hostname) && (hostname[0] != '\0') && (hostname[0] != '?') ) node = hostname; memset( &hints, 0, sizeof(hints) ); hints.ai_socktype = type; hints.ai_family = family; hints.ai_flags = flags; if( (error = getaddrinfo( node, service, &hints, &res )) ) { res = NULL; fprintf( stderr, "[udp] error: %s \n", gai_strerror( error ) ); } return res; } static int udp_set_url( struct sockaddr_storage *addr, const char *hostname, int port ) { struct addrinfo *res0; int addr_len; res0 = udp_resolve_host( hostname, port, SOCK_DGRAM, AF_UNSPEC, 0 ); if( res0 == 0 ) return -1; memcpy( addr, res0->ai_addr, res0->ai_addrlen ); addr_len = res0->ai_addrlen; freeaddrinfo( res0 ); return addr_len; } static int udp_socket_create( obe_udp_ctx *s, struct sockaddr_storage *addr, int *addr_len ) { int udp_fd = -1; struct addrinfo *res0 = NULL, *res = NULL; int family = AF_UNSPEC; if( ((struct sockaddr *) &s->dest_addr)->sa_family ) family = ((struct sockaddr *) &s->dest_addr)->sa_family; res0 = udp_resolve_host( 0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE ); if( res0 == 0 ) goto fail; for( res = res0; res; res=res->ai_next ) { udp_fd = socket( res->ai_family, SOCK_DGRAM, 0 ); if( udp_fd > 0 ) break; // TODO error } if( udp_fd < 0 ) goto fail; memcpy( addr, res->ai_addr, res->ai_addrlen ); *addr_len = res->ai_addrlen; freeaddrinfo( res0 ); return udp_fd; fail: if( udp_fd >= 0 ) close( udp_fd ); if( res0 ) freeaddrinfo( res0 ); return -1; }