ref: 675ebaeca3c38d2684b249faae1fc24c5c2b6e0e
parent: f0ea4af5efff9e1e1d0fc5992edd1096c44d41ed
author: cinap_lenrek <[email protected]>
date: Sat Jun 27 12:40:53 EDT 2020
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.
--- a/sys/man/8/trampoline
+++ b/sys/man/8/trampoline
@@ -13,6 +13,9 @@
[
.B -m
.I netdir
+] [
+.B -t
+.I timeout
]
.I addr
.SH DESCRIPTION
@@ -55,6 +58,11 @@
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
--- a/sys/src/cmd/aux/trampoline.c
+++ b/sys/src/cmd/aux/trampoline.c
@@ -22,14 +22,16 @@
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 @@
case 'm':
checkmac = EARGF(usage());
break;
+ case 't':
+ timeout = atoi(EARGF(usage()));
+ break;
default:
usage();
}ARGEND;
@@ -71,6 +76,9 @@
}
}
+ if(timeout > 0)
+ alarm(timeout);
+
fd0 = 0;
fd1 = 1;
if(altaddr){
@@ -84,10 +92,28 @@
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 @@
(*x)(fd, fd1);
break;
}
- postnote(PNGROUP, getpid(), "die yankee pig dog");
- exits(0);
+ postnote(PNGROUP, getpid(), "hangup");
+ exits(nil);
}
void
@@ -105,9 +131,12 @@
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 @@
}
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 @@
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 @@
if(mac == nil)
return 0;
free(p = csgetvalue("/net", "ether", mac, "trampok", nil));
- return !(p == nil);
+ return p != nil;
}