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
.I netdir
] [
.B -t
.I timeout
]
.I addr
.SH DESCRIPTION
@ -55,6 +58,11 @@ contains an entry with
and the attribute
.BR trampok .
If no such entry is found, the call is rejected.
.TP
.BI -t " timeout
Terminates the connection after
.I timeout
milliseconds of inactivity.
.PD
.SH FILES
.TF /sys/log/trampoline

View file

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