CONTRIB: tcploop: add basic loops via a jump instruction

This one jumps back to the oldest post-fork and post-accept action,
so it allows to recv(), pause() and send() in loops after a fork()
and an accept() for example. This is handy for bugs that reproduce
once in a while or to keep idle connections working.
This commit is contained in:
Willy Tarreau 2016-11-12 18:54:20 +01:00
parent 1973e81c06
commit 29cc11ca41

View File

@ -99,6 +99,7 @@ __attribute__((noreturn)) void usage(int code, const char *arg0)
" Note: fd=socket,connect(fd)\n" " Note: fd=socket,connect(fd)\n"
" A[<count>] : Accepts <count> incoming sockets and closes count-1\n" " A[<count>] : Accepts <count> incoming sockets and closes count-1\n"
" Note: fd=accept(fd)\n" " Note: fd=accept(fd)\n"
" J : Jump back to oldest post-fork/post-accept action\n"
" G : disable lingering\n" " G : disable lingering\n"
" T : set TCP_NODELAY\n" " T : set TCP_NODELAY\n"
" Q : disable TCP Quick-ack\n" " Q : disable TCP Quick-ack\n"
@ -705,6 +706,7 @@ int main(int argc, char **argv)
struct sockaddr_storage ss; struct sockaddr_storage ss;
struct err_msg err; struct err_msg err;
const char *arg0; const char *arg0;
int loop_arg;
int arg; int arg;
int ret; int ret;
int sock; int sock;
@ -739,7 +741,8 @@ int main(int argc, char **argv)
gettimeofday(&start_time, NULL); gettimeofday(&start_time, NULL);
sock = -1; sock = -1;
for (arg = 2; arg < argc; arg++) { loop_arg = 2;
for (arg = loop_arg; arg < argc; arg++) {
switch (argv[arg][0]) { switch (argv[arg][0]) {
case 'L': case 'L':
/* silently ignore existing connections */ /* silently ignore existing connections */
@ -765,6 +768,7 @@ int main(int argc, char **argv)
if (sock < 0) if (sock < 0)
die(1, "Fatal: tcp_accept() failed.\n"); die(1, "Fatal: tcp_accept() failed.\n");
dolog("accept\n"); dolog("accept\n");
loop_arg = arg + 1; // cannot loop before accept()
break; break;
case 'T': case 'T':
@ -866,12 +870,18 @@ int main(int argc, char **argv)
die(1, "Fatal: fork() failed.\n"); die(1, "Fatal: fork() failed.\n");
if (ret > 0) { if (ret > 0) {
/* loop back to first arg */ /* loop back to first arg */
arg = 1; arg = loop_arg - 1;
continue; continue;
} }
/* OK we're in the child, let's continue */ /* OK we're in the child, let's continue */
pid = getpid(); pid = getpid();
loop_arg = arg + 1;
break; break;
case 'J': // jump back to oldest post-fork action
arg = loop_arg - 1;
continue;
default: default:
usage(1, arg0); usage(1, arg0);
} }