M port/devip.c => port/devip.c +185 -118
@@ 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)
M port/ipdat.h => port/ipdat.h +23 -18
@@ 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;
M port/stil.c => port/stil.c +29 -19
@@ 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) {
M port/stip.c => port/stip.c +22 -57
@@ 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);
}
M port/tcpinput.c => port/tcpinput.c +11 -12
@@ 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);
}
M port/tcptimer.c => port/tcptimer.c +14 -12
@@ 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);
}
}
}