/* Miscellaneous servers */ #include #include "machdep.h" #include "mbuf.h" #include "netuser.h" #include "timer.h" #include "tcp.h" static struct tcb *disc_tcb,*echo_tcb; /* Start up discard server */ discard_start(argc,argv) int argc; char *argv[]; { struct socket lsocket; void r_discard(),t_state(),t_state(); lsocket.address = ip_addr; if(argc < 2) lsocket.port = 9; else lsocket.port = atoi(argv[1]); disc_tcb = open_tcp(&lsocket,NULLSOCK,TCP_PASSIVE,0,r_discard,NULLVFP,t_state,0); } /* Start echo server */ echo_start(argc,argv) int argc; char *argv[]; { void r_echo(),t_echo(),t_state(); struct socket lsocket; lsocket.address = ip_addr; if(argc < 2) lsocket.port = 7; else lsocket.port = atoi(argv[1]); echo_tcb = open_tcp(&lsocket,NULLSOCK,TCP_PASSIVE,0,r_echo,t_echo,t_state,0); } /* Shut down miscellaneous servers */ discard_stop() { if(disc_tcb != NULLTCB) close_tcp(disc_tcb); } echo_stop() { if(echo_tcb != NULLTCB) close_tcp(echo_tcb); } /* Discard server receiver upcall */ static void r_discard(tcb,cnt) struct tcb *tcb; int cnt; { struct mbuf *bp; if(recv_tcp(tcb,&bp,cnt) > 0) free_p(bp); /* Discard */ } /* Echo server receive * Copies only as much will fit on the transmit queue */ static void r_echo(tcb,cnt) struct tcb *tcb; int cnt; { struct mbuf *bp; int acnt; if(cnt == 0){ close_tcp(tcb); return; } acnt = min(cnt,tcb->snd.wnd); if(acnt > 0){ /* Get only as much will fit in the send window */ recv_tcp(tcb,&bp,tcb->snd.wnd); send_tcp(tcb,bp); } } /* Echo server transmit * Copies anything that might have been left in the receiver queue */ static void t_echo(tcb,cnt) struct tcb *tcb; int cnt; { struct mbuf *bp; if(tcb->rcvcnt > 0){ /* Get only as much will fit in the send window */ recv_tcp(tcb,&bp,cnt); send_tcp(tcb,bp); } } /* Log connection state changes; also respond to remote closes */ static void t_state(tcb,old,new) register struct tcb *tcb; char old,new; { switch(new){ case ESTABLISHED: log(tcb,"open %d",tcb->conn.local.port); break; case CLOSE_WAIT: close_tcp(tcb); break; case CLOSED: log(tcb,"close %d",tcb->conn.local.port); del_tcp(tcb); /* Clean up if server is being shut down */ if(tcb == disc_tcb) disc_tcb = NULLTCB; else if(tcb == echo_tcb) echo_tcb = NULLTCB; break; } }