18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1995 Danny Gasparovski. 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Please read the file COPYRIGHT for the 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * terms and conditions of the copyright. 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <slirp.h> 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint if_queued = 0; /* Number of packets queued so far */ 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct mbuf if_fastq; /* fast queue (for interactive data) */ 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct mbuf if_batchq; /* queue for non-interactive data */ 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct mbuf *next_m; /* Pointer to next mbuf to output */ 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void 195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerifs_insque(struct mbuf *ifm, struct mbuf *ifmhead) 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifs_next = ifmhead->ifs_next; 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifmhead->ifs_next = ifm; 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifs_prev = ifmhead; 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifs_next->ifs_prev = ifm; 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerifs_remque(struct mbuf *ifm) 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifs_prev->ifs_next = ifm->ifs_next; 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifs_next->ifs_prev = ifm->ifs_prev; 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerif_init(void) 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq; 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq; 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project // sl_compress_init(&comp_s); 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next_m = &if_batchq; 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This shouldn't be needed since the modem is blocking and 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * we don't expect any signals, but what the hell.. 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectinline int 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectwriten(fd, bptr, n) 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int fd; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project char *bptr; 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int n; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int total; 565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* This should succeed most of the time */ 585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = send(fd, bptr, n,0); 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret == n || ret <= 0) 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Didn't write everything, go into the loop */ 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total = ret; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (n > total) { 655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = send(fd, bptr+total, n-total,0); 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret <= 0) 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project total += ret; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return total; 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if_input - read() the tty, do "top level" processing (ie: check for any escapes), 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * and pass onto (*ttyp->if_input) 765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXXXX Any zeros arriving by themselves are NOT placed into the arriving packet. 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define INBUFF_SIZE 2048 /* XXX */ 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectif_input(ttyp) 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct ttys *ttyp; 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project u_char if_inbuff[INBUFF_SIZE]; 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int if_n; 865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("if_input"); 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("ttyp = %lx", (long)ttyp); 895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if_n = recv(ttyp->fd, (char *)if_inbuff, INBUFF_SIZE,0); 915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_MISC((dfd, " read %d bytes\n", if_n)); 935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (if_n <= 0) { 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (if_n == 0 || (errno != EINTR && errno != EAGAIN)) { 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ttyp->up) 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project link_up--; 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tty_detached(ttyp, 0); 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (if_n == 1) { 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*if_inbuff == '0') { 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ttyp->ones = 0; 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (++ttyp->zeros >= 5) 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project slirp_exit(0); 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (*if_inbuff == '1') { 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ttyp->zeros = 0; 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (++ttyp->ones >= 5) 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tty_detached(ttyp, 0); 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ttyp->ones = ttyp->zeros = 0; 1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (*ttyp->if_input)(ttyp, if_inbuff, if_n); 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * if_output: Queue packet into an output queue. 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * There are 2 output queue's, if_fastq and if_batchq. 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Each output queue is a doubly linked list of double linked lists 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of mbufs, each list belonging to one "session" (socket). This 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * way, we can output packets fairly by sending one packet from each 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * session, instead of all the packets from one session, then all packets 1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * from the next session, etc. Packets on the if_fastq get absolute 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * priority, but if one session hogs the link, it gets "downgraded" 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to the batchq until it runs out of packets, then it'll return 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to the fastq (eg. if the user does an ls -alR in a telnet session, 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * it'll temporarily get downgraded to the batchq) 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerif_output(struct socket *so, struct mbuf *ifm) 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct mbuf *ifq; 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int on_fastq = 1; 1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("if_output"); 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("so = %lx", (long)so); 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_ARG("ifm = %lx", (long)ifm); 1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * First remove the mbuf from m_usedlist, 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * since we're gonna use m_next and m_prev ourselves 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX Shouldn't need this, gotta change dtom() etc. 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ifm->m_flags & M_USEDLIST) { 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remque(ifm); 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->m_flags &= ~M_USEDLIST; 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * See if there's already a batchq list for this session. 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This can include an interactive session, which should go on fastq, 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but gets too greedy... hence it'll be downgraded from fastq to batchq. 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We mustn't put this packet back on the fastq (or we'll send it out of order) 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * XXX add cache here? 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) { 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so == ifq->ifq_so) { 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* A match! */ 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifq_so = so; 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifs_insque(ifm, ifq->ifs_prev); 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto diddit; 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* No match, check which queue to put it on */ 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so && (so->so_iptos & IPTOS_LOWDELAY)) { 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifq = if_fastq.ifq_prev; 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project on_fastq = 1; 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check if this packet is a part of the last 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * packet's session 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ifq->ifq_so == so) { 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifq_so = so; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifs_insque(ifm, ifq->ifs_prev); 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto diddit; 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifq = if_batchq.ifq_prev; 1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Create a new doubly linked list for this session */ 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifq_so = so; 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifs_init(ifm); 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insque(ifm, ifq); 1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdiddit: 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ++if_queued; 1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (so) { 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Update *_queued */ 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_queued++; 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project so->so_nqueued++; 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Check if the interactive session should be downgraded to 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the batchq. A session is downgraded if it has queued 6 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * packets without pausing, and at least 3 of those packets 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * have been sent over the link 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (XXX These are arbitrary numbers, probably not optimal..) 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (on_fastq && ((so->so_nqueued >= 6) && 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (so->so_nqueued - so->so_queued) >= 3)) { 2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Remove from current queue... */ 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remque(ifm->ifs_next); 2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* ...And insert in the new. That'll teach ya! */ 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insque(ifm->ifs_next, &if_batchq); 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef FULL_BOLT 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This prevents us from malloc()ing too many mbufs 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (link_up) { 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* if_start will check towrite */ 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if_start(); 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Send a packet 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * We choose a packet based on it's position in the output queues; 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If there are packets on the fastq, they are sent FIFO, before 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * everything else. Otherwise we choose the first packet from the 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * batchq and send it. the next packet chosen will be from the session 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * after this one, then the session after that one, and so on.. So, 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for example, if there are 3 ftp session's fighting for bandwidth, 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * one packet will be sent from the first session, then one packet 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * from the second session, then one packet from the third, then back 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to the first, etc. etc. 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectif_start(void) 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct mbuf *ifm, *ifqt; 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DEBUG_CALL("if_start"); 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (if_queued == 0) 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; /* Nothing to do */ 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project again: 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* check if we can really output */ 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!slirp_can_output()) 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * See which queue to get next packet from 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * If there's something in the fastq, select it immediately 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (if_fastq.ifq_next != &if_fastq) { 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm = if_fastq.ifq_next; 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Nothing on fastq, see if next_m is valid */ 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (next_m != &if_batchq) 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm = next_m; 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm = if_batchq.ifq_next; 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Set which packet to send on next iteration */ 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next_m = ifm->ifq_next; 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Remove it from the queue */ 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifqt = ifm->ifq_prev; 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project remque(ifm); 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project --if_queued; 2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* If there are more packets for this session, re-queue them */ 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm) { 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project insque(ifm->ifs_next, ifqt); 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifs_remque(ifm); 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Update so_queued */ 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ifm->ifq_so) { 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (--ifm->ifq_so->so_queued == 0) 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* If there's no more queued, reset nqueued */ 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ifm->ifq_so->so_nqueued = 0; 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Encapsulate the packet for sending */ 2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if_encap((uint8_t *)ifm->m_data, ifm->m_len); 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner m_free(ifm); 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (if_queued) 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto again; 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 297