Mercurial > libavformat.hg
annotate udp.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | 42ed3629601d |
children | 8329c0373f69 |
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 */ |
3231 | 21 |
22 /** | |
23 * @file udp.c | |
24 * UDP protocol | |
25 */ | |
26 | |
0 | 27 #include "avformat.h" |
28 #include <unistd.h> | |
1754 | 29 #include "network.h" |
2773 | 30 #include "os_support.h" |
0 | 31 |
834 | 32 #ifndef IPV6_ADD_MEMBERSHIP |
33 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP | |
34 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP | |
35 #endif | |
3221 | 36 #ifndef IN_MULTICAST |
37 #define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) | |
38 #endif | |
39 #ifndef IN6_IS_ADDR_MULTICAST | |
40 #define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff) | |
41 #endif | |
834 | 42 |
0 | 43 typedef struct { |
44 int udp_fd; | |
45 int ttl; | |
46 int is_multicast; | |
47 int local_port; | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
48 int reuse_socket; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
49 #ifndef CONFIG_IPV6 |
0 | 50 struct sockaddr_in dest_addr; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
51 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
52 struct sockaddr_storage dest_addr; |
2738
1f5c5c223764
Remove some ifdefs by using the "dest_addr_len" field in both the IPv4-only
lucabe
parents:
2689
diff
changeset
|
53 #endif |
3287
8570df039c75
Fix type of dest_addr_len to respect return value of udp_set_url.
cehoyos
parents:
3231
diff
changeset
|
54 int dest_addr_len; |
0 | 55 } UDPContext; |
56 | |
57 #define UDP_TX_BUF_SIZE 32768 | |
2391 | 58 #define UDP_MAX_PKT_SIZE 65536 |
0 | 59 |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
60 static int udp_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
61 #ifdef IP_MULTICAST_TTL |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
62 if (addr->sa_family == AF_INET) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
63 if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { |
2768 | 64 av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
65 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
66 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
67 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
68 #endif |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
69 #ifdef CONFIG_IPV6 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
70 if (addr->sa_family == AF_INET6) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
71 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { |
2768 | 72 av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
73 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
74 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
75 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
76 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
77 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
78 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
79 |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
80 static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
81 #ifdef IP_ADD_MEMBERSHIP |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
82 if (addr->sa_family == AF_INET) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
83 struct ip_mreq mreq; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
84 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
85 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
|
86 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
|
87 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
2768 | 88 av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); |
579
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 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
92 #endif |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
93 #ifdef CONFIG_IPV6 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
94 if (addr->sa_family == AF_INET6) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
95 struct ipv6_mreq mreq6; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
96 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
97 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
|
98 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
99 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
2768 | 100 av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
101 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
102 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
103 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
104 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
105 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
106 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
107 |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
108 static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
109 #ifdef IP_DROP_MEMBERSHIP |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
110 if (addr->sa_family == AF_INET) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
111 struct ip_mreq mreq; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
112 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
113 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
|
114 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
|
115 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
2768 | 116 av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
117 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
118 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
119 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
120 #endif |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
121 #ifdef CONFIG_IPV6 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
122 if (addr->sa_family == AF_INET6) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
123 struct ipv6_mreq mreq6; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
124 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
125 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
|
126 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
127 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
2768 | 128 av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
129 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
130 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
131 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
132 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
133 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
134 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
135 |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
136 #ifdef CONFIG_IPV6 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
137 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
|
138 struct addrinfo hints, *res = 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
139 int error; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
140 char sport[16]; |
2687
f4d24b10d33d
Resolve hosts and bind sockets even when the local_port is not set (0)
lucabe
parents:
2391
diff
changeset
|
141 const char *node = 0, *service = "0"; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
142 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
143 if (port > 0) { |
644 | 144 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
|
145 service = sport; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
146 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
147 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
|
148 node = hostname; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
149 } |
2688 | 150 memset(&hints, 0, sizeof(hints)); |
151 hints.ai_socktype = type; | |
152 hints.ai_family = family; | |
153 hints.ai_flags = flags; | |
154 if ((error = getaddrinfo(node, service, &hints, &res))) { | |
155 av_log(NULL, AV_LOG_ERROR, "udp_ipv6_resolve_host: %s\n", gai_strerror(error)); | |
156 } | |
157 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
158 return res; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
159 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
160 |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
161 static int udp_set_url(struct sockaddr_storage *addr, const char *hostname, int port) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
162 struct addrinfo *res0; |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
163 int addr_len; |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
164 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
165 res0 = udp_ipv6_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
166 if (res0 == 0) return AVERROR(EIO); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
167 memcpy(addr, res0->ai_addr, res0->ai_addrlen); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
168 addr_len = res0->ai_addrlen; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
169 freeaddrinfo(res0); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
170 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
171 return addr_len; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
172 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
173 |
3221 | 174 static int is_multicast_address(struct sockaddr_storage *addr) |
175 { | |
176 if (addr->ss_family == AF_INET) { | |
177 return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); | |
178 } | |
179 if (addr->ss_family == AF_INET6) { | |
180 return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); | |
181 } | |
182 | |
183 return 0; | |
184 } | |
185 | |
2752 | 186 static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr, int *addr_len) |
187 { | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
188 int udp_fd = -1; |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
189 struct addrinfo *res0 = NULL, *res = NULL; |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
190 int family = AF_UNSPEC; |
885 | 191 |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
192 if (((struct sockaddr *) &s->dest_addr)->sa_family) |
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
193 family = ((struct sockaddr *) &s->dest_addr)->sa_family; |
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
194 res0 = udp_ipv6_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); |
2688 | 195 if (res0 == 0) |
196 goto fail; | |
197 for (res = res0; res; res=res->ai_next) { | |
198 udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); | |
199 if (udp_fd > 0) break; | |
2768 | 200 av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno)); |
2688 | 201 } |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
202 |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
203 if (udp_fd < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
204 goto fail; |
885 | 205 |
2752 | 206 memcpy(addr, res->ai_addr, res->ai_addrlen); |
207 *addr_len = res->ai_addrlen; | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
208 |
2752 | 209 freeaddrinfo(res0); |
885 | 210 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
211 return udp_fd; |
885 | 212 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
213 fail: |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
214 if (udp_fd >= 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
215 closesocket(udp_fd); |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
216 if(res0) |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
217 freeaddrinfo(res0); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
218 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
219 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
220 |
2752 | 221 static int udp_port(struct sockaddr_storage *addr, int addr_len) |
222 { | |
3025
41d68d056417
Do not use GNU-specific (or BSD-specific or whatever they may be)
rfelker
parents:
2773
diff
changeset
|
223 char sbuf[sizeof(int)*3+1]; |
2752 | 224 |
3025
41d68d056417
Do not use GNU-specific (or BSD-specific or whatever they may be)
rfelker
parents:
2773
diff
changeset
|
225 if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) { |
2768 | 226 av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno)); |
2752 | 227 return -1; |
228 } | |
229 | |
230 return strtol(sbuf, NULL, 10); | |
231 } | |
232 | |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
233 #else |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
234 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
235 static int udp_set_url(struct sockaddr_in *addr, const char *hostname, int port) |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
236 { |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
237 /* set the destination address */ |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
238 if (resolve_host(&addr->sin_addr, hostname) < 0) |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
239 return AVERROR(EIO); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
240 addr->sin_family = AF_INET; |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
241 addr->sin_port = htons(port); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
242 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
243 return sizeof(struct sockaddr_in); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
244 } |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
245 |
3221 | 246 static int is_multicast_address(struct sockaddr_in *addr) |
247 { | |
248 return IN_MULTICAST(ntohl(addr->sin_addr.s_addr)); | |
249 } | |
250 | |
2752 | 251 static int udp_socket_create(UDPContext *s, struct sockaddr_in *addr, int *addr_len) |
252 { | |
253 int fd; | |
254 | |
255 fd = socket(AF_INET, SOCK_DGRAM, 0); | |
256 if (fd < 0) | |
257 return -1; | |
258 | |
259 addr->sin_family = AF_INET; | |
260 addr->sin_addr.s_addr = htonl (INADDR_ANY); | |
261 addr->sin_port = htons(s->local_port); | |
262 *addr_len = sizeof(struct sockaddr_in); | |
263 | |
264 return fd; | |
265 } | |
266 | |
267 static int udp_port(struct sockaddr_in *addr, int len) | |
268 { | |
269 return ntohs(addr->sin_port); | |
270 } | |
2162 | 271 #endif /* CONFIG_IPV6 */ |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
272 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
273 |
0 | 274 /** |
275 * If no filename is given to av_open_input_file because you want to | |
276 * get the local port first, then you must call this function to set | |
277 * the remote server address. | |
278 * | |
279 * url syntax: udp://host:port[?option=val...] | |
3221 | 280 * option: 'ttl=n' : set the ttl value (for multicast only) |
0 | 281 * 'localport=n' : set the local port |
62 | 282 * '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
|
283 * 'reuse=1' : enable reusing the socket |
0 | 284 * |
285 * @param s1 media file context | |
286 * @param uri of the remote server | |
287 * @return zero if no error. | |
288 */ | |
289 int udp_set_remote_url(URLContext *h, const char *uri) | |
290 { | |
291 UDPContext *s = h->priv_data; | |
292 char hostname[256]; | |
293 int port; | |
885 | 294 |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
295 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
0 | 296 |
297 /* set the destination address */ | |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
298 s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
299 if (s->dest_addr_len < 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
300 return AVERROR(EIO); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
301 } |
3221 | 302 s->is_multicast = is_multicast_address(&s->dest_addr); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
303 |
0 | 304 return 0; |
305 } | |
306 | |
307 /** | |
308 * Return the local port used by the UDP connexion | |
309 * @param s1 media file context | |
310 * @return the local port number | |
311 */ | |
312 int udp_get_local_port(URLContext *h) | |
313 { | |
314 UDPContext *s = h->priv_data; | |
315 return s->local_port; | |
316 } | |
317 | |
318 /** | |
319 * Return the udp file handle for select() usage to wait for several RTP | |
320 * streams at the same time. | |
321 * @param h media file context | |
322 */ | |
323 int udp_get_file_handle(URLContext *h) | |
324 { | |
325 UDPContext *s = h->priv_data; | |
326 return s->udp_fd; | |
327 } | |
328 | |
329 /* put it in UDP context */ | |
330 /* return non zero if error */ | |
331 static int udp_open(URLContext *h, const char *uri, int flags) | |
332 { | |
333 char hostname[1024]; | |
334 int port, udp_fd = -1, tmp; | |
335 UDPContext *s = NULL; | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
336 int is_output; |
0 | 337 const char *p; |
338 char buf[256]; | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
339 #ifndef CONFIG_IPV6 |
2751 | 340 struct sockaddr_in my_addr; |
2752 | 341 #else |
342 struct sockaddr_storage my_addr; | |
343 #endif | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
344 int len; |
0 | 345 |
346 h->is_streamed = 1; | |
62 | 347 h->max_packet_size = 1472; |
0 | 348 |
349 is_output = (flags & URL_WRONLY); | |
885 | 350 |
3753
42ed3629601d
Fix memleak on some OSes in case network initialization fails. See
rbultje
parents:
3287
diff
changeset
|
351 if(!ff_network_init()) |
42ed3629601d
Fix memleak on some OSes in case network initialization fails. See
rbultje
parents:
3287
diff
changeset
|
352 return AVERROR(EIO); |
42ed3629601d
Fix memleak on some OSes in case network initialization fails. See
rbultje
parents:
3287
diff
changeset
|
353 |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
354 s = av_mallocz(sizeof(UDPContext)); |
0 | 355 if (!s) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
356 return AVERROR(ENOMEM); |
0 | 357 |
358 h->priv_data = s; | |
359 s->ttl = 16; | |
360 p = strchr(uri, '?'); | |
361 if (p) { | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
362 s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p); |
0 | 363 if (find_info_tag(buf, sizeof(buf), "ttl", p)) { |
364 s->ttl = strtol(buf, NULL, 10); | |
365 } | |
366 if (find_info_tag(buf, sizeof(buf), "localport", p)) { | |
367 s->local_port = strtol(buf, NULL, 10); | |
368 } | |
62 | 369 if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { |
370 h->max_packet_size = strtol(buf, NULL, 10); | |
371 } | |
0 | 372 } |
373 | |
374 /* 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
|
375 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
885 | 376 |
0 | 377 /* XXX: fix url_split */ |
378 if (hostname[0] == '\0' || hostname[0] == '?') { | |
379 /* only accepts null hostname if input */ | |
3221 | 380 if (flags & URL_WRONLY) |
0 | 381 goto fail; |
382 } else { | |
383 udp_set_remote_url(h, uri); | |
384 } | |
385 | |
2750
b3a11a0966af
Use the same code to set local_port in the IPv4-only case and in the
lucabe
parents:
2744
diff
changeset
|
386 if (s->is_multicast && !(h->flags & URL_WRONLY)) |
b3a11a0966af
Use the same code to set local_port in the IPv4-only case and in the
lucabe
parents:
2744
diff
changeset
|
387 s->local_port = port; |
2752 | 388 udp_fd = udp_socket_create(s, &my_addr, &len); |
0 | 389 if (udp_fd < 0) |
390 goto fail; | |
391 | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
392 if (s->reuse_socket) |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
393 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
|
394 goto fail; |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
395 |
0 | 396 /* the bind is needed to give a port to the socket now */ |
2752 | 397 if (bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) |
0 | 398 goto fail; |
399 | |
2751 | 400 len = sizeof(my_addr); |
401 getsockname(udp_fd, (struct sockaddr *)&my_addr, &len); | |
2752 | 402 s->local_port = udp_port(&my_addr, len); |
403 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
404 if (s->is_multicast) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
405 if (h->flags & URL_WRONLY) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
406 /* output */ |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
407 if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
408 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
409 } else { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
410 /* input */ |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
411 if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
412 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
413 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
414 } |
0 | 415 |
416 if (is_output) { | |
417 /* limit the tx buf size to limit latency */ | |
418 tmp = UDP_TX_BUF_SIZE; | |
419 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { | |
2768 | 420 av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno)); |
0 | 421 goto fail; |
422 } | |
2391 | 423 } else { |
424 /* set udp recv buffer size to the largest possible udp packet size to | |
425 * avoid losing data on OSes that set this too low by default. */ | |
426 tmp = UDP_MAX_PKT_SIZE; | |
427 setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)); | |
0 | 428 } |
429 | |
430 s->udp_fd = udp_fd; | |
431 return 0; | |
432 fail: | |
433 if (udp_fd >= 0) | |
434 closesocket(udp_fd); | |
435 av_free(s); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
436 return AVERROR(EIO); |
0 | 437 } |
438 | |
65 | 439 static int udp_read(URLContext *h, uint8_t *buf, int size) |
0 | 440 { |
441 UDPContext *s = h->priv_data; | |
1332 | 442 int len; |
0 | 443 |
444 for(;;) { | |
2742
c51f5ad5d131
Use recv() instead of recvfrom() (removes some other differences between
lucabe
parents:
2741
diff
changeset
|
445 len = recv(s->udp_fd, buf, size, 0); |
0 | 446 if (len < 0) { |
2056
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
447 if (ff_neterrno() != FF_NETERROR(EAGAIN) && |
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
448 ff_neterrno() != FF_NETERROR(EINTR)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
449 return AVERROR(EIO); |
0 | 450 } else { |
451 break; | |
452 } | |
453 } | |
454 return len; | |
455 } | |
456 | |
65 | 457 static int udp_write(URLContext *h, uint8_t *buf, int size) |
0 | 458 { |
459 UDPContext *s = h->priv_data; | |
460 int ret; | |
461 | |
462 for(;;) { | |
885 | 463 ret = sendto (s->udp_fd, buf, size, 0, |
0 | 464 (struct sockaddr *) &s->dest_addr, |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
465 s->dest_addr_len); |
0 | 466 if (ret < 0) { |
2056
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
467 if (ff_neterrno() != FF_NETERROR(EINTR) && |
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
468 ff_neterrno() != FF_NETERROR(EAGAIN)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
469 return AVERROR(EIO); |
0 | 470 } else { |
471 break; | |
472 } | |
473 } | |
474 return size; | |
475 } | |
476 | |
477 static int udp_close(URLContext *h) | |
478 { | |
479 UDPContext *s = h->priv_data; | |
480 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
481 if (s->is_multicast && !(h->flags & URL_WRONLY)) |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
482 udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); |
0 | 483 closesocket(s->udp_fd); |
2351
b9a881c0967e
Add initialization and cleanup functions for Winsock
ramiro
parents:
2274
diff
changeset
|
484 ff_network_close(); |
0 | 485 av_free(s); |
486 return 0; | |
487 } | |
488 | |
489 URLProtocol udp_protocol = { | |
490 "udp", | |
491 udp_open, | |
492 udp_read, | |
493 udp_write, | |
494 NULL, /* seek */ | |
495 udp_close, | |
496 }; |