Revision fdcdd539

View differences:

libavformat/tcp.c
34 34
/* return non zero if error */
35 35
static int tcp_open(URLContext *h, const char *uri, int flags)
36 36
{
37
    struct sockaddr_in dest_addr;
37
    struct addrinfo hints, *ai, *cur_ai;
38 38
    int port, fd = -1;
39 39
    TCPContext *s = NULL;
40 40
    fd_set wfds;
......
42 42
    struct timeval tv;
43 43
    socklen_t optlen;
44 44
    char hostname[1024],proto[1024],path[1024];
45
    char portstr[10];
45 46

  
46 47
    if(!ff_network_init())
47 48
        return AVERROR(EIO);
......
51 52
    if (strcmp(proto,"tcp") || port <= 0 || port >= 65536)
52 53
        return AVERROR(EINVAL);
53 54

  
54
    dest_addr.sin_family = AF_INET;
55
    dest_addr.sin_port = htons(port);
56
    if (resolve_host(&dest_addr.sin_addr, hostname) < 0)
55
    memset(&hints, 0, sizeof(hints));
56
    hints.ai_family = PF_UNSPEC;
57
    hints.ai_socktype = SOCK_STREAM;
58
    snprintf(portstr, sizeof(portstr), "%d", port);
59
    if (getaddrinfo(hostname, portstr, &hints, &ai))
57 60
        return AVERROR(EIO);
58 61

  
59
    fd = socket(AF_INET, SOCK_STREAM, 0);
62
    cur_ai = ai;
63

  
64
 restart:
65
    fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol);
60 66
    if (fd < 0)
61
        return AVERROR(EIO);
67
        goto fail;
62 68
    ff_socket_nonblock(fd, 1);
63 69

  
64 70
 redo:
65
    ret = connect(fd, (struct sockaddr *)&dest_addr,
66
                  sizeof(dest_addr));
71
    ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
67 72
    if (ret < 0) {
68 73
        if (ff_neterrno() == FF_NETERROR(EINTR))
69 74
            goto redo;
......
94 99
            goto fail;
95 100
    }
96 101
    s = av_malloc(sizeof(TCPContext));
97
    if (!s)
102
    if (!s) {
103
        freeaddrinfo(ai);
98 104
        return AVERROR(ENOMEM);
105
    }
99 106
    h->priv_data = s;
100 107
    h->is_streamed = 1;
101 108
    s->fd = fd;
109
    freeaddrinfo(ai);
102 110
    return 0;
103 111

  
104 112
 fail:
113
    if (cur_ai->ai_next) {
114
        /* Retry with the next sockaddr */
115
        cur_ai = cur_ai->ai_next;
116
        if (fd >= 0)
117
            closesocket(fd);
118
        goto restart;
119
    }
105 120
    ret = AVERROR(EIO);
106 121
 fail1:
107 122
    if (fd >= 0)
108 123
        closesocket(fd);
124
    freeaddrinfo(ai);
109 125
    return ret;
110 126
}
111 127

  

Also available in: Unified diff