/**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))
*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);}