Annotation of qemu/slirp/socket.c, revision 1.1.1.6

1.1       root        1: /*
                      2:  * Copyright (c) 1995 Danny Gasparovski.
1.1.1.3   root        3:  *
                      4:  * Please read the file COPYRIGHT for the
1.1       root        5:  * terms and conditions of the copyright.
                      6:  */
                      7: 
1.1.1.4   root        8: #include "qemu-common.h"
1.1       root        9: #include <slirp.h>
                     10: #include "ip_icmp.h"
1.1.1.2   root       11: #ifdef __sun__
                     12: #include <sys/filio.h>
                     13: #endif
1.1       root       14: 
1.1.1.3   root       15: static void sofcantrcvmore(struct socket *so);
                     16: static void sofcantsendmore(struct socket *so);
                     17: 
1.1       root       18: struct socket *
1.1.1.5   root       19: solookup(struct socket *head, struct in_addr laddr, u_int lport,
                     20:          struct in_addr faddr, u_int fport)
1.1       root       21: {
                     22:        struct socket *so;
1.1.1.3   root       23: 
1.1       root       24:        for (so = head->so_next; so != head; so = so->so_next) {
1.1.1.3   root       25:                if (so->so_lport == lport &&
1.1       root       26:                    so->so_laddr.s_addr == laddr.s_addr &&
                     27:                    so->so_faddr.s_addr == faddr.s_addr &&
                     28:                    so->so_fport == fport)
                     29:                   break;
                     30:        }
1.1.1.3   root       31: 
1.1       root       32:        if (so == head)
                     33:           return (struct socket *)NULL;
                     34:        return so;
1.1.1.3   root       35: 
1.1       root       36: }
                     37: 
                     38: /*
                     39:  * Create a new socket, initialise the fields
                     40:  * It is the responsibility of the caller to
                     41:  * insque() it into the correct linked-list
                     42:  */
                     43: struct socket *
1.1.1.5   root       44: socreate(Slirp *slirp)
1.1       root       45: {
                     46:   struct socket *so;
1.1.1.3   root       47: 
1.1       root       48:   so = (struct socket *)malloc(sizeof(struct socket));
                     49:   if(so) {
                     50:     memset(so, 0, sizeof(struct socket));
                     51:     so->so_state = SS_NOFDREF;
                     52:     so->s = -1;
1.1.1.5   root       53:     so->slirp = slirp;
1.1       root       54:   }
                     55:   return(so);
                     56: }
                     57: 
                     58: /*
                     59:  * remque and free a socket, clobber cache
                     60:  */
                     61: void
1.1.1.5   root       62: sofree(struct socket *so)
1.1       root       63: {
1.1.1.5   root       64:   Slirp *slirp = so->slirp;
                     65: 
1.1       root       66:   if (so->so_emu==EMU_RSH && so->extra) {
                     67:        sofree(so->extra);
                     68:        so->extra=NULL;
                     69:   }
1.1.1.5   root       70:   if (so == slirp->tcp_last_so) {
                     71:       slirp->tcp_last_so = &slirp->tcb;
                     72:   } else if (so == slirp->udp_last_so) {
                     73:       slirp->udp_last_so = &slirp->udb;
                     74:   }
1.1       root       75:   m_free(so->so_m);
1.1.1.3   root       76: 
                     77:   if(so->so_next && so->so_prev)
1.1       root       78:     remque(so);  /* crashes if so is not in a queue */
                     79: 
                     80:   free(so);
                     81: }
                     82: 
