38 #ifndef IPV6_ADD_MEMBERSHIP
39 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
40 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
55 #define UDP_TX_BUF_SIZE 32768
56 #define UDP_MAX_PKT_SIZE 65536
62 av_log(ctx, level,
"%s: %s\n", prefix, errbuf);
66 struct sockaddr *addr)
68 #ifdef IP_MULTICAST_TTL
69 if (addr->sa_family == AF_INET) {
70 if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL,
sizeof(mcastTTL)) < 0) {
76 #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
77 if (addr->sa_family == AF_INET6) {
78 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL,
sizeof(mcastTTL)) < 0) {
89 #ifdef IP_ADD_MEMBERSHIP
90 if (addr->sa_family == AF_INET) {
93 mreq.imr_multiaddr.s_addr = ((
struct sockaddr_in *)addr)->sin_addr.s_addr;
94 mreq.imr_interface.s_addr= INADDR_ANY;
95 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
const void *)&mreq,
sizeof(mreq)) < 0) {
101 #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
102 if (addr->sa_family == AF_INET6) {
103 struct ipv6_mreq mreq6;
105 memcpy(&mreq6.ipv6mr_multiaddr, &(((
struct sockaddr_in6 *)addr)->sin6_addr),
sizeof(
struct in6_addr));
106 mreq6.ipv6mr_interface= 0;
118 #ifdef IP_DROP_MEMBERSHIP
119 if (addr->sa_family == AF_INET) {
122 mreq.imr_multiaddr.s_addr = ((
struct sockaddr_in *)addr)->sin_addr.s_addr;
123 mreq.imr_interface.s_addr= INADDR_ANY;
124 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (
const void *)&mreq,
sizeof(mreq)) < 0) {
130 #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
131 if (addr->sa_family == AF_INET6) {
132 struct ipv6_mreq mreq6;
134 memcpy(&mreq6.ipv6mr_multiaddr, &(((
struct sockaddr_in6 *)addr)->sin6_addr),
sizeof(
struct in6_addr));
135 mreq6.ipv6mr_interface= 0;
146 int type,
int family,
int flags)
148 struct addrinfo hints = { 0 }, *res = 0;
151 const char *node = 0, *service =
"0";
154 snprintf(sport,
sizeof(sport),
"%d", port);
157 if ((hostname) && (hostname[0] !=
'\0') && (hostname[0] !=
'?')) {
163 if ((error =
getaddrinfo(node, service, &hints, &res))) {
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)
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;
183 SOCK_DGRAM, AF_UNSPEC,
188 mreqs.gsr_interface = 0;
189 memcpy(&mreqs.gsr_group, addr, addr_len);
193 if (setsockopt(sockfd, level,
194 include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
195 (
const void *)&mreqs,
sizeof(mreqs)) < 0) {
203 #elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE)
205 if (addr->sa_family != AF_INET) {
207 "Setting multicast sources only supported for IPv4\n");
210 for (i = 0; i < nb_sources; i++) {
211 struct ip_mreq_source mreqs;
213 SOCK_DGRAM, AF_UNSPEC,
217 if (sourceaddr->
ai_addr->sa_family != AF_INET) {
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;
229 if (setsockopt(sockfd, IPPROTO_IP,
230 include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
231 (
const void *)&mreqs,
sizeof(mreqs)) < 0) {
245 const char *hostname,
int port)
251 if (res0 == 0)
return AVERROR(EIO);
260 socklen_t *addr_len,
const char *localaddr)
264 int family = AF_UNSPEC;
266 if (((
struct sockaddr *) &s->
dest_addr)->sa_family)
267 family = ((
struct sockaddr *) &s->
dest_addr)->sa_family;
272 for (res = res0; res; res=res->
ai_next) {
273 udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
274 if (udp_fd != -1)
break;
281 memcpy(addr, res->ai_addr, res->ai_addrlen);
282 *addr_len = res->ai_addrlen;
298 char sbuf[
sizeof(int)*3+1];
306 return strtol(sbuf,
NULL, 10);
328 char hostname[256], buf[10];
340 p = strchr(uri,
'?');
385 char hostname[1024], localaddr[1024] =
"";
386 int port, udp_fd = -1, tmp, bind_ret = -1;
393 int reuse_specified = 0;
394 int i, include = 0, num_sources = 0;
405 p = strchr(uri,
'?');
416 s->
ttl = strtol(buf,
NULL, 10);
431 av_strlcpy(localaddr, buf,
sizeof(localaddr));
440 char *next = strchr(source_start,
',');
443 sources[num_sources] =
av_strdup(source_start);
444 if (!sources[num_sources])
446 source_start = next + 1;
458 if (hostname[0] ==
'\0' || hostname[0] ==
'?') {
487 bind_ret = bind(udp_fd,(
struct sockaddr *)&s->
dest_addr, len);
492 if (bind_ret < 0 && bind(udp_fd,(
struct sockaddr *)&my_addr, len) < 0) {
497 len =
sizeof(my_addr);
498 getsockname(udp_fd, (
struct sockaddr *)&my_addr, &len);
509 if (num_sources == 0 || !include) {
517 }
else if (include && num_sources) {
530 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp,
sizeof(tmp)) < 0) {
538 if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp,
sizeof(tmp)) < 0) {
551 for (i = 0; i < num_sources; i++)
559 for (i = 0; i < num_sources; i++)
574 ret = recv(s->
udp_fd, buf, size, 0);
590 ret = sendto (s->
udp_fd, buf, size, 0,
594 ret = send(s->
udp_fd, buf, size, 0);