1/* 2 * UDP prototype streaming system 3 * Copyright (c) 2000, 2001, 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 */ 21 22/** 23 * @file 24 * UDP protocol 25 */ 26 27#define _DEFAULT_SOURCE 28#define _BSD_SOURCE /* Needed for using struct ip_mreq with recent glibc */ 29 30#include "avformat.h" 31#include "avio_internal.h" 32#include "libavutil/avassert.h" 33#include "libavutil/parseutils.h" 34#include "libavutil/fifo.h" 35#include "libavutil/intreadwrite.h" 36#include "libavutil/avstring.h" 37#include "libavutil/opt.h" 38#include "libavutil/log.h" 39#include "libavutil/time.h" 40#include "internal.h" 41#include "network.h" 42#include "os_support.h" 43#include "url.h" 44#include "ip.h" 45 46#ifdef __APPLE__ 47#include "TargetConditionals.h" 48#endif 49 50#if HAVE_UDPLITE_H 51#include "udplite.h" 52#else 53/* On many Linux systems, udplite.h is missing but the kernel supports UDP-Lite. 54 * So, we provide a fallback here. 55 */ 56#define UDPLITE_SEND_CSCOV 10 57#define UDPLITE_RECV_CSCOV 11 58#endif 59 60#ifndef IPPROTO_UDPLITE 61#define IPPROTO_UDPLITE 136 62#endif 63 64#if HAVE_W32THREADS 65#undef HAVE_PTHREAD_CANCEL 66#define HAVE_PTHREAD_CANCEL 1 67#endif 68 69#if HAVE_PTHREAD_CANCEL 70#include "libavutil/thread.h" 71#endif 72 73#ifndef IPV6_ADD_MEMBERSHIP 74#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 75#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP 76#endif 77 78#define UDP_TX_BUF_SIZE 32768 79#define UDP_RX_BUF_SIZE 393216 80#define UDP_MAX_PKT_SIZE 65536 81#define UDP_HEADER_SIZE 8 82 83typedef struct UDPContext { 84 const AVClass *class; 85 int udp_fd; 86 int ttl; 87 int udplite_coverage; 88 int buffer_size; 89 int pkt_size; 90 int is_multicast; 91 int is_broadcast; 92 int local_port; 93 int reuse_socket; 94 int overrun_nonfatal; 95 struct sockaddr_storage dest_addr; 96 int dest_addr_len; 97 int is_connected; 98 99 /* Circular Buffer variables for use in UDP receive code */ 100 int circular_buffer_size; 101 AVFifo *fifo; 102 int circular_buffer_error; 103 int64_t bitrate; /* number of bits to send per second */ 104 int64_t burst_bits; 105 int close_req; 106#if HAVE_PTHREAD_CANCEL 107 pthread_t circular_buffer_thread; 108 pthread_mutex_t mutex; 109 pthread_cond_t cond; 110 int thread_started; 111#endif 112 uint8_t tmp[UDP_MAX_PKT_SIZE+4]; 113 int remaining_in_dg; 114 char *localaddr; 115 int timeout; 116 struct sockaddr_storage local_addr_storage; 117 char *sources; 118 char *block; 119 IPSourceFilters filters; 120} UDPContext; 121 122#define OFFSET(x) offsetof(UDPContext, x) 123#define D AV_OPT_FLAG_DECODING_PARAM 124#define E AV_OPT_FLAG_ENCODING_PARAM 125static const AVOption options[] = { 126 { "buffer_size", "System data size (in bytes)", OFFSET(buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, 127 { "bitrate", "Bits to send per second", OFFSET(bitrate), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, .flags = E }, 128 { "burst_bits", "Max length of bursts in bits (when using bitrate)", OFFSET(burst_bits), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, .flags = E }, 129 { "localport", "Local port", OFFSET(local_port), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, D|E }, 130 { "local_port", "Local port", OFFSET(local_port), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, 131 { "localaddr", "Local address", OFFSET(localaddr), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, 132 { "udplite_coverage", "choose UDPLite head size which should be validated by checksum", OFFSET(udplite_coverage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E }, 133 { "pkt_size", "Maximum UDP packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = 1472 }, -1, INT_MAX, .flags = D|E }, 134 { "reuse", "explicitly allow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, D|E }, 135 { "reuse_socket", "explicitly allow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E }, 136 { "broadcast", "explicitly allow or disallow broadcast destination", OFFSET(is_broadcast), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, 137 { "ttl", "Time to live (multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, { .i64 = 16 }, 0, 255, E }, 138 { "connect", "set if connect() should be called on socket", OFFSET(is_connected), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, 139 { "fifo_size", "set the UDP receiving circular buffer size, expressed as a number of packets with size of 188 bytes", OFFSET(circular_buffer_size), AV_OPT_TYPE_INT, {.i64 = 7*4096}, 0, INT_MAX, D }, 140 { "overrun_nonfatal", "survive in case of UDP receiving circular buffer overrun", OFFSET(overrun_nonfatal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, D }, 141 { "timeout", "set raise error timeout, in microseconds (only in read mode)",OFFSET(timeout), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D }, 142 { "sources", "Source list", OFFSET(sources), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, 143 { "block", "Block list", OFFSET(block), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, 144 { NULL } 145}; 146 147static const AVClass udp_class = { 148 .class_name = "udp", 149 .item_name = av_default_item_name, 150 .option = options, 151 .version = LIBAVUTIL_VERSION_INT, 152}; 153 154static const AVClass udplite_context_class = { 155 .class_name = "udplite", 156 .item_name = av_default_item_name, 157 .option = options, 158 .version = LIBAVUTIL_VERSION_INT, 159}; 160 161static int udp_set_multicast_ttl(int sockfd, int mcastTTL, 162 struct sockaddr *addr, 163 void *logctx) 164{ 165 int protocol, cmd; 166 167 /* There is some confusion in the world whether IP_MULTICAST_TTL 168 * takes a byte or an int as an argument. 169 * BSD seems to indicate byte so we are going with that and use 170 * int and fall back to byte to be safe */ 171 switch (addr->sa_family) { 172#ifdef IP_MULTICAST_TTL 173 case AF_INET: 174 protocol = IPPROTO_IP; 175 cmd = IP_MULTICAST_TTL; 176 break; 177#endif 178#ifdef IPV6_MULTICAST_HOPS 179 case AF_INET6: 180 protocol = IPPROTO_IPV6; 181 cmd = IPV6_MULTICAST_HOPS; 182 break; 183#endif 184 default: 185 return 0; 186 } 187 188 if (setsockopt(sockfd, protocol, cmd, &mcastTTL, sizeof(mcastTTL)) < 0) { 189 /* BSD compatibility */ 190 unsigned char ttl = (unsigned char) mcastTTL; 191 192 ff_log_net_error(logctx, AV_LOG_DEBUG, "setsockopt(IPV4/IPV6 MULTICAST TTL)"); 193 if (setsockopt(sockfd, protocol, cmd, &ttl, sizeof(ttl)) < 0) { 194 ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV4/IPV6 MULTICAST TTL)"); 195 return ff_neterrno(); 196 } 197 } 198 199 return 0; 200} 201 202static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, 203 struct sockaddr *local_addr, void *logctx) 204{ 205#ifdef IP_ADD_MEMBERSHIP 206 if (addr->sa_family == AF_INET) { 207 struct ip_mreq mreq; 208 209 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; 210 if (local_addr) 211 mreq.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr; 212 else 213 mreq.imr_interface.s_addr = INADDR_ANY; 214 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { 215 ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)"); 216 return ff_neterrno(); 217 } 218 } 219#endif 220#if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) 221 if (addr->sa_family == AF_INET6) { 222 struct ipv6_mreq mreq6; 223 224 memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); 225 //TODO: Interface index should be looked up from local_addr 226 mreq6.ipv6mr_interface = 0; 227 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { 228 ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)"); 229 return ff_neterrno(); 230 } 231 } 232#endif 233 return 0; 234} 235 236static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, 237 struct sockaddr *local_addr, void *logctx) 238{ 239#ifdef IP_DROP_MEMBERSHIP 240 if (addr->sa_family == AF_INET) { 241 struct ip_mreq mreq; 242 243 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; 244 if (local_addr) 245 mreq.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr; 246 else 247 mreq.imr_interface.s_addr = INADDR_ANY; 248 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { 249 ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)"); 250 return -1; 251 } 252 } 253#endif 254#if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) 255 if (addr->sa_family == AF_INET6) { 256 struct ipv6_mreq mreq6; 257 258 memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); 259 //TODO: Interface index should be looked up from local_addr 260 mreq6.ipv6mr_interface = 0; 261 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { 262 ff_log_net_error(logctx, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)"); 263 return -1; 264 } 265 } 266#endif 267 return 0; 268} 269 270static int udp_set_multicast_sources(URLContext *h, 271 int sockfd, struct sockaddr *addr, 272 int addr_len, struct sockaddr_storage *local_addr, 273 struct sockaddr_storage *sources, 274 int nb_sources, int include) 275{ 276 int i; 277 if (addr->sa_family != AF_INET) { 278#if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) 279 /* For IPv4 prefer the old approach, as that alone works reliably on 280 * Windows and it also supports supplying the interface based on its 281 * address. */ 282 int i; 283 for (i = 0; i < nb_sources; i++) { 284 struct group_source_req mreqs; 285 int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; 286 287 //TODO: Interface index should be looked up from local_addr 288 mreqs.gsr_interface = 0; 289 memcpy(&mreqs.gsr_group, addr, addr_len); 290 memcpy(&mreqs.gsr_source, &sources[i], sizeof(*sources)); 291 292 if (setsockopt(sockfd, level, 293 include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE, 294 (const void *)&mreqs, sizeof(mreqs)) < 0) { 295 if (include) 296 ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)"); 297 else 298 ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)"); 299 return ff_neterrno(); 300 } 301 } 302 return 0; 303#else 304 av_log(h, AV_LOG_ERROR, 305 "Setting multicast sources only supported for IPv4\n"); 306 return AVERROR(EINVAL); 307#endif 308 } 309#if HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE) 310 for (i = 0; i < nb_sources; i++) { 311 struct ip_mreq_source mreqs; 312 if (sources[i].ss_family != AF_INET) { 313 av_log(h, AV_LOG_ERROR, "Source/block address %d is of incorrect protocol family\n", i + 1); 314 return AVERROR(EINVAL); 315 } 316 317 mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; 318 if (local_addr) 319 mreqs.imr_interface = ((struct sockaddr_in *)local_addr)->sin_addr; 320 else 321 mreqs.imr_interface.s_addr = INADDR_ANY; 322 mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)&sources[i])->sin_addr.s_addr; 323 324 if (setsockopt(sockfd, IPPROTO_IP, 325 include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE, 326 (const void *)&mreqs, sizeof(mreqs)) < 0) { 327 if (include) 328 ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)"); 329 else 330 ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)"); 331 return ff_neterrno(); 332 } 333 } 334#else 335 return AVERROR(ENOSYS); 336#endif 337 return 0; 338} 339static int udp_set_url(URLContext *h, 340 struct sockaddr_storage *addr, 341 const char *hostname, int port) 342{ 343 struct addrinfo *res0; 344 int addr_len; 345 346 res0 = ff_ip_resolve_host(h, hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); 347 if (!res0) return AVERROR(EIO); 348 memcpy(addr, res0->ai_addr, res0->ai_addrlen); 349 addr_len = res0->ai_addrlen; 350 freeaddrinfo(res0); 351 352 return addr_len; 353} 354 355static int udp_socket_create(URLContext *h, struct sockaddr_storage *addr, 356 socklen_t *addr_len, const char *localaddr) 357{ 358 UDPContext *s = h->priv_data; 359 int udp_fd = -1; 360 struct addrinfo *res0, *res; 361 int family = AF_UNSPEC; 362 363 if (((struct sockaddr *) &s->dest_addr)->sa_family) 364 family = ((struct sockaddr *) &s->dest_addr)->sa_family; 365 res0 = ff_ip_resolve_host(h, (localaddr && localaddr[0]) ? localaddr : NULL, 366 s->local_port, 367 SOCK_DGRAM, family, AI_PASSIVE); 368 if (!res0) 369 goto fail; 370 for (res = res0; res; res=res->ai_next) { 371 if (s->udplite_coverage) 372 udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, IPPROTO_UDPLITE, h); 373 else 374 udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0, h); 375 if (udp_fd != -1) break; 376 ff_log_net_error(h, AV_LOG_ERROR, "socket"); 377 } 378 379 if (udp_fd < 0) 380 goto fail; 381 382 memcpy(addr, res->ai_addr, res->ai_addrlen); 383 *addr_len = res->ai_addrlen; 384 385 freeaddrinfo(res0); 386 387 return udp_fd; 388 389 fail: 390 if (udp_fd >= 0) 391 closesocket(udp_fd); 392 if(res0) 393 freeaddrinfo(res0); 394 return -1; 395} 396 397static int udp_port(struct sockaddr_storage *addr, int addr_len) 398{ 399 char sbuf[sizeof(int)*3+1]; 400 int error; 401 402 if ((error = getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV)) != 0) { 403 av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(error)); 404 return -1; 405 } 406 407 return strtol(sbuf, NULL, 10); 408} 409 410 411/** 412 * If no filename is given to av_open_input_file because you want to 413 * get the local port first, then you must call this function to set 414 * the remote server address. 415 * 416 * url syntax: udp://host:port[?option=val...] 417 * option: 'ttl=n' : set the ttl value (for multicast only) 418 * 'localport=n' : set the local port 419 * 'pkt_size=n' : set max packet size 420 * 'reuse=1' : enable reusing the socket 421 * 'overrun_nonfatal=1': survive in case of circular buffer overrun 422 * 423 * @param h media file context 424 * @param uri of the remote server 425 * @return zero if no error. 426 */ 427int ff_udp_set_remote_url(URLContext *h, const char *uri) 428{ 429 UDPContext *s = h->priv_data; 430 char hostname[256], buf[10]; 431 int port; 432 const char *p; 433 434 av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); 435 436 /* set the destination address */ 437 s->dest_addr_len = udp_set_url(h, &s->dest_addr, hostname, port); 438 if (s->dest_addr_len < 0) { 439 return AVERROR(EIO); 440 } 441 s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr); 442 p = strchr(uri, '?'); 443 if (p) { 444 if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { 445 int was_connected = s->is_connected; 446 s->is_connected = strtol(buf, NULL, 10); 447 if (s->is_connected && !was_connected) { 448 if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr, 449 s->dest_addr_len)) { 450 s->is_connected = 0; 451 ff_log_net_error(h, AV_LOG_ERROR, "connect"); 452 return AVERROR(EIO); 453 } 454 } 455 } 456 } 457 458 return 0; 459} 460 461/** 462 * Return the local port used by the UDP connection 463 * @param h media file context 464 * @return the local port number 465 */ 466int ff_udp_get_local_port(URLContext *h) 467{ 468 UDPContext *s = h->priv_data; 469 return s->local_port; 470} 471 472/** 473 * Return the udp file handle for select() usage to wait for several RTP 474 * streams at the same time. 475 * @param h media file context 476 */ 477static int udp_get_file_handle(URLContext *h) 478{ 479 UDPContext *s = h->priv_data; 480 return s->udp_fd; 481} 482 483#if HAVE_PTHREAD_CANCEL 484static void *circular_buffer_task_rx( void *_URLContext) 485{ 486 URLContext *h = _URLContext; 487 UDPContext *s = h->priv_data; 488 int old_cancelstate; 489 490 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate); 491 pthread_mutex_lock(&s->mutex); 492 if (ff_socket_nonblock(s->udp_fd, 0) < 0) { 493 av_log(h, AV_LOG_ERROR, "Failed to set blocking mode"); 494 s->circular_buffer_error = AVERROR(EIO); 495 goto end; 496 } 497 while(1) { 498 int len; 499 struct sockaddr_storage addr; 500 socklen_t addr_len = sizeof(addr); 501 502 pthread_mutex_unlock(&s->mutex); 503 /* Blocking operations are always cancellation points; 504 see "General Information" / "Thread Cancelation Overview" 505 in Single Unix. */ 506 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate); 507 len = recvfrom(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0, (struct sockaddr *)&addr, &addr_len); 508 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate); 509 pthread_mutex_lock(&s->mutex); 510 if (len < 0) { 511 if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) { 512 s->circular_buffer_error = ff_neterrno(); 513 goto end; 514 } 515 continue; 516 } 517 if (ff_ip_check_source_lists(&addr, &s->filters)) 518 continue; 519 AV_WL32(s->tmp, len); 520 521 if (av_fifo_can_write(s->fifo) < len + 4) { 522 /* No Space left */ 523 if (s->overrun_nonfatal) { 524 av_log(h, AV_LOG_WARNING, "Circular buffer overrun. " 525 "Surviving due to overrun_nonfatal option\n"); 526 continue; 527 } else { 528 av_log(h, AV_LOG_ERROR, "Circular buffer overrun. " 529 "To avoid, increase fifo_size URL option. " 530 "To survive in such case, use overrun_nonfatal option\n"); 531 s->circular_buffer_error = AVERROR(EIO); 532 goto end; 533 } 534 } 535 av_fifo_write(s->fifo, s->tmp, len + 4); 536 pthread_cond_signal(&s->cond); 537 } 538 539end: 540 pthread_cond_signal(&s->cond); 541 pthread_mutex_unlock(&s->mutex); 542 return NULL; 543} 544 545static void *circular_buffer_task_tx( void *_URLContext) 546{ 547 URLContext *h = _URLContext; 548 UDPContext *s = h->priv_data; 549 int64_t target_timestamp = av_gettime_relative(); 550 int64_t start_timestamp = av_gettime_relative(); 551 int64_t sent_bits = 0; 552 int64_t burst_interval = s->bitrate ? (s->burst_bits * 1000000 / s->bitrate) : 0; 553 int64_t max_delay = s->bitrate ? ((int64_t)h->max_packet_size * 8 * 1000000 / s->bitrate + 1) : 0; 554 555 pthread_mutex_lock(&s->mutex); 556 557 if (ff_socket_nonblock(s->udp_fd, 0) < 0) { 558 av_log(h, AV_LOG_ERROR, "Failed to set blocking mode"); 559 s->circular_buffer_error = AVERROR(EIO); 560 goto end; 561 } 562 563 for(;;) { 564 int len; 565 const uint8_t *p; 566 uint8_t tmp[4]; 567 int64_t timestamp; 568 569 len = av_fifo_can_read(s->fifo); 570 571 while (len<4) { 572 if (s->close_req) 573 goto end; 574 pthread_cond_wait(&s->cond, &s->mutex); 575 len = av_fifo_can_read(s->fifo); 576 } 577 578 av_fifo_read(s->fifo, tmp, 4); 579 len = AV_RL32(tmp); 580 581 av_assert0(len >= 0); 582 av_assert0(len <= sizeof(s->tmp)); 583 584 av_fifo_read(s->fifo, s->tmp, len); 585 586 pthread_mutex_unlock(&s->mutex); 587 588 if (s->bitrate) { 589 timestamp = av_gettime_relative(); 590 if (timestamp < target_timestamp) { 591 int64_t delay = target_timestamp - timestamp; 592 if (delay > max_delay) { 593 delay = max_delay; 594 start_timestamp = timestamp + delay; 595 sent_bits = 0; 596 } 597 av_usleep(delay); 598 } else { 599 if (timestamp - burst_interval > target_timestamp) { 600 start_timestamp = timestamp - burst_interval; 601 sent_bits = 0; 602 } 603 } 604 sent_bits += len * 8; 605 target_timestamp = start_timestamp + sent_bits * 1000000 / s->bitrate; 606 } 607 608 p = s->tmp; 609 while (len) { 610 int ret; 611 av_assert0(len > 0); 612 if (!s->is_connected) { 613 ret = sendto (s->udp_fd, p, len, 0, 614 (struct sockaddr *) &s->dest_addr, 615 s->dest_addr_len); 616 } else 617 ret = send(s->udp_fd, p, len, 0); 618 if (ret >= 0) { 619 len -= ret; 620 p += ret; 621 } else { 622 ret = ff_neterrno(); 623 if (ret != AVERROR(EAGAIN) && ret != AVERROR(EINTR)) { 624 pthread_mutex_lock(&s->mutex); 625 s->circular_buffer_error = ret; 626 pthread_mutex_unlock(&s->mutex); 627 return NULL; 628 } 629 } 630 } 631 632 pthread_mutex_lock(&s->mutex); 633 } 634 635end: 636 pthread_mutex_unlock(&s->mutex); 637 return NULL; 638} 639 640 641#endif 642 643/* put it in UDP context */ 644/* return non zero if error */ 645static int udp_open(URLContext *h, const char *uri, int flags) 646{ 647 char hostname[1024]; 648 int port, udp_fd = -1, tmp, bind_ret = -1, dscp = -1; 649 UDPContext *s = h->priv_data; 650 int is_output; 651 const char *p; 652 char buf[256]; 653 struct sockaddr_storage my_addr; 654 socklen_t len; 655 int ret; 656 657 h->is_streamed = 1; 658 659 is_output = !(flags & AVIO_FLAG_READ); 660 if (s->buffer_size < 0) 661 s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_RX_BUF_SIZE; 662 663 if (s->sources) { 664 if ((ret = ff_ip_parse_sources(h, s->sources, &s->filters)) < 0) 665 goto fail; 666 } 667 668 if (s->block) { 669 if ((ret = ff_ip_parse_blocks(h, s->block, &s->filters)) < 0) 670 goto fail; 671 } 672 673 p = strchr(uri, '?'); 674 if (p) { 675 if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) { 676 char *endptr = NULL; 677 s->reuse_socket = strtol(buf, &endptr, 10); 678 /* assume if no digits were found it is a request to enable it */ 679 if (buf == endptr) 680 s->reuse_socket = 1; 681 } 682 if (av_find_info_tag(buf, sizeof(buf), "overrun_nonfatal", p)) { 683 char *endptr = NULL; 684 s->overrun_nonfatal = strtol(buf, &endptr, 10); 685 /* assume if no digits were found it is a request to enable it */ 686 if (buf == endptr) 687 s->overrun_nonfatal = 1; 688 if (!HAVE_PTHREAD_CANCEL) 689 av_log(h, AV_LOG_WARNING, 690 "'overrun_nonfatal' option was set but it is not supported " 691 "on this build (pthread support is required)\n"); 692 } 693 if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) { 694 s->ttl = strtol(buf, NULL, 10); 695 if (s->ttl < 0 || s->ttl > 255) { 696 av_log(h, AV_LOG_ERROR, "ttl(%d) should be in range [0,255]\n", s->ttl); 697 ret = AVERROR(EINVAL); 698 goto fail; 699 } 700 } 701 if (av_find_info_tag(buf, sizeof(buf), "udplite_coverage", p)) { 702 s->udplite_coverage = strtol(buf, NULL, 10); 703 } 704 if (av_find_info_tag(buf, sizeof(buf), "localport", p)) { 705 s->local_port = strtol(buf, NULL, 10); 706 } 707 if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) { 708 s->pkt_size = strtol(buf, NULL, 10); 709 } 710 if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) { 711 s->buffer_size = strtol(buf, NULL, 10); 712 } 713 if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { 714 s->is_connected = strtol(buf, NULL, 10); 715 } 716 if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) { 717 dscp = strtol(buf, NULL, 10); 718 } 719 if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) { 720 s->circular_buffer_size = strtol(buf, NULL, 10); 721 if (!HAVE_PTHREAD_CANCEL) 722 av_log(h, AV_LOG_WARNING, 723 "'circular_buffer_size' option was set but it is not supported " 724 "on this build (pthread support is required)\n"); 725 } 726 if (av_find_info_tag(buf, sizeof(buf), "bitrate", p)) { 727 s->bitrate = strtoll(buf, NULL, 10); 728 if (!HAVE_PTHREAD_CANCEL) 729 av_log(h, AV_LOG_WARNING, 730 "'bitrate' option was set but it is not supported " 731 "on this build (pthread support is required)\n"); 732 } 733 if (av_find_info_tag(buf, sizeof(buf), "burst_bits", p)) { 734 s->burst_bits = strtoll(buf, NULL, 10); 735 } 736 if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) { 737 av_freep(&s->localaddr); 738 s->localaddr = av_strdup(buf); 739 } 740 if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { 741 if ((ret = ff_ip_parse_sources(h, buf, &s->filters)) < 0) 742 goto fail; 743 } 744 if (av_find_info_tag(buf, sizeof(buf), "block", p)) { 745 if ((ret = ff_ip_parse_blocks(h, buf, &s->filters)) < 0) 746 goto fail; 747 } 748 if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p)) 749 s->timeout = strtol(buf, NULL, 10); 750 if (is_output && av_find_info_tag(buf, sizeof(buf), "broadcast", p)) 751 s->is_broadcast = strtol(buf, NULL, 10); 752 } 753 /* handling needed to support options picking from both AVOption and URL */ 754 s->circular_buffer_size *= 188; 755 if (flags & AVIO_FLAG_WRITE) { 756 h->max_packet_size = s->pkt_size; 757 } else { 758 h->max_packet_size = UDP_MAX_PKT_SIZE; 759 } 760 h->rw_timeout = s->timeout; 761 762 /* fill the dest addr */ 763 av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); 764 765 /* XXX: fix av_url_split */ 766 if (hostname[0] == '\0' || hostname[0] == '?') { 767 /* only accepts null hostname if input */ 768 if (!(flags & AVIO_FLAG_READ)) { 769 ret = AVERROR(EINVAL); 770 goto fail; 771 } 772 } else { 773 if ((ret = ff_udp_set_remote_url(h, uri)) < 0) 774 goto fail; 775 } 776 777 if ((s->is_multicast || s->local_port <= 0) && (h->flags & AVIO_FLAG_READ)) 778 s->local_port = port; 779 780 udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr); 781 if (udp_fd < 0) { 782 ret = AVERROR(EIO); 783 goto fail; 784 } 785 786 s->local_addr_storage=my_addr; //store for future multicast join 787 788 /* Follow the requested reuse option, unless it's multicast in which 789 * case enable reuse unless explicitly disabled. 790 */ 791 if (s->reuse_socket > 0 || (s->is_multicast && s->reuse_socket < 0)) { 792 s->reuse_socket = 1; 793 if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) { 794 ret = ff_neterrno(); 795 goto fail; 796 } 797 } 798 799 if (s->is_broadcast) { 800#ifdef SO_BROADCAST 801 if (setsockopt (udp_fd, SOL_SOCKET, SO_BROADCAST, &(s->is_broadcast), sizeof(s->is_broadcast)) != 0) { 802 ret = ff_neterrno(); 803 goto fail; 804 } 805#else 806 ret = AVERROR(ENOSYS); 807 goto fail; 808#endif 809 } 810 811 /* Set the checksum coverage for UDP-Lite (RFC 3828) for sending and receiving. 812 * The receiver coverage has to be less than or equal to the sender coverage. 813 * Otherwise, the receiver will drop all packets. 814 */ 815 if (s->udplite_coverage) { 816 if (setsockopt (udp_fd, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, &(s->udplite_coverage), sizeof(s->udplite_coverage)) != 0) 817 av_log(h, AV_LOG_WARNING, "socket option UDPLITE_SEND_CSCOV not available"); 818 819 if (setsockopt (udp_fd, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, &(s->udplite_coverage), sizeof(s->udplite_coverage)) != 0) 820 av_log(h, AV_LOG_WARNING, "socket option UDPLITE_RECV_CSCOV not available"); 821 } 822 823 if (dscp >= 0) { 824 dscp <<= 2; 825 if (setsockopt (udp_fd, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) != 0) { 826 ret = ff_neterrno(); 827 goto fail; 828 } 829 } 830 831 /* If multicast, try binding the multicast address first, to avoid 832 * receiving UDP packets from other sources aimed at the same UDP 833 * port. This fails on windows. This makes sending to the same address 834 * using sendto() fail, so only do it if we're opened in read-only mode. */ 835 if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) { 836 bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); 837 } 838 /* bind to the local address if not multicast or if the multicast 839 * bind failed */ 840 /* the bind is needed to give a port to the socket now */ 841 if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) { 842 ff_log_net_error(h, AV_LOG_ERROR, "bind failed"); 843 ret = ff_neterrno(); 844 goto fail; 845 } 846 847 len = sizeof(my_addr); 848 getsockname(udp_fd, (struct sockaddr *)&my_addr, &len); 849 s->local_port = udp_port(&my_addr, len); 850 851 if (s->is_multicast) { 852 if (h->flags & AVIO_FLAG_WRITE) { 853 /* output */ 854 if ((ret = udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr, h)) < 0) 855 goto fail; 856 } 857 if (h->flags & AVIO_FLAG_READ) { 858 /* input */ 859 if (s->filters.nb_include_addrs) { 860 if ((ret = udp_set_multicast_sources(h, udp_fd, 861 (struct sockaddr *)&s->dest_addr, 862 s->dest_addr_len, &s->local_addr_storage, 863 s->filters.include_addrs, 864 s->filters.nb_include_addrs, 1)) < 0) 865 goto fail; 866 } else { 867 if ((ret = udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr, 868 (struct sockaddr *)&s->local_addr_storage, h)) < 0) 869 goto fail; 870 } 871 if (s->filters.nb_exclude_addrs) { 872 if ((ret = udp_set_multicast_sources(h, udp_fd, 873 (struct sockaddr *)&s->dest_addr, 874 s->dest_addr_len, &s->local_addr_storage, 875 s->filters.exclude_addrs, 876 s->filters.nb_exclude_addrs, 0)) < 0) 877 goto fail; 878 } 879 } 880 } 881 882 if (is_output) { 883 /* limit the tx buf size to limit latency */ 884 tmp = s->buffer_size; 885 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { 886 ff_log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)"); 887 ret = ff_neterrno(); 888 goto fail; 889 } 890 } else { 891 /* set udp recv buffer size to the requested value (default UDP_RX_BUF_SIZE) */ 892 tmp = s->buffer_size; 893 if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) { 894 ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)"); 895 } 896 len = sizeof(tmp); 897 if (getsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, &len) < 0) { 898 ff_log_net_error(h, AV_LOG_WARNING, "getsockopt(SO_RCVBUF)"); 899 } else { 900 av_log(h, AV_LOG_DEBUG, "end receive buffer size reported is %d\n", tmp); 901 if(tmp < s->buffer_size) 902 av_log(h, AV_LOG_WARNING, "attempted to set receive buffer to size %d but it only ended up set as %d\n", s->buffer_size, tmp); 903 } 904 905 /* make the socket non-blocking */ 906 ff_socket_nonblock(udp_fd, 1); 907 } 908 if (s->is_connected) { 909 if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) { 910 ff_log_net_error(h, AV_LOG_ERROR, "connect"); 911 ret = ff_neterrno(); 912 goto fail; 913 } 914 } 915 916 s->udp_fd = udp_fd; 917 918#if HAVE_PTHREAD_CANCEL 919 /* 920 Create thread in case of: 921 1. Input and circular_buffer_size is set 922 2. Output and bitrate and circular_buffer_size is set 923 */ 924 925 if (is_output && s->bitrate && !s->circular_buffer_size) { 926 /* Warn user in case of 'circular_buffer_size' is not set */ 927 av_log(h, AV_LOG_WARNING,"'bitrate' option was set but 'circular_buffer_size' is not, but required\n"); 928 } 929 930 if ((!is_output && s->circular_buffer_size) || (is_output && s->bitrate && s->circular_buffer_size)) { 931 /* start the task going */ 932 s->fifo = av_fifo_alloc2(s->circular_buffer_size, 1, 0); 933 if (!s->fifo) { 934 ret = AVERROR(ENOMEM); 935 goto fail; 936 } 937 ret = pthread_mutex_init(&s->mutex, NULL); 938 if (ret != 0) { 939 av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret)); 940 ret = AVERROR(ret); 941 goto fail; 942 } 943 ret = pthread_cond_init(&s->cond, NULL); 944 if (ret != 0) { 945 av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret)); 946 ret = AVERROR(ret); 947 goto cond_fail; 948 } 949 ret = pthread_create(&s->circular_buffer_thread, NULL, is_output?circular_buffer_task_tx:circular_buffer_task_rx, h); 950 if (ret != 0) { 951 av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret)); 952 ret = AVERROR(ret); 953 goto thread_fail; 954 } 955 s->thread_started = 1; 956 } 957#endif 958 959 return 0; 960#if HAVE_PTHREAD_CANCEL 961 thread_fail: 962 pthread_cond_destroy(&s->cond); 963 cond_fail: 964 pthread_mutex_destroy(&s->mutex); 965#endif 966 fail: 967 if (udp_fd >= 0) 968 closesocket(udp_fd); 969 av_fifo_freep2(&s->fifo); 970 ff_ip_reset_filters(&s->filters); 971 return ret; 972} 973 974static int udplite_open(URLContext *h, const char *uri, int flags) 975{ 976 UDPContext *s = h->priv_data; 977 978 // set default checksum coverage 979 s->udplite_coverage = UDP_HEADER_SIZE; 980 981 return udp_open(h, uri, flags); 982} 983 984static int udp_read(URLContext *h, uint8_t *buf, int size) 985{ 986 UDPContext *s = h->priv_data; 987 int ret; 988 struct sockaddr_storage addr; 989 socklen_t addr_len = sizeof(addr); 990#if HAVE_PTHREAD_CANCEL 991 int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK; 992 993 if (s->fifo) { 994 pthread_mutex_lock(&s->mutex); 995 do { 996 avail = av_fifo_can_read(s->fifo); 997 if (avail) { // >=size) { 998 uint8_t tmp[4]; 999 1000 av_fifo_read(s->fifo, tmp, 4); 1001 avail = AV_RL32(tmp); 1002 if(avail > size){ 1003 av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n"); 1004 avail = size; 1005 } 1006 1007 av_fifo_read(s->fifo, buf, avail); 1008 av_fifo_drain2(s->fifo, AV_RL32(tmp) - avail); 1009 pthread_mutex_unlock(&s->mutex); 1010 return avail; 1011 } else if(s->circular_buffer_error){ 1012 int err = s->circular_buffer_error; 1013 pthread_mutex_unlock(&s->mutex); 1014 return err; 1015 } else if(nonblock) { 1016 pthread_mutex_unlock(&s->mutex); 1017 return AVERROR(EAGAIN); 1018 } else { 1019 /* FIXME: using the monotonic clock would be better, 1020 but it does not exist on all supported platforms. */ 1021 int64_t t = av_gettime() + 100000; 1022 struct timespec tv = { .tv_sec = t / 1000000, 1023 .tv_nsec = (t % 1000000) * 1000 }; 1024 int err = pthread_cond_timedwait(&s->cond, &s->mutex, &tv); 1025 if (err) { 1026 pthread_mutex_unlock(&s->mutex); 1027 return AVERROR(err == ETIMEDOUT ? EAGAIN : err); 1028 } 1029 nonblock = 1; 1030 } 1031 } while(1); 1032 } 1033#endif 1034 1035 if (!(h->flags & AVIO_FLAG_NONBLOCK)) { 1036 ret = ff_network_wait_fd(s->udp_fd, 0); 1037 if (ret < 0) 1038 return ret; 1039 } 1040 ret = recvfrom(s->udp_fd, buf, size, 0, (struct sockaddr *)&addr, &addr_len); 1041 if (ret < 0) 1042 return ff_neterrno(); 1043 if (ff_ip_check_source_lists(&addr, &s->filters)) 1044 return AVERROR(EINTR); 1045 return ret; 1046} 1047 1048static int udp_write(URLContext *h, const uint8_t *buf, int size) 1049{ 1050 UDPContext *s = h->priv_data; 1051 int ret; 1052 1053#if HAVE_PTHREAD_CANCEL 1054 if (s->fifo) { 1055 uint8_t tmp[4]; 1056 1057 pthread_mutex_lock(&s->mutex); 1058 1059 /* 1060 Return error if last tx failed. 1061 Here we can't know on which packet error was, but it needs to know that error exists. 1062 */ 1063 if (s->circular_buffer_error<0) { 1064 int err = s->circular_buffer_error; 1065 pthread_mutex_unlock(&s->mutex); 1066 return err; 1067 } 1068 1069 if (av_fifo_can_write(s->fifo) < size + 4) { 1070 /* What about a partial packet tx ? */ 1071 pthread_mutex_unlock(&s->mutex); 1072 return AVERROR(ENOMEM); 1073 } 1074 AV_WL32(tmp, size); 1075 av_fifo_write(s->fifo, tmp, 4); /* size of packet */ 1076 av_fifo_write(s->fifo, buf, size); /* the data */ 1077 pthread_cond_signal(&s->cond); 1078 pthread_mutex_unlock(&s->mutex); 1079 return size; 1080 } 1081#endif 1082 if (!(h->flags & AVIO_FLAG_NONBLOCK)) { 1083 ret = ff_network_wait_fd(s->udp_fd, 1); 1084 if (ret < 0) 1085 return ret; 1086 } 1087 1088 if (!s->is_connected) { 1089 ret = sendto (s->udp_fd, buf, size, 0, 1090 (struct sockaddr *) &s->dest_addr, 1091 s->dest_addr_len); 1092 } else 1093 ret = send(s->udp_fd, buf, size, 0); 1094 1095 return ret < 0 ? ff_neterrno() : ret; 1096} 1097 1098static int udp_close(URLContext *h) 1099{ 1100 UDPContext *s = h->priv_data; 1101 1102#if HAVE_PTHREAD_CANCEL 1103 // Request close once writing is finished 1104 if (s->thread_started && !(h->flags & AVIO_FLAG_READ)) { 1105 pthread_mutex_lock(&s->mutex); 1106 s->close_req = 1; 1107 pthread_cond_signal(&s->cond); 1108 pthread_mutex_unlock(&s->mutex); 1109 } 1110#endif 1111 1112 if (s->is_multicast && (h->flags & AVIO_FLAG_READ)) 1113 udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr, 1114 (struct sockaddr *)&s->local_addr_storage, h); 1115#if HAVE_PTHREAD_CANCEL 1116 if (s->thread_started) { 1117 int ret; 1118 // Cancel only read, as write has been signaled as success to the user 1119 if (h->flags & AVIO_FLAG_READ) { 1120#ifdef _WIN32 1121 /* recvfrom() is not a cancellation point for win32, so we shutdown 1122 * the socket and abort pending IO, subsequent recvfrom() calls 1123 * will fail with WSAESHUTDOWN causing the thread to exit. */ 1124 shutdown(s->udp_fd, SD_RECEIVE); 1125 CancelIoEx((HANDLE)(SOCKET)s->udp_fd, NULL); 1126#else 1127 pthread_cancel(s->circular_buffer_thread); 1128#endif 1129 } 1130 ret = pthread_join(s->circular_buffer_thread, NULL); 1131 if (ret != 0) 1132 av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret)); 1133 pthread_mutex_destroy(&s->mutex); 1134 pthread_cond_destroy(&s->cond); 1135 } 1136#endif 1137 closesocket(s->udp_fd); 1138 av_fifo_freep2(&s->fifo); 1139 ff_ip_reset_filters(&s->filters); 1140 return 0; 1141} 1142 1143const URLProtocol ff_udp_protocol = { 1144 .name = "udp", 1145 .url_open = udp_open, 1146 .url_read = udp_read, 1147 .url_write = udp_write, 1148 .url_close = udp_close, 1149 .url_get_file_handle = udp_get_file_handle, 1150 .priv_data_size = sizeof(UDPContext), 1151 .priv_data_class = &udp_class, 1152 .flags = URL_PROTOCOL_FLAG_NETWORK, 1153}; 1154 1155const URLProtocol ff_udplite_protocol = { 1156 .name = "udplite", 1157 .url_open = udplite_open, 1158 .url_read = udp_read, 1159 .url_write = udp_write, 1160 .url_close = udp_close, 1161 .url_get_file_handle = udp_get_file_handle, 1162 .priv_data_size = sizeof(UDPContext), 1163 .priv_data_class = &udplite_context_class, 1164 .flags = URL_PROTOCOL_FLAG_NETWORK, 1165}; 1166