53 #define OFFSET(x) offsetof(TCPContext, x)
54 #define D AV_OPT_FLAG_DECODING_PARAM
55 #define E AV_OPT_FLAG_ENCODING_PARAM
57 {
"listen",
"Listen for incoming connections",
OFFSET(listen),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, .flags =
D|
E },
60 {
"timeout",
"set timeout (in microseconds) of socket I/O operations",
OFFSET(rw_timeout),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
61 {
"listen_timeout",
"Connection awaiting timeout (in milliseconds)",
OFFSET(listen_timeout),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
62 {
"send_buffer_size",
"Socket send buffer size (in bytes)",
OFFSET(send_buffer_size),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
63 {
"recv_buffer_size",
"Socket receive buffer size (in bytes)",
OFFSET(recv_buffer_size),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
64 {
"tcp_nodelay",
"Use TCP_NODELAY to disable nagle's algorithm",
OFFSET(tcp_nodelay),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags =
D|
E },
65 {
"tcp_keepalive",
"Use TCP keepalive to detect dead connections and keep long-lived connections active.",
OFFSET(tcp_keepalive),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags =
D|
E },
67 {
"tcp_mss",
"Maximum segment size for outgoing TCP packets",
OFFSET(tcp_mss),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
83 if (
s->local_addr ||
s->local_port) {
84 struct addrinfo hints = { 0 }, *ai, *cur_ai;
93 "Failed to getaddrinfo local addr: %s port: %s err: %s\n",
100 ret = bind(fd, (
struct sockaddr *)cur_ai->ai_addr, (
int)cur_ai->ai_addrlen);
102 cur_ai = cur_ai->ai_next;
115 if (
s->recv_buffer_size > 0) {
116 if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &
s->recv_buffer_size, sizeof (
s->recv_buffer_size))) {
120 if (
s->send_buffer_size > 0) {
121 if (setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &
s->send_buffer_size, sizeof (
s->send_buffer_size))) {
125 if (
s->tcp_nodelay > 0) {
126 if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &
s->tcp_nodelay, sizeof (
s->tcp_nodelay))) {
130 if (
s->tcp_keepalive > 0) {
131 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &
s->tcp_keepalive,
sizeof(
s->tcp_keepalive))) {
137 if (
s->tcp_mss > 0) {
138 if (setsockopt (fd, IPPROTO_TCP, TCP_MAXSEG, &
s->tcp_mss, sizeof (
s->tcp_mss))) {
150 struct addrinfo hints = { 0 }, *ai, *cur_ai;
156 char hostname[1024],proto[1024],path[1024];
158 s->open_timeout = 5000000;
161 &port, path,
sizeof(path), uri);
162 if (strcmp(proto,
"tcp"))
164 if (port <= 0 || port >= 65536) {
168 p = strchr(uri,
'?');
172 s->listen = strtol(buf, &endptr, 10);
190 s->rw_timeout = strtol(buf,
NULL, 10);
193 s->listen_timeout = strtol(buf,
NULL, 10);
196 s->tcp_nodelay = strtol(buf,
NULL, 10);
199 s->tcp_keepalive = strtol(buf,
NULL, 10);
202 if (
s->rw_timeout >= 0) {
204 h->rw_timeout =
s->rw_timeout;
208 snprintf(portstr,
sizeof(portstr),
"%d", port);
217 "Failed to resolve hostname %s: %s\n",
224 #if HAVE_STRUCT_SOCKADDR_IN6
226 if (cur_ai->ai_family == AF_INET6){
227 struct sockaddr_in6 * sockaddr_v6 = (
struct sockaddr_in6 *)cur_ai->ai_addr;
228 if (!sockaddr_v6->sin6_port){
229 sockaddr_v6->sin6_port = htons(port);
235 while (cur_ai && fd < 0) {
238 cur_ai->ai_protocol,
h);
241 cur_ai = cur_ai->ai_next;
249 if (
s->listen == 2) {
251 if ((
ret =
ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
h)) < 0)
253 }
else if (
s->listen == 1) {
256 s->listen_timeout,
h)) < 0)
287 cc = (*c)->priv_data;
340 return shutdown(
s->fd, how);
360 socklen_t avail_len =
sizeof(avail);
365 if (
s->recv_buffer_size < 0) {
370 if (getsockopt(
s->fd, SOL_SOCKET, SO_RCVBUF, &avail, &avail_len)) {