udp.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. * UDP prototype streaming system
  3. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file
  23. * UDP protocol
  24. */
  25. #define _BSD_SOURCE /* Needed for using struct ip_mreq with recent glibc */
  26. #define _DARWIN_C_SOURCE /* Needed for using IP_MULTICAST_TTL on OS X */
  27. #include "avformat.h"
  28. #include "libavutil/parseutils.h"
  29. #include <unistd.h>
  30. #include "internal.h"
  31. #include "network.h"
  32. #include "os_support.h"
  33. #if HAVE_POLL_H
  34. #include <poll.h>
  35. #endif
  36. #include <sys/time.h>
  37. #ifndef IPV6_ADD_MEMBERSHIP
  38. #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
  39. #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
  40. #endif
  41. typedef struct {
  42. int udp_fd;
  43. int ttl;
  44. int buffer_size;
  45. int is_multicast;
  46. int local_port;
  47. int reuse_socket;
  48. struct sockaddr_storage dest_addr;
  49. int dest_addr_len;
  50. int is_connected;
  51. } UDPContext;
  52. #define UDP_TX_BUF_SIZE 32768
  53. #define UDP_MAX_PKT_SIZE 65536
  54. static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
  55. struct sockaddr *addr)
  56. {
  57. #ifdef IP_MULTICAST_TTL
  58. if (addr->sa_family == AF_INET) {
  59. if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
  60. av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno));
  61. return -1;
  62. }
  63. }
  64. #endif
  65. #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
  66. if (addr->sa_family == AF_INET6) {
  67. if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
  68. av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno));
  69. return -1;
  70. }
  71. }
  72. #endif
  73. return 0;
  74. }
  75. static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
  76. {
  77. #ifdef IP_ADD_MEMBERSHIP
  78. if (addr->sa_family == AF_INET) {
  79. struct ip_mreq mreq;
  80. mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
  81. mreq.imr_interface.s_addr= INADDR_ANY;
  82. if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
  83. av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno));
  84. return -1;
  85. }
  86. }
  87. #endif
  88. #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
  89. if (addr->sa_family == AF_INET6) {
  90. struct ipv6_mreq mreq6;
  91. memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
  92. mreq6.ipv6mr_interface= 0;
  93. if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
  94. av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno));
  95. return -1;
  96. }
  97. }
  98. #endif
  99. return 0;
  100. }
  101. static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr)
  102. {
  103. #ifdef IP_DROP_MEMBERSHIP
  104. if (addr->sa_family == AF_INET) {
  105. struct ip_mreq mreq;
  106. mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
  107. mreq.imr_interface.s_addr= INADDR_ANY;
  108. if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
  109. av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno));
  110. return -1;
  111. }
  112. }
  113. #endif
  114. #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
  115. if (addr->sa_family == AF_INET6) {
  116. struct ipv6_mreq mreq6;
  117. memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
  118. mreq6.ipv6mr_interface= 0;
  119. if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
  120. av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno));
  121. return -1;
  122. }
  123. }
  124. #endif
  125. return 0;
  126. }
  127. static struct addrinfo* udp_resolve_host(const char *hostname, int port,
  128. int type, int family, int flags)
  129. {
  130. struct addrinfo hints, *res = 0;
  131. int error;
  132. char sport[16];
  133. const char *node = 0, *service = "0";
  134. if (port > 0) {
  135. snprintf(sport, sizeof(sport), "%d", port);
  136. service = sport;
  137. }
  138. if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) {
  139. node = hostname;
  140. }
  141. memset(&hints, 0, sizeof(hints));
  142. hints.ai_socktype = type;
  143. hints.ai_family = family;
  144. hints.ai_flags = flags;
  145. if ((error = getaddrinfo(node, service, &hints, &res))) {
  146. res = NULL;
  147. av_log(NULL, AV_LOG_ERROR, "udp_resolve_host: %s\n", gai_strerror(error));
  148. }
  149. return res;
  150. }
  151. static int udp_set_url(struct sockaddr_storage *addr,
  152. const char *hostname, int port)
  153. {
  154. struct addrinfo *res0;
  155. int addr_len;
  156. res0 = udp_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0);
  157. if (res0 == 0) return AVERROR(EIO);
  158. memcpy(addr, res0->ai_addr, res0->ai_addrlen);
  159. addr_len = res0->ai_addrlen;
  160. freeaddrinfo(res0);
  161. return addr_len;
  162. }
  163. static int udp_socket_create(UDPContext *s,
  164. struct sockaddr_storage *addr, int *addr_len)
  165. {
  166. int udp_fd = -1;
  167. struct addrinfo *res0 = NULL, *res = NULL;
  168. int family = AF_UNSPEC;
  169. if (((struct sockaddr *) &s->dest_addr)->sa_family)
  170. family = ((struct sockaddr *) &s->dest_addr)->sa_family;
  171. res0 = udp_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE);
  172. if (res0 == 0)
  173. goto fail;
  174. for (res = res0; res; res=res->ai_next) {
  175. udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
  176. if (udp_fd > 0) break;
  177. av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno));
  178. }
  179. if (udp_fd < 0)
  180. goto fail;
  181. memcpy(addr, res->ai_addr, res->ai_addrlen);
  182. *addr_len = res->ai_addrlen;
  183. freeaddrinfo(res0);
  184. return udp_fd;
  185. fail:
  186. if (udp_fd >= 0)
  187. closesocket(udp_fd);
  188. if(res0)
  189. freeaddrinfo(res0);
  190. return -1;
  191. }
  192. static int udp_port(struct sockaddr_storage *addr, int addr_len)
  193. {
  194. char sbuf[sizeof(int)*3+1];
  195. if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) {
  196. av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno));
  197. return -1;
  198. }
  199. return strtol(sbuf, NULL, 10);
  200. }
  201. /**
  202. * If no filename is given to av_open_input_file because you want to
  203. * get the local port first, then you must call this function to set
  204. * the remote server address.
  205. *
  206. * url syntax: udp://host:port[?option=val...]
  207. * option: 'ttl=n' : set the ttl value (for multicast only)
  208. * 'localport=n' : set the local port
  209. * 'pkt_size=n' : set max packet size
  210. * 'reuse=1' : enable reusing the socket
  211. *
  212. * @param h media file context
  213. * @param uri of the remote server
  214. * @return zero if no error.
  215. */
  216. int udp_set_remote_url(URLContext *h, const char *uri)
  217. {
  218. UDPContext *s = h->priv_data;
  219. char hostname[256], buf[10];
  220. int port;
  221. const char *p;
  222. av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
  223. /* set the destination address */
  224. s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port);
  225. if (s->dest_addr_len < 0) {
  226. return AVERROR(EIO);
  227. }
  228. s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr);
  229. p = strchr(uri, '?');
  230. if (p) {
  231. if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
  232. int was_connected = s->is_connected;
  233. s->is_connected = strtol(buf, NULL, 10);
  234. if (s->is_connected && !was_connected) {
  235. if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr,
  236. s->dest_addr_len)) {
  237. s->is_connected = 0;
  238. av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
  239. return AVERROR(EIO);
  240. }
  241. }
  242. }
  243. }
  244. return 0;
  245. }
  246. /**
  247. * Return the local port used by the UDP connection
  248. * @param h media file context
  249. * @return the local port number
  250. */
  251. int udp_get_local_port(URLContext *h)
  252. {
  253. UDPContext *s = h->priv_data;
  254. return s->local_port;
  255. }
  256. /**
  257. * Return the udp file handle for select() usage to wait for several RTP
  258. * streams at the same time.
  259. * @param h media file context
  260. */
  261. #if !FF_API_UDP_GET_FILE
  262. static
  263. #endif
  264. int udp_get_file_handle(URLContext *h)
  265. {
  266. UDPContext *s = h->priv_data;
  267. return s->udp_fd;
  268. }
  269. /* put it in UDP context */
  270. /* return non zero if error */
  271. static int udp_open(URLContext *h, const char *uri, int flags)
  272. {
  273. char hostname[1024];
  274. int port, udp_fd = -1, tmp, bind_ret = -1;
  275. UDPContext *s = NULL;
  276. int is_output;
  277. const char *p;
  278. char buf[256];
  279. struct sockaddr_storage my_addr;
  280. int len;
  281. int reuse_specified = 0;
  282. h->is_streamed = 1;
  283. h->max_packet_size = 1472;
  284. is_output = (flags & URL_WRONLY);
  285. s = av_mallocz(sizeof(UDPContext));
  286. if (!s)
  287. return AVERROR(ENOMEM);
  288. h->priv_data = s;
  289. s->ttl = 16;
  290. s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
  291. p = strchr(uri, '?');
  292. if (p) {
  293. if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
  294. const char *endptr=NULL;
  295. s->reuse_socket = strtol(buf, &endptr, 10);
  296. /* assume if no digits were found it is a request to enable it */
  297. if (buf == endptr)
  298. s->reuse_socket = 1;
  299. reuse_specified = 1;
  300. }
  301. if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
  302. s->ttl = strtol(buf, NULL, 10);
  303. }
  304. if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
  305. s->local_port = strtol(buf, NULL, 10);
  306. }
  307. if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
  308. h->max_packet_size = strtol(buf, NULL, 10);
  309. }
  310. if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
  311. s->buffer_size = strtol(buf, NULL, 10);
  312. }
  313. if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
  314. s->is_connected = strtol(buf, NULL, 10);
  315. }
  316. }
  317. /* fill the dest addr */
  318. av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
  319. /* XXX: fix av_url_split */
  320. if (hostname[0] == '\0' || hostname[0] == '?') {
  321. /* only accepts null hostname if input */
  322. if (flags & URL_WRONLY)
  323. goto fail;
  324. } else {
  325. if (udp_set_remote_url(h, uri) < 0)
  326. goto fail;
  327. }
  328. if (s->is_multicast && !(h->flags & URL_WRONLY))
  329. s->local_port = port;
  330. udp_fd = udp_socket_create(s, &my_addr, &len);
  331. if (udp_fd < 0)
  332. goto fail;
  333. /* Follow the requested reuse option, unless it's multicast in which
  334. * case enable reuse unless explicitely disabled.
  335. */
  336. if (s->reuse_socket || (s->is_multicast && !reuse_specified)) {
  337. s->reuse_socket = 1;
  338. if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
  339. goto fail;
  340. }
  341. /* the bind is needed to give a port to the socket now */
  342. /* if multicast, try the multicast address bind first */
  343. if (s->is_multicast && !(h->flags & URL_WRONLY)) {
  344. bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len);
  345. }
  346. /* bind to the local address if not multicast or if the multicast
  347. * bind failed */
  348. if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0)
  349. goto fail;
  350. len = sizeof(my_addr);
  351. getsockname(udp_fd, (struct sockaddr *)&my_addr, &len);
  352. s->local_port = udp_port(&my_addr, len);
  353. if (s->is_multicast) {
  354. if (h->flags & URL_WRONLY) {
  355. /* output */
  356. if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)
  357. goto fail;
  358. } else {
  359. /* input */
  360. if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0)
  361. goto fail;
  362. }
  363. }
  364. if (is_output) {
  365. /* limit the tx buf size to limit latency */
  366. tmp = s->buffer_size;
  367. if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {
  368. av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno));
  369. goto fail;
  370. }
  371. } else {
  372. /* set udp recv buffer size to the largest possible udp packet size to
  373. * avoid losing data on OSes that set this too low by default. */
  374. tmp = s->buffer_size;
  375. if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {
  376. av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno));
  377. }
  378. /* make the socket non-blocking */
  379. ff_socket_nonblock(udp_fd, 1);
  380. }
  381. if (s->is_connected) {
  382. if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) {
  383. av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
  384. goto fail;
  385. }
  386. }
  387. s->udp_fd = udp_fd;
  388. return 0;
  389. fail:
  390. if (udp_fd >= 0)
  391. closesocket(udp_fd);
  392. av_free(s);
  393. return AVERROR(EIO);
  394. }
  395. static int udp_read(URLContext *h, uint8_t *buf, int size)
  396. {
  397. UDPContext *s = h->priv_data;
  398. struct pollfd p = {s->udp_fd, POLLIN, 0};
  399. int len;
  400. int ret;
  401. for(;;) {
  402. if (url_interrupt_cb())
  403. return AVERROR_EXIT;
  404. ret = poll(&p, 1, 100);
  405. if (ret < 0) {
  406. if (ff_neterrno() == AVERROR(EINTR))
  407. continue;
  408. return AVERROR(EIO);
  409. }
  410. if (!(ret == 1 && p.revents & POLLIN))
  411. continue;
  412. len = recv(s->udp_fd, buf, size, 0);
  413. if (len < 0) {
  414. if (ff_neterrno() != AVERROR(EAGAIN) &&
  415. ff_neterrno() != AVERROR(EINTR))
  416. return AVERROR(EIO);
  417. } else {
  418. break;
  419. }
  420. }
  421. return len;
  422. }
  423. static int udp_write(URLContext *h, const uint8_t *buf, int size)
  424. {
  425. UDPContext *s = h->priv_data;
  426. int ret;
  427. for(;;) {
  428. if (!s->is_connected) {
  429. ret = sendto (s->udp_fd, buf, size, 0,
  430. (struct sockaddr *) &s->dest_addr,
  431. s->dest_addr_len);
  432. } else
  433. ret = send(s->udp_fd, buf, size, 0);
  434. if (ret < 0) {
  435. if (ff_neterrno() != AVERROR(EINTR) &&
  436. ff_neterrno() != AVERROR(EAGAIN))
  437. return ff_neterrno();
  438. } else {
  439. break;
  440. }
  441. }
  442. return size;
  443. }
  444. static int udp_close(URLContext *h)
  445. {
  446. UDPContext *s = h->priv_data;
  447. if (s->is_multicast && !(h->flags & URL_WRONLY))
  448. udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
  449. closesocket(s->udp_fd);
  450. av_free(s);
  451. return 0;
  452. }
  453. URLProtocol ff_udp_protocol = {
  454. "udp",
  455. udp_open,
  456. udp_read,
  457. udp_write,
  458. NULL, /* seek */
  459. udp_close,
  460. .url_get_file_handle = udp_get_file_handle,
  461. };