// Routine to respond to the arrival of block of // packets over some particular link j. // Assume concatenated headers aligned on 64KB. // PL in each header is aligned on 2 bytes. // This code is big-endian. #include #include #include #include void ex(int e) {exit(printf("Local hardware fault %d\n", e));} void sec(int e) {exit(printf("Bogus packet %d\n", e));} void code(int e) {exit(printf("write more code %d\n", e));} void lock(pthread_mutex_t * l) { if(pthread_mutex_lock(l)) exit(printf("Bad lockL\n"));} void unlock(pthread_mutex_t * l) { if(pthread_mutex_unlock(l)) exit(printf("Bad lockU\n"));} typedef unsigned long int li; typedef unsigned short int si; typedef unsigned int ui; li const msk = (1L<<16)-1; typedef struct {char type, oc, cur, pad; ui money; char turns[0];} ph; extern pthread_mutex_t exc; typedef struct {void *cur, *lim;} hb; extern hb zh[16]; // under exc extern short Open; // under exc extern int booty; // under exc void np(int j, ph * header, ui sz){ int hs = *(si *)((li)header-2); ph * p = (ph*)((li)header-hs); if((li)header&msk) { // Do all the earlier packets in this block first. if (((li)p&msk) > ((li)header&msk)) ex(1); np(j, (void *)p, hs);} if(!p->type) { // A datagram int phl = 2*(4+((p->oc+1)>>1)); if(10+phl >= sz) sec(1); int out = ({int c = p->cur; if(p->octurns[c>>1]>>((c&1)<<2));}); ++p->cur; lock(&exc); if((Open>>out)&1) { {int y = p->money-3; if(y<0) code(3); p->money = y; booty+=3;} void * q = zh[out].cur+sz; if(q>zh[out].lim) code(4); zh[out].cur = (void *)p; unlock(&exc); memcpy(q, (void*)p+sizeof(ph), phl); memcpy(q+sizeof(ph), p, 10);} else code(1);} else if(p->type == 1) { // a packet for a circuit. code(2);} }