version 1.1.1.1, 2016/10/18 13:28:18
|
version 1.1.1.2, 2021/03/17 00:36:46
|
Line 1
|
Line 1
|
/* |
/* |
* iperf, Copyright (c) 2014, 2015, The Regents of the University of | * iperf, Copyright (c) 2014-2019, The Regents of the University of |
* California, through Lawrence Berkeley National Laboratory (subject |
* California, through Lawrence Berkeley National Laboratory (subject |
* to receipt of any required approvals from the U.S. Dept. of |
* to receipt of any required approvals from the U.S. Dept. of |
* Energy). All rights reserved. |
* Energy). All rights reserved. |
Line 35
|
Line 35
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <netdb.h> |
#include <netdb.h> |
#include <netinet/tcp.h> |
|
#include <sys/time.h> |
#include <sys/time.h> |
#include <sys/select.h> |
#include <sys/select.h> |
|
#include <limits.h> |
|
|
#ifdef HAVE_NETINET_SCTP_H |
#ifdef HAVE_NETINET_SCTP_H |
#include <netinet/sctp.h> |
#include <netinet/sctp.h> |
Line 57
|
Line 57
|
int |
int |
iperf_sctp_recv(struct iperf_stream *sp) |
iperf_sctp_recv(struct iperf_stream *sp) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
int r; |
int r; |
|
|
r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Psctp); |
r = Nread(sp->socket, sp->buffer, sp->settings->blksize, Psctp); |
if (r < 0) |
if (r < 0) |
return r; |
return r; |
|
|
sp->result->bytes_received += r; | /* Only count bytes received while we're in the correct state. */ |
sp->result->bytes_received_this_interval += r; | if (sp->test->state == TEST_RUNNING) { |
| sp->result->bytes_received += r; |
| sp->result->bytes_received_this_interval += r; |
| } |
| else { |
| if (sp->test->debug) |
| printf("Late receive, state = %d\n", sp->test->state); |
| } |
|
|
return r; |
return r; |
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |
|
|
|
|
Line 82 iperf_sctp_recv(struct iperf_stream *sp)
|
Line 89 iperf_sctp_recv(struct iperf_stream *sp)
|
int |
int |
iperf_sctp_send(struct iperf_stream *sp) |
iperf_sctp_send(struct iperf_stream *sp) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
int r; |
int r; |
|
|
r = Nwrite(sp->socket, sp->buffer, sp->settings->blksize, Psctp); |
r = Nwrite(sp->socket, sp->buffer, sp->settings->blksize, Psctp); |
Line 96 iperf_sctp_send(struct iperf_stream *sp)
|
Line 103 iperf_sctp_send(struct iperf_stream *sp)
|
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |
|
|
|
|
Line 108 iperf_sctp_send(struct iperf_stream *sp)
|
Line 115 iperf_sctp_send(struct iperf_stream *sp)
|
int |
int |
iperf_sctp_accept(struct iperf_test * test) |
iperf_sctp_accept(struct iperf_test * test) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
int s; |
int s; |
signed char rbuf = ACCESS_DENIED; |
signed char rbuf = ACCESS_DENIED; |
char cookie[COOKIE_SIZE]; |
char cookie[COOKIE_SIZE]; |
Line 124 iperf_sctp_accept(struct iperf_test * test)
|
Line 131 iperf_sctp_accept(struct iperf_test * test)
|
|
|
if (Nread(s, cookie, COOKIE_SIZE, Psctp) < 0) { |
if (Nread(s, cookie, COOKIE_SIZE, Psctp) < 0) { |
i_errno = IERECVCOOKIE; |
i_errno = IERECVCOOKIE; |
|
close(s); |
return -1; |
return -1; |
} |
} |
|
|
if (strcmp(test->cookie, cookie) != 0) { | if (strncmp(test->cookie, cookie, COOKIE_SIZE) != 0) { |
if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Psctp) < 0) { |
if (Nwrite(s, (char*) &rbuf, sizeof(rbuf), Psctp) < 0) { |
i_errno = IESENDMESSAGE; |
i_errno = IESENDMESSAGE; |
|
close(s); |
return -1; |
return -1; |
} |
} |
close(s); |
close(s); |
Line 139 iperf_sctp_accept(struct iperf_test * test)
|
Line 148 iperf_sctp_accept(struct iperf_test * test)
|
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |
|
|
|
|
Line 150 iperf_sctp_accept(struct iperf_test * test)
|
Line 159 iperf_sctp_accept(struct iperf_test * test)
|
int |
int |
iperf_sctp_listen(struct iperf_test *test) |
iperf_sctp_listen(struct iperf_test *test) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
struct addrinfo hints, *res; |
struct addrinfo hints, *res; |
char portstr[6]; |
char portstr[6]; |
int s, opt; | int s, opt, saved_errno; |
|
|
close(test->listener); |
close(test->listener); |
|
|
snprintf(portstr, 6, "%d", test->server_port); |
snprintf(portstr, 6, "%d", test->server_port); |
memset(&hints, 0, sizeof(hints)); |
memset(&hints, 0, sizeof(hints)); |
hints.ai_family = (test->settings->domain == AF_UNSPEC ? AF_INET6 : test->settings->domain); | /* |
| * If binding to the wildcard address with no explicit address |
| * family specified, then force us to get an AF_INET6 socket. |
| * More details in the comments in netanounce(). |
| */ |
| if (test->settings->domain == AF_UNSPEC && !test->bind_address) { |
| hints.ai_family = AF_INET6; |
| } else { |
| hints.ai_family = test->settings->domain; |
| } |
hints.ai_socktype = SOCK_STREAM; |
hints.ai_socktype = SOCK_STREAM; |
hints.ai_flags = AI_PASSIVE; |
hints.ai_flags = AI_PASSIVE; |
if (getaddrinfo(test->bind_address, portstr, &hints, &res) != 0) { | if ((gerror = getaddrinfo(test->bind_address, portstr, &hints, &res)) != 0) { |
i_errno = IESTREAMLISTEN; |
i_errno = IESTREAMLISTEN; |
return -1; |
return -1; |
} |
} |
Line 173 iperf_sctp_listen(struct iperf_test *test)
|
Line 191 iperf_sctp_listen(struct iperf_test *test)
|
return -1; |
return -1; |
} |
} |
|
|
|
if ((opt = test->settings->socket_bufsize)) { |
|
int saved_errno; |
|
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(res); |
|
errno = saved_errno; |
|
i_errno = IESETBUF; |
|
return -1; |
|
} |
|
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(res); |
|
errno = saved_errno; |
|
i_errno = IESETBUF; |
|
return -1; |
|
} |
|
} |
|
|
#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) |
#if defined(IPV6_V6ONLY) && !defined(__OpenBSD__) |
if (test->settings->domain == AF_UNSPEC || test->settings->domain == AF_INET6) { | if (res->ai_family == AF_INET6 && (test->settings->domain == AF_UNSPEC || |
| test->settings->domain == AF_INET6)) { |
if (test->settings->domain == AF_UNSPEC) |
if (test->settings->domain == AF_UNSPEC) |
opt = 0; |
opt = 0; |
else if (test->settings->domain == AF_INET6) | else |
opt = 1; |
opt = 1; |
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, |
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, |
(char *) &opt, sizeof(opt)) < 0) { |
(char *) &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(res); |
freeaddrinfo(res); |
|
errno = saved_errno; |
i_errno = IEPROTOCOL; |
i_errno = IEPROTOCOL; |
return -1; |
return -1; |
} |
} |
Line 191 iperf_sctp_listen(struct iperf_test *test)
|
Line 232 iperf_sctp_listen(struct iperf_test *test)
|
|
|
opt = 1; |
opt = 1; |
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { |
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(res); |
freeaddrinfo(res); |
|
errno = saved_errno; |
i_errno = IEREUSEADDR; |
i_errno = IEREUSEADDR; |
return -1; |
return -1; |
} |
} |
|
|
/* servers must call sctp_bindx() _instead_ of bind() */ |
/* servers must call sctp_bindx() _instead_ of bind() */ |
if (!TAILQ_EMPTY(&test->xbind_addrs)) { |
if (!TAILQ_EMPTY(&test->xbind_addrs)) { |
freeaddrinfo(res); | if (iperf_sctp_bindx(test, s, IPERF_SCTP_SERVER)) { |
if (iperf_sctp_bindx(test, s, IPERF_SCTP_SERVER)) | close(s); |
| freeaddrinfo(res); |
return -1; |
return -1; |
|
} |
} else |
} else |
if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) { |
if (bind(s, (struct sockaddr *) res->ai_addr, res->ai_addrlen) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(res); |
freeaddrinfo(res); |
|
errno = saved_errno; |
i_errno = IESTREAMLISTEN; |
i_errno = IESTREAMLISTEN; |
return -1; |
return -1; |
} |
} |
|
|
freeaddrinfo(res); |
freeaddrinfo(res); |
|
|
if (listen(s, 5) < 0) { | if (listen(s, INT_MAX) < 0) { |
i_errno = IESTREAMLISTEN; |
i_errno = IESTREAMLISTEN; |
return -1; |
return -1; |
} |
} |
Line 223 iperf_sctp_listen(struct iperf_test *test)
|
Line 270 iperf_sctp_listen(struct iperf_test *test)
|
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |
|
|
|
|
Line 234 iperf_sctp_listen(struct iperf_test *test)
|
Line 281 iperf_sctp_listen(struct iperf_test *test)
|
int |
int |
iperf_sctp_connect(struct iperf_test *test) |
iperf_sctp_connect(struct iperf_test *test) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
int s, opt; | int s, opt, saved_errno; |
char portstr[6]; |
char portstr[6]; |
struct addrinfo hints, *local_res, *server_res; |
struct addrinfo hints, *local_res, *server_res; |
|
|
Line 243 iperf_sctp_connect(struct iperf_test *test)
|
Line 290 iperf_sctp_connect(struct iperf_test *test)
|
memset(&hints, 0, sizeof(hints)); |
memset(&hints, 0, sizeof(hints)); |
hints.ai_family = test->settings->domain; |
hints.ai_family = test->settings->domain; |
hints.ai_socktype = SOCK_STREAM; |
hints.ai_socktype = SOCK_STREAM; |
if (getaddrinfo(test->bind_address, NULL, &hints, &local_res) != 0) { | if ((gerror = getaddrinfo(test->bind_address, NULL, &hints, &local_res)) != 0) { |
i_errno = IESTREAMCONNECT; |
i_errno = IESTREAMCONNECT; |
return -1; |
return -1; |
} |
} |
Line 253 iperf_sctp_connect(struct iperf_test *test)
|
Line 300 iperf_sctp_connect(struct iperf_test *test)
|
hints.ai_family = test->settings->domain; |
hints.ai_family = test->settings->domain; |
hints.ai_socktype = SOCK_STREAM; |
hints.ai_socktype = SOCK_STREAM; |
snprintf(portstr, sizeof(portstr), "%d", test->server_port); |
snprintf(portstr, sizeof(portstr), "%d", test->server_port); |
if (getaddrinfo(test->server_hostname, portstr, &hints, &server_res) != 0) { | if ((gerror = getaddrinfo(test->server_hostname, portstr, &hints, &server_res)) != 0) { |
if (test->bind_address) |
if (test->bind_address) |
freeaddrinfo(local_res); |
freeaddrinfo(local_res); |
i_errno = IESTREAMCONNECT; |
i_errno = IESTREAMCONNECT; |
Line 269 iperf_sctp_connect(struct iperf_test *test)
|
Line 316 iperf_sctp_connect(struct iperf_test *test)
|
return -1; |
return -1; |
} |
} |
|
|
|
if ((opt = test->settings->socket_bufsize)) { |
|
int saved_errno; |
|
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(server_res); |
|
errno = saved_errno; |
|
i_errno = IESETBUF; |
|
return -1; |
|
} |
|
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(server_res); |
|
errno = saved_errno; |
|
i_errno = IESETBUF; |
|
return -1; |
|
} |
|
} |
|
|
|
/* |
|
* Various ways to bind the local end of the connection. |
|
* 1. --bind (with or without --cport). |
|
*/ |
|
if (test->bind_address) { |
|
struct sockaddr_in *lcladdr; |
|
lcladdr = (struct sockaddr_in *)local_res->ai_addr; |
|
lcladdr->sin_port = htons(test->bind_port); |
|
|
|
if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(local_res); |
|
freeaddrinfo(server_res); |
|
errno = saved_errno; |
|
i_errno = IESTREAMCONNECT; |
|
return -1; |
|
} |
|
freeaddrinfo(local_res); |
|
} |
|
/* --cport, no --bind */ |
|
else if (test->bind_port) { |
|
size_t addrlen; |
|
struct sockaddr_storage lcl; |
|
|
|
/* IPv4 */ |
|
if (server_res->ai_family == AF_INET) { |
|
struct sockaddr_in *lcladdr = (struct sockaddr_in *) &lcl; |
|
lcladdr->sin_family = AF_INET; |
|
lcladdr->sin_port = htons(test->bind_port); |
|
lcladdr->sin_addr.s_addr = INADDR_ANY; |
|
addrlen = sizeof(struct sockaddr_in); |
|
} |
|
/* IPv6 */ |
|
else if (server_res->ai_family == AF_INET6) { |
|
struct sockaddr_in6 *lcladdr = (struct sockaddr_in6 *) &lcl; |
|
lcladdr->sin6_family = AF_INET6; |
|
lcladdr->sin6_port = htons(test->bind_port); |
|
lcladdr->sin6_addr = in6addr_any; |
|
addrlen = sizeof(struct sockaddr_in6); |
|
} |
|
/* Unknown protocol */ |
|
else { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(server_res); |
|
errno = saved_errno; |
|
i_errno = IEPROTOCOL; |
|
return -1; |
|
} |
|
|
|
if (bind(s, (struct sockaddr *) &lcl, addrlen) < 0) { |
|
saved_errno = errno; |
|
close(s); |
|
freeaddrinfo(server_res); |
|
errno = saved_errno; |
|
i_errno = IESTREAMCONNECT; |
|
return -1; |
|
} |
|
} |
|
|
if (test->no_delay != 0) { |
if (test->no_delay != 0) { |
opt = 1; |
opt = 1; |
if (setsockopt(s, IPPROTO_SCTP, SCTP_NODELAY, &opt, sizeof(opt)) < 0) { |
if (setsockopt(s, IPPROTO_SCTP, SCTP_NODELAY, &opt, sizeof(opt)) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(server_res); |
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESETNODELAY; |
i_errno = IESETNODELAY; |
return -1; |
return -1; |
} |
} |
Line 303 iperf_sctp_connect(struct iperf_test *test)
|
Line 433 iperf_sctp_connect(struct iperf_test *test)
|
av.assoc_value = test->settings->mss; |
av.assoc_value = test->settings->mss; |
|
|
if (setsockopt(s, IPPROTO_SCTP, SCTP_MAXSEG, &av, sizeof(av)) < 0) { |
if (setsockopt(s, IPPROTO_SCTP, SCTP_MAXSEG, &av, sizeof(av)) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(server_res); |
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESETMSS; |
i_errno = IESETMSS; |
return -1; |
return -1; |
} |
} |
Line 317 iperf_sctp_connect(struct iperf_test *test)
|
Line 449 iperf_sctp_connect(struct iperf_test *test)
|
*/ |
*/ |
if (setsockopt(s, IPPROTO_SCTP, SCTP_MAXSEG, &opt, sizeof(opt)) < 0 && |
if (setsockopt(s, IPPROTO_SCTP, SCTP_MAXSEG, &opt, sizeof(opt)) < 0 && |
errno != ENOPROTOOPT) { |
errno != ENOPROTOOPT) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(server_res); |
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESETMSS; |
i_errno = IESETMSS; |
return -1; |
return -1; |
} |
} |
#endif HAVE_STRUCT_SCTP_ASSOC_VALUE | #endif /* HAVE_STRUCT_SCTP_ASSOC_VALUE */ |
} |
} |
|
|
if (test->settings->num_ostreams > 0) { |
if (test->settings->num_ostreams > 0) { |
Line 332 iperf_sctp_connect(struct iperf_test *test)
|
Line 466 iperf_sctp_connect(struct iperf_test *test)
|
initmsg.sinit_num_ostreams = test->settings->num_ostreams; |
initmsg.sinit_num_ostreams = test->settings->num_ostreams; |
|
|
if (setsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg)) < 0) { |
if (setsockopt(s, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(struct sctp_initmsg)) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(server_res); |
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESETSCTPNSTREAM; |
i_errno = IESETSCTPNSTREAM; |
return -1; |
return -1; |
} |
} |
Line 341 iperf_sctp_connect(struct iperf_test *test)
|
Line 477 iperf_sctp_connect(struct iperf_test *test)
|
|
|
/* clients must call bind() followed by sctp_bindx() before connect() */ |
/* clients must call bind() followed by sctp_bindx() before connect() */ |
if (!TAILQ_EMPTY(&test->xbind_addrs)) { |
if (!TAILQ_EMPTY(&test->xbind_addrs)) { |
if (iperf_sctp_bindx(test, s, IPERF_SCTP_CLIENT)) | if (iperf_sctp_bindx(test, s, IPERF_SCTP_CLIENT)) { |
| freeaddrinfo(server_res); |
| close(s); |
return -1; |
return -1; |
|
} |
} |
} |
|
|
/* TODO support sctp_connectx() to avoid heartbeating. */ |
/* TODO support sctp_connectx() to avoid heartbeating. */ |
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) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(server_res); |
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESTREAMCONNECT; |
i_errno = IESTREAMCONNECT; |
return -1; |
return -1; |
} |
} |
freeaddrinfo(server_res); |
|
|
|
/* Send cookie for verification */ |
/* Send cookie for verification */ |
if (Nwrite(s, test->cookie, COOKIE_SIZE, Psctp) < 0) { |
if (Nwrite(s, test->cookie, COOKIE_SIZE, Psctp) < 0) { |
|
saved_errno = errno; |
close(s); |
close(s); |
|
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESENDCOOKIE; |
i_errno = IESENDCOOKIE; |
return -1; |
return -1; |
} |
} |
Line 371 iperf_sctp_connect(struct iperf_test *test)
|
Line 514 iperf_sctp_connect(struct iperf_test *test)
|
opt = 0; |
opt = 0; |
if (setsockopt(s, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &opt, sizeof(opt)) < 0 && |
if (setsockopt(s, IPPROTO_SCTP, SCTP_DISABLE_FRAGMENTS, &opt, sizeof(opt)) < 0 && |
errno != ENOPROTOOPT) { |
errno != ENOPROTOOPT) { |
|
saved_errno = errno; |
close(s); |
close(s); |
freeaddrinfo(server_res); |
freeaddrinfo(server_res); |
|
errno = saved_errno; |
i_errno = IESETSCTPDISABLEFRAG; |
i_errno = IESETSCTPDISABLEFRAG; |
return -1; |
return -1; |
} |
} |
|
|
|
freeaddrinfo(server_res); |
return s; |
return s; |
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |
|
|
|
|
Line 389 iperf_sctp_connect(struct iperf_test *test)
|
Line 535 iperf_sctp_connect(struct iperf_test *test)
|
int |
int |
iperf_sctp_init(struct iperf_test *test) |
iperf_sctp_init(struct iperf_test *test) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
return 0; |
return 0; |
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |
|
|
|
|
Line 406 iperf_sctp_init(struct iperf_test *test)
|
Line 552 iperf_sctp_init(struct iperf_test *test)
|
int |
int |
iperf_sctp_bindx(struct iperf_test *test, int s, int is_server) |
iperf_sctp_bindx(struct iperf_test *test, int s, int is_server) |
{ |
{ |
#if defined(HAVE_SCTP) | #if defined(HAVE_SCTP_H) |
struct addrinfo hints; |
struct addrinfo hints; |
char portstr[6]; |
char portstr[6]; |
char *servname; |
char *servname; |
Line 418 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
Line 564 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
int nxaddrs; |
int nxaddrs; |
int retval; |
int retval; |
int domain; |
int domain; |
|
int saved_errno; |
|
|
domain = test->settings->domain; |
domain = test->settings->domain; |
xbe0 = NULL; |
xbe0 = NULL; |
Line 449 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
Line 596 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
xbe0 = TAILQ_FIRST(&test->xbind_addrs); |
xbe0 = TAILQ_FIRST(&test->xbind_addrs); |
TAILQ_REMOVE(&test->xbind_addrs, xbe0, link); |
TAILQ_REMOVE(&test->xbind_addrs, xbe0, link); |
|
|
if (getaddrinfo(xbe0->name, servname, &hints, &xbe0->ai) != 0) { | if ((gerror = getaddrinfo(xbe0->name, servname, &hints, &xbe0->ai)) != 0) { |
i_errno = IESETSCTPBINDX; |
i_errno = IESETSCTPBINDX; |
retval = -1; |
retval = -1; |
goto out; |
goto out; |
Line 493 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
Line 640 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
TAILQ_FOREACH(xbe, &test->xbind_addrs, link) { |
TAILQ_FOREACH(xbe, &test->xbind_addrs, link) { |
if (xbe->ai != NULL) |
if (xbe->ai != NULL) |
freeaddrinfo(xbe->ai); |
freeaddrinfo(xbe->ai); |
if (getaddrinfo(xbe->name, servname, &hints, &xbe->ai) != 0) { | if ((gerror = getaddrinfo(xbe->name, servname, &hints, &xbe->ai)) != 0) { |
i_errno = IESETSCTPBINDX; |
i_errno = IESETSCTPBINDX; |
retval = -1; |
retval = -1; |
goto out; |
goto out; |
Line 526 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
Line 673 iperf_sctp_bindx(struct iperf_test *test, int s, int i
|
} |
} |
|
|
if (sctp_bindx(s, xaddrs, nxaddrs, SCTP_BINDX_ADD_ADDR) == -1) { |
if (sctp_bindx(s, xaddrs, nxaddrs, SCTP_BINDX_ADD_ADDR) == -1) { |
|
saved_errno = errno; |
close(s); |
close(s); |
free(xaddrs); |
free(xaddrs); |
|
errno = saved_errno; |
i_errno = IESETSCTPBINDX; |
i_errno = IESETSCTPBINDX; |
retval = -1; |
retval = -1; |
goto out; |
goto out; |
Line 552 out:
|
Line 701 out:
|
#else |
#else |
i_errno = IENOSCTP; |
i_errno = IENOSCTP; |
return -1; |
return -1; |
#endif /* HAVE_SCTP */ | #endif /* HAVE_SCTP_H */ |
} |
} |