Mercurial > libavformat.hg
annotate udp.c @ 1779:de2cf54eb68f libavformat
mxf aes decryption support, patch by Reimar, simplified to only look for first crypto context, will be extended once we get files with multiple cryptocontext, and hope that they won't have broken container ul
author | bcoudurier |
---|---|
date | Sun, 11 Feb 2007 12:50:33 +0000 |
parents | 1f7a6dc01100 |
children | eb16c64144ee |
rev | line source |
---|---|
0 | 1 /* |
2 * UDP prototype streaming system | |
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
21 #include "avformat.h" | |
22 #include <unistd.h> | |
1754 | 23 #include "network.h" |
0 | 24 |
834 | 25 #ifndef IPV6_ADD_MEMBERSHIP |
26 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP | |
27 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP | |
28 #endif | |
29 | |
0 | 30 typedef struct { |
31 int udp_fd; | |
32 int ttl; | |
33 int is_multicast; | |
34 int local_port; | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
35 int reuse_socket; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
36 #ifndef CONFIG_IPV6 |
0 | 37 struct ip_mreq mreq; |
38 struct sockaddr_in dest_addr; | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
39 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
40 struct sockaddr_storage dest_addr; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
41 size_t dest_addr_len; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
42 #endif |
0 | 43 } UDPContext; |
44 | |
45 #define UDP_TX_BUF_SIZE 32768 | |
46 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
47 #ifdef CONFIG_IPV6 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
48 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
49 static int udp_ipv6_is_multicast_address(const struct sockaddr *addr) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
50 if (addr->sa_family == AF_INET) |
885 | 51 return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
52 if (addr->sa_family == AF_INET6) |
885 | 53 return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
54 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
55 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
56 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
57 static int udp_ipv6_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
58 if (addr->sa_family == AF_INET) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
59 if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
60 perror("setsockopt(IP_MULTICAST_TTL)"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
61 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
62 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
63 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
64 if (addr->sa_family == AF_INET6) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
65 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
66 perror("setsockopt(IPV6_MULTICAST_HOPS)"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
67 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
68 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
69 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
70 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
71 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
72 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
73 static int udp_ipv6_join_multicast_group(int sockfd, struct sockaddr *addr) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
74 struct ip_mreq mreq; |
885 | 75 struct ipv6_mreq mreq6; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
76 if (addr->sa_family == AF_INET) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
77 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
78 mreq.imr_interface.s_addr= INADDR_ANY; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
79 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
80 perror("setsockopt(IP_ADD_MEMBERSHIP)"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
81 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
82 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
83 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
84 if (addr->sa_family == AF_INET6) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
85 memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
86 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
87 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
88 perror("setsockopt(IPV6_ADD_MEMBERSHIP)"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
89 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
90 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
91 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
92 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
93 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
94 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
95 static int udp_ipv6_leave_multicast_group(int sockfd, struct sockaddr *addr) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
96 struct ip_mreq mreq; |
885 | 97 struct ipv6_mreq mreq6; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
98 if (addr->sa_family == AF_INET) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
99 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
100 mreq.imr_interface.s_addr= INADDR_ANY; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
101 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
102 perror("setsockopt(IP_DROP_MEMBERSHIP)"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
103 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
104 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
105 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
106 if (addr->sa_family == AF_INET6) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
107 memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
108 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
109 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
110 perror("setsockopt(IPV6_DROP_MEMBERSHIP)"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
111 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
112 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
113 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
114 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
115 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
116 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
117 static struct addrinfo* udp_ipv6_resolve_host(const char *hostname, int port, int type, int family, int flags) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
118 struct addrinfo hints, *res = 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
119 int error; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
120 char sport[16]; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
121 const char *node = 0, *service = 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
122 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
123 if (port > 0) { |
644 | 124 snprintf(sport, sizeof(sport), "%d", port); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
125 service = sport; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
126 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
127 if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
128 node = hostname; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
129 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
130 if ((node) || (service)) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
131 memset(&hints, 0, sizeof(hints)); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
132 hints.ai_socktype = type; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
133 hints.ai_family = family; |
885 | 134 hints.ai_flags = flags; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
135 if ((error = getaddrinfo(node, service, &hints, &res))) { |
815
5f9e330500d9
printf-> av_log patch by (Benjamin Larsson, banan: student ltu se)
michael
parents:
683
diff
changeset
|
136 av_log(NULL, AV_LOG_ERROR, "udp_ipv6_resolve_host: %s\n", gai_strerror(error)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
137 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
138 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
139 return res; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
140 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
141 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
142 static int udp_ipv6_set_remote_url(URLContext *h, const char *uri) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
143 UDPContext *s = h->priv_data; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
144 char hostname[256]; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
145 int port; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
146 struct addrinfo *res0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
147 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
148 res0 = udp_ipv6_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
149 if (res0 == 0) return AVERROR_IO; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
150 memcpy(&s->dest_addr, res0->ai_addr, res0->ai_addrlen); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
151 s->dest_addr_len = res0->ai_addrlen; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
152 freeaddrinfo(res0); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
153 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
154 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
155 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
156 static int udp_ipv6_set_local(URLContext *h) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
157 UDPContext *s = h->priv_data; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
158 int udp_fd = -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
159 struct sockaddr_storage clientaddr; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
160 socklen_t addrlen; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
161 char sbuf[NI_MAXSERV]; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
162 char hbuf[NI_MAXHOST]; |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
163 struct addrinfo *res0 = NULL, *res = NULL; |
885 | 164 |
165 if (s->local_port != 0) { | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
166 res0 = udp_ipv6_resolve_host(0, s->local_port, SOCK_DGRAM, AF_UNSPEC, AI_PASSIVE); |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
167 if (res0 == 0) |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
168 goto fail; |
885 | 169 for (res = res0; res; res=res->ai_next) { |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
170 udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
171 if (udp_fd > 0) break; |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
172 perror("socket"); |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
173 } |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
174 } else { |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
175 udp_fd = socket(s->dest_addr.ss_family, SOCK_DGRAM, 0); |
885 | 176 if (udp_fd < 0) |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
177 perror("socket"); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
178 } |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
179 |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
180 if (udp_fd < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
181 goto fail; |
885 | 182 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
183 if (s->local_port != 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
184 if (bind(udp_fd, res0->ai_addr, res0->ai_addrlen) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
185 perror("bind"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
186 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
187 } |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
188 freeaddrinfo(res0); |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
189 res0 = NULL; |
885 | 190 } |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
191 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
192 addrlen = sizeof(clientaddr); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
193 if (getsockname(udp_fd, (struct sockaddr *)&clientaddr, &addrlen) < 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
194 perror("getsockname"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
195 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
196 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
197 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
198 if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) != 0) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
199 perror("getnameinfo"); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
200 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
201 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
202 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
203 s->local_port = strtol(sbuf, NULL, 10); |
885 | 204 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
205 return udp_fd; |
885 | 206 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
207 fail: |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
208 if (udp_fd >= 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
209 closesocket(udp_fd); |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
210 if(res0) |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
211 freeaddrinfo(res0); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
212 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
213 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
214 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
215 #endif |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
216 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
217 |
0 | 218 /** |
219 * If no filename is given to av_open_input_file because you want to | |
220 * get the local port first, then you must call this function to set | |
221 * the remote server address. | |
222 * | |
223 * url syntax: udp://host:port[?option=val...] | |
885 | 224 * option: 'multicast=1' : enable multicast |
0 | 225 * 'ttl=n' : set the ttl value (for multicast only) |
226 * 'localport=n' : set the local port | |
62 | 227 * 'pkt_size=n' : set max packet size |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
228 * 'reuse=1' : enable reusing the socket |
0 | 229 * |
230 * @param s1 media file context | |
231 * @param uri of the remote server | |
232 * @return zero if no error. | |
233 */ | |
234 int udp_set_remote_url(URLContext *h, const char *uri) | |
235 { | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
236 #ifdef CONFIG_IPV6 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
237 return udp_ipv6_set_remote_url(h, uri); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
238 #else |
0 | 239 UDPContext *s = h->priv_data; |
240 char hostname[256]; | |
241 int port; | |
885 | 242 |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
243 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
0 | 244 |
245 /* set the destination address */ | |
246 if (resolve_host(&s->dest_addr.sin_addr, hostname) < 0) | |
482 | 247 return AVERROR_IO; |
0 | 248 s->dest_addr.sin_family = AF_INET; |
249 s->dest_addr.sin_port = htons(port); | |
250 return 0; | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
251 #endif |
0 | 252 } |
253 | |
254 /** | |
255 * Return the local port used by the UDP connexion | |
256 * @param s1 media file context | |
257 * @return the local port number | |
258 */ | |
259 int udp_get_local_port(URLContext *h) | |
260 { | |
261 UDPContext *s = h->priv_data; | |
262 return s->local_port; | |
263 } | |
264 | |
265 /** | |
266 * Return the udp file handle for select() usage to wait for several RTP | |
267 * streams at the same time. | |
268 * @param h media file context | |
269 */ | |
270 int udp_get_file_handle(URLContext *h) | |
271 { | |
272 UDPContext *s = h->priv_data; | |
273 return s->udp_fd; | |
274 } | |
275 | |
276 /* put it in UDP context */ | |
277 /* return non zero if error */ | |
278 static int udp_open(URLContext *h, const char *uri, int flags) | |
279 { | |
280 char hostname[1024]; | |
281 int port, udp_fd = -1, tmp; | |
282 UDPContext *s = NULL; | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
283 int is_output; |
0 | 284 const char *p; |
285 char buf[256]; | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
286 #ifndef CONFIG_IPV6 |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
287 struct sockaddr_in my_addr, my_addr1; |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
288 int len; |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
289 #endif |
0 | 290 |
291 h->is_streamed = 1; | |
62 | 292 h->max_packet_size = 1472; |
0 | 293 |
294 is_output = (flags & URL_WRONLY); | |
885 | 295 |
0 | 296 s = av_malloc(sizeof(UDPContext)); |
297 if (!s) | |
298 return -ENOMEM; | |
299 | |
300 h->priv_data = s; | |
301 s->ttl = 16; | |
302 s->is_multicast = 0; | |
161
e01949598794
undefined local_port fix by (Giancarlo Formicuccia <ilsensine at inwind dot it>)
michaelni
parents:
65
diff
changeset
|
303 s->local_port = 0; |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
304 s->reuse_socket = 0; |
0 | 305 p = strchr(uri, '?'); |
306 if (p) { | |
307 s->is_multicast = find_info_tag(buf, sizeof(buf), "multicast", p); | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
308 s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p); |
0 | 309 if (find_info_tag(buf, sizeof(buf), "ttl", p)) { |
310 s->ttl = strtol(buf, NULL, 10); | |
311 } | |
312 if (find_info_tag(buf, sizeof(buf), "localport", p)) { | |
313 s->local_port = strtol(buf, NULL, 10); | |
314 } | |
62 | 315 if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { |
316 h->max_packet_size = strtol(buf, NULL, 10); | |
317 } | |
0 | 318 } |
319 | |
320 /* fill the dest addr */ | |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
321 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
885 | 322 |
0 | 323 /* XXX: fix url_split */ |
324 if (hostname[0] == '\0' || hostname[0] == '?') { | |
325 /* only accepts null hostname if input */ | |
326 if (s->is_multicast || (flags & URL_WRONLY)) | |
327 goto fail; | |
328 } else { | |
329 udp_set_remote_url(h, uri); | |
330 } | |
331 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
332 #ifndef CONFIG_IPV6 |
0 | 333 udp_fd = socket(PF_INET, SOCK_DGRAM, 0); |
334 if (udp_fd < 0) | |
335 goto fail; | |
336 | |
337 my_addr.sin_family = AF_INET; | |
338 my_addr.sin_addr.s_addr = htonl (INADDR_ANY); | |
339 if (s->is_multicast && !(h->flags & URL_WRONLY)) { | |
340 /* special case: the bind must be done on the multicast address port */ | |
341 my_addr.sin_port = s->dest_addr.sin_port; | |
342 } else { | |
343 my_addr.sin_port = htons(s->local_port); | |
344 } | |
345 | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
346 if (s->reuse_socket) |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
347 if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
348 goto fail; |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
349 |
0 | 350 /* the bind is needed to give a port to the socket now */ |
885 | 351 if (bind(udp_fd,(struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) |
0 | 352 goto fail; |
353 | |
354 len = sizeof(my_addr1); | |
355 getsockname(udp_fd, (struct sockaddr *)&my_addr1, &len); | |
356 s->local_port = ntohs(my_addr1.sin_port); | |
357 | |
1671
f695f8fc4a63
The long awaited BeOS cleanup, phase 1.1: removed useless ifdef, changed check for net_server to IP_MULTICAST_TTL.
mmu_man
parents:
1670
diff
changeset
|
358 #ifdef IP_MULTICAST_TTL |
0 | 359 if (s->is_multicast) { |
360 if (h->flags & URL_WRONLY) { | |
361 /* output */ | |
885 | 362 if (setsockopt(udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, |
0 | 363 &s->ttl, sizeof(s->ttl)) < 0) { |
364 perror("IP_MULTICAST_TTL"); | |
365 goto fail; | |
366 } | |
367 } else { | |
368 /* input */ | |
369 memset(&s->mreq, 0, sizeof(s->mreq)); | |
370 s->mreq.imr_multiaddr = s->dest_addr.sin_addr; | |
371 s->mreq.imr_interface.s_addr = htonl (INADDR_ANY); | |
885 | 372 if (setsockopt(udp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, |
0 | 373 &s->mreq, sizeof(s->mreq)) < 0) { |
374 perror("rtp: IP_ADD_MEMBERSHIP"); | |
375 goto fail; | |
376 } | |
377 } | |
378 } | |
379 #endif | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
380 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
381 if (s->is_multicast && !(h->flags & URL_WRONLY)) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
382 s->local_port = port; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
383 udp_fd = udp_ipv6_set_local(h); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
384 if (udp_fd < 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
385 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
386 if (s->is_multicast) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
387 if (h->flags & URL_WRONLY) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
388 if (udp_ipv6_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
389 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
390 } else { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
391 if (udp_ipv6_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
392 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
393 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
394 } |
885 | 395 #endif |
0 | 396 |
397 if (is_output) { | |
398 /* limit the tx buf size to limit latency */ | |
399 tmp = UDP_TX_BUF_SIZE; | |
400 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { | |
401 perror("setsockopt sndbuf"); | |
402 goto fail; | |
403 } | |
404 } | |
405 | |
406 s->udp_fd = udp_fd; | |
407 return 0; | |
408 fail: | |
409 if (udp_fd >= 0) | |
410 closesocket(udp_fd); | |
411 av_free(s); | |
482 | 412 return AVERROR_IO; |
0 | 413 } |
414 | |
65 | 415 static int udp_read(URLContext *h, uint8_t *buf, int size) |
0 | 416 { |
417 UDPContext *s = h->priv_data; | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
418 #ifndef CONFIG_IPV6 |
0 | 419 struct sockaddr_in from; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
420 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
421 struct sockaddr_storage from; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
422 #endif |
1332 | 423 socklen_t from_len; |
424 int len; | |
0 | 425 |
426 for(;;) { | |
427 from_len = sizeof(from); | |
428 len = recvfrom (s->udp_fd, buf, size, 0, | |
429 (struct sockaddr *)&from, &from_len); | |
430 if (len < 0) { | |
431 if (errno != EAGAIN && errno != EINTR) | |
482 | 432 return AVERROR_IO; |
0 | 433 } else { |
434 break; | |
435 } | |
436 } | |
437 return len; | |
438 } | |
439 | |
65 | 440 static int udp_write(URLContext *h, uint8_t *buf, int size) |
0 | 441 { |
442 UDPContext *s = h->priv_data; | |
443 int ret; | |
444 | |
445 for(;;) { | |
885 | 446 ret = sendto (s->udp_fd, buf, size, 0, |
0 | 447 (struct sockaddr *) &s->dest_addr, |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
448 #ifndef CONFIG_IPV6 |
0 | 449 sizeof (s->dest_addr)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
450 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
451 s->dest_addr_len); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
452 #endif |
0 | 453 if (ret < 0) { |
454 if (errno != EINTR && errno != EAGAIN) | |
482 | 455 return AVERROR_IO; |
0 | 456 } else { |
457 break; | |
458 } | |
459 } | |
460 return size; | |
461 } | |
462 | |
463 static int udp_close(URLContext *h) | |
464 { | |
465 UDPContext *s = h->priv_data; | |
466 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
467 #ifndef CONFIG_IPV6 |
1670 | 468 #ifdef IP_DROP_MEMBERSHIP |
0 | 469 if (s->is_multicast && !(h->flags & URL_WRONLY)) { |
885 | 470 if (setsockopt(s->udp_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, |
0 | 471 &s->mreq, sizeof(s->mreq)) < 0) { |
472 perror("IP_DROP_MEMBERSHIP"); | |
473 } | |
474 } | |
1670 | 475 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
476 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
477 if (s->is_multicast && !(h->flags & URL_WRONLY)) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
478 udp_ipv6_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
479 #endif |
0 | 480 closesocket(s->udp_fd); |
481 av_free(s); | |
482 return 0; | |
483 } | |
484 | |
485 URLProtocol udp_protocol = { | |
486 "udp", | |
487 udp_open, | |
488 udp_read, | |
489 udp_write, | |
490 NULL, /* seek */ | |
491 udp_close, | |
492 }; |