static int unix_open(URLContext *h, const char *filename, int flags) { UnixContext *s = h->priv_data; int fd, ret; av_strstart(filename, "unix:", &filename); s->addr.sun_family = AF_UNIX; av_strlcpy(s->addr.sun_path, filename, sizeof(s->addr.sun_path)); if ((fd = ff_socket(AF_UNIX, s->type, 0)) < 0) return ff_neterrno(); if (s->timeout < 0 && h->rw_timeout) s->timeout = h->rw_timeout / 1000; if (s->listen) { ret = ff_listen_bind(fd, (struct sockaddr *)&s->addr, sizeof(s->addr), s->timeout, h); if (ret < 0) goto fail; fd = ret; } else { ret = ff_listen_connect(fd, (struct sockaddr *)&s->addr, sizeof(s->addr), s->timeout, h, 0); if (ret < 0) goto fail; } s->fd = fd; return 0; fail: if (s->listen && AVUNERROR(ret) != EADDRINUSE) unlink(s->addr.sun_path); if (fd >= 0) closesocket(fd); return ret; }
/* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { struct addrinfo hints = { 0 }, *ai, *cur_ai; int port, fd = -1; TCPContext *s = h->priv_data; int listen_socket = 0; const char *p; char buf[256]; int ret; int timeout = 100, listen_timeout = -1; char hostname[1024],proto[1024],path[1024]; char portstr[10]; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto, "tcp")) return AVERROR(EINVAL); if (port <= 0 || port >= 65536) { av_log(h, AV_LOG_ERROR, "Port missing in uri\n"); return AVERROR(EINVAL); } p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "listen", p)) listen_socket = 1; if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { timeout = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) { listen_timeout = strtol(buf, NULL, 10); } } hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portstr, sizeof(portstr), "%d", port); if (listen_socket) hints.ai_flags |= AI_PASSIVE; if (!hostname[0]) ret = getaddrinfo(NULL, portstr, &hints, &ai); else ret = getaddrinfo(hostname, portstr, &hints, &ai); if (ret) { av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", hostname, gai_strerror(ret)); return AVERROR(EIO); } cur_ai = ai; restart: fd = ff_socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); if (fd < 0) { ret = ff_neterrno(); goto fail; } if (listen_socket) { if ((fd = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, listen_timeout, h)) < 0) { ret = fd; goto fail1; } } else { if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, timeout * 100, h, !!cur_ai->ai_next)) < 0) { if (ret == AVERROR_EXIT) goto fail1; else goto fail; } } h->is_streamed = 1; s->fd = fd; freeaddrinfo(ai); return 0; fail: if (cur_ai->ai_next) { /* Retry with the next sockaddr */ cur_ai = cur_ai->ai_next; if (fd >= 0) closesocket(fd); ret = 0; goto restart; } fail1: if (fd >= 0) closesocket(fd); freeaddrinfo(ai); return ret; }
/* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { struct addrinfo hints = { 0 }, *ai, *cur_ai; int port, fd = -1; TCPContext *s = h->priv_data; const char *p; char buf[256]; int ret; char hostname[1024],proto[1024],path[1024]; char portstr[10]; s->open_timeout = 5000000; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto, "tcp")) return AVERROR(EINVAL); if (port <= 0 || port >= 65536) { av_log(h, AV_LOG_ERROR, "Port missing in uri\n"); return AVERROR(EINVAL); } p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "listen", p)) { char *endptr = NULL; s->listen = strtol(buf, &endptr, 10); /* assume if no digits were found it is a request to enable it */ if (buf == endptr) s->listen = 1; } if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { s->rw_timeout = strtol(buf, NULL, 10); } if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) { s->listen_timeout = strtol(buf, NULL, 10); } } if (s->rw_timeout >= 0) { s->open_timeout = h->rw_timeout = s->rw_timeout; } hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portstr, sizeof(portstr), "%d", port); if (s->listen) hints.ai_flags |= AI_PASSIVE; if (!hostname[0]) ret = getaddrinfo(NULL, portstr, &hints, &ai); else ret = getaddrinfo(hostname, portstr, &hints, &ai); if (ret) { av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", hostname, gai_strerror(ret)); return AVERROR(EIO); } cur_ai = ai; restart: #if HAVE_STRUCT_SOCKADDR_IN6 // workaround for IOS9 getaddrinfo in IPv6 only network use hardcode IPv4 address can not resolve port number. if (cur_ai->ai_family == AF_INET6) { struct sockaddr_in6 * sockaddr_v6 = (struct sockaddr_in6 *)cur_ai->ai_addr; if (!sockaddr_v6->sin6_port) { sockaddr_v6->sin6_port = htons(port); } } #endif fd = ff_socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); if (fd < 0) { ret = ff_neterrno(); goto fail; } if (s->listen == 2) { // multi-client if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0) goto fail1; } else if (s->listen == 1) { // single client if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, s->listen_timeout, h)) < 0) goto fail1; // Socket descriptor already closed here. Safe to overwrite to client one. fd = ret; } else { if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, s->open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) { if (ret == AVERROR_EXIT) goto fail1; else goto fail; } } h->is_streamed = 1; s->fd = fd; /* Set the socket's send or receive buffer sizes, if specified. If unspecified or setting fails, system default is used. */ if (s->recv_buffer_size > 0) { setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size)); } if (s->send_buffer_size > 0) { setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size)); } freeaddrinfo(ai); return 0; fail: if (cur_ai->ai_next) { /* Retry with the next sockaddr */ cur_ai = cur_ai->ai_next; if (fd >= 0) closesocket(fd); ret = 0; goto restart; } fail1: if (fd >= 0) closesocket(fd); freeaddrinfo(ai); return ret; }
static int sctp_open(URLContext *h, const char *uri, int flags) { struct addrinfo *ai, *cur_ai; struct addrinfo hints = { 0 }; struct sctp_event_subscribe event = { 0 }; struct sctp_initmsg initparams = { 0 }; int port; int fd = -1; SCTPContext *s = h->priv_data; const char *p; char buf[256]; int ret; char hostname[1024], proto[1024], path[1024]; char portstr[10]; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto, "sctp")) return AVERROR(EINVAL); if (port <= 0 || port >= 65536) { av_log(s, AV_LOG_ERROR, "Port missing in uri\n"); return AVERROR(EINVAL); } p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "listen", p)) s->listen = 1; if (av_find_info_tag(buf, sizeof(buf), "max_streams", p)) s->max_streams = strtol(buf, NULL, 10); } hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portstr, sizeof(portstr), "%d", port); ret = getaddrinfo(hostname, portstr, &hints, &ai); if (ret) { av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", hostname, gai_strerror(ret)); return AVERROR(EIO); } cur_ai = ai; restart: fd = ff_socket(cur_ai->ai_family, SOCK_STREAM, IPPROTO_SCTP); if (fd < 0) { ret = ff_neterrno(); goto fail; } if (s->listen) { if ((fd = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, s->listen_timeout, h)) < 0) { ret = fd; goto fail1; } } else { if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, s->timeout, h, !!cur_ai->ai_next)) < 0) { if (ret == AVERROR_EXIT) goto fail1; else goto fail; } } event.sctp_data_io_event = 1; /* TODO: Subscribe to more event types and handle them */ if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(event)) != 0) { av_log(h, AV_LOG_ERROR, "SCTP ERROR: Unable to subscribe to events\n"); goto fail1; } if (s->max_streams) { initparams.sinit_max_instreams = s->max_streams; initparams.sinit_num_ostreams = s->max_streams; if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &initparams, sizeof(initparams)) < 0) { av_log(h, AV_LOG_ERROR, "SCTP ERROR: Unable to initialize socket max streams %d\n", s->max_streams); ret = ff_neterrno(); goto fail1; } } h->priv_data = s; h->is_streamed = 1; s->fd = fd; freeaddrinfo(ai); return 0; fail: if (cur_ai->ai_next) { /* Retry with the next sockaddr */ cur_ai = cur_ai->ai_next; if (fd >= 0) closesocket(fd); ret = 0; goto restart; } fail1: ret = AVERROR(EIO); freeaddrinfo(ai); return ret; }
/* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { struct addrinfo hints = { 0 }, *ai, *cur_ai; int port, fd = -1; TCPContext *s = h->priv_data; const char *p; char buf[256]; int ret; char hostname[1024],proto[1024],path[1024]; char portstr[10]; s->open_timeout = 5000000; av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port, path, sizeof(path), uri); if (strcmp(proto, "tcp")) return AVERROR(EINVAL); if (port <= 0 || port >= 65536) { av_log(h, AV_LOG_ERROR, "Port missing in uri\n"); return AVERROR(EINVAL); } p = strchr(uri, '?'); if (p) { if (av_find_info_tag(buf, sizeof(buf), "listen", p)) s->listen = 1; if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { s->rw_timeout = strtol(buf, NULL, 10); // av_log(NULL,AV_LOG_ERROR,"TCPopen:OPTtimeout=%lld",s->rw_timeout); } if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) { s->listen_timeout = strtol(buf, NULL, 10); } } if (s->rw_timeout >= 0) { s->open_timeout = s->rw_timeout; h->rw_timeout = s->rw_timeout; // av_log(NULL,AV_LOG_ERROR,"TCPopen:timeout=%lld",h->rw_timeout); } hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; snprintf(portstr, sizeof(portstr), "%d", port); //add by xhr, in order for add timeout prevent block too many time /* if (signal(SIGALRM, sig_alrm) == SIG_ERR) av_log(NULL,AV_LOG_ERROR,"Hery, signal err"); canjump = 1; if (sigsetjmp(jmpbuf, 1)) { av_log(NULL,AV_LOG_ERROR,"Hery, getaddrinfo err"); return -1; } alarm(8); */ if (s->listen) hints.ai_flags |= AI_PASSIVE; if (!hostname[0]) ret = getaddrinfo(NULL, portstr, &hints, &ai); else ret = getaddrinfo(hostname, portstr, &hints, &ai); // canjump = 0; add by xhr // alarm(0); add by xhr if (ret) { av_log(h, AV_LOG_ERROR, "Failed to resolve hostname %s: %s\n", hostname, gai_strerror(ret)); return AVERROR(EIO); } cur_ai = ai; restart: fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); if (fd < 0) { ret = ff_neterrno(); goto fail; } if (s->listen) { if ((fd = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, s->listen_timeout, h)) < 0) { ret = fd; goto fail1; } } else { if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, s->open_timeout / 1000, h)) < 0) { if (ret == AVERROR_EXIT) goto fail1; else goto fail; } //Notify ip , IPV4 only for fjcmcc SQM if(cur_ai->ai_family == AF_INET) { char* ipaddr = inet_ntoa(((struct sockaddr_in *)(ai->ai_addr))->sin_addr); int int_addr = inet_addr(ipaddr); ff_send_message(&(h->interrupt_callback), MEDIA_INFO_SERVER_CHANGE, int_addr); } } h->is_streamed = 1; s->fd = fd; freeaddrinfo(ai); return 0; fail: if (cur_ai->ai_next) { /* Retry with the next sockaddr */ cur_ai = cur_ai->ai_next; if (fd >= 0) closesocket(fd); ret = 0; goto restart; } fail1: if (fd >= 0) closesocket(fd); freeaddrinfo(ai); return ret; }