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:
parent
f0ea4af5ef
commit
675ebaeca3
2 changed files with 48 additions and 21 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue