1 /*
2 * TCP protocol
3 * Copyright (c) 2002 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
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
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
29 #if HAVE_POLL_H
30 #include <poll.h>
31 #endif
32
41
42 #define OFFSET(x) offsetof(TCPContext, x)
43 #define D AV_OPT_FLAG_DECODING_PARAM
44 #define E AV_OPT_FLAG_ENCODING_PARAM
47 {
"timeout",
"timeout of socket i/o operations",
OFFSET(rw_timeout),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
D|
E },
48 {
"listen_timeout",
"connection awaiting timeout",
OFFSET(listen_timeout),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
D|
E },
49 {NULL}
50 };
51
57 };
58
59 /* return non zero if error */
61 {
62 struct addrinfo hints = { 0 }, *ai, *cur_ai;
63 int port, fd = -1;
65 const char *p;
68 char hostname[1024],proto[1024],path[1024];
69 char portstr[10];
71
72 av_url_split(proto,
sizeof(proto), NULL, 0, hostname,
sizeof(hostname),
73 &port, path, sizeof(path), uri);
74 if (strcmp(proto, "tcp"))
76 if (port <= 0 || port >= 65536) {
79 }
80 p = strchr(uri, '?');
81 if (p) {
86 }
89 }
90 }
94 }
97 snprintf(portstr,
sizeof(portstr),
"%d", port);
100 if (!hostname[0])
102 else
104 if (ret) {
106 "Failed to resolve hostname %s: %s\n",
109 }
110
111 cur_ai = ai;
112
113 restart:
114 fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
115 if (fd < 0) {
117 goto fail;
118 }
119
123 ret = fd;
124 goto fail1;
125 }
126 } else {
129
131 goto fail1;
132 else
133 goto fail;
134 }
135 }
136
140 return 0;
141
142 fail:
143 if (cur_ai->ai_next) {
144 /* Retry with the next sockaddr */
145 cur_ai = cur_ai->ai_next;
146 if (fd >= 0)
148 ret = 0;
149 goto restart;
150 }
151 fail1:
152 if (fd >= 0)
156 }
157
159 {
162
165 if (ret)
167 }
168 ret = recv(s->
fd, buf, size, 0);
170 }
171
173 {
176
179 if (ret)
181 }
182 ret = send(s->
fd, buf, size, 0);
184 }
185
187 {
189 int how;
190
192 how = SHUT_RDWR;
194 how = SHUT_WR;
195 } else {
196 how = SHUT_RD;
197 }
198
199 return shutdown(s->
fd, how);
200 }
201
203 {
206 return 0;
207 }
208
210 {
213 }
214
224 .priv_data_class = &tcp_context_class,
226 };