} UDPContext;
#define UDP_TX_BUF_SIZE 32768
+#define UDP_MAX_PKT_SIZE 65536
#ifdef CONFIG_IPV6
-static int udp_ipv6_is_multicast_address(const struct sockaddr *addr) {
- if (addr->sa_family == AF_INET)
- return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
- if (addr->sa_family == AF_INET6)
- return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
- return -1;
-}
-
static int udp_ipv6_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) {
if (addr->sa_family == AF_INET) {
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
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;
+ if (res0 == 0) return AVERROR(EIO);
memcpy(&s->dest_addr, res0->ai_addr, res0->ai_addrlen);
s->dest_addr_len = res0->ai_addrlen;
freeaddrinfo(res0);
return -1;
}
-#endif
+#endif /* CONFIG_IPV6 */
/**
/* set the destination address */
if (resolve_host(&s->dest_addr.sin_addr, hostname) < 0)
- return AVERROR_IO;
+ return AVERROR(EIO);
s->dest_addr.sin_family = AF_INET;
s->dest_addr.sin_port = htons(port);
return 0;
udp_set_remote_url(h, uri);
}
+ if(!ff_network_init())
+ return AVERROR(EIO);
+
#ifndef CONFIG_IPV6
udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_fd < 0)
goto fail;
}
}
-#endif
+#endif /* CONFIG_IPV6 */
if (is_output) {
/* limit the tx buf size to limit latency */
perror("setsockopt sndbuf");
goto fail;
}
+ } else {
+ /* set udp recv buffer size to the largest possible udp packet size to
+ * avoid losing data on OSes that set this too low by default. */
+ tmp = UDP_MAX_PKT_SIZE;
+ setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp));
}
s->udp_fd = udp_fd;
if (udp_fd >= 0)
closesocket(udp_fd);
av_free(s);
- return AVERROR_IO;
+ return AVERROR(EIO);
}
static int udp_read(URLContext *h, uint8_t *buf, int size)
len = recvfrom (s->udp_fd, buf, size, 0,
(struct sockaddr *)&from, &from_len);
if (len < 0) {
- if (errno != EAGAIN && errno != EINTR)
- return AVERROR_IO;
+ if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+ ff_neterrno() != FF_NETERROR(EINTR))
+ return AVERROR(EIO);
} else {
break;
}
s->dest_addr_len);
#endif
if (ret < 0) {
- if (errno != EINTR && errno != EAGAIN)
- return AVERROR_IO;
+ if (ff_neterrno() != FF_NETERROR(EINTR) &&
+ ff_neterrno() != FF_NETERROR(EAGAIN))
+ return AVERROR(EIO);
} else {
break;
}
udp_ipv6_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
#endif
closesocket(s->udp_fd);
+ ff_network_close();
av_free(s);
return 0;
}