| plan 9 kernel history: overview | file list | diff list |
1999/1211/port/devsdp.c (diff list | history)
| 1999/1116/sys/src/9/port/devsdp.c:41,48 – 1999/1211/sys/src/9/port/devsdp.c:41,48 (short | long | prev | next) | ||
| 1999/0824 | ||
| 1999/0907 | Maxconv= 256, // power of 2 Nfs= 4, // number of file systems | |
| 1999/1001 |
| |
| 1999/0909 |
| |
| 1999/1211 | MaxRetries= 4, KeepAlive = 10, // keep alive in seconds | |
| 1999/1015 | SecretLength= 32, // a secret per direction | |
| 1999/1001 | SeqMax = (1<<24), SeqWindow = 32, | |
| 1999/1116/sys/src/9/port/devsdp.c:104,109 – 1999/1211/sys/src/9/port/devsdp.c:104,110 | ||
| 1999/0901 | ||
| 1999/0907 | // conv states | |
| 1999/0902 | enum { | |
| 1999/1211 | CFree, | |
| 1999/0906 | CInit, | |
| 1999/0909 | CDial, CAccept, | |
| 1999/1116/sys/src/9/port/devsdp.c:115,126 – 1999/1211/sys/src/9/port/devsdp.c:116,130 | ||
| 1999/0902 | ||
| 1999/0901 | struct Conv { QLock; | |
| 1999/0824 |
| |
| 1999/0906 |
| |
| 1999/0824 | Sdp *sdp; | |
| 1999/1211 | int id; | |
| 1999/0901 | ||
| 1999/1211 | int ref; // holds conv up | |
| 1999/0902 | int state; | |
| 1999/0906 |
| |
| 1999/1211 | int dataopen; // ref count of opens on Qdata int controlopen; // ref count of opens on Qcontrol | |
| 1999/0910 | int reader; // reader proc has been started | |
| 1999/0901 | ||
| 1999/0929 | Stats lstats; | |
| 1999/1116/sys/src/9/port/devsdp.c:137,143 – 1999/1211/sys/src/9/port/devsdp.c:141,147 | ||
| 1999/0910 | QLock readlk; // protects readproc | |
| 1999/0907 | Proc *readproc; | |
| 1999/0910 | ||
| 1999/0902 |
| |
| 1999/1211 | Chan *chan; // packet channel | |
| 1999/0910 | char *channame; | |
| 1999/0902 | ||
| 1999/0907 | char owner[NAMELEN]; /* protections */ | |
| 1999/1116/sys/src/9/port/devsdp.c:268,302 – 1999/1211/sys/src/9/port/devsdp.c:272,308 | ||
| 1999/0824 | static Dirtab *dirtab[MaxQ]; static Sdp sdptab[Nfs]; | |
| 1999/0908 | static char *convstatename[] = { | |
| 1999/0909 |
| |
| 1999/0908 |
| |
| 1999/1211 | [CFree] "Free", [CInit] "Init", [CDial] "Dial", [CAccept] "Accept", [COpen] "Open", | |
| 1999/0910 | [CLocalClose] "LocalClose", [CRemoteClose] "RemoteClose", | |
| 1999/0908 |
| |
| 1999/1211 | [CClosed] "Closed", | |
| 1999/0908 | }; | |
| 1999/0824 | static int sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp); | |
| 1999/0901 | static Conv *sdpclone(Sdp *sdp); | |
| 1999/0906 |
| |
| 1999/0907 | static void onewaycleanup(OneWay *ow); static int readready(void *a); static int controlread(); | |
| 1999/1211 | static void convsetstate(Conv *c, int state); static Block *readcontrol(Conv *c, int n); static void writecontrol(Conv *c, void *p, int n, int wait); static Block *readdata(Conv *c, int n); static long writedata(Conv *c, Block *b); static void convderef(Conv *c); | |
| 1999/0907 | static Block *conviput(Conv *c, Block *b, int control); | |
| 1999/1015 | static void conviconnect(Conv *c, int op, Block *b); static void convicontrol(Conv *c, int op, Block *b); | |
| 1999/1016 | static Block *convicomp(Conv *c, int op, ulong, Block *b); | |
| 1999/0929 |
| |
| 1999/0907 |
| |
| 1999/0915 |
| |
| 1999/1015 | static void convoput(Conv *c, int type, int subtype, Block *b); static void convoconnect(Conv *c, int op, ulong dialid, ulong acceptid); | |
| 1999/0910 |
| |
| 1999/0914 | static void convopenchan(Conv *c, char *path); | |
| 1999/0929 | static void convstats(Conv *c, int local, char *buf, int n); | |
| 1999/1211 | static void convreader(void *a); | |
| 1999/0824 | ||
| 1999/1022 | static void setalg(Conv *c, char *name, Algorithm *tab, Algorithm **); | |
| 1999/1015 | static void setsecret(OneWay *cc, char *secret); | |
| 1999/1116/sys/src/9/port/devsdp.c:412,417 – 1999/1211/sys/src/9/port/devsdp.c:418,424 | ||
| 1999/0824 | devstat(c, db, nil, 0, sdpgen); } | |
| 1999/1211 | ||
| 1999/0824 | static Chan* | |
| 1999/0901 | sdpopen(Chan* ch, int omode) | |
| 1999/0824 | { | |
| 1999/1116/sys/src/9/port/devsdp.c:450,455 – 1999/1211/sys/src/9/port/devsdp.c:457,463 | ||
| 1999/0929 | case Qstats: case Qrstats: | |
| 1999/0902 | c = sdp->conv[CONV(ch->qid)]; | |
| 1999/1211 | print("open %d:%d: ref=%d\n", c->id, TYPE(ch->qid), c->ref); | |
| 1999/0902 | qlock(c); if(waserror()) { qunlock(c); | |
| 1999/1116/sys/src/9/port/devsdp.c:458,469 – 1999/1211/sys/src/9/port/devsdp.c:466,481 | ||
| 1999/0902 | if((perm & (c->perm>>6)) != perm) | |
| 1999/0907 | if(strcmp(up->user, c->owner) != 0 || (perm & c->perm) != perm) | |
| 1999/0902 | error(Eperm); | |
| 1999/1211 | ||
| 1999/0902 | c->ref++; | |
| 1999/0910 | if(TYPE(ch->qid) == Qdata) { | |
| 1999/1211 | c->dataopen++; // kill reader if Qdata is opened for the first time if(c->dataopen == 1) | |
| 1999/0910 | if(c->readproc != nil) postnote(c->readproc, 1, "interrupt", 0); | |
| 1999/0907 |
| |
| 1999/1211 | } else if(TYPE(ch->qid) == Qcontrol) { c->controlopen++; | |
| 1999/0910 | } | |
| 1999/0902 | qunlock(c); poperror(); | |
| 1999/1116/sys/src/9/port/devsdp.c:481,512 – 1999/1211/sys/src/9/port/devsdp.c:493,537 | ||
| 1999/0902 | Sdp *sdp = sdptab + ch->dev; | |
| 1999/0907 | Conv *c; | |
| 1999/0824 | ||
| 1999/1211 | if(!(ch->flag & COPEN)) return; | |
| 1999/0902 | switch(TYPE(ch->qid)) { | |
| 1999/0824 | case Qlog: | |
| 1999/0902 |
| |
| 1999/0824 |
| |
| 1999/1211 | logclose(sdp); | |
| 1999/0824 | break; | |
| 1999/0907 |
| |
| 1999/1211 | case Qstats: case Qrstats: | |
| 1999/0907 | c = sdp->conv[CONV(ch->qid)]; qlock(c); | |
| 1999/1211 | convderef(c); qunlock(c); break; case Qdata: c = sdp->conv[CONV(ch->qid)]; qlock(c); c->dataopen--; convderef(c); if(c->dataopen == 0) if(c->reader == 0) if(c->chan != nil) if(!waserror()) { kproc("convreader", convreader, c); c->reader = 1; c->ref++; poperror(); | |
| 1999/0907 | } | |
| 1999/0915 |
| |
| 1999/0907 |
| |
| 1999/1211 | qunlock(c); break; case Qcontrol: c = sdp->conv[CONV(ch->qid)]; qlock(c); c->controlopen--; convderef(c); if(c->controlopen == 0 && c->ref != 0) { | |
| 1999/0907 | switch(c->state) { default: convsetstate(c, CClosed); | |
| 1999/1116/sys/src/9/port/devsdp.c:515,522 – 1999/1211/sys/src/9/port/devsdp.c:540,545 | ||
| 1999/0907 | case COpen: | |
| 1999/0910 | convsetstate(c, CLocalClose); | |
| 1999/0907 | break; | |
| 1999/0910 |
| |
| 1999/0907 | } } qunlock(c); | |
| 1999/1116/sys/src/9/port/devsdp.c:771,778 – 1999/1211/sys/src/9/port/devsdp.c:794,802 | ||
| 1999/0901 | sdp->nconv++; break; } | |
| 1999/1116 |
| |
| 1999/1211 | if(c->ref == 0 && canqlock(c)){ print("%d: state=%d reader=%d ref=%d\n", c->id, c->state, c->reader, c->ref); if(c->ref == 0) | |
| 1999/0901 | break; qunlock(c); } | |
| 1999/1116/sys/src/9/port/devsdp.c:783,789 – 1999/1211/sys/src/9/port/devsdp.c:807,815 | ||
| 1999/0902 | if(pp >= ep) | |
| 1999/0901 | return nil; | |
| 1999/0902 |
| |
| 1999/1211 | assert(c->state == CFree); // set ref to 2 - 1 ref for open - 1 ref for channel state c->ref = 2; | |
| 1999/0906 | c->state = CInit; | |
| 1999/1001 | c->in.window = ~0; | |
| 1999/0907 | strncpy(c->owner, up->user, sizeof(c->owner)); | |
| 1999/1116/sys/src/9/port/devsdp.c:819,824 – 1999/1211/sys/src/9/port/devsdp.c:845,851 | ||
| 1999/0906 | return 1; } | |
| 1999/1211 | // assumes c is locked | |
| 1999/0902 | static void | |
| 1999/0906 | convtimer(Conv *c, ulong sec) | |
| 1999/0902 | { | |
| 1999/1116/sys/src/9/port/devsdp.c:826,837 – 1999/1211/sys/src/9/port/devsdp.c:853,862 | ||
| 1999/0914 | ||
| 1999/1001 | if(c->timeout > sec) | |
| 1999/0906 | return; | |
| 1999/0902 |
| |
| 1999/0906 |
| |
| 1999/0902 |
| |
| 1999/0906 |
| |
| 1999/0902 |
| |
| 1999/1211 | ||
| 1999/0906 | switch(c->state) { | |
| 1999/1211 | case CInit: break; | |
| 1999/0909 | case CDial: | |
| 1999/0914 | if(convretry(c, 1)) | |
| 1999/1015 | convoconnect(c, ConOpenRequest, c->dialid, 0); | |
| 1999/1116/sys/src/9/port/devsdp.c:873,883 – 1999/1211/sys/src/9/port/devsdp.c:898,905 | ||
| 1999/0906 | break; | |
| 1999/0914 | case CRemoteClose: case CClosed: | |
| 1999/1001 |
| |
| 1999/0914 | break; | |
| 1999/0906 | } | |
| 1999/0914 |
| |
| 1999/0906 |
| |
| 1999/0902 | ||
| 1999/1116/sys/src/9/port/devsdp.c:895,904 – 1999/1211/sys/src/9/port/devsdp.c:917,932 | ||
| 1999/0906 | qlock(sdp); for(i=0; i<sdp->nconv; i++) { c = sdp->conv[i]; | |
| 1999/1211 | if(c->ref == 0) continue; qunlock(sdp); qlock(c); if(c->ref > 0 && !waserror()) { | |
| 1999/0906 | convtimer(c, sec); poperror(); } | |
| 1999/1211 | qunlock(c); qlock(sdp); | |
| 1999/0906 | } qunlock(sdp); | |
| 1999/0902 | } | |
| 1999/1116/sys/src/9/port/devsdp.c:949,954 – 1999/1211/sys/src/9/port/devsdp.c:977,983 | ||
| 1999/0909 | break; | |
| 1999/0906 | case COpen: | |
| 1999/0909 | assert(c->state == CDial || c->state == CAccept); | |
| 1999/1211 | c->lastrecv = TK2SEC(m->ticks); | |
| 1999/0909 | if(c->state == CDial) { convretryinit(c); | |
| 1999/1015 | convoconnect(c, ConOpenAckAck, c->dialid, c->acceptid); | |
| 1999/1116/sys/src/9/port/devsdp.c:971,977 – 1999/1211/sys/src/9/port/devsdp.c:1000,1006 | ||
| 1999/0906 | break; | |
| 1999/0910 | case CRemoteClose: | |
| 1999/0914 | wakeup(&c->in.controlready); | |
| 1999/1027 |
| |
| 1999/1211 | wakeup(&c->out.controlready); | |
| 1999/0910 | break; | |
| 1999/0906 | case CClosed: | |
| 1999/0914 | wakeup(&c->in.controlready); | |
| 1999/1116/sys/src/9/port/devsdp.c:978,1014 – 1999/1211/sys/src/9/port/devsdp.c:1007,1058 | ||
| 1999/0915 | wakeup(&c->out.controlready); | |
| 1999/0907 | if(c->readproc) postnote(c->readproc, 1, "interrupt", 0); | |
| 1999/0915 |
| |
| 1999/0907 |
| |
| 1999/0915 |
| |
| 1999/0910 |
| |
| 1999/1022 |
| |
| 1999/1001 |
| |
| 1999/0907 |
| |
| 1999/1001 |
| |
| 1999/0907 |
| |
| 1999/1001 |
| |
| 1999/1211 | if(c->state != CClosed) convderef(c); | |
| 1999/0906 | break; } c->state = state; } | |
| 1999/1211 | //assumes c is locked | |
| 1999/0906 | static void | |
| 1999/1211 | convderef(Conv *c) { c->ref--; print("convderef: %d: ref == %d\n", c->id, c->ref); if(c->ref > 0) return; assert(c->ref == 0); assert(c->dataopen == 0); assert(c->controlopen == 0); //print("convderef: %d: ref == 0!\n", c->id); c->state = CFree; if(c->chan) { cclose(c->chan); c->chan = nil; } if(c->channame) { free(c->channame); c->channame = nil; } c->cipher = nil; c->auth = nil; c->comp = nil; strcpy(c->owner, "network"); c->perm = 0660; c->dialid = 0; c->acceptid = 0; c->timeout = 0; c->retries = 0; c->drop = 0; onewaycleanup(&c->in); onewaycleanup(&c->out); memset(&c->lstats, 0, sizeof(Stats)); memset(&c->rstats, 0, sizeof(Stats)); } static void | |
| 1999/0907 | onewaycleanup(OneWay *ow) | |
| 1999/0906 | { | |
| 1999/0907 | if(ow->controlpkt) | |
| 1999/1116/sys/src/9/port/devsdp.c:1040,1046 – 1999/1211/sys/src/9/port/devsdp.c:1084,1095 | ||
| 1999/0914 | nexterror(); } kproc("convreader", convreader, c); | |
| 1999/1211 | assert(c->reader == 0 && c->ref > 0); // after kproc in case it fails | |
| 1999/0914 | c->reader = 1; | |
| 1999/1211 | c->ref++; | |
| 1999/0914 | poperror(); } | |
| 1999/0907 | ||
| 1999/1116/sys/src/9/port/devsdp.c:1215,1221 – 1999/1211/sys/src/9/port/devsdp.c:1264,1270 | ||
| 1999/1001 | if(seqdiff > 0) { while(seqdiff > 0 && c->in.window != 0) { if((c->in.window & (1<<(SeqWindow-1))) == 0) { | |
| 1999/1211 | //print("missing packet: %ld\n", seq - seqdiff); | |
| 1999/1001 | c->lstats.inMissing++; } c->in.window <<= 1; | |
| 1999/1116/sys/src/9/port/devsdp.c:1222,1228 – 1999/1211/sys/src/9/port/devsdp.c:1271,1277 | ||
| 1999/1001 | seqdiff--; } if(seqdiff > 0) { | |
| 1999/1211 | //print("missing packets: %ld-%ld\n", seq - SeqWindow - seqdiff+1, seq-SeqWindow); | |
| 1999/1001 | c->lstats.inMissing += seqdiff; } c->in.seq = seq; | |
| 1999/1116/sys/src/9/port/devsdp.c:1520,1529 – 1999/1211/sys/src/9/port/devsdp.c:1569,1575 | ||
| 1999/0930 | Block *b; | |
| 1999/0907 | ||
| 1999/0929 | c->lstats.outPackets++; | |
| 1999/0906 |
| |
| 1999/1211 | assert(c->chan != nil); | |
| 1999/1015 | b = allocb(9); b->wp[0] = (TConnect << 4) | op; hnputl(b->wp+1, dialid); | |
| 1999/1116/sys/src/9/port/devsdp.c:1530,1536 – 1999/1211/sys/src/9/port/devsdp.c:1576,1585 | ||
| 1999/1015 | hnputl(b->wp+5, acceptid); b->wp += 9; | |
| 1999/0906 | ||
| 1999/0930 |
| |
| 1999/1211 | if(!waserror()) { convwriteblock(c, b); poperror(); } | |
| 1999/0907 | } | |
| 1999/0910 | static Block * | |
| 1999/1116/sys/src/9/port/devsdp.c:1537,1549 – 1999/1211/sys/src/9/port/devsdp.c:1586,1596 | ||
| 1999/0910 | convreadblock(Conv *c, int n) { Block *b; | |
| 1999/1211 | Chan *ch; | |
| 1999/0910 | qlock(&c->readlk); if(waserror()) { c->readproc = nil; | |
| 1999/1116/sys/src/9/port/devsdp.c:1554,1565 – 1999/1211/sys/src/9/port/devsdp.c:1601,1611 | ||
| 1999/0910 | } c->readproc = up; ch = c->chan; | |
| 1999/1211 | assert(c->ref > 0); | |
| 1999/0910 | qunlock(c); b = devtab[ch->type]->bread(ch, n, 0); c->readproc = nil; | |
| 1999/1116/sys/src/9/port/devsdp.c:1770,1779 – 1999/1211/sys/src/9/port/devsdp.c:1816,1822 | ||
| 1999/0910 | if(b == nil) { | |
| 1999/0915 | print("up->error = %s\n", up->error); if(strcmp(up->error, Eintr) != 0) { | |
| 1999/1211 | convsetstate(c, CClosed); | |
| 1999/0915 | break; } } else if(!waserror()) { | |
| 1999/1116/sys/src/9/port/devsdp.c:1783,1788 – 1999/1211/sys/src/9/port/devsdp.c:1826,1832 | ||
| 1999/0910 | } | |
| 1999/0914 | print("convreader exiting\n"); | |
| 1999/0910 | c->reader = 0; | |
| 1999/1211 | convderef(c); | |
| 1999/0910 | qunlock(c); pexit("hangup", 1); | |
| 1999/0906 | } | |
| 1999/1116/sys/src/9/port/devsdp.c:2025,2031 – 1999/1211/sys/src/9/port/devsdp.c:2069,2075 | ||
| 1999/1022 | cr->ovalid = 0; } } else if(d > 0) { | |
| 1999/1211 | //print("missing packet: %uld %ld\n", seq, d); | |
| 1999/1022 | // this link is hosed if(d > RC4forward) return 0; | |
| 1999/1116/sys/src/9/port/devsdp.c:2039,2045 – 1999/1211/sys/src/9/port/devsdp.c:2083,2089 | ||
| 1999/1022 | rc4(&cr->current, p, n); cr->cseq = seq+n; } else { | |
| 1999/1211 | //print("reordered packet: %uld %ld\n", seq, d); | |
| 1999/1022 | dd = seq - cr->oseq; if(!cr->ovalid || -d > RC4back || dd < 0) return 0; | |