/**Copyright(c)1995DannyGasparovski.**PleasereadthefileCOPYRIGHTforthe*termsandconditionsofthecopyright.*/#include<slirp.h>intif_queued=0;/* Number of packets queued so far */structmbufif_fastq;/* fast queue (for interactive data) */structmbufif_batchq;/* queue for non-interactive data */structmbuf*next_m;/* Pointer to next mbuf to output */#defineifs_init(ifm)((ifm)->ifs_next=(ifm)->ifs_prev=(ifm))voidifs_insque(ifm,ifmhead)structmbuf*ifm,*ifmhead;{ifm->ifs_next=ifmhead->ifs_next;ifmhead->ifs_next=ifm;ifm->ifs_prev=ifmhead;ifm->ifs_next->ifs_prev=ifm;}voidifs_remque(ifm)structmbuf*ifm;{ifm->ifs_prev->ifs_next=ifm->ifs_next;ifm->ifs_next->ifs_prev=ifm->ifs_prev;}voidif_init(){if_fastq.ifq_next=if_fastq.ifq_prev=&if_fastq;if_batchq.ifq_next=if_batchq.ifq_prev=&if_batchq;//sl_compress_init(&comp_s);next_m=&if_batchq;}#if0/**Thisshouldn'tbeneededsincethemodemisblockingand*wedon'texpectanysignals,butwhatthehell..*/inlineintwriten(fd,bptr,n)intfd;char*bptr;intn;{intret;inttotal;
*Thiscanincludeaninteractivesession,whichshouldgoonfastq,*butgetstoogreedy...henceit'llbedowngradedfromfastqtobatchq.*Wemustn'tputthispacketbackonthefastq(orwe'llsenditoutoforder)*XXXaddcachehere?*/for(ifq=if_batchq.ifq_prev;ifq!=&if_batchq;ifq=ifq->ifq_prev){if(so==ifq->ifq_so){/* A match! */ifm->ifq_so=so;ifs_insque(ifm,ifq->ifs_prev);gotodiddit;}}
/* No match, check which queue to put it on */if(so&&(so->so_iptos&IPTOS_LOWDELAY)){ifq=if_fastq.ifq_prev;on_fastq=1;/**Checkifthispacketisapartofthelast*packet'ssession*/if(ifq->ifq_so==so){ifm->ifq_so=so;ifs_insque(ifm,ifq->ifs_prev);gotodiddit;}}elseifq=if_batchq.ifq_prev;
/* ...And insert in the new. That'll teach ya! */insque(ifm->ifs_next,&if_batchq);}}#ifndefFULL_BOLT/**Thispreventsusfrommalloc()ingtoomanymbufs*/if(link_up){/* if_start will check towrite */if_start();}#endif}/**Sendapacket*Wechooseapacketbasedonit'spositionintheoutputqueues;*Iftherearepacketsonthefastq,theyaresentFIFO,before*everythingelse.Otherwisewechoosethefirstpacketfromthe*batchqandsendit.thenextpacketchosenwillbefromthesession*afterthisone,thenthesessionafterthatone,andsoon..So,*forexample,ifthereare3ftpsession'sfightingforbandwidth,*onepacketwillbesentfromthefirstsession,thenonepacket*fromthesecondsession,thenonepacketfromthethird,thenback*tothefirst,etc.etc.*/voidif_start(void){structmbuf*ifm,*ifqt;
again:/* check if we can really output */if(!slirp_can_output())return;/**Seewhichqueuetogetnextpacketfrom*Ifthere'ssomethinginthefastq,selectitimmediately*/if(if_fastq.ifq_next!=&if_fastq){ifm=if_fastq.ifq_next;}else{/* Nothing on fastq, see if next_m is valid */if(next_m!=&if_batchq)ifm=next_m;elseifm=if_batchq.ifq_next;
/* If there are more packets for this session, re-queue them */if(ifm->ifs_next!=/* ifm->ifs_prev != */ifm){insque(ifm->ifs_next,ifqt);ifs_remque(ifm);}