1.1.1.4   root       83: size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
1.1       root       84: {
1.1.1.4   root       85:        int n, lss, total;
1.1       root       86:        struct sbuf *sb = &so->so_snd;
                     87:        int len = sb->sb_datalen - sb->sb_cc;
                     88:        int mss = so->so_tcpcb->t_maxseg;
1.1.1.3   root       89: 
1.1.1.4   root       90:        DEBUG_CALL("sopreprbuf");
1.1       root       91:        DEBUG_ARG("so = %lx", (long )so);
1.1.1.3   root       92: 
1.1       root       93:        len = sb->sb_datalen - sb->sb_cc;
1.1.1.3   root       94: 
1.1.1.4   root       95:        if (len <= 0)
                     96:                return 0;
                     97: 
1.1       root       98:        iov[0].iov_base = sb->sb_wptr;
1.1.1.4   root       99:         iov[1].iov_base = NULL;
                    100:         iov[1].iov_len = 0;
1.1       root      101:        if (sb->sb_wptr < sb->sb_rptr) {
                    102:                iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
                    103:                /* Should never succeed, but... */
                    104:                if (iov[0].iov_len > len)
                    105:                   iov[0].iov_len = len;
                    106:                if (iov[0].iov_len > mss)
                    107:                   iov[0].iov_len -= iov[0].iov_len%mss;
                    108:                n = 1;
                    109:        } else {
                    110:                iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
                    111:                /* Should never succeed, but... */
                    112:                if (iov[0].iov_len > len) iov[0].iov_len = len;
                    113:                len -= iov[0].iov_len;
                    114:                if (len) {
                    115:                        iov[1].iov_base = sb->sb_data;
                    116:                        iov[1].iov_len = sb->sb_rptr - sb->sb_data;
                    117:                        if(iov[1].iov_len > len)
                    118:                           iov[1].iov_len = len;
                    119:                        total = iov[0].iov_len + iov[1].iov_len;
                    120:                        if (total > mss) {
                    121:                                lss = total%mss;
                    122:                                if (iov[1].iov_len > lss) {
                    123:                                        iov[1].iov_len -= lss;
                    124:                                        n = 2;
                    125:                                } else {
                    126:                                        lss -= iov[1].iov_len;
                    127:                                        iov[0].iov_len -= lss;
                    128:                                        n = 1;
                    129:                                }
                    130:                        } else
                    131:                                n = 2;
                    132:                } else {
                    133:                        if (iov[0].iov_len > mss)
                    134:                           iov[0].iov_len -= iov[0].iov_len%mss;
                    135:                        n = 1;
                    136:                }
                    137:        }
1.1.1.4   root      138:        if (np)
                    139:                *np = n;
                    140: 
                    141:        return iov[0].iov_len + (n - 1) * iov[1].iov_len;
                    142: }
                    143: 
                    144: /*
                    145:  * Read from so's socket into sb_snd, updating all relevant sbuf fields
                    146:  * NOTE: This will only be called if it is select()ed for reading, so
                    147:  * a read() of 0 (or less) means it's disconnected
                    148:  */
                    149: int
1.1.1.5   root      150: soread(struct socket *so)
1.1.1.4   root      151: {
                    152:        int n, nn;
                    153:        struct sbuf *sb = &so->so_snd;
                    154:        struct iovec iov[2];
                    155: 
                    156:        DEBUG_CALL("soread");
                    157:        DEBUG_ARG("so = %lx", (long )so);
                    158: 
                    159:        /*
                    160:         * No need to check if there's enough room to read.
                    161:         * soread wouldn't have been called if there weren't
                    162:         */
                    163:        sopreprbuf(so, iov, &n);
1.1.1.3   root      164: 
1.1       root      165: #ifdef HAVE_READV
                    166:        nn = readv(so->s, (struct iovec *)iov, n);
                    167:        DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
                    168: #else
                    169:        nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
1.1.1.3   root      170: #endif
1.1       root      171:        if (nn <= 0) {
                    172:                if (nn < 0 && (errno == EINTR || errno == EAGAIN))
                    173:                        return 0;
                    174:                else {
                    175:                        DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
                    176:                        sofcantrcvmore(so);
                    177:                        tcp_sockclosed(sototcpcb(so));
                    178:                        return -1;
                    179:                }
                    180:        }
1.1.1.3   root      181: 
1.1       root      182: #ifndef HAVE_READV
                    183:        /*
                    184:         * If there was no error, try and read the second time round
                    185:         * We read again if n = 2 (ie, there's another part of the buffer)
                    186:         * and we read as much as we could in the first read
                    187:         * We don't test for <= 0 this time, because there legitimately
                    188:         * might not be any more data (since the socket is non-blocking),
                    189:         * a close will be detected on next iteration.
                    190:         * A return of -1 wont (shouldn't) happen, since it didn't happen above
                    191:         */
                    192:        if (n == 2 && nn == iov[0].iov_len) {
                    193:             int ret;
                    194:             ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
                    195:             if (ret > 0)
                    196:                 nn += ret;
                    197:         }
1.1.1.3   root      198: 
1.1       root      199:        DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
                    200: #endif
1.1.1.3   root      201: 
1.1       root      202:        /* Update fields */
                    203:        sb->sb_cc += nn;
                    204:        sb->sb_wptr += nn;
                    205:        if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
                    206:                sb->sb_wptr -= sb->sb_datalen;
                    207:        return nn;
                    208: }
