#include #include #include #include #include #include #include #include "aio.h" #include "tester.h" extern const char *__progname; typedef struct pri PRI; struct pri { int lastqueued; int lastsent; ARC4_STATE a4; } ; static unsigned int rseed; static AIO_PQ q; static int nq; static PRI pri[NPRI]; static unsigned char zbuf[MAXPKT] = { 0 }; static unsigned char rstate[256] __attribute__((__aligned__(__alignof__(unsigned long int)))); static void consistency_check(void) { if (nq != aio_pq_qlen(&q)) panic(); } static void send_done(void *buf) { int p; int s; int l; bcopy(buf,&p,sizeof(int)); bcopy(sizeof(int)+(char *)buf,&s,sizeof(int)); bcopy((2*sizeof(int))+(char *)buf,&l,sizeof(int)); printf("write: done pri %d serial %d len %d\n",p,s,l); if ((p < 0) || (p >= NPRI)) panic(); if (s != pri[p].lastsent+1) panic(); pri[p].lastsent ++; free(buf); } static int sender(void *arg __attribute__((__unused__))) { int i; int p; int l; int s; unsigned char *dbp; unsigned char *dbp0; if (aio_pq_qlen(&q) > MAXQ) return(AIO_BLOCK_NIL); do { i = random() % ((NPRI * (NPRI+1)) / 2); p = 0; while (1) { if (p >= NPRI) panic(); i -= NPRI - p; if (i < 0) break; p ++; } l = random() % MAXPKT; s = ++pri[p].lastqueued; printf("write: queued pri %d serial %d len %d\n",p,s,l); dbp0 = malloc((3*sizeof(int))+l); dbp = dbp0; bcopy(&p,dbp,sizeof(int)); dbp += sizeof(int); bcopy(&s,dbp,sizeof(int)); dbp += sizeof(int); bcopy(&l,dbp,sizeof(int)); dbp += sizeof(int); if (l > 0) arc4_crypt(&pri[p].a4,&zbuf[0],l,dbp); aio_pq_queue_cb(&q,p,dbp0,(3*sizeof(int))+l,&send_done,dbp0); aio_pq_boundary(&q,p); nq += (3 * sizeof(int)) + l; consistency_check(); } while (aio_pq_qlen(&q) < MAXQ); return(AIO_BLOCK_LOOP); } static int s_wtest(void *arg __attribute__((__unused__))) { return(aio_pq_nonempty(&q)); } static void s_wr(void *arg __attribute__((__unused__))) { int n; n = aio_pq_writev_drop(&q,scpipe[1],-1); if (n < 0) { switch (errno) { case EINTR: case EWOULDBLOCK: return; break; } fprintf(stderr,"%s: writev: %s\n",__progname,strerror(errno)); exit(1); } printf("write: wrote %d\n",n); nq -= n; consistency_check(); } void sender_main(void) { int i; unsigned long int r; unsigned char k[sizeof(int)+sizeof(unsigned long int)]; close(crpipe[0]); close(crpipe[1]); close(scpipe[0]); set_nbio(scpipe[1]); rseed = time(0); printf("sender: random seed %u\n",rseed); initstate(rseed,&rstate[0],sizeof(rstate)); setstate(&rstate[0]); aio_pq_init(&q,NPRI); for (i=NPRI-1;i>=0;i--) { pri[i].lastqueued = 0; pri[i].lastsent = 0; arc4_init(&pri[i].a4); r = random(); bcopy(&i,&k[0],sizeof(int)); bcopy(&r,&k[sizeof(int)],sizeof(unsigned long int)); arc4_setkey(&pri[i].a4,&k[0],sizeof(k),0); } aio_pq_queue_copy(&q,NPRI-1,"Magic!",6); aio_pq_queue_copy(&q,NPRI-1,&rseed,sizeof(rseed)); aio_pq_boundary(&q,NPRI-1); nq = 6 + sizeof(rseed); aio_poll_init(); aio_add_block(&sender,0); aio_add_poll(scpipe[1],&aio_rwtest_never,&s_wtest,0,&s_wr,0); aio_event_loop(); fprintf(stderr,"%s: poll: %s\n",__progname,strerror(errno)); exit(1); }