Fixed some memory & fd leaks in error cases of various network setup

routines.
This commit is contained in:
Jef Poskanzer 2013-11-09 14:23:36 -08:00
parent 0e60ef1f9c
commit 32ebd649b3
2 changed files with 52 additions and 4 deletions

View File

@ -135,6 +135,7 @@ iperf_tcp_listen(struct iperf_test *test)
}
if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
freeaddrinfo(res);
i_errno = IESTREAMLISTEN;
return -1;
}
@ -142,6 +143,8 @@ iperf_tcp_listen(struct iperf_test *test)
if (test->no_delay) {
opt = 1;
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IESETNODELAY;
return -1;
}
@ -149,22 +152,30 @@ iperf_tcp_listen(struct iperf_test *test)
// XXX: Setting MSS is very buggy!
if ((opt = test->settings->mss)) {
if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IESETMSS;
return -1;
}
}
if ((opt = test->settings->socket_bufsize)) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IESETBUF;
return -1;
}
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IESETBUF;
return -1;
}
}
opt = 1;
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IEREUSEADDR;
return -1;
}
@ -178,6 +189,7 @@ iperf_tcp_listen(struct iperf_test *test)
if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IESTREAMLISTEN;
return -1;
}
@ -222,17 +234,25 @@ iperf_tcp_connect(struct iperf_test *test)
hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", test->server_port);
if (getaddrinfo(test->server_hostname, portstr, &hints, &server_res) != 0) {
if (test->bind_address)
freeaddrinfo(local_res);
i_errno = IESTREAMCONNECT;
return -1;
}
if ((s = socket(server_res->ai_family, SOCK_STREAM, 0)) < 0) {
if (test->bind_address)
freeaddrinfo(local_res);
freeaddrinfo(server_res);
i_errno = IESTREAMCONNECT;
return -1;
}
if (test->bind_address) {
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
close(s);
freeaddrinfo(local_res);
freeaddrinfo(server_res);
i_errno = IESTREAMCONNECT;
return -1;
}
@ -243,28 +263,38 @@ iperf_tcp_connect(struct iperf_test *test)
if (test->no_delay) {
opt = 1;
if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETNODELAY;
return -1;
}
}
if ((opt = test->settings->mss)) {
if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETMSS;
return -1;
}
}
if ((opt = test->settings->socket_bufsize)) {
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETBUF;
return -1;
}
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETBUF;
return -1;
}
}
if (test->settings->flowlabel) {
if (server_res->ai_addr->sa_family != AF_INET6) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETFLOW;
return -1;
} else {
@ -274,6 +304,8 @@ iperf_tcp_connect(struct iperf_test *test)
}
if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) {
close(s);
freeaddrinfo(server_res);
i_errno = IESTREAMCONNECT;
return -1;
}
@ -282,6 +314,7 @@ iperf_tcp_connect(struct iperf_test *test)
/* Send cookie for verification */
if (Nwrite(s, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
close(s);
i_errno = IESENDCOOKIE;
return -1;
}

View File

@ -65,18 +65,29 @@ netdial(int domain, int proto, char *local, char *server, int port)
return -1;
s = socket(server_res->ai_family, proto, 0);
if (s < 0)
if (s < 0) {
if (local)
freeaddrinfo(local_res);
freeaddrinfo(server_res);
return -1;
}
if (local) {
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0)
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) {
close(s);
freeaddrinfo(local_res);
freeaddrinfo(server_res);
return -1;
}
freeaddrinfo(local_res);
}
((struct sockaddr_in *) server_res->ai_addr)->sin_port = htons(port);
if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS)
if (connect(s, (struct sockaddr *) server_res->ai_addr, server_res->ai_addrlen) < 0 && errno != EINPROGRESS) {
close(s);
freeaddrinfo(server_res);
return -1;
}
freeaddrinfo(server_res);
return s;
@ -100,8 +111,10 @@ netannounce(int domain, int proto, char *local, int port)
return -1;
s = socket(res->ai_family, proto, 0);
if (s < 0)
if (s < 0) {
freeaddrinfo(res);
return -1;
}
opt = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
@ -115,6 +128,7 @@ netannounce(int domain, int proto, char *local, int port)
if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) {
close(s);
freeaddrinfo(res);
return -1;
}
@ -122,6 +136,7 @@ netannounce(int domain, int proto, char *local, int port)
if (proto == SOCK_STREAM) {
if (listen(s, 5) < 0) {
close(s);
return -1;
}
}