From 15408a804093865b265e2d13b5fafbea23a63194 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 1 Aug 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-08-01 --- boot/boot.h | 4 +-- boot/embed.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ boot/rc.c | 24 ---------------- ip/tcp.c | 34 +++++++++++++++-------- port/chan.c | 8 ++++++ port/portdat.h | 2 +- 6 files changed, 108 insertions(+), 38 deletions(-) create mode 100644 boot/embed.c delete mode 100644 boot/rc.c diff --git a/boot/boot.h b/boot/boot.h index 6021220b614966dca398c35b2c5d2a060606d5ac..1e1a30c59eb10fec73d6cffc9546271d7ec6e6d8 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -67,8 +67,8 @@ extern int connectsac(void); extern void configpaq(Method*); extern int connectpaq(void); -extern void configrc(Method*); -extern int connectrc(void); +extern void configembed(Method*); +extern int connectembed(void); /* hack for passing authentication address */ extern char *authaddr; diff --git a/boot/embed.c b/boot/embed.c new file mode 100644 index 0000000000000000000000000000000000000000..c4c27eacfc4ec35b534fe493222a9ad48a469190 --- /dev/null +++ b/boot/embed.c @@ -0,0 +1,74 @@ +#include +#include +#include <../boot/boot.h> + +static char *paqfile; + +void +configembed(Method *m) +{ + if(*sys == '/' || *sys == '#'){ + /* + * if the user specifies the disk in the boot cmd or + * 'root is from' prompt, use it + */ + paqfile = sys; + } else if(m->arg){ + /* + * a default is supplied when the kernel is made + */ + paqfile = m->arg; + } +} + +int +connectembed(void) +{ + int i, p[2]; + Dir *dir; + char **arg, **argp; + + dir = dirstat("/paqfs"); + if(dir == nil) + return -1; + free(dir); + + dir = dirstat(paqfile); + if(dir == nil || dir->mode & DMDIR) + return -1; + free(dir); + + print("paqfs..."); + if(bind("#c", "/dev", MREPL) < 0) + fatal("bind #c"); + if(bind("#p", "/proc", MREPL) < 0) + fatal("bind #p"); + if(pipe(p)<0) + fatal("pipe"); + switch(fork()){ + case -1: + fatal("fork"); + case 0: + arg = malloc((bargc+5)*sizeof(char*)); + argp = arg; + *argp++ = "/paqfs"; + *argp++ = "-iv"; + *argp++ = paqfile; + for(i=1; i -#include -#include <../boot/boot.h> - -/* minimal rc main */ -char rcmain[] = "home=/\n" - "ifs=' \t\n'\n" - "prompt=('% ' '\t')\n" - "path=/\n"; - -void -configrc(Method *) -{ - setenv("rcmain", rcmain); - execl("/rc", "/rc", "-m", "#e/rcmain", "-i", 0); - fatal("rc"); -} - -int -connectrc(void) -{ - // does not get here - return -1; -} diff --git a/ip/tcp.c b/ip/tcp.c index 718b72667e7be994f5effef41995e41eff5af89f..a7bf835d696cffcba03b9c0edfae54c47cdf033f 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -50,6 +50,7 @@ enum DEF_KAT = 30000, /* Default time ms) between keep alives */ TCP_LISTEN = 0, /* Listen connection */ TCP_CONNECT = 1, /* Outgoing connection */ + SYNACK_RXTIMER = 250, /* ms between SYNACK retransmits */ TCPREXMTTHRESH = 3, /* dupack threshhold for rxt */ @@ -248,7 +249,7 @@ struct Tcpctl * New calls are put in limbo rather than having a conversation structure * allocated. Thus, a SYN attack results in lots of limbo'd calls but not * any real Conv structures mucking things up. Calls in limbo rexmit their - * SYN ACK every 250 ms up to 4 times, i.e., they disappear after 1 second. + * SYN ACK every SYNACK_RXTIMER ms up to 4 times, i.e., they disappear after 1 second. * * In particular they aren't on a listener's queue so that they don't figure * in the input queue limit. @@ -342,6 +343,17 @@ struct Tcppriv ulong stats[Nstats]; }; +/* + * Setting tcpporthogdefense to non-zero enables Dong Lin's + * solution to hijacked systems staking out port's as a form + * of DoS attack. + * + * To avoid stateless Conv hogs, we pick a sequence number at random. If + * it that number gets acked by the other end, we shut down the connection. + * Look for tcpporthogedefense in the code. + */ +int tcpporthogdefense = 0; + int addreseq(Tcpctl*, Tcp*, Block*, ushort); void getreseq(Tcpctl*, Tcp*, Block**, ushort*); void localclose(Conv*, char*); @@ -1374,7 +1386,7 @@ limbo(Conv *s, uchar *source, uchar *dest, Tcp *seg, int version) } /* - * resend SYN ACK's once every 250 ms. + * resend SYN ACK's once every SYNACK_RXTIMER ms. */ static void limborexmit(Proto *tcp) @@ -1395,11 +1407,11 @@ limborexmit(Proto *tcp) for(l = &tpriv->lht[h]; *l != nil && seen < tpriv->nlimbo; ){ lp = *l; seen++; - if(now - lp->lastsend < 250) + if(now - lp->lastsend < (lp->rexmits+1)*SYNACK_RXTIMER) continue; /* time it out after 1 second */ - if(++(lp->rexmits) > 4){ + if(++(lp->rexmits) > 5){ tpriv->nlimbo--; *l = lp->next; free(lp); @@ -1540,7 +1552,7 @@ tcpincoming(Conv *s, Tcp *segp, uchar *src, uchar *dst, uchar version) tcb->cwind = tcb->mss; /* set initial round trip time */ - tcb->sndsyntime = lp->lastsend; + tcb->sndsyntime = lp->lastsend+lp->rexmits*SYNACK_RXTIMER; tcpsynackrtt(new); free(lp); @@ -1998,7 +2010,8 @@ reset: * corresponding code in tcpsendka(). */ if(tcb->state != Syn_received && (seg.flags & RST) == 0){ - if(seq_within(seg.ack, tcb->snd.una-(1<<31), tcb->snd.una-(1<<29))){ + if(tcpporthogdefense + && seq_within(seg.ack, tcb->snd.una-(1<<31), tcb->snd.una-(1<<29))){ print("stateless hog %I.%d->%I.%d f %ux %lux - %lux - %lux\n", source, seg.source, dest, seg.dest, seg.flags, tcb->snd.una-(1<<31), seg.ack, tcb->snd.una-(1<<29)); @@ -2462,10 +2475,6 @@ tcpoutput(Conv *s) /* * the BSD convention (hack?) for keep alives. resend last uchar acked. - * - * To avoid stateless Conv hogs, we pick a sequence number at random. If - * it that number gets acked by the other end, we shut down the connection. - * See the equivalent code in tcpiput(). */ void tcpsendka(Conv *s) @@ -2482,7 +2491,10 @@ tcpsendka(Conv *s) seg.dest = s->rport; seg.flags = ACK|PSH; seg.mss = 0; - seg.seq = tcb->snd.una-(1<<30)-nrand(1<<20); + if(tcpporthogdefense) + seg.seq = tcb->snd.una-(1<<30)-nrand(1<<20); + else + seg.seq = tcb->snd.una-1; seg.ack = tcb->rcv.nxt; tcb->rcv.lastacked = tcb->rcv.nxt; seg.wnd = tcb->rcv.wnd; diff --git a/port/chan.c b/port/chan.c index 566039320e5e4d5d391e05acd040d43a17dcda0b..b5bf665bcbe342f76175f96080f22f2d633f7f60 100644 --- a/port/chan.c +++ b/port/chan.c @@ -769,6 +769,10 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) cnameclose(cname); cclose(c); strcpy(up->errstr, Enotdir); + if(mh != nil) +{print("walk 1\n"); + putmhead(mh); +} return -1; } ntry = nnames - nhave; @@ -813,6 +817,8 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) cnameclose(cname); if(nerror) *nerror = nhave+1; + if(mh != nil) + putmhead(mh); return -1; } } @@ -845,6 +851,8 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) strcpy(up->errstr, Enotdir); } free(wq); + if(mh != nil) + putmhead(mh); return -1; } n = wq->nqid; diff --git a/port/portdat.h b/port/portdat.h index 3c1c037f55c479e1527f5cf126896d5ea4038f89..04477e0423129b6973098f8d4b7f757e9b93e642 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -556,7 +556,7 @@ struct Schedq struct Proc { Label sched; /* known to l.s */ - char *kstack; /* known to l.s */ + char *kstack; /* known to l.s */ Mach *mach; /* machine running this proc */ char *text; char *user;