1.1.1.3   root      209: 
1.1.1.4   root      210: int soreadbuf(struct socket *so, const char *buf, int size)
                    211: {
                    212:     int n, nn, copy = size;
                    213:        struct sbuf *sb = &so->so_snd;
                    214:        struct iovec iov[2];
                    215: 
                    216:        DEBUG_CALL("soreadbuf");
                    217:        DEBUG_ARG("so = %lx", (long )so);
                    218: 
                    219:        /*
                    220:         * No need to check if there's enough room to read.
                    221:         * soread wouldn't have been called if there weren't
                    222:         */
                    223:        if (sopreprbuf(so, iov, &n) < size)
                    224:         goto err;
                    225: 
                    226:     nn = MIN(iov[0].iov_len, copy);
                    227:     memcpy(iov[0].iov_base, buf, nn);
                    228: 
                    229:     copy -= nn;
                    230:     buf += nn;
                    231: 
                    232:     if (copy == 0)
                    233:         goto done;
                    234: 
                    235:     memcpy(iov[1].iov_base, buf, copy);
                    236: 
                    237: done:
                    238:     /* Update fields */
                    239:        sb->sb_cc += size;
                    240:        sb->sb_wptr += size;
                    241:        if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
                    242:                sb->sb_wptr -= sb->sb_datalen;
                    243:     return size;
                    244: err:
                    245: 
                    246:     sofcantrcvmore(so);
                    247:     tcp_sockclosed(sototcpcb(so));
                    248:     fprintf(stderr, "soreadbuf buffer to small");
                    249:     return -1;
                    250: }
                    251: 
1.1       root      252: /*
                    253:  * Get urgent data
1.1.1.3   root      254:  *
1.1       root      255:  * When the socket is created, we set it SO_OOBINLINE,
                    256:  * so when OOB data arrives, we soread() it and everything
                    257:  * in the send buffer is sent as urgent data
                    258:  */
                    259: void
1.1.1.5   root      260: sorecvoob(struct socket *so)
1.1       root      261: {
                    262:        struct tcpcb *tp = sototcpcb(so);
                    263: 
                    264:        DEBUG_CALL("sorecvoob");
                    265:        DEBUG_ARG("so = %lx", (long)so);
1.1.1.3   root      266: 
1.1       root      267:        /*
                    268:         * We take a guess at how much urgent data has arrived.
                    269:         * In most situations, when urgent data arrives, the next
                    270:         * read() should get all the urgent data.  This guess will
                    271:         * be wrong however if more data arrives just after the
1.1.1.3   root      272:         * urgent data, or the read() doesn't return all the
1.1       root      273:         * urgent data.
                    274:         */
                    275:        soread(so);
                    276:        tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
                    277:        tp->t_force = 1;
                    278:        tcp_output(tp);
                    279:        tp->t_force = 0;
                    280: }
                    281: 
                    282: /*
                    283:  * Send urgent data
                    284:  * There's a lot duplicated code here, but...
                    285:  */
                    286: int
