Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore out of order packts during UDP connection in Reverse Mode #1260

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/iperf.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,12 @@ struct iperf_test

extern int gerror; /* error value from getaddrinfo(3), for use in internal error handling */

/* UDP "connect" message and reply (textual value for Wireshark, etc. readability - legacy was numeric) */
#define UDP_CONNECT_MSG 0x36373839 // "6789" - legacy value was 123456789
#define UDP_CONNECT_REPLY 0x39383736 // "9876" - legacy value was 987654321
#define LEGACY_UDP_CONNECT_REPLY 987654321 // Old servers may still reply with the legacy value

/* In Reverse mode, maxmimum number of packtes to wait for "accept" response - to handle out of order packets */
#define MAX_REVERSE_OUT_OF_ORDER_PACKETS 2

#endif /* !__IPERF_H */
32 changes: 26 additions & 6 deletions src/iperf_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ int
iperf_udp_accept(struct iperf_test *test)
{
struct sockaddr_storage sa_peer;
int buf;
unsigned int buf;
socklen_t len;
int sz, s;
int rc;
Expand Down Expand Up @@ -452,7 +452,7 @@ iperf_udp_accept(struct iperf_test *test)
test->max_fd = (test->max_fd < test->prot_listener) ? test->prot_listener : test->max_fd;

/* Let the client know we're ready "accept" another UDP "stream" */
buf = 987654321; /* any content will work here */
buf = UDP_CONNECT_REPLY;
if (write(s, &buf, sizeof(buf)) < 0) {
i_errno = IESTREAMWRITE;
return -1;
Expand Down Expand Up @@ -494,11 +494,13 @@ iperf_udp_listen(struct iperf_test *test)
int
iperf_udp_connect(struct iperf_test *test)
{
int s, buf, sz;
int s, sz;
unsigned int buf;
#ifdef SO_RCVTIMEO
struct timeval tv;
#endif
int rc;
int i, max_len_wait_for_reply;

/* Create and bind our local socket. */
if ((s = netdial(test->settings->domain, Pudp, test->bind_address, test->bind_dev, test->bind_port, test->server_hostname, test->server_port, -1)) < 0) {
Expand Down Expand Up @@ -564,17 +566,35 @@ iperf_udp_connect(struct iperf_test *test)
* Write a datagram to the UDP stream to let the server know we're here.
* The server learns our address by obtaining its peer's address.
*/
buf = 123456789; /* this can be pretty much anything */
buf = UDP_CONNECT_MSG;
if (test->debug) {
printf("Sending Connect message to Sockt %d\n", s);
}
if (write(s, &buf, sizeof(buf)) < 0) {
// XXX: Should this be changed to IESTREAMCONNECT?
i_errno = IESTREAMWRITE;
return -1;
}

/*
* Wait until the server replies back to us.
* Wait until the server replies back to us with the "accept" response.
*/
if ((sz = recv(s, &buf, sizeof(buf), 0)) < 0) {
i = 0;
max_len_wait_for_reply = sizeof(buf);
if (test->reverse) /* In reverse mode allow few packets to have the "accept" response - to handle out of order packets */
max_len_wait_for_reply += MAX_REVERSE_OUT_OF_ORDER_PACKETS * test->settings->blksize;
do {
if ((sz = recv(s, &buf, sizeof(buf), 0)) < 0) {
i_errno = IESTREAMREAD;
return -1;
}
if (test->debug) {
printf("Connect received for Socket %d, sz=%d, buf=%x, i=%d, max_len_wait_for_reply=%d\n", s, sz, buf, i, max_len_wait_for_reply);
}
i += sz;
} while (buf != UDP_CONNECT_REPLY && buf != LEGACY_UDP_CONNECT_REPLY && i < max_len_wait_for_reply);

if (buf != UDP_CONNECT_REPLY && buf != LEGACY_UDP_CONNECT_REPLY) {
i_errno = IESTREAMREAD;
return -1;
}
Expand Down