57
55
#define UDP_TX_BUF_SIZE 32768
58
56
#define UDP_MAX_PKT_SIZE 65536
58
static void log_net_error(void *ctx, int level, const char* prefix)
61
av_strerror(ff_neterrno(), errbuf, sizeof(errbuf));
62
av_log(ctx, level, "%s: %s\n", prefix, errbuf);
60
65
static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
61
66
struct sockaddr *addr)
63
68
#ifdef IP_MULTICAST_TTL
64
69
if (addr->sa_family == AF_INET) {
65
70
if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
66
av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno));
71
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)");
71
76
#if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
72
77
if (addr->sa_family == AF_INET6) {
73
78
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
74
av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno));
79
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)");
88
93
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
89
94
mreq.imr_interface.s_addr= INADDR_ANY;
90
95
if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
91
av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno));
96
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)");
100
105
memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
101
106
mreq6.ipv6mr_interface= 0;
102
107
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
103
av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno));
108
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)");
117
122
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
118
123
mreq.imr_interface.s_addr= INADDR_ANY;
119
124
if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
120
av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno));
125
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)");
129
134
memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
130
135
mreq6.ipv6mr_interface= 0;
131
136
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
132
av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno));
137
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)");
171
static int udp_set_multicast_sources(int sockfd, struct sockaddr *addr,
172
int addr_len, char **sources,
173
int nb_sources, int include)
175
#if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32)
176
/* These ones are available in the microsoft SDK, but don't seem to work
177
* as on linux, so just prefer the v4-only approach there for now. */
179
for (i = 0; i < nb_sources; i++) {
180
struct group_source_req mreqs;
181
int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
182
struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
183
SOCK_DGRAM, AF_UNSPEC,
186
return AVERROR(ENOENT);
188
mreqs.gsr_interface = 0;
189
memcpy(&mreqs.gsr_group, addr, addr_len);
190
memcpy(&mreqs.gsr_source, sourceaddr->ai_addr, sourceaddr->ai_addrlen);
191
freeaddrinfo(sourceaddr);
193
if (setsockopt(sockfd, level,
194
include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
195
(const void *)&mreqs, sizeof(mreqs)) < 0) {
197
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)");
199
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)");
200
return ff_neterrno();
203
#elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE)
205
if (addr->sa_family != AF_INET) {
206
av_log(NULL, AV_LOG_ERROR,
207
"Setting multicast sources only supported for IPv4\n");
208
return AVERROR(EINVAL);
210
for (i = 0; i < nb_sources; i++) {
211
struct ip_mreq_source mreqs;
212
struct addrinfo *sourceaddr = udp_resolve_host(sources[i], 0,
213
SOCK_DGRAM, AF_UNSPEC,
216
return AVERROR(ENOENT);
217
if (sourceaddr->ai_addr->sa_family != AF_INET) {
218
freeaddrinfo(sourceaddr);
219
av_log(NULL, AV_LOG_ERROR, "%s is of incorrect protocol family\n",
221
return AVERROR(EINVAL);
224
mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
225
mreqs.imr_interface.s_addr = INADDR_ANY;
226
mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)sourceaddr->ai_addr)->sin_addr.s_addr;
227
freeaddrinfo(sourceaddr);
229
if (setsockopt(sockfd, IPPROTO_IP,
230
include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
231
(const void *)&mreqs, sizeof(mreqs)) < 0) {
233
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)");
235
log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)");
236
return ff_neterrno();
240
return AVERROR(ENOSYS);
167
244
static int udp_set_url(struct sockaddr_storage *addr,
168
245
const char *hostname, int port)
219
296
static int udp_port(struct sockaddr_storage *addr, int addr_len)
221
298
char sbuf[sizeof(int)*3+1];
223
if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) {
224
av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno));
301
if ((error = getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV)) != 0) {
302
av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(error));
350
430
if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
351
431
av_strlcpy(localaddr, buf, sizeof(localaddr));
433
if (av_find_info_tag(buf, sizeof(buf), "sources", p))
435
if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) {
440
char *next = strchr(source_start, ',');
443
sources[num_sources] = av_strdup(source_start);
444
if (!sources[num_sources])
446
source_start = next + 1;
448
if (num_sources >= FF_ARRAY_ELEMS(sources) || !next)
355
454
/* fill the dest addr */
383
/* the bind is needed to give a port to the socket now */
384
/* if multicast, try the multicast address bind first */
385
if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) {
482
/* If multicast, try binding the multicast address first, to avoid
483
* receiving UDP packets from other sources aimed at the same UDP
484
* port. This fails on windows. This makes sending to the same address
485
* using sendto() fail, so only do it if we're opened in read-only mode. */
486
if (s->is_multicast && !(h->flags & AVIO_FLAG_WRITE)) {
386
487
bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len);
388
489
/* bind to the local address if not multicast or if the multicast
390
if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0)
491
/* the bind is needed to give a port to the socket now */
492
if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) {
493
log_net_error(h, AV_LOG_ERROR, "bind failed");
393
497
len = sizeof(my_addr);
394
498
getsockname(udp_fd, (struct sockaddr *)&my_addr, &len);
395
499
s->local_port = udp_port(&my_addr, len);
397
501
if (s->is_multicast) {
398
if (!(h->flags & AVIO_FLAG_READ)) {
502
if (h->flags & AVIO_FLAG_WRITE) {
400
504
if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)
507
if (h->flags & AVIO_FLAG_READ) {
404
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
509
if (num_sources == 0 || !include) {
510
if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
514
if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0)
517
} else if (include && num_sources) {
518
if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0)
521
av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n");
410
528
/* limit the tx buf size to limit latency */
411
529
tmp = s->buffer_size;
412
530
if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {
413
av_log(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno));
531
log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)");
418
536
* avoid losing data on OSes that set this too low by default. */
419
537
tmp = s->buffer_size;
420
538
if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {
421
av_log(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno));
539
log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)");
423
541
/* make the socket non-blocking */
424
542
ff_socket_nonblock(udp_fd, 1);
426
544
if (s->is_connected) {
427
545
if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) {
428
av_log(h, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
546
log_net_error(h, AV_LOG_ERROR, "connect");
551
for (i = 0; i < num_sources; i++)
433
554
s->udp_fd = udp_fd;
437
558
closesocket(udp_fd);
559
for (i = 0; i < num_sources; i++)
438
561
return AVERROR(EIO);