aux/trampoline: Implement inactivity timeout (-t option)

Using aux/trampoline to relay udp traffic needs a inactivity
timeout to be practical as there is no explicit connection
termination.
This commit is contained in:
cinap_lenrek 2020-06-27 16:40:53 +02:00
parent f0ea4af5ef
commit 675ebaeca3
2 changed files with 48 additions and 21 deletions

View file

@ -13,6 +13,9 @@ trampoline \- forward incoming calls to another address
[ [
.B -m .B -m
.I netdir .I netdir
] [
.B -t
.I timeout
] ]
.I addr .I addr
.SH DESCRIPTION .SH DESCRIPTION
@ -55,6 +58,11 @@ contains an entry with
and the attribute and the attribute
.BR trampok . .BR trampok .
If no such entry is found, the call is rejected. If no such entry is found, the call is rejected.
.TP
.BI -t " timeout
Terminates the connection after
.I timeout
milliseconds of inactivity.
.PD .PD
.SH FILES .SH FILES
.TF /sys/log/trampoline .TF /sys/log/trampoline

View file

@ -22,14 +22,16 @@ struct Endpoints
void xfer(int, int); void xfer(int, int);
void xfer9p(int, int); void xfer9p(int, int);
Endpoints* getendpoints(char*); Endpoints* getendpoints(char*);
void freeendpoints(Endpoints*);
char* iptomac(char*, char*); char* iptomac(char*, char*);
int macok(char*); int macok(char*);
int timeout;
int activity;
void void
usage(void) usage(void)
{ {
fprint(2, "usage: trampoline [-9] [-a addr] [-m netdir] addr\n"); fprint(2, "usage: trampoline [-9] [-a addr] [-m netdir] [-t timeout] addr\n");
exits("usage"); exits("usage");
} }
@ -54,6 +56,9 @@ main(int argc, char **argv)
case 'm': case 'm':
checkmac = EARGF(usage()); checkmac = EARGF(usage());
break; break;
case 't':
timeout = atoi(EARGF(usage()));
break;
default: default:
usage(); usage();
}ARGEND; }ARGEND;
@ -71,6 +76,9 @@ main(int argc, char **argv)
} }
} }
if(timeout > 0)
alarm(timeout);
fd0 = 0; fd0 = 0;
fd1 = 1; fd1 = 1;
if(altaddr){ if(altaddr){
@ -84,10 +92,28 @@ main(int argc, char **argv)
sysfatal("dial %s: %r", argv[0]); sysfatal("dial %s: %r", argv[0]);
rfork(RFNOTEG); rfork(RFNOTEG);
switch(fork()){ if(timeout > 0){
alarm(0);
switch(rfork(RFPROC|RFMEM)){
case -1:
fprint(2, "%s: fork: %r\n", argv0);
exits("fork");
case 0:
break;
default:
do {
activity = 0;
sleep(timeout);
} while(activity);
postnote(PNGROUP, getpid(), "timeout");
exits("timeout");
}
}
switch(rfork(RFPROC|RFMEM)){
case -1: case -1:
fprint(2, "%s: fork: %r\n", argv0); fprint(2, "%s: fork: %r\n", argv0);
exits("dial"); if(timeout <= 0) exits("fork");
break;
case 0: case 0:
(*x)(fd0, fd); (*x)(fd0, fd);
break; break;
@ -95,8 +121,8 @@ main(int argc, char **argv)
(*x)(fd, fd1); (*x)(fd, fd1);
break; break;
} }
postnote(PNGROUP, getpid(), "die yankee pig dog"); postnote(PNGROUP, getpid(), "hangup");
exits(0); exits(nil);
} }
void void
@ -105,9 +131,12 @@ xfer(int from, int to)
char buf[12*1024]; char buf[12*1024];
int n; int n;
while((n = read(from, buf, sizeof buf)) > 0) while((n = read(from, buf, sizeof buf)) > 0){
if(write(to, buf, n) < 0) if(write(to, buf, n) < 0)
break; break;
if(timeout > 0)
activity = 1;
}
} }
void void
@ -134,10 +163,10 @@ xfer9p(int from, int to)
} }
if(readn(from, buf+4, n-4) != n-4) if(readn(from, buf+4, n-4) != n-4)
break; break;
if(write(to, buf, n) != n){ if(write(to, buf, n) != n)
sysfatal("oops: %r");
break; break;
} if(timeout > 0)
activity = 1;
} }
} }
@ -192,16 +221,6 @@ getendpoints(char *dir)
return ep; return ep;
} }
void
freeendpoints(Endpoints *ep)
{
free(ep->lsys);
free(ep->rsys);
free(ep->lserv);
free(ep->rserv);
free(ep);
}
char* char*
iptomac(char *ip, char *net) iptomac(char *ip, char *net)
{ {
@ -237,5 +256,5 @@ macok(char *mac)
if(mac == nil) if(mac == nil)
return 0; return 0;
free(p = csgetvalue("/net", "ether", mac, "trampok", nil)); free(p = csgetvalue("/net", "ether", mac, "trampok", nil));
return !(p == nil); return p != nil;
} }