1.1.1.5   root      287: sosendoob(struct socket *so)
1.1       root      288: {
                    289:        struct sbuf *sb = &so->so_rcv;
                    290:        char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
1.1.1.3   root      291: 
1.1       root      292:        int n, len;
1.1.1.3   root      293: 
1.1       root      294:        DEBUG_CALL("sosendoob");
                    295:        DEBUG_ARG("so = %lx", (long)so);
                    296:        DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
1.1.1.3   root      297: 
1.1       root      298:        if (so->so_urgc > 2048)
                    299:           so->so_urgc = 2048; /* XXXX */
1.1.1.3   root      300: 
1.1       root      301:        if (sb->sb_rptr < sb->sb_wptr) {
                    302:                /* We can send it directly */
1.1.1.4   root      303:                n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
1.1       root      304:                so->so_urgc -= n;
1.1.1.3   root      305: 
1.1       root      306:                DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
                    307:        } else {
1.1.1.3   root      308:                /*
1.1       root      309:                 * Since there's no sendv or sendtov like writev,
                    310:                 * we must copy all data to a linear buffer then
                    311:                 * send it all
                    312:                 */
                    313:                len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
                    314:                if (len > so->so_urgc) len = so->so_urgc;
                    315:                memcpy(buff, sb->sb_rptr, len);
                    316:                so->so_urgc -= len;
                    317:                if (so->so_urgc) {
                    318:                        n = sb->sb_wptr - sb->sb_data;
                    319:                        if (n > so->so_urgc) n = so->so_urgc;
                    320:                        memcpy((buff + len), sb->sb_data, n);
                    321:                        so->so_urgc -= n;
                    322:                        len += n;
                    323:                }
1.1.1.4   root      324:                n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
1.1       root      325: #ifdef DEBUG
                    326:                if (n != len)
                    327:                   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
1.1.1.3   root      328: #endif
1.1       root      329:                DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
                    330:        }
1.1.1.3   root      331: 
1.1       root      332:        sb->sb_cc -= n;
                    333:        sb->sb_rptr += n;
                    334:        if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
                    335:                sb->sb_rptr -= sb->sb_datalen;
1.1.1.3   root      336: 
1.1       root      337:        return n;
                    338: }
                    339: 
                    340: /*
1.1.1.3   root      341:  * Write data from so_rcv to so's socket,
1.1       root      342:  * updating all sbuf field as necessary
                    343:  */
                    344: int
1.1.1.5   root      345: sowrite(struct socket *so)
1.1       root      346: {
                    347:        int  n,nn;
                    348:        struct sbuf *sb = &so->so_rcv;
                    349:        int len = sb->sb_cc;
                    350:        struct iovec iov[2];
1.1.1.3   root      351: 
1.1       root      352:        DEBUG_CALL("sowrite");
                    353:        DEBUG_ARG("so = %lx", (long)so);
1.1.1.3   root      354: 
1.1       root      355:        if (so->so_urgc) {
                    356:                sosendoob(so);
                    357:                if (sb->sb_cc == 0)
                    358:                        return 0;
                    359:        }
                    360: 
                    361:        /*
                    362:         * No need to check if there's something to write,
                    363:         * sowrite wouldn't have been called otherwise
                    364:         */
1.1.1.3   root      365: 
1.1       root      366:         len = sb->sb_cc;
1.1.1.3   root      367: 
1.1       root      368:        iov[0].iov_base = sb->sb_rptr;
1.1.1.4   root      369:         iov[1].iov_base = NULL;
                    370:         iov[1].iov_len = 0;
1.1       root      371:        if (sb->sb_rptr < sb->sb_wptr) {
                    372:                iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
                    373:                /* Should never succeed, but... */
                    374:                if (iov[0].iov_len > len) iov[0].iov_len = len;
                    375:                n = 1;
                    376:        } else {
                    377:                iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
                    378:                if (iov[0].iov_len > len) iov[0].iov_len = len;
                    379:                len -= iov[0].iov_len;
                    380:                if (len) {
                    381:                        iov[1].iov_base = sb->sb_data;
                    382:                        iov[1].iov_len = sb->sb_wptr - sb->sb_data;
                    383:                        if (iov[1].iov_len > len) iov[1].iov_len = len;
                    384:                        n = 2;
                    385:                } else
                    386:                        n = 1;
                    387:        }
                    388:        /* Check if there's urgent data to send, and if so, send it */
                    389: 
                    390: #ifdef HAVE_READV
                    391:        nn = writev(so->s, (const struct iovec *)iov, n);
1.1.1.3   root      392: 
1.1       root      393:        DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
                    394: #else
1.1.1.4   root      395:        nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
1.1       root      396: #endif
                    397:        /* This should never happen, but people tell me it does *shrug* */
                    398:        if (nn < 0 && (errno == EAGAIN || errno == EINTR))
                    399:                return 0;
1.1.1.3   root      400: 
1.1       root      401:        if (nn <= 0) {
                    402:                DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
                    403:                        so->so_state, errno));
                    404:                sofcantsendmore(so);
                    405:                tcp_sockclosed(sototcpcb(so));
                    406:                return -1;
                    407:        }
1.1.1.3   root      408: 
1.1       root      409: #ifndef HAVE_READV
                    410:        if (n == 2 && nn == iov[0].iov_len) {
                    411:             int ret;
1.1.1.4   root      412:             ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
1.1       root      413:             if (ret > 0)
                    414:                 nn += ret;
                    415:         }
                    416:         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
                    417: #endif
