From: Martin Molnar Date: Wed, 20 May 2009 17:58:11 +0000 (+0200) Subject: FFmpeg UDP protocol hacked to be delivered through FNA endpoinds (Simply:Zprasene... X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/ffmpeg.git/commitdiff_plain/0b0d4ecdb4665fba286c01aa18084250a3dcadd2 FFmpeg UDP protocol hacked to be delivered through FNA endpoinds (Simply:Zprasene UDP). The RTPS uses UDP and this way it is targeted to FWP layer. Signed-off-by: Martin --- diff --git a/libavformat/udp.c b/libavformat/udp.c index a89de0080..b79628200 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -34,16 +34,8 @@ #endif #include -#ifndef IPV6_ADD_MEMBERSHIP -#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP -#endif -#ifndef IN_MULTICAST -#define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) -#endif -#ifndef IN6_IS_ADDR_MULTICAST -#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff) -#endif +#include +#include typedef struct { int udp_fd; @@ -52,192 +44,35 @@ typedef struct { int is_multicast; int local_port; int reuse_socket; -#if !CONFIG_IPV6 struct sockaddr_in dest_addr; -#else - struct sockaddr_storage dest_addr; -#endif int dest_addr_len; + + frsh_send_endpoint_t sepoint; + frsh_send_endpoint_t repoint; + frsh_vres_id_t vres; + frsh_send_endpoint_protocol_info_t send_pinfo; + frsh_contract_t contract; + frsh_rel_time_t budget, period; } UDPContext; #define UDP_TX_BUF_SIZE 32768 #define UDP_MAX_PKT_SIZE 65536 -static int udp_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) { -#ifdef IP_MULTICAST_TTL - if (addr->sa_family == AF_INET) { - if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno)); - return -1; - } - } -#endif -#if CONFIG_IPV6 - if (addr->sa_family == AF_INET6) { - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno)); - return -1; - } - } -#endif - return 0; -} - -static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) { -#ifdef IP_ADD_MEMBERSHIP - if (addr->sa_family == AF_INET) { - struct ip_mreq mreq; - - mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - mreq.imr_interface.s_addr= INADDR_ANY; - if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif -#if CONFIG_IPV6 - if (addr->sa_family == AF_INET6) { - struct ipv6_mreq mreq6; - - memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); - mreq6.ipv6mr_interface= 0; - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif - return 0; -} - -static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) { -#ifdef IP_DROP_MEMBERSHIP - if (addr->sa_family == AF_INET) { - struct ip_mreq mreq; - - mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - mreq.imr_interface.s_addr= INADDR_ANY; - if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif -#if CONFIG_IPV6 - if (addr->sa_family == AF_INET6) { - struct ipv6_mreq mreq6; - - memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); - mreq6.ipv6mr_interface= 0; - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { - av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno)); - return -1; - } - } -#endif - return 0; -} - -#if CONFIG_IPV6 -static struct addrinfo* udp_ipv6_resolve_host(const char *hostname, int port, int type, int family, int flags) { - struct addrinfo hints, *res = 0; - int error; - char sport[16]; - const char *node = 0, *service = "0"; - - if (port > 0) { - snprintf(sport, sizeof(sport), "%d", port); - service = sport; - } - if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) { - node = hostname; - } - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = type; - hints.ai_family = family; - hints.ai_flags = flags; - if ((error = getaddrinfo(node, service, &hints, &res))) { - av_log(NULL, AV_LOG_ERROR, "udp_ipv6_resolve_host: %s\n", gai_strerror(error)); - } - - return res; -} - -static int udp_set_url(struct sockaddr_storage *addr, const char *hostname, int port) { - struct addrinfo *res0; - int addr_len; - - res0 = udp_ipv6_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); - if (res0 == 0) return AVERROR(EIO); - memcpy(addr, res0->ai_addr, res0->ai_addrlen); - addr_len = res0->ai_addrlen; - freeaddrinfo(res0); - - return addr_len; -} - -static int is_multicast_address(struct sockaddr_storage *addr) +static int udp_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) { - if (addr->ss_family == AF_INET) { - return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); - } - if (addr->ss_family == AF_INET6) { - return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); - } - return 0; } -static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr, int *addr_len) +static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) { - int udp_fd = -1; - struct addrinfo *res0 = NULL, *res = NULL; - int family = AF_UNSPEC; - - if (((struct sockaddr *) &s->dest_addr)->sa_family) - family = ((struct sockaddr *) &s->dest_addr)->sa_family; - res0 = udp_ipv6_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); - if (res0 == 0) - goto fail; - for (res = res0; res; res=res->ai_next) { - udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); - if (udp_fd > 0) break; - av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno)); - } - - if (udp_fd < 0) - goto fail; - - memcpy(addr, res->ai_addr, res->ai_addrlen); - *addr_len = res->ai_addrlen; - - freeaddrinfo(res0); - - return udp_fd; - - fail: - if (udp_fd >= 0) - closesocket(udp_fd); - if(res0) - freeaddrinfo(res0); - return -1; + return 0; } -static int udp_port(struct sockaddr_storage *addr, int addr_len) +static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) { - char sbuf[sizeof(int)*3+1]; - - if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) { - av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno)); - return -1; - } - - return strtol(sbuf, NULL, 10); + return 0; } -#else - static int udp_set_url(struct sockaddr_in *addr, const char *hostname, int port) { /* set the destination address */ @@ -251,31 +86,69 @@ static int udp_set_url(struct sockaddr_in *addr, const char *hostname, int port) static int is_multicast_address(struct sockaddr_in *addr) { - return IN_MULTICAST(ntohl(addr->sin_addr.s_addr)); + return 0; } -static int udp_socket_create(UDPContext *s, struct sockaddr_in *addr, int *addr_len) +static int +udp_socket_create(UDPContext *s, struct sockaddr_in *addr, int *addr_len) { - int fd; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) - return -1; + int ret,fd; + unsigned int node, port; + fwp_endpoint_attr_t attr; addr->sin_family = AF_INET; addr->sin_addr.s_addr = htonl (INADDR_ANY); addr->sin_port = htons(s->local_port); *addr_len = sizeof(struct sockaddr_in); - return fd; + /* set params for contract */ + frsh_network_bytes_to_budget(FRSH_NETPF_FWP, 60000, &s->budget); + s->period = fosa_msec_to_rel_time(1000); + s->send_pinfo.body = NULL; + + if (frsh_send_endpoint_create(FRSH_NETPF_FWP, + s->dest_addr.sin_addr.s_addr, + ntohs(s->dest_addr.sin_port), s->send_pinfo, + &s->sepoint) < 0) { + + return -1; + } + + /* Contract negotiation */ + ret = frsh_contract_init(&s->contract); + //if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init"); + if (ret) return -1; + + ret = frsh_contract_set_basic_params(&s->contract, + &s->budget, + &s->period, + FRSH_WT_BOUNDED, + FRSH_CT_REGULAR); + //if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params"); + if (ret) return -1; + ret = frsh_contract_set_resource_and_label(&s->contract,FRSH_RT_NETWORK, + FRSH_NETPF_FWP, "net_cont1"); + //if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label"); + if (ret) return -1; + + ret = frsh_contract_negotiate(&s->contract, &s->vres); + //if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate"); + if (ret) return -1; + + printf("Send endpoint created\n"); + frsh_send_endpoint_bind(s->vres, s->sepoint); + printf("Send endpoint bounded\n"); + + //fwp_endpoint_get_params(s->sepoint->protocol_info.body, &node, + // &port, &attr, &fd); + + return 0; } static int udp_port(struct sockaddr_in *addr, int len) { return ntohs(addr->sin_port); } -#endif /* CONFIG_IPV6 */ - /** * If no filename is given to av_open_input_file because you want to @@ -340,16 +213,12 @@ int udp_get_file_handle(URLContext *h) static int udp_open(URLContext *h, const char *uri, int flags) { char hostname[1024]; - int port, udp_fd = -1, tmp, bind_ret = -1; + int port, udp_fd = -1, tmp; UDPContext *s = NULL; int is_output; const char *p; char buf[256]; -#if !CONFIG_IPV6 struct sockaddr_in my_addr; -#else - struct sockaddr_storage my_addr; -#endif int len; h->is_streamed = 1; @@ -397,42 +266,23 @@ static int udp_open(URLContext *h, const char *uri, int flags) udp_set_remote_url(h, uri); } - if (s->is_multicast && !(h->flags & URL_WRONLY)) - s->local_port = port; udp_fd = udp_socket_create(s, &my_addr, &len); if (udp_fd < 0) goto fail; - +#if 0 if (s->reuse_socket) if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) goto fail; - /* the bind is needed to give a port to the socket now */ - /* if multicast, try the multicast address bind first */ - if (s->is_multicast && !(h->flags & URL_WRONLY)) { - bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); - } /* bind to the local address if not multicast or if the multicast * bind failed */ - if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) - goto fail; + /*if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) + goto fail;*/ len = sizeof(my_addr); getsockname(udp_fd, (struct sockaddr *)&my_addr, &len); s->local_port = udp_port(&my_addr, len); - if (s->is_multicast) { - if (h->flags & URL_WRONLY) { - /* output */ - if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) - goto fail; - } else { - /* input */ - if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) - goto fail; - } - } - if (is_output) { /* limit the tx buf size to limit latency */ tmp = s->buffer_size; @@ -450,7 +300,7 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* make the socket non-blocking */ ff_socket_nonblock(udp_fd, 1); } - +#endif s->udp_fd = udp_fd; return 0; fail: @@ -463,65 +313,29 @@ static int udp_open(URLContext *h, const char *uri, int flags) static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; - int len; - fd_set rfds; - int ret; - struct timeval tv; - - for(;;) { - if (url_interrupt_cb()) - return AVERROR(EINTR); - FD_ZERO(&rfds); - FD_SET(s->udp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv); - if (ret < 0) - return AVERROR(EIO); - if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) - continue; - len = recv(s->udp_fd, buf, size, 0); - if (len < 0) { - if (ff_neterrno() != FF_NETERROR(EAGAIN) && - ff_neterrno() != FF_NETERROR(EINTR)) - return AVERROR(EIO); - } else { - break; - } - } - return len; + unsigned int from; + int len; + + return frsh_receive_sync(s->repoint, buf, size, &len, &from); } static int udp_write(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; int ret; - - for(;;) { - ret = sendto (s->udp_fd, buf, size, 0, - (struct sockaddr *) &s->dest_addr, - s->dest_addr_len); - if (ret < 0) { - if (ff_neterrno() != FF_NETERROR(EINTR) && - ff_neterrno() != FF_NETERROR(EAGAIN)) - return AVERROR(EIO); - } else { - break; - } - } - return size; + + ret = frsh_send_async(s->sepoint, buf, size); + return ret; } static int udp_close(URLContext *h) { UDPContext *s = h->priv_data; - - if (s->is_multicast && !(h->flags & URL_WRONLY)) - udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); - closesocket(s->udp_fd); - ff_network_close(); - av_free(s); - return 0; + int ret1, ret2; + + ret1 = frsh_send_endpoint_destroy(s->sepoint); + ret2 = frsh_receive_endpoint_destroy(s->repoint); + return (ret1 || ret2); } URLProtocol udp_protocol = {