You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

525 lines
15KB

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