1.1.1.3   root      418: 
1.1       root      419:        /* Update sbuf */
                    420:        sb->sb_cc -= nn;
                    421:        sb->sb_rptr += nn;
                    422:        if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
                    423:                sb->sb_rptr -= sb->sb_datalen;
1.1.1.3   root      424: 
1.1       root      425:        /*
                    426:         * If in DRAIN mode, and there's no more data, set
                    427:         * it CANTSENDMORE
                    428:         */
                    429:        if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
                    430:                sofcantsendmore(so);
1.1.1.3   root      431: 
1.1       root      432:        return nn;
                    433: }
                    434: 
                    435: /*
                    436:  * recvfrom() a UDP socket
                    437:  */
                    438: void
1.1.1.5   root      439: sorecvfrom(struct socket *so)
1.1       root      440: {
                    441:        struct sockaddr_in addr;
1.1.1.4   root      442:        socklen_t addrlen = sizeof(struct sockaddr_in);
1.1.1.3   root      443: 
1.1       root      444:        DEBUG_CALL("sorecvfrom");
                    445:        DEBUG_ARG("so = %lx", (long)so);
1.1.1.3   root      446: 
1.1       root      447:        if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
                    448:          char buff[256];
                    449:          int len;
1.1.1.3   root      450: 
                    451:          len = recvfrom(so->s, buff, 256, 0,
1.1       root      452:                         (struct sockaddr *)&addr, &addrlen);
                    453:          /* XXX Check if reply is "correct"? */
1.1.1.3   root      454: 
1.1       root      455:          if(len == -1 || len == 0) {
                    456:            u_char code=ICMP_UNREACH_PORT;
                    457: 
                    458:            if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
                    459:            else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
1.1.1.3   root      460: 
1.1       root      461:            DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
                    462:                        errno,strerror(errno)));
                    463:            icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
                    464:          } else {
                    465:            icmp_reflect(so->so_m);
1.1.1.5   root      466:             so->so_m = NULL; /* Don't m_free() it again! */
1.1       root      467:          }
                    468:          /* No need for this socket anymore, udp_detach it */
                    469:          udp_detach(so);
                    470:        } else {                                /* A "normal" UDP packet */
                    471:          struct mbuf *m;
1.1.1.5   root      472:           int len;
                    473: #ifdef _WIN32
                    474:           unsigned long n;
                    475: #else
                    476:           int n;
                    477: #endif
1.1       root      478: 
1.1.1.5   root      479:          m = m_get(so->slirp);
                    480:          if (!m) {
                    481:              return;
                    482:          }
1.1.1.3   root      483:          m->m_data += IF_MAXLINKHDR;
                    484: 
                    485:          /*
1.1       root      486:           * XXX Shouldn't FIONREAD packets destined for port 53,
                    487:           * but I don't know the max packet size for DNS lookups
                    488:           */
                    489:          len = M_FREEROOM(m);
                    490:          /* if (so->so_fport != htons(53)) { */
                    491:          ioctlsocket(so->s, FIONREAD, &n);
1.1.1.3   root      492: 
1.1       root      493:          if (n > len) {
                    494:            n = (m->m_data - m->m_dat) + m->m_len + n + 1;
                    495:            m_inc(m, n);
                    496:            len = M_FREEROOM(m);
                    497:          }
                    498:          /* } */
1.1.1.3   root      499: 
1.1       root      500:          m->m_len = recvfrom(so->s, m->m_data, len, 0,
                    501:                              (struct sockaddr *)&addr, &addrlen);
1.1.1.3   root      502:          DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
1.1       root      503:                      m->m_len, errno,strerror(errno)));
                    504:          if(m->m_len<0) {
                    505:            u_char code=ICMP_UNREACH_PORT;
                    506: 
                    507:            if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
                    508:            else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
1.1.1.3   root      509: 
1.1       root      510:            DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
                    511:            icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
                    512:            m_free(m);
                    513:          } else {
                    514:          /*
                    515:           * Hack: domain name lookup will be used the most for UDP,
                    516:           * and since they'll only be used once there's no need
                    517:           * for the 4 minute (or whatever) timeout... So we time them
                    518:           * out much quicker (10 seconds  for now...)
                    519:           */
                    520:            if (so->so_expire) {
                    521:              if (so->so_fport == htons(53))
                    522:                so->so_expire = curtime + SO_EXPIREFAST;
                    523:              else
                    524:                so->so_expire = curtime + SO_EXPIRE;
                    525:            }
                    526: 
1.1.1.3   root      527:            /*
1.1       root      528:             * If this packet was destined for CTL_ADDR,
                    529:             * make it look like that's where it came from, done by udp_output
                    530:             */
                    531:            udp_output(so, m, &addr);
                    532:          } /* rx error */
                    533:        } /* if ping packet */
                    534: }
                    535: 
                    536: /*
                    537:  * sendto() a socket
                    538:  */
                    539: int
