Implements TCP half-duplex close. It is needed for Go and may be useful too. Reference: /n/sources/patch/tcp-halfduplex-close Date: Thu Feb 9 23:45:43 CET 2017 Signed-off-by: skip.tavakkolian@gmail.com --- /sys/src/9/ip/tcp.c Thu Feb 9 23:41:10 2017 +++ /sys/src/9/ip/tcp.c Thu Feb 9 23:41:02 2017 @@ -432,6 +432,7 @@ static void tcpsynackrtt(Conv*); static void tcptimeout(void*); static int tcptrim(Tcpctl*, Tcp*, Block**, ushort*); +static char* tcphangup_rdwr(Conv*); static void tcpsetstate(Conv *s, uchar newstate) @@ -1410,11 +1411,43 @@ } /* + * close the conversation or perform half-duplex close in the specified direction + * called with s qlocked + */ +static char* +tcphangup(Conv *s, char **f, int n) +{ + Tcpctl *tcb; + + if(n == 1) + return tcphangup_rdwr(s); + + tcb = (Tcpctl*)s->ptcl; + if(tcb->state != Established) + return "connection must be in Establised state"; + + if(strcmp(f[1], "read") == 0){ + qhangup(s->rq, nil); + tcb->rcv.blocked = 1; + tcb->rcv.wnd = 0; + } else if(strcmp(f[1], "write") == 0){ + qhangup(s->wq, nil); + tcb->flgcnt++; + tcb->snd.nxt++; + tcpsetstate(s, Finwait1); + } else + return "hangup needs read or write parameter"; + + tcpoutput(s); + return nil; +} + +/* * send a reset to the remote side and close the conversation * called with s qlocked */ static char* -tcphangup(Conv *s) +tcphangup_rdwr(Conv *s) { Tcp seg; Tcpctl *tcb; @@ -3287,13 +3320,13 @@ static char* tcpctl(Conv* c, char** f, int n) { - if(n == 1 && strcmp(f[0], "hangup") == 0) - return tcphangup(c); + if(n >= 1 && strcmp(f[0], "hangup") == 0) + return tcphangup(c, f, n); if(n >= 1 && strcmp(f[0], "keepalive") == 0) return tcpstartka(c, f, n); - if(n >= 1 && strcmp(f[0], "checksum") == 0) + if(n > 1 && strcmp(f[0], "checksum") == 0) return tcpsetchecksum(c, f, n); - if(n >= 1 && strcmp(f[0], "tcpporthogdefense") == 0) + if(n > 1 && strcmp(f[0], "tcpporthogdefense") == 0) return tcpporthogdefensectl(f[1]); return "unknown control request"; } --- /sys/man/3/ip Thu Feb 9 23:41:16 2017 +++ /sys/man/3/ip Thu Feb 9 23:41:12 2017 @@ -720,8 +720,16 @@ .TF "\fLkeepalive\fI n\fR" .PD .TP -.B hangup -close down this TCP connection +.BI hangup \ [direction] +close down this TCP connection. If specified, the +.I direction +can be used to perform a +.I half-duplex +close. Specifying +.B read +will close the incoming side of the connection; a +.I write +will close the outgoing side. .TP .BI keepalive \ n turn on keep alive messages.