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_ipv6_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_ipv6_set_local(URLContext *h) { UDPContext *s = h->priv_data; int udp_fd = -1; struct sockaddr_storage clientaddr; socklen_t addrlen; char sbuf[NI_MAXSERV]; char hbuf[NI_MAXHOST]; struct addrinfo *res0 = NULL, *res = NULL; if (s->local_port != 0) { res0 = udp_ipv6_resolve_host(0, s->local_port, SOCK_DGRAM, AF_UNSPEC, 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; perror("socket"); } } else { udp_fd = socket(s->dest_addr.ss_family, SOCK_DGRAM, 0); if (udp_fd < 0) perror("socket"); } if (udp_fd < 0) goto fail; if (s->local_port != 0) { if (bind(udp_fd, res0->ai_addr, res0->ai_addrlen) < 0) { perror("bind"); goto fail; } freeaddrinfo(res0); res0 = NULL; } addrlen = sizeof(clientaddr); if (getsockname(udp_fd, (struct sockaddr *)&clientaddr, &addrlen) < 0) { perror("getsockname"); goto fail; } if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) { perror("getnameinfo"); goto fail; } s->local_port = strtol(sbuf, NULL, 10); 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_ipv6_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; }
int udp_ipv6_set_remote_url(URLContext *h, const char *uri) { UDPContext *s = h->priv_data; char hostname[256]; int port; struct addrinfo *res0; url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); res0 = udp_ipv6_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); if (res0 == 0) return AVERROR_IO; memcpy(&s->dest_addr, res0->ai_addr, res0->ai_addrlen); s->dest_addr_len = res0->ai_addrlen; freeaddrinfo(res0); return 0; }