From b0329a43e9223778376a326de32ab87a47f33df9 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 26 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-26 --- port/devip.c | 303 +++++++++++++++++++++++++++++------------------- port/ipdat.h | 41 ++++--- port/stil.c | 48 +++++--- port/stip.c | 79 ++++--------- port/tcpinput.c | 23 ++-- port/tcptimer.c | 26 +++-- 6 files changed, 284 insertions(+), 236 deletions(-) diff --git a/port/devip.c b/port/devip.c index f06b61be933286c8e2796f59aa24e4eb744598d9..ace70054a215e7dc32726461d8b728071f512d30 100644 --- a/port/devip.c +++ b/port/devip.c @@ -13,15 +13,15 @@ enum { Nrprotocol = 3, /* Number of protocols supported by this driver */ Nipsubdir = 4, /* Number of subdirectory entries per connection */ + Nfrag = 32, /* Ip reassembly queue entries */ + Nifc = 4, /* max interfaces */ }; int udpsum = 1; Queue *Ipoutput; /* Control message stream for tcp/il */ -Ipifc *ipifc; /* IP protocol interfaces for stip */ -Ipconv *ipconv[Nrprotocol]; /* Connections for each protocol */ -Network *ipnet[Nrprotocol]; /* User level interface for protocol */ +Ipifc *ipifc[Nrprotocol+1]; QLock ipalloc; /* Protocol port allocation lock */ -Ipconv *tcpbase; /* Base tcp connection */ +Ipconv **tcpbase; Streamput udpstiput, udpstoput, tcpstiput, tcpstoput, iliput, iloput, bsdiput, bsdoput; Streamopen udpstopen, tcpstopen, ilopen, bsdopen; @@ -35,46 +35,39 @@ Qinfo bsdinfo = { bsdiput, bsdoput, bsdopen, bsdclose, "bsd", 0, 1 }; Qinfo *protocols[] = { &tcpinfo, &udpinfo, &ilinfo, 0 }; void -ipinitnet(Network *np, Qinfo *stproto, Ipconv *cp) +ipinitifc(Ipifc *ifc, Qinfo *stproto) { int j; - for(j = 0; j < conf.ip; j++, cp++){ - cp->stproto = stproto; - cp->net = np; - netadd(np, cp, j); - } - np->name = stproto->name; - np->nconv = conf.ip; - np->devp = &ipinfo; - np->protop = stproto; + ifc->conv = xalloc(Nipconv * sizeof(Ipconv*)); + ifc->protop = stproto; + ifc->nconv = Nipconv; + ifc->devp = &ipinfo; if(stproto != &udpinfo) - np->listen = iplisten; - np->clone = ipclonecon; - np->ninfo = 3; - np->info[0].name = "remote"; - np->info[0].fill = ipremotefill; - np->info[1].name = "local"; - np->info[1].fill = iplocalfill; - np->info[2].name = "status"; - np->info[2].fill = ipstatusfill; + ifc->listen = iplisten; + ifc->clone = ipclonecon; + ifc->ninfo = 3; + ifc->info[0].name = "remote"; + ifc->info[0].fill = ipremotefill; + ifc->info[1].name = "local"; + ifc->info[1].fill = iplocalfill; + ifc->info[2].name = "status"; + ifc->info[2].fill = ipstatusfill; + ifc->name = stproto->name; } void ipreset(void) { - int i, j; - - ipifc = (Ipifc *)xalloc(sizeof(Ipifc) * conf.ip); + int i; for(i = 0; protocols[i]; i++) { - ipconv[i] = (Ipconv *)xalloc(sizeof(Ipconv) * conf.ip); - ipnet[i] = (Network *)xalloc(sizeof(Network)); - ipinitnet(ipnet[i], protocols[i], ipconv[i]); + ipifc[i] = xalloc(sizeof(Ipifc)); + ipinitifc(ipifc[i], protocols[i]); newqinfo(protocols[i]); } - initfrag(conf.frag); + initfrag(Nfrag); } void @@ -114,40 +107,79 @@ ipclone(Chan *c, Chan *nc) int ipwalk(Chan *c, char *name) { - return netwalk(c, name, ipnet[c->dev]); + return netwalk(c, name, ipifc[c->dev]); } void ipstat(Chan *c, char *db) { - netstat(c, db, ipnet[c->dev]); + netstat(c, db, ipifc[c->dev]); } Chan * ipopen(Chan *c, int omode) { - return netopen(c, omode, ipnet[c->dev]); + return netopen(c, omode, ipifc[c->dev]); } int ipclonecon(Chan *c) { - Ipconv *new, *base; + Ipconv *new; - base = ipconv[c->dev]; - new = ipincoming(base, 0); + new = ipincoming(ipifc[c->dev], 0); if(new == 0) error(Enodev); - return new - base; + return new->id; } -Ipconv * -ipincoming(Ipconv *base, Ipconv *from) +/* + * create a new conversation structure if none exists for this conversation slot + */ +Ipconv* +ipcreateconv(Ipifc *ifc, int id) { - Ipconv *new, *etab; + Ipconv **p; + Ipconv *new; + + p = &ifc->conv[id]; + if(*p) + return *p; + qlock(ifc); + p = &ifc->conv[id]; + if(*p){ + qunlock(ifc); + return *p; + } + if(waserror()){ + qunlock(ifc); + nexterror(); + } + new = smalloc(sizeof(Ipconv)); + new->ifc = ifc; + netadd(ifc, new, p - ifc->conv); + new->ref = 1; + *p = new; + qunlock(ifc); + poperror(); + return new; +} - etab = &base[conf.ip]; - for(new = base; new < etab; new++) { +/* + * allocate a conversation structure. + */ +Ipconv* +ipincoming(Ipifc *ifc, Ipconv *from) +{ + Ipconv **p, **etab; + Ipconv *new; + + /* look for an unused existing conversation */ + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; p < etab; p++) { + new = *p; + if(new == 0) + break; if(new->ref == 0 && canqlock(new)) { if(new->ref || ipconbusy(new)) { qunlock(new); @@ -163,7 +195,35 @@ ipincoming(Ipconv *base, Ipconv *from) return new; } } - return 0; + + /* create one */ + qlock(ifc); + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; ; p++){ + if(p == etab){ + qunlock(ifc); + return 0; + } + if(*p == 0) + break; + } + if(waserror()){ + qunlock(ifc); + nexterror(); + } + new = smalloc(sizeof(Ipconv)); + new->ifc = ifc; + netadd(ifc, new, p - ifc->conv); + qlock(new); + *p = new; + qunlock(ifc); + if(from) /* copy ownership from listening channel */ + netown(new, from->owner, 0); + else /* current user becomes owner */ + netown(new, u->p->user, 0); + new->ref = 1; + qunlock(new); + return new; } void @@ -183,7 +243,7 @@ ipremove(Chan *c) void ipwstat(Chan *c, char *dp) { - netwstat(c, dp, ipnet[c->dev]); + netwstat(c, dp, ipifc[c->dev]); } void @@ -196,7 +256,7 @@ ipclose(Chan *c) long ipread(Chan *c, void *a, long n, ulong offset) { - return netread(c, a, n, offset, ipnet[c->dev]); + return netread(c, a, n, offset, ipifc[c->dev]); } long @@ -214,7 +274,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset) if (type != Sctlqid) error(Eperm); - cp = &ipconv[c->dev][STREAMID(c->qid.path)]; + cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); m = n; if(m > sizeof(buf)-1) @@ -251,13 +311,13 @@ ipwrite(Chan *c, char *a, long n, ulong offset) /* If we have no local port assign one */ if(cp->psrc == 0){ qlock(&ipalloc); - cp->psrc = nextport(ipconv[c->dev], priv); + cp->psrc = nextport(ipifc[c->dev], priv); qunlock(&ipalloc); } - if(cp->stproto == &tcpinfo) + if(cp->ifc->protop == &tcpinfo) tcpstart(cp, TCP_ACTIVE, Streamhi, 0); - else if(cp->stproto == &ilinfo) + else if(cp->ifc->protop == &ilinfo) ilstart(cp, IL_ACTIVE, 20); /* @@ -274,7 +334,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset) } } else if(strcmp(field[0], "disconnect") == 0) { - if(cp->stproto != &udpinfo) + if(cp->ifc->protop != &udpinfo) error(Eperm); cp->dst = 0; @@ -291,7 +351,7 @@ ipwrite(Chan *c, char *a, long n, ulong offset) if(port){ qlock(&ipalloc); - if(portused(ipconv[c->dev], port)) { + if(portused(ipifc[c->dev], port)) { qunlock(&ipalloc); error(Einuse); } @@ -299,14 +359,14 @@ ipwrite(Chan *c, char *a, long n, ulong offset) qunlock(&ipalloc); } else if(*field[1] != '*'){ qlock(&ipalloc); - cp->psrc = nextport(ipconv[c->dev], 0); + cp->psrc = nextport(ipifc[c->dev], 0); qunlock(&ipalloc); } else cp->psrc = 0; - if(cp->stproto == &tcpinfo) + if(cp->ifc->protop == &tcpinfo) tcpstart(cp, TCP_PASSIVE, Streamhi, 0); - else if(cp->stproto == &ilinfo) + else if(cp->ifc->protop == &ilinfo) ilstart(cp, IL_PASSIVE, 10); if(cp->backlog == 0) @@ -331,11 +391,11 @@ ipwrite(Chan *c, char *a, long n, ulong offset) int ipconbusy(Ipconv *cp) { - if(cp->stproto == &tcpinfo) + if(cp->ifc->protop == &tcpinfo) if(cp->tcpctl.state != Closed) return 1; - if(cp->stproto == &ilinfo) + if(cp->ifc->protop == &ilinfo) if(cp->ilctl.state != Ilclosed) return 1; @@ -352,9 +412,9 @@ udpstiput(Queue *q, Block *bp) * udprcvmsg - called by stip to multiplex udp ports onto conversations */ void -udprcvmsg(Ipconv *muxed, Block *bp) +udprcvmsg(Ipifc *ifc, Block *bp) { - Ipconv *ifc, *etab; + Ipconv *cp, **p, **etab; Udphdr *uh; Port dport, sport; ushort sum, len; @@ -383,11 +443,14 @@ udprcvmsg(Ipconv *muxed, Block *bp) sport = nhgets(uh->udpsport); /* Look for a conversation structure for this port */ - etab = &muxed[conf.ip]; - for(ifc = muxed; ifc < etab; ifc++) { - if(ifc->ref) - if(ifc->psrc == dport) - if(ifc->pdst == 0 || ifc->pdst == sport) { + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; p < etab; p++) { + cp = *p; + if(cp == 0) + break; + if(cp->ref) + if(cp->psrc == dport) + if(cp->pdst == 0 || cp->pdst == sport) { /* Trim the packet down to data size */ len = len - (UDP_HDRSIZE-UDP_PHDRSIZE); bp = btrim(bp, UDP_EHSIZE+UDP_HDRSIZE, len); @@ -395,9 +458,9 @@ udprcvmsg(Ipconv *muxed, Block *bp) return; /* Stuff the src address into the remote file */ - ifc->dst = addr; - ifc->pdst = sport; - PUTNEXT(ifc->readq, bp); + cp->dst = addr; + cp->pdst = sport; + PUTNEXT(cp->readq, bp); return; } } @@ -476,8 +539,6 @@ udpstclose(Queue *q) ipc->psrc = 0; ipc->pdst = 0; ipc->dst = 0; - - closeipifc(ipc->ipinterface); } void @@ -485,13 +546,12 @@ udpstopen(Queue *q, Stream *s) { Ipconv *ipc; - ipc = &ipconv[s->dev][s->id]; - ipc->ipinterface = newipifc(IP_UDPPROTO, udprcvmsg, ipconv[s->dev], - 1500, 512, ETHER_HDR, "UDP"); + ipc = ipcreateconv(ipifc[s->dev], s->id); + initipifc(ipifc[s->dev], IP_UDPPROTO, udprcvmsg, 1500, 512, ETHER_HDR, "UDP"); ipc->readq = RD(q); RD(q)->ptr = (void *)ipc; - WR(q)->next->ptr = (void *)ipc->ipinterface; + WR(q)->next->ptr = (void *)ipc->ifc; WR(q)->ptr = (void *)ipc; } @@ -564,6 +624,7 @@ void tcpstopen(Queue *q, Stream *s) { Ipconv *ipc; + Ipifc *ifc; Tcpctl *tcb; Block *bp; static int tcpkprocs; @@ -578,22 +639,22 @@ tcpstopen(Queue *q, Stream *s) if(tcpkprocs == 0) { tcpkprocs = 1; kproc("tcpack", tcpackproc, 0); - kproc("tcpflow", tcpflow, &ipconv[s->dev]); + kproc("tcpflow", tcpflow, ipifc[s->dev]); } if(tcpbase == 0) - tcpbase = ipconv[s->dev]; - ipc = &ipconv[s->dev][s->id]; - ipc->ipinterface = newipifc(IP_TCPPROTO, tcp_input, ipconv[s->dev], - 1500, 512, ETHER_HDR, "TCP"); + tcpbase = ipifc[s->dev]->conv; + ifc = ipifc[s->dev]; + initipifc(ifc, IP_TCPPROTO, tcp_input, 1500, 512, ETHER_HDR, "TCP"); + ipc = ipcreateconv(ifc, s->id); ipc->readq = RD(q); ipc->readq->rp = &tcpflowr; ipc->err = 0; RD(q)->ptr = (void *)ipc; - WR(q)->next->ptr = (void *)ipc->ipinterface; + WR(q)->next->ptr = (void *)ipc->ifc; WR(q)->ptr = (void *)ipc; /* pass any waiting data upstream */ @@ -607,22 +668,18 @@ tcpstopen(Queue *q, Stream *s) void ipremotefill(Chan *c, char *buf, int len) { - int connection; Ipconv *cp; - connection = STREAMID(c->qid.path); - cp = &ipconv[c->dev][connection]; + cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(cp->dst), cp->pdst); } void iplocalfill(Chan *c, char *buf, int len) { - int connection; Ipconv *cp; - connection = STREAMID(c->qid.path); - cp = &ipconv[c->dev][connection]; + cp = ipcreateconv(ipifc[c->dev], STREAMID(c->qid.path)); sprint(buf, "%d.%d.%d.%d %d\n", fmtaddr(Myip[Myself]), cp->psrc); } @@ -633,17 +690,17 @@ ipstatusfill(Chan *c, char *buf, int len) Ipconv *cp; connection = STREAMID(c->qid.path); - cp = &ipconv[c->dev][connection]; - if(cp->stproto == &tcpinfo) + cp = ipcreateconv(ipifc[c->dev], connection); + if(cp->ifc->protop == &tcpinfo) sprint(buf, "tcp/%d %d %s %s\n", connection, cp->ref, tcpstate[cp->tcpctl.state], cp->tcpctl.flags & CLONE ? "listen" : "connect"); - else if(cp->stproto == &ilinfo) + else if(cp->ifc->protop == &ilinfo) sprint(buf, "il/%d %d %s rtt %d ms %d csum\n", connection, cp->ref, ilstate[cp->ilctl.state], cp->ilctl.rtt, - cp->ipinterface ? cp->ipinterface->chkerrs : 0); + cp->ifc ? cp->ifc->chkerrs : 0); else - sprint(buf, "%s/%d %d\n", cp->stproto->name, connection, cp->ref); + sprint(buf, "%s/%d %d\n", cp->ifc->protop->name, connection, cp->ref); } int @@ -655,20 +712,19 @@ iphavecon(Ipconv *s) int iplisten(Chan *c) { - Ipconv *etab, *new; - Ipconv *s, *base; + Ipconv **p, **etab, *new; + Ipconv *s; int connection; Ipconv *cp; connection = STREAMID(c->qid.path); - s = &ipconv[c->dev][connection]; - base = ipconv[c->dev]; + s = ipcreateconv(ipifc[c->dev], connection); - if(s->stproto == &tcpinfo) + if(s->ifc->protop == &tcpinfo) if(s->tcpctl.state != Listen) error(Enolisten); - if(s->stproto == &ilinfo) + if(s->ifc->protop == &ilinfo) if(s->ilctl.state != Illistening) error(Enolisten); @@ -680,15 +736,18 @@ iplisten(Chan *c) } sleep(&s->listenr, iphavecon, s); poperror(); - new = base; - for(etab = &base[conf.ip]; new < etab; new++) { + etab = &ipifc[c->dev]->conv[Nipconv]; + for(p = ipifc[c->dev]->conv; p < etab; p++) { + new = *p; + if(new == 0) + break; if(new->newcon == s) { qlock(s); s->curlog--; qunlock(s); new->newcon = 0; qunlock(&s->listenq); - return new - base; + return new->id; } } qunlock(&s->listenq); @@ -701,7 +760,7 @@ void tcpstclose(Queue *q) { Ipconv *s; - Ipconv *etab, *ifc; + Ipconv **etab, **p; Tcpctl *tcb; s = (Ipconv *)(q->ptr); @@ -720,11 +779,11 @@ tcpstclose(Queue *q) qlock(s); s->backlog = 0; s->curlog = 0; - etab = &tcpbase[conf.ip]; - for(ifc = tcpbase; ifc < etab; ifc++){ - if(ifc->newcon == s) { - ifc->newcon = 0; - tcpflushincoming(ifc); + etab = &tcpbase[Nipconv]; + for(p = tcpbase; p < etab && *p; p++){ + if((*p)->newcon == s) { + (*p)->newcon = 0; + tcpflushincoming(*p); } } qunlock(s); @@ -921,17 +980,22 @@ btrim(Block *bp, int offset, int len) } Ipconv * -portused(Ipconv *ic, Port port) +portused(Ipifc *ifc, Port port) { - Ipconv *ifc, *etab; + Ipconv **p, **etab; + Ipconv *cp; if(port == 0) return 0; - etab = &ic[conf.ip]; - for(ifc = ic; ifc < etab; ifc++) - if(ifc->psrc == port) - return ifc; + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; p < etab; p++){ + cp = *p; + if(cp == 0) + break; + if(cp->psrc == port) + return cp; + } return 0; } @@ -939,7 +1003,7 @@ portused(Ipconv *ic, Port port) static Port lastport[2] = { PORTALLOC-1, PRIVPORTALLOC-1 }; Port -nextport(Ipconv *ic, int priv) +nextport(Ipifc *ifc, int priv) { Port base; Port max; @@ -957,10 +1021,10 @@ nextport(Ipconv *ic, int priv) } for(i = *p + 1; i < max; i++) - if(!portused(ic, i)) + if(!portused(ifc, i)) return(*p = i); for(i = base ; i <= *p; i++) - if(!portused(ic, i)) + if(!portused(ifc, i)) return(*p = i); return(0); @@ -968,14 +1032,17 @@ nextport(Ipconv *ic, int priv) /* NEEDS HASHING ! */ -Ipconv * -ip_conn(Ipconv *ic, Port dst, Port src, Ipaddr dest, char proto) +Ipconv* +ip_conn(Ipifc *ifc, Port dst, Port src, Ipaddr dest, char proto) { - Ipconv *s, *etab; + Ipconv **p, *s, **etab; /* Look for a conversation structure for this port */ - etab = &ic[conf.ip]; - for(s = ic; s < etab; s++) { + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; p < etab; p++) { + s = *p; + if(s == 0) + break; if(s->psrc == dst) if(s->pdst == src) if(s->dst == dest || dest == 0) diff --git a/port/ipdat.h b/port/ipdat.h index 8024da707de39b750c63a03addb11049fc133d22..db109b9408c28b5bae461797a71646b2ea69606e 100644 --- a/port/ipdat.h +++ b/port/ipdat.h @@ -280,13 +280,11 @@ struct Ipconv QLock; /* Ref count lock */ Netprot; /* stat info */ int ref; - Qinfo *stproto; /* Stream protocol for this device */ - Network *net; /* user level network interface */ Ipaddr dst; /* Destination from connect */ Port psrc; /* Source port */ Port pdst; /* Destination port */ - Ipifc *ipinterface; /* Ip protocol interface */ + Ipifc *ifc; /* Ip protocol interface */ Queue *readq; /* Pointer to upstream read q */ QLock listenq; /* List of people waiting incoming cons */ Rendez listenr; /* Some where to sleep while waiting */ @@ -360,24 +358,31 @@ enum /* Tcp connection states */ Time_wait }; +enum +{ + Nipconv= 512, /* max conversations per interface */ +}; + /* * Ip interface structure. We have one for each active protocol driver */ struct Ipifc { QLock; - int ref; + Network; /* user level network interface */ + Ipifc *next; + int inited; uchar protocol; /* Ip header protocol number */ - char name[NAMELEN]; /* Protocol name */ - void (*iprcv) (Ipconv *, Block *); /* Receive demultiplexor */ - Ipconv *connections; /* Connection list */ + void (*iprcv) (Ipifc*, Block*); /* Receive demultiplexor */ int maxmtu; /* Maximum transfer unit */ int minmtu; /* Minumum tranfer unit */ int hsize; /* Media header size */ ulong chkerrs; /* checksum errors */ - Lock; + Lock; + Ipconv **conv; /* conversations */ }; + struct Fragq { QLock; @@ -423,7 +428,6 @@ int arp_lookup(uchar*, uchar*); int backoff(int); Block* btrim(Block*, int, int); void close_self(Ipconv *, char []); -void closeipifc(Ipifc*); int dupb(Block **, Block *, int, int); void extract_oob(Block **, Block **, Tcp *); void get_reseq(Tcpctl *, char *, Tcp *, Block **, ushort *); @@ -436,15 +440,17 @@ void ilstart(Ipconv *, int, int); int inb_window(Tcpctl *, int); void init_tcpctl(Ipconv *); void initfrag(int); -Ipconv* ip_conn(Ipconv *, Port, Port, Ipaddr dest, char proto); +void initipifc(Ipifc*, uchar, void (*)(Ipifc*, Block*), int, int, int, char*); +Ipconv* ip_conn(Ipifc*, Port, Port, Ipaddr dest, char proto); ushort ip_csum(uchar*); Block* ip_reassemble(int, Block*, Etherhdr*); int ipclonecon(Chan *); int ipconbusy(Ipconv*); +Ipconv* ipcreateconv(Ipifc*, int); int ipforme(uchar*); Fragq* ipfragallo(void); void ipfragfree(Fragq*, int); -Ipconv* ipincoming(Ipconv*, Ipconv*); +Ipconv* ipincoming(Ipifc*, Ipconv*); int iplisten(Chan *); void iplocalfill(Chan*, char*, int); void ipmkdir(Qinfo *, Dirtab *, Ipconv *); @@ -453,13 +459,12 @@ void ipremotefill(Chan*, char*, int); void iproute(uchar*, uchar*); void ipsetaddrs(void); void ipstatusfill(Chan*, char*, int); -Ipifc* newipifc(uchar, void (*)(Ipconv *, Block*), Ipconv *, int, int, int, char*); -Port nextport(Ipconv *, int); -ulong nhgetl(uchar*); +Port nextport(Ipifc*, int); ushort nhgets(uchar*); +ulong nhgetl(uchar*); int ntohtcp(Tcp *, Block **); int ntohtcp(Tcp*, Block**); -Ipconv* portused(Ipconv *, Port); +Ipconv* portused(Ipifc*, Port); void ppkt(Block*); void proc_syn(Ipconv*, char, Tcp*); ushort ptcl_csum(Block*bp, int, int); @@ -478,7 +483,7 @@ void start_timer(Timer *); void state_upcall(Ipconv*, char oldstate, char newstate); void stop_timer(Timer *); void tcp_acktimer(void *); -void tcp_input(Ipconv *, Block *); +void tcp_input(Ipifc*, Block *); void tcp_output(Ipconv*); void tcp_timeout(void *); void tcpackproc(void*); @@ -487,7 +492,7 @@ void tcpflushincoming(Ipconv*); void tcprcvwin(Ipconv *); void tcpstart(Ipconv *, int, ushort, char); int trim(Tcpctl *, Tcp *, Block **, ushort *); -void udprcvmsg(Ipconv *, Block*); +void udprcvmsg(Ipifc*, Block*); void update(Ipconv *, Tcp *); #define fmtaddr(xx) (xx>>24)&0xff,(xx>>16)&0xff,(xx>>8)&0xff,xx&0xff @@ -501,7 +506,7 @@ extern Ipaddr Myip[7]; extern Ipaddr Mymask; extern Ipaddr Mynetmask; extern Ipaddr classmask[4]; -extern Ipconv *ipconv[]; +extern Ipifc *ipifc[]; extern char *tcpstate[]; extern char *ilstate[]; extern Rendez tcpflowr; diff --git a/port/stil.c b/port/stil.c index c8c47eb6b6ac72d5c8df8053f084d33f34b21dcc..b65a65b16277f6c0bd01380ca29827a84f794d1c 100644 --- a/port/stil.c +++ b/port/stil.c @@ -44,7 +44,7 @@ enum (s)->fasttime = (Fasttime*(s)->rtt)/Iltickms; \ (s)->slowtime = (Slowtime*(s)->rtt)/Iltickms; } -void ilrcvmsg(Ipconv*, Block*); +void ilrcvmsg(Ipifc*, Block*); void ilackproc(void*); void ilsendctl(Ipconv*, Ilhdr*, int, ulong, ulong); void ilackq(Ilcb*, Block*); @@ -69,16 +69,15 @@ ilopen(Queue *q, Stream *s) if(ilkproc == 0) { ilkproc = 1; - kproc("ilack", ilackproc, ipconv[s->dev]); + kproc("ilack", ilackproc, ipifc[s->dev]); } - ipc = &ipconv[s->dev][s->id]; - ipc->ipinterface = newipifc(IP_ILPROTO, ilrcvmsg, ipconv[s->dev], - 1500, 60, ETHER_HDR, "IL"); + ipc = ipcreateconv(ipifc[s->dev], s->id); + initipifc(ipc->ifc, IP_ILPROTO, ilrcvmsg, 1500, 60, ETHER_HDR, "IL"); ipc->readq = RD(q); RD(q)->ptr = (void *)ipc; - WR(q)->next->ptr = (void *)ipc->ipinterface; + WR(q)->next->ptr = (void *)ipc->ifc; WR(q)->ptr = (void *)ipc; } @@ -259,12 +258,12 @@ iliput(Queue *q, Block *bp) } void -ilrcvmsg(Ipconv *ipc, Block *bp) +ilrcvmsg(Ipifc *ifc, Block *bp) { Ilhdr *ih; Ilcb *ic; int plen, illen; - Ipconv *s, *etab, *new; + Ipconv *s, **p, **etab, *new; short sp, dp; Ipaddr dst; char *st; @@ -283,39 +282,46 @@ ilrcvmsg(Ipconv *ipc, Block *bp) dst = nhgetl(ih->src); if(ilcksum && ptcl_csum(bp, IL_EHSIZE, illen) != 0) { - ipc->ipinterface->chkerrs++; + ifc->chkerrs++; /* st = (ih->iltype < 0 || ih->iltype > Ilclose) ? "?" : iltype[ih->iltype]; print("il: cksum error, pkt(%s id %lud ack %lud %d.%d.%d.%d/%d->%d)\n", st, nhgetl(ih->ilid), nhgetl(ih->ilack), fmtaddr(dst), sp, dp); /**/ goto drop; } - etab = &ipc[conf.ip]; - for(s = ipc; s < etab; s++) + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; p < etab; p++) { + s = *p; + if(s == 0) + break; if(s->psrc == sp) if(s->pdst == dp) if(s->dst == dst) { ilprocess(s, ih, bp); return; } + } if(ih->iltype != Ilsync) goto drop; /* Look for a listener */ - for(s = ipc; s < etab; s++) { + for(p = ifc->conv; p < etab; p++) { + s = *p; + if(s == 0) + break; if(s->ilctl.state == Illistening) if(s->pdst == 0) if(s->dst == 0) { if(s->curlog > s->backlog) goto reset; - new = ipincoming(ipc, s); + new = ipincoming(ifc, s); if(new == 0) goto reset; new->newcon = s; - new->ipinterface = s->ipinterface; + new->ifc = s->ifc; new->psrc = sp; new->pdst = dp; new->dst = nhgetl(ih->src); @@ -334,7 +340,6 @@ ilrcvmsg(Ipconv *ipc, Block *bp) ic->window = Defaultwin; ilprocess(new, ih, bp); - s->ipinterface->ref++; s->curlog++; wakeup(&s->listenr); return; @@ -549,6 +554,7 @@ ilhangup(Ipconv *s, char *msg) ic = &s->ilctl; callout = ic->state == Ilsyncer; ic->state = Ilclosed; + qlock(s); if(s->readq) { if(msg) { l = strlen(msg); @@ -562,6 +568,7 @@ ilhangup(Ipconv *s, char *msg) nb->flags |= S_DELIM; PUTNEXT(s->readq, nb); } + qunlock(s); if(callout) wakeup(&ic->syncer); s->psrc = 0; @@ -703,16 +710,19 @@ ilsendctl(Ipconv *ipc, Ilhdr *inih, int type, ulong id, ulong ack) void ilackproc(void *a) { - Ipconv *base, *end, *s; + Ipifc *ifc; + Ipconv **base, **p, **end, *s; Ilcb *ic; Block *bp, *np; - base = (Ipconv*)a; - end = &base[conf.ip]; + ifc = (Ipifc*)a; + base = ifc->conv; + end = &base[Nipconv]; for(;;) { tsleep(&ilackr, return0, 0, Iltickms); - for(s = base; s < end; s++) { + for(p = base; p < end && *p; p++) { + s = *p; ic = &s->ilctl; ic->timeout += Iltickms; switch(ic->state) { diff --git a/port/stip.c b/port/stip.c index 25ba8089733fd455f7d5c1c3d808523586248dea..8375df5209e2d9340dddeb4b9fd486a1478b62e1 100644 --- a/port/stip.c +++ b/port/stip.c @@ -17,7 +17,6 @@ #define DPRINT if(pip)print int pip = 0; int ipcksum = 1; -extern Ipifc *ipifc; int Id = 1; Fragq *flisthead; @@ -81,7 +80,7 @@ ipetheropen(Queue *q, Stream *s) s->inuse++; ipsetaddrs(); } else { - ipc = &ipconv[s->dev][s->id]; + ipc = ipcreateconv(ipifc[s->dev], s->id); RD(q)->ptr = (void *)ipc; WR(q)->ptr = (void *)ipc; ipc->ref = 1; @@ -92,50 +91,27 @@ ipetheropen(Queue *q, Stream *s) } /* - * newipifc - Attach to or Create a new protocol interface + * initipifc - set parameters of an ip protocol interface */ - -Ipifc * -newipifc(uchar ptcl, void (*recvfun)(Ipconv *, Block *bp), - Ipconv *con, int max, int min, int hdrsize, char *name) +void +initipifc(Ipifc *ifc, uchar ptcl, void (*recvfun)(Ipifc*, Block *bp), int max, + int min, int hdrsize, char *name) { - Ipifc *ifc, *free; - - free = 0; - for(ifc = ipifc; ifc < &ipifc[conf.ipif]; ifc++) { - qlock(ifc); - if(ifc->protocol == ptcl) { - ifc->ref++; - qunlock(ifc); - return(ifc); - } - if(!free && ifc->ref == 0) { - ifc->ref = 1; - free = ifc; - } - else - qunlock(ifc); - } - - if(!free) - error(Enoifc); - - free->iprcv = recvfun; + qlock(ifc); + ifc->iprcv = recvfun; /* If media supports large transfer units limit maxmtu * to max ip size */ if(max > IP_MAX) max = IP_MAX; - free->maxmtu = max; - free->minmtu = min; - free->hsize = hdrsize; - free->connections = con; + ifc->maxmtu = max; + ifc->minmtu = min; + ifc->hsize = hdrsize; - free->protocol = ptcl; - strncpy(free->name, name, NAMELEN); + ifc->protocol = ptcl; + ifc->inited = 1; - qunlock(free); - return(free); + qunlock(ifc); } static void @@ -150,20 +126,6 @@ ipetherclose(Queue *q) } } -void -closeipifc(Ipifc *ifc) -{ - /* If this is the last reference to the protocol multiplexor - * cancel upcalls from this stream - */ - qlock(ifc); - if(--ifc->ref == 0) { - ifc->protocol = 0; - ifc->name[0] = 0; - } - qunlock(ifc); -} - static void ipetheroput(Queue *q, Block *bp) { @@ -301,7 +263,7 @@ drop: static void ipetheriput(Queue *q, Block *bp) { - Ipifc *ep, *ifp; + Ipifc *ifc, **ifp; Etherhdr *h; ushort frag; @@ -345,13 +307,16 @@ ipetheriput(Queue *q, Block *bp) /* * Look for an ip interface attached to this protocol */ - ep = &ipifc[conf.ipif]; - for(ifp = ipifc; ifp < ep; ifp++) - if(ifp->protocol == h->proto) { - (*ifp->iprcv)(ifp->connections, bp); + for(ifp = ipifc; ; ifp++){ + ifc = *ifp; + if(ifc == 0) + break; + if(ifc->protocol == h->proto) { + (*ifc->iprcv)(ifc, bp); return; } - + } + drop: freeb(bp); } diff --git a/port/tcpinput.c b/port/tcpinput.c index f872bf35dd4f62976e3d97def0d5fc92b2faa7e7..22158b528647f4875d5de591e2eb48084eebb859 100644 --- a/port/tcpinput.c +++ b/port/tcpinput.c @@ -92,7 +92,7 @@ tcpmove(struct Tctl *to, struct Tctl *from) } Ipconv* -tcpincoming(Ipconv *ipc, Ipconv *s, Tcp *segp, Ipaddr source) +tcpincoming(Ipifc *ifc, Ipconv *s, Tcp *segp, Ipaddr source) { Ipconv *new; @@ -102,7 +102,7 @@ tcpincoming(Ipconv *ipc, Ipconv *s, Tcp *segp, Ipaddr source) return 0; } - new = ipincoming(ipc, s); + new = ipincoming(ifc, s); if(new == 0){ qunlock(s); return 0; @@ -120,17 +120,15 @@ tcpincoming(Ipconv *ipc, Ipconv *s, Tcp *segp, Ipaddr source) new->tcpctl.acktimer.arg = new; new->tcpctl.acktimer.state = TIMER_STOP; new->newcon = s; - new->ipinterface = s->ipinterface; - s->ipinterface->ref++; wakeup(&s->listenr); return new; } void -tcp_input(Ipconv *ipc, Block *bp) +tcp_input(Ipifc *ifc, Block *bp) { - Ipconv *s, *e; + Ipconv *s, **p, **etab; Ipconv *spec, *gen; Tcpctl *tcb; Tcphdr *h; @@ -164,7 +162,7 @@ tcp_input(Ipconv *ipc, Block *bp) return; /* Look for a connection, failing that attempt to establish a listen */ - s = ip_conn(ipc, seg.dest, seg.source, source, IP_TCPPROTO); + s = ip_conn(ifc, seg.dest, seg.source, source, IP_TCPPROTO); if (s == 0) { if(seg.flags & SYN){ /* @@ -173,8 +171,9 @@ tcp_input(Ipconv *ipc, Block *bp) */ spec = 0; gen = 0; - e = &ipc[conf.ip]; - for(s = ipc; s < e; s++) { + etab = &ifc->conv[Nipconv]; + for(p = ifc->conv; p < etab && *p; p++) { + s = *p; if(s->tcpctl.state == Listen) if(s->pdst == 0) if(s->dst == 0) { @@ -187,9 +186,9 @@ tcp_input(Ipconv *ipc, Block *bp) } } if(spec) - s = tcpincoming(ipc, spec, &seg, source); + s = tcpincoming(ifc, spec, &seg, source); else if(gen) - s = tcpincoming(ipc, gen, &seg, source); + s = tcpincoming(ifc, gen, &seg, source); else s = 0; } @@ -583,7 +582,7 @@ proc_syn(Ipconv *s, char tos, Tcp *seg) tcb->mss = seg->mss; tcb->max_snd = seg->wnd; - if((mtu = s->ipinterface->maxmtu) != 0) { + if((mtu = s->ifc->maxmtu) != 0) { mtu -= TCP_HDRSIZE + TCP_EHSIZE + TCP_PHDRSIZE; tcb->cwind = tcb->mss = MIN(mtu, tcb->mss); } diff --git a/port/tcptimer.c b/port/tcptimer.c index b2a51611ee381a2c55c3fdbc1288e8661c833d16..b829400a27144ce77650036debb96aa12ae98063 100644 --- a/port/tcptimer.c +++ b/port/tcptimer.c @@ -108,23 +108,25 @@ stop_timer(Timer *t) } void -tcpflow(void *conv) +tcpflow(void *x) { - Ipconv *base, *ifc, *etab; + Ipifc *ifc; + Ipconv *cp, **p, **etab; - base = (Ipconv*)conv; - - etab = &base[conf.ip]; + ifc = x; + etab = &ifc->conv[Nipconv]; for(;;) { sleep(&tcpflowr, return0, 0); - for(ifc = base; ifc < etab; ifc++) { - if(ifc->readq) - if(ifc->ref != 0) - if(ifc->stproto == &tcpinfo) - if(!QFULL(ifc->readq->next)) { - tcprcvwin(ifc); - tcp_acktimer(ifc); + for(p = ifc->conv; p < etab; p++) { + cp = *p; + if(cp == 0) + break; + if(cp->readq) + if(cp->ref != 0) + if(!QFULL(cp->readq->next)) { + tcprcvwin(cp); + tcp_acktimer(cp); } } }