180ee5cbfSDavid du Colombier #include "u.h" 280ee5cbfSDavid du Colombier #include "../port/lib.h" 380ee5cbfSDavid du Colombier #include "mem.h" 480ee5cbfSDavid du Colombier #include "dat.h" 580ee5cbfSDavid du Colombier #include "fns.h" 680ee5cbfSDavid du Colombier #include "../port/error.h" 780ee5cbfSDavid du Colombier 880ee5cbfSDavid du Colombier #include "ip.h" 980ee5cbfSDavid du Colombier 1080ee5cbfSDavid du Colombier enum 1180ee5cbfSDavid du Colombier { 1280ee5cbfSDavid du Colombier Maxtu= 16*1024, 1380ee5cbfSDavid du Colombier }; 1480ee5cbfSDavid du Colombier 1580ee5cbfSDavid du Colombier typedef struct LB LB; 1680ee5cbfSDavid du Colombier struct LB 1780ee5cbfSDavid du Colombier { 1880ee5cbfSDavid du Colombier Proc *readp; 1980ee5cbfSDavid du Colombier Queue *q; 2080ee5cbfSDavid du Colombier Fs *f; 2180ee5cbfSDavid du Colombier }; 2280ee5cbfSDavid du Colombier 2380ee5cbfSDavid du Colombier static void loopbackread(void *a); 2480ee5cbfSDavid du Colombier 2580ee5cbfSDavid du Colombier static void 2680ee5cbfSDavid du Colombier loopbackbind(Ipifc *ifc, int, char**) 2780ee5cbfSDavid du Colombier { 2880ee5cbfSDavid du Colombier LB *lb; 2980ee5cbfSDavid du Colombier 3080ee5cbfSDavid du Colombier lb = smalloc(sizeof(*lb)); 3180ee5cbfSDavid du Colombier lb->f = ifc->conv->p->f; 32*3ff48bf5SDavid du Colombier lb->q = qopen(128*1024, Qmsg, nil, nil); 3380ee5cbfSDavid du Colombier ifc->arg = lb; 3480ee5cbfSDavid du Colombier 3580ee5cbfSDavid du Colombier kproc("loopbackread", loopbackread, ifc); 3680ee5cbfSDavid du Colombier 3780ee5cbfSDavid du Colombier } 3880ee5cbfSDavid du Colombier 3980ee5cbfSDavid du Colombier static void 4080ee5cbfSDavid du Colombier loopbackunbind(Ipifc *ifc) 4180ee5cbfSDavid du Colombier { 4280ee5cbfSDavid du Colombier LB *lb = ifc->arg; 4380ee5cbfSDavid du Colombier 4480ee5cbfSDavid du Colombier if(lb->readp) 4580ee5cbfSDavid du Colombier postnote(lb->readp, 1, "unbind", 0); 4680ee5cbfSDavid du Colombier 4780ee5cbfSDavid du Colombier /* wait for reader to die */ 4880ee5cbfSDavid du Colombier while(lb->readp != 0) 4980ee5cbfSDavid du Colombier tsleep(&up->sleep, return0, 0, 300); 5080ee5cbfSDavid du Colombier 5180ee5cbfSDavid du Colombier /* clean up */ 5280ee5cbfSDavid du Colombier qfree(lb->q); 5380ee5cbfSDavid du Colombier free(lb); 5480ee5cbfSDavid du Colombier } 5580ee5cbfSDavid du Colombier 5680ee5cbfSDavid du Colombier static void 5780ee5cbfSDavid du Colombier loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*) 5880ee5cbfSDavid du Colombier { 5980ee5cbfSDavid du Colombier LB *lb; 6080ee5cbfSDavid du Colombier 6180ee5cbfSDavid du Colombier lb = ifc->arg; 6280ee5cbfSDavid du Colombier if(qpass(lb->q, bp) < 0) 6380ee5cbfSDavid du Colombier ifc->outerr++; 6480ee5cbfSDavid du Colombier ifc->out++; 6580ee5cbfSDavid du Colombier } 6680ee5cbfSDavid du Colombier 6780ee5cbfSDavid du Colombier static void 6880ee5cbfSDavid du Colombier loopbackread(void *a) 6980ee5cbfSDavid du Colombier { 7080ee5cbfSDavid du Colombier Ipifc *ifc; 7180ee5cbfSDavid du Colombier Block *bp; 7280ee5cbfSDavid du Colombier LB *lb; 7380ee5cbfSDavid du Colombier 7480ee5cbfSDavid du Colombier ifc = a; 7580ee5cbfSDavid du Colombier lb = ifc->arg; 7680ee5cbfSDavid du Colombier lb->readp = up; /* hide identity under a rock for unbind */ 7780ee5cbfSDavid du Colombier if(waserror()){ 7880ee5cbfSDavid du Colombier lb->readp = 0; 7980ee5cbfSDavid du Colombier pexit("hangup", 1); 8080ee5cbfSDavid du Colombier } 8180ee5cbfSDavid du Colombier for(;;){ 8280ee5cbfSDavid du Colombier bp = qbread(lb->q, Maxtu); 8380ee5cbfSDavid du Colombier if(bp == nil) 8480ee5cbfSDavid du Colombier continue; 8580ee5cbfSDavid du Colombier ifc->in++; 8680ee5cbfSDavid du Colombier if(!canrlock(ifc)){ 8780ee5cbfSDavid du Colombier freeb(bp); 8880ee5cbfSDavid du Colombier continue; 8980ee5cbfSDavid du Colombier } 9080ee5cbfSDavid du Colombier if(waserror()){ 9180ee5cbfSDavid du Colombier runlock(ifc); 9280ee5cbfSDavid du Colombier nexterror(); 9380ee5cbfSDavid du Colombier } 9480ee5cbfSDavid du Colombier if(ifc->lifc == nil) 9580ee5cbfSDavid du Colombier freeb(bp); 9680ee5cbfSDavid du Colombier else 97*3ff48bf5SDavid du Colombier ipiput4(lb->f, ifc, bp); 9880ee5cbfSDavid du Colombier runlock(ifc); 9980ee5cbfSDavid du Colombier poperror(); 10080ee5cbfSDavid du Colombier } 10180ee5cbfSDavid du Colombier } 10280ee5cbfSDavid du Colombier 10380ee5cbfSDavid du Colombier Medium loopbackmedium = 10480ee5cbfSDavid du Colombier { 10580ee5cbfSDavid du Colombier .hsize= 0, 10680ee5cbfSDavid du Colombier .minmtu= 0, 10780ee5cbfSDavid du Colombier .maxmtu= Maxtu, 10880ee5cbfSDavid du Colombier .maclen= 0, 10980ee5cbfSDavid du Colombier .name= "loopback", 11080ee5cbfSDavid du Colombier .bind= loopbackbind, 11180ee5cbfSDavid du Colombier .unbind= loopbackunbind, 11280ee5cbfSDavid du Colombier .bwrite= loopbackbwrite, 11380ee5cbfSDavid du Colombier }; 11480ee5cbfSDavid du Colombier 11580ee5cbfSDavid du Colombier void 11680ee5cbfSDavid du Colombier loopbackmediumlink(void) 11780ee5cbfSDavid du Colombier { 11880ee5cbfSDavid du Colombier addipmedium(&loopbackmedium); 11980ee5cbfSDavid du Colombier } 120