git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Cutthrough: fix for port-number defined by router. Bug 2229
[exim.git]
/
test
/
src
/
server.c
diff --git
a/test/src/server.c
b/test/src/server.c
index 1abd3f49a6cd0e204d3499fae5e798e1b2606d5a..d433ebe0e0331f1f0cbd4fb04027eb99d9249568 100644
(file)
--- a/
test/src/server.c
+++ b/
test/src/server.c
@@
-26,9
+26,10
@@
on all interfaces, unless the option -noipv6 is given. */
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
+#include <netinet/tcp.h>
#ifdef HAVE_NETINET_IP_VAR_H
#ifdef HAVE_NETINET_IP_VAR_H
-#include <netinet/ip_var.h>
+#
include <netinet/ip_var.h>
#endif
#include <netdb.h>
#endif
#include <netdb.h>
@@
-52,6
+53,7
@@
on all interfaces, unless the option -noipv6 is given. */
#ifndef CS
# define CS (char *)
#ifndef CS
# define CS (char *)
+# define CCS (const char *)
#endif
#endif
@@
-61,6
+63,10
@@
typedef struct line {
char line[1];
} line;
char line[1];
} line;
+typedef unsigned BOOL;
+#define FALSE 0
+#define TRUE 1
+
/*************************************************
* SIGALRM handler - crash out *
/*************************************************
* SIGALRM handler - crash out *
@@
-164,7
+170,7
@@
int connection_count = 1;
int count;
int on = 1;
int timeout = 5;
int count;
int on = 1;
int timeout = 5;
-int initial_pause = 0;
+int initial_pause = 0
, tfo = 0
;
int use_ipv4 = 1;
int use_ipv6 = 1;
int debug = 0;
int use_ipv4 = 1;
int use_ipv6 = 1;
int debug = 0;
@@
-209,6
+215,7
@@
if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
"\n\t-noipv6 disable ipv6"
"\n\t-oP file write PID to file"
"\n\t-t n n seconds timeout"
"\n\t-noipv6 disable ipv6"
"\n\t-oP file write PID to file"
"\n\t-t n n seconds timeout"
+ "\n\t-tfo enable TCP Fast Open"
);
exit(0);
}
);
exit(0);
}
@@
-216,6
+223,7
@@
if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")))
while (na < argc && argv[na][0] == '-')
{
if (strcmp(argv[na], "-d") == 0) debug = 1;
while (na < argc && argv[na][0] == '-')
{
if (strcmp(argv[na], "-d") == 0) debug = 1;
+ else if (strcmp(argv[na], "-tfo") == 0) tfo = 1;
else if (strcmp(argv[na], "-t") == 0)
{
if (tmo_noerror = ((timeout = atoi(argv[++na])) < 0)) timeout = -timeout;
else if (strcmp(argv[na], "-t") == 0)
{
if (tmo_noerror = ((timeout = atoi(argv[++na])) < 0)) timeout = -timeout;
@@
-290,7
+298,15
@@
else
printf("IPv6 socket creation failed: %s\n", strerror(errno));
exit(1);
}
printf("IPv6 socket creation failed: %s\n", strerror(errno));
exit(1);
}
-
+#ifdef TCP_FASTOPEN
+ if (tfo)
+ {
+ int backlog = 5;
+ if (setsockopt(listen_socket[v6n], IPPROTO_TCP, TCP_FASTOPEN,
+ &backlog, sizeof(backlog)))
+ if (debug) printf("setsockopt TCP_FASTOPEN: %s\n", strerror(errno));
+ }
+#endif
/* If this is an IPv6 wildcard socket, set IPV6_V6ONLY if that option is
available. */
/* If this is an IPv6 wildcard socket, set IPV6_V6ONLY if that option is
available. */
@@
-314,6
+330,15
@@
else
printf("IPv4 socket creation failed: %s\n", strerror(errno));
exit(1);
}
printf("IPv4 socket creation failed: %s\n", strerror(errno));
exit(1);
}
+#ifdef TCP_FASTOPEN
+ if (tfo)
+ {
+ int backlog = 5;
+ if (setsockopt(listen_socket[v4n], IPPROTO_TCP, TCP_FASTOPEN,
+ &backlog, sizeof(backlog)))
+ if (debug) printf("setsockopt TCP_FASTOPEN: %s\n", strerror(errno));
+ }
+#endif
}
}
}
}
@@
-376,7
+401,7
@@
else
sin6.sin6_addr = anyaddr6;
if (bind(listen_socket[i], (struct sockaddr *)&sin6, sizeof(sin6)) < 0)
{
sin6.sin6_addr = anyaddr6;
if (bind(listen_socket[i], (struct sockaddr *)&sin6, sizeof(sin6)) < 0)
{
- printf("IPv6 socket bind(
) failed: %s\n"
, strerror(errno));
+ printf("IPv6 socket bind(
port %d) failed: %s\n", port
, strerror(errno));
exit(1);
}
}
exit(1);
}
}
@@
-393,10
+418,9
@@
else
sin4.sin_addr.s_addr = (S_ADDR_TYPE)INADDR_ANY;
sin4.sin_port = htons(port);
if (bind(listen_socket[i], (struct sockaddr *)&sin4, sizeof(sin4)) < 0)
sin4.sin_addr.s_addr = (S_ADDR_TYPE)INADDR_ANY;
sin4.sin_port = htons(port);
if (bind(listen_socket[i], (struct sockaddr *)&sin4, sizeof(sin4)) < 0)
- {
if (listen_socket[v6n] < 0 || errno != EADDRINUSE)
{
if (listen_socket[v6n] < 0 || errno != EADDRINUSE)
{
- printf("IPv4 socket bind(
) failed: %s\n"
, strerror(errno));
+ printf("IPv4 socket bind(
port %d) failed: %s\n", port
, strerror(errno));
exit(1);
}
else
exit(1);
}
else
@@
-404,7
+428,6
@@
else
close(listen_socket[i]);
listen_socket[i] = -1;
}
close(listen_socket[i]);
listen_socket[i] = -1;
}
- }
}
}
}
}
}
}
@@
-496,6
+519,11
@@
s = script;
for (count = 0; count < connection_count; count++)
{
for (count = 0; count < connection_count; count++)
{
+ struct {
+ int left;
+ BOOL in_use;
+ } content_length = { 0, FALSE };
+
alarm(timeout);
if (port <= 0)
{
alarm(timeout);
if (port <= 0)
{
@@
-521,8
+549,7
@@
for (count = 0; count < connection_count; count++)
if (listen_socket[i] > max_socket) max_socket = listen_socket[i];
}
if (listen_socket[i] > max_socket) max_socket = listen_socket[i];
}
- lcount = select(max_socket + 1, &select_listen, NULL, NULL, NULL);
- if (lcount < 0)
+ if ((lcount = select(max_socket + 1, &select_listen, NULL, NULL, NULL)) < 0)
{
printf("Select failed\n");
fflush(stdout);
{
printf("Select failed\n");
fflush(stdout);
@@
-531,7
+558,6
@@
for (count = 0; count < connection_count; count++)
accept_socket = -1;
for (i = 0; i < skn; i++)
accept_socket = -1;
for (i = 0; i < skn; i++)
- {
if (listen_socket[i] > 0 && FD_ISSET(listen_socket[i], &select_listen))
{
accept_socket = accept(listen_socket[i],
if (listen_socket[i] > 0 && FD_ISSET(listen_socket[i], &select_listen))
{
accept_socket = accept(listen_socket[i],
@@
-539,7
+565,6
@@
for (count = 0; count < connection_count; count++)
FD_CLR(listen_socket[i], &select_listen);
break;
}
FD_CLR(listen_socket[i], &select_listen);
break;
}
- }
}
alarm(0);
}
alarm(0);
@@
-591,7
+616,7
@@
for (count = 0; count < connection_count; count++)
doesn't work for other tests (e.g. ident tests) so we have explicit '<' and
'>' flags for input and output as well as the defaults. */
doesn't work for other tests (e.g. ident tests) so we have explicit '<' and
'>' flags for input and output as well as the defaults. */
- for (; s
!= NULL
; s = s->next)
+ for (; s; s = s->next)
{
char *ss = s->line;
{
char *ss = s->line;
@@
-656,7
+681,7
@@
for (count = 0; count < connection_count; count++)
n = dlen < sizeof(buffer) ? dlen : sizeof(buffer);
if ((n = read(dup_accept_socket, CS buffer, n)) == 0)
{
n = dlen < sizeof(buffer) ? dlen : sizeof(buffer);
if ((n = read(dup_accept_socket, CS buffer, n)) == 0)
{
- printf("Unxpected EOF read from client\n");
+ printf("Un
e
xpected EOF read from client\n");
s = s->next;
goto END_OFF;
}
s = s->next;
goto END_OFF;
}
@@
-666,7
+691,7
@@
for (count = 0; count < connection_count; count++)
while (dlen-- > 0)
if (fgetc(in) == EOF)
{
while (dlen-- > 0)
if (fgetc(in) == EOF)
{
- printf("Unxpected EOF read from client\n");
+ printf("Un
e
xpected EOF read from client\n");
s = s->next;
goto END_OFF;
}
s = s->next;
goto END_OFF;
}
@@
-709,6
+734,7
@@
for (count = 0; count < connection_count; count++)
alarm(timeout);
n = read(dup_accept_socket, CS buffer+offset, s->len - offset);
alarm(timeout);
n = read(dup_accept_socket, CS buffer+offset, s->len - offset);
+ if (content_length.in_use) content_length.left -= n;
if (n == 0)
{
printf("%sxpected EOF read from client\n",
if (n == 0)
{
printf("%sxpected EOF read from client\n",
@@
-721,13
+747,14
@@
for (count = 0; count < connection_count; count++)
alarm(0);
n += offset;
alarm(0);
n += offset;
- printit(buffer, n);
+ printit(
CS
buffer, n);
if (data) do
{
n = (read(dup_accept_socket, &c, 1) == 1 && c == '.');
if (data) do
{
n = (read(dup_accept_socket, &c, 1) == 1 && c == '.');
+ if (content_length.in_use) content_length.left--;
while (c != '\n' && read(dup_accept_socket, &c, 1) == 1)
while (c != '\n' && read(dup_accept_socket, &c, 1) == 1)
- ;
+
if (content_length.in_use) content_length.left--
;
} while (!n);
else if (memcmp(ss, buffer, n) != 0)
{
} while (!n);
else if (memcmp(ss, buffer, n) != 0)
{
@@
-750,7
+777,8
@@
for (count = 0; count < connection_count; count++)
goto END_OFF;
}
alarm(0);
goto END_OFF;
}
alarm(0);
- n = (int)strlen(CS buffer);
+ n = strlen(CS buffer);
+ if (content_length.in_use) content_length.left -= (n - offset);
while (n > 0 && isspace(buffer[n-1])) n--;
buffer[n] = 0;
printf("%s\n", buffer);
while (n > 0 && isspace(buffer[n-1])) n--;
buffer[n] = 0;
printf("%s\n", buffer);
@@
-764,6
+792,11
@@
for (count = 0; count < connection_count; count++)
break;
}
}
break;
}
}
+
+ if (sscanf(CCS buffer, "<Content-length: %d", &content_length.left))
+ content_length.in_use = TRUE;
+ if (content_length.in_use && content_length.left <= 0)
+ shutdown(dup_accept_socket, SHUT_RD);
}
}
}
}
@@
-774,7
+807,7
@@
for (count = 0; count < connection_count; count++)
if (s == NULL) printf("End of script\n");
if (s == NULL) printf("End of script\n");
-if (sockname
!= NULL
) unlink(sockname);
+if (sockname) unlink(sockname);
exit(0);
}
exit(0);
}