1.1.1.5   root      540: sosendto(struct socket *so, struct mbuf *m)
1.1       root      541: {
1.1.1.5   root      542:        Slirp *slirp = so->slirp;
1.1       root      543:        int ret;
                    544:        struct sockaddr_in addr;
                    545: 
                    546:        DEBUG_CALL("sosendto");
                    547:        DEBUG_ARG("so = %lx", (long)so);
                    548:        DEBUG_ARG("m = %lx", (long)m);
1.1.1.3   root      549: 
1.1       root      550:         addr.sin_family = AF_INET;
1.1.1.5   root      551:        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
                    552:            slirp->vnetwork_addr.s_addr) {
1.1       root      553:          /* It's an alias */
1.1.1.5   root      554:          if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
1.1.1.6 ! root      555:            if (get_dns_addr(&addr.sin_addr) < 0)
        !           556:              addr.sin_addr = loopback_addr;
1.1.1.5   root      557:          } else {
1.1       root      558:            addr.sin_addr = loopback_addr;
                    559:          }
                    560:        } else
                    561:          addr.sin_addr = so->so_faddr;
                    562:        addr.sin_port = so->so_fport;
                    563: 
                    564:        DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
1.1.1.3   root      565: 
1.1       root      566:        /* Don't care what port we get */
                    567:        ret = sendto(so->s, m->m_data, m->m_len, 0,
                    568:                     (struct sockaddr *)&addr, sizeof (struct sockaddr));
                    569:        if (ret < 0)
                    570:                return -1;
1.1.1.3   root      571: 
1.1       root      572:        /*
                    573:         * Kill the socket if there's no reply in 4 minutes,
                    574:         * but only if it's an expirable socket
                    575:         */
                    576:        if (so->so_expire)
                    577:                so->so_expire = curtime + SO_EXPIRE;
1.1.1.5   root      578:        so->so_state &= SS_PERSISTENT_MASK;
                    579:        so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
1.1       root      580:        return 0;
                    581: }
                    582: 
                    583: /*
1.1.1.5   root      584:  * Listen for incoming TCP connections
1.1       root      585:  */
                    586: struct socket *
1.1.1.5   root      587: tcp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
                    588:            u_int lport, int flags)
1.1       root      589: {
                    590:        struct sockaddr_in addr;
                    591:        struct socket *so;
1.1.1.4   root      592:        int s, opt = 1;
                    593:        socklen_t addrlen = sizeof(addr);
1.1       root      594: 
1.1.1.5   root      595:        DEBUG_CALL("tcp_listen");
                    596:        DEBUG_ARG("haddr = %x", haddr);
                    597:        DEBUG_ARG("hport = %d", hport);
1.1       root      598:        DEBUG_ARG("laddr = %x", laddr);
                    599:        DEBUG_ARG("lport = %d", lport);
                    600:        DEBUG_ARG("flags = %x", flags);
1.1.1.3   root      601: 
1.1.1.5   root      602:        so = socreate(slirp);
                    603:        if (!so) {
1.1       root      604:          return NULL;
                    605:        }
1.1.1.3   root      606: 
1.1       root      607:        /* Don't tcp_attach... we don't need so_snd nor so_rcv */
                    608:        if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
                    609:                free(so);
                    610:                return NULL;
                    611:        }
1.1.1.5   root      612:        insque(so, &slirp->tcb);
1.1.1.3   root      613: 
                    614:        /*
1.1       root      615:         * SS_FACCEPTONCE sockets must time out.
                    616:         */
                    617:        if (flags & SS_FACCEPTONCE)
                    618:           so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
1.1.1.3   root      619: 
1.1.1.5   root      620:        so->so_state &= SS_PERSISTENT_MASK;
                    621:        so->so_state |= (SS_FACCEPTCONN | flags);
1.1       root      622:        so->so_lport = lport; /* Kept in network format */
                    623:        so->so_laddr.s_addr = laddr; /* Ditto */
1.1.1.3   root      624: 
1.1       root      625:        addr.sin_family = AF_INET;
1.1.1.5   root      626:        addr.sin_addr.s_addr = haddr;
                    627:        addr.sin_port = hport;
1.1.1.3   root      628: 
1.1.1.6 ! root      629:        if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
1.1.1.2   root      630:            (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
1.1       root      631:            (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
                    632:            (listen(s,1) < 0)) {
                    633:                int tmperrno = errno; /* Don't clobber the real reason we failed */
1.1.1.3   root      634: 
1.1       root      635:                close(s);
                    636:                sofree(so);
                    637:                /* Restore the real errno */
                    638: #ifdef _WIN32
                    639:                WSASetLastError(tmperrno);
                    640: #else
                    641:                errno = tmperrno;
                    642: #endif
                    643:                return NULL;
                    644:        }
                    645:        setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
1.1.1.3   root      646: 
1.1       root      647:        getsockname(s,(struct sockaddr *)&addr,&addrlen);
                    648:        so->so_fport = addr.sin_port;
                    649:        if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
1.1.1.5   root      650:           so->so_faddr = slirp->vhost_addr;
1.1       root      651:        else
                    652:           so->so_faddr = addr.sin_addr;
                    653: 
                    654:        so->s = s;
                    655:        return so;
                    656: }
                    657: 
                    658: /*
                    659:  * Various session state calls
                    660:  * XXX Should be #define's
                    661:  * The socket state stuff needs work, these often get call 2 or 3
                    662:  * times each when only 1 was needed
                    663:  */
                    664: void
1.1.1.5   root      665: soisfconnecting(struct socket *so)
1.1       root      666: {
                    667:        so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
                    668:                          SS_FCANTSENDMORE|SS_FWDRAIN);
                    669:        so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
                    670: }
                    671: 
                    672: void
1.1.1.5   root      673: soisfconnected(struct socket *so)
1.1       root      674: {
                    675:        so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
                    676:        so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
                    677: }
                    678: 
1.1.1.3   root      679: static void
                    680: sofcantrcvmore(struct socket *so)
1.1       root      681: {
                    682:        if ((so->so_state & SS_NOFDREF) == 0) {
                    683:                shutdown(so->s,0);
                    684:                if(global_writefds) {
                    685:                  FD_CLR(so->s,global_writefds);
                    686:                }
                    687:        }
                    688:        so->so_state &= ~(SS_ISFCONNECTING);
1.1.1.5   root      689:        if (so->so_state & SS_FCANTSENDMORE) {
                    690:           so->so_state &= SS_PERSISTENT_MASK;
                    691:           so->so_state |= SS_NOFDREF; /* Don't select it */
                    692:        } else {
1.1       root      693:           so->so_state |= SS_FCANTRCVMORE;
1.1.1.5   root      694:        }
1.1       root      695: }
                    696: 
1.1.1.3   root      697: static void
                    698: sofcantsendmore(struct socket *so)
1.1       root      699: {
                    700:        if ((so->so_state & SS_NOFDREF) == 0) {
                    701:             shutdown(so->s,1);           /* send FIN to fhost */
                    702:             if (global_readfds) {
                    703:                 FD_CLR(so->s,global_readfds);
                    704:             }
                    705:             if (global_xfds) {
                    706:                 FD_CLR(so->s,global_xfds);
                    707:             }
                    708:        }
                    709:        so->so_state &= ~(SS_ISFCONNECTING);
1.1.1.5   root      710:        if (so->so_state & SS_FCANTRCVMORE) {
                    711:           so->so_state &= SS_PERSISTENT_MASK;
                    712:           so->so_state |= SS_NOFDREF; /* as above */
                    713:        } else {
1.1       root      714:           so->so_state |= SS_FCANTSENDMORE;
1.1.1.5   root      715:        }
1.1       root      716: }
                    717: 
                    718: /*
                    719:  * Set write drain mode
                    720:  * Set CANTSENDMORE once all data has been write()n
                    721:  */
                    722: void
1.1.1.5   root      723: sofwdrain(struct socket *so)
1.1       root      724: {
                    725:        if (so->so_rcv.sb_cc)
                    726:                so->so_state |= SS_FWDRAIN;
                    727:        else
                    728:                sofcantsendmore(so);
                    729: }

unix.superglobalmegacorp.com