qemu/slirp/src/socket.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause */
   2/*
   3 * Copyright (c) 1995 Danny Gasparovski.
   4 */
   5
   6#include "slirp.h"
   7#include "ip_icmp.h"
   8#ifdef __sun__
   9#include <sys/filio.h>
  10#endif
  11
  12static void sofcantrcvmore(struct socket *so);
  13static void sofcantsendmore(struct socket *so);
  14
  15struct socket *solookup(struct socket **last, struct socket *head,
  16        struct sockaddr_storage *lhost, struct sockaddr_storage *fhost)
  17{
  18    struct socket *so = *last;
  19
  20    /* Optimisation */
  21    if (so != head && sockaddr_equal(&(so->lhost.ss), lhost)
  22            && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
  23        return so;
  24    }
  25
  26    for (so = head->so_next; so != head; so = so->so_next) {
  27        if (sockaddr_equal(&(so->lhost.ss), lhost)
  28                && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
  29            *last = so;
  30            return so;
  31        }
  32    }
  33
  34    return (struct socket *)NULL;
  35}
  36
  37/*
  38 * Create a new socket, initialise the fields
  39 * It is the responsibility of the caller to
  40 * insque() it into the correct linked-list
  41 */
  42struct socket *
  43socreate(Slirp *slirp)
  44{
  45    struct socket *so = g_new(struct socket, 1);
  46
  47    memset(so, 0, sizeof(struct socket));
  48    so->so_state = SS_NOFDREF;
  49    so->s = -1;
  50    so->slirp = slirp;
  51    so->pollfds_idx = -1;
  52
  53    return so;
  54}
  55
  56/*
  57 * Remove references to so from the given message queue.
  58 */
  59static void
  60soqfree(struct socket *so, struct quehead *qh)
  61{
  62    struct mbuf *ifq;
  63
  64    for (ifq = (struct mbuf *) qh->qh_link;
  65             (struct quehead *) ifq != qh;
  66             ifq = ifq->ifq_next) {
  67        if (ifq->ifq_so == so) {
  68            struct mbuf *ifm;
  69            ifq->ifq_so = NULL;
  70            for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) {
  71                ifm->ifq_so = NULL;
  72            }
  73        }
  74    }
  75}
  76
  77/*
  78 * remque and free a socket, clobber cache
  79 */
  80void
  81sofree(struct socket *so)
  82{
  83  Slirp *slirp = so->slirp;
  84
  85  soqfree(so, &slirp->if_fastq);
  86  soqfree(so, &slirp->if_batchq);
  87
  88  if (so == slirp->tcp_last_so) {
  89      slirp->tcp_last_so = &slirp->tcb;
  90  } else if (so == slirp->udp_last_so) {
  91      slirp->udp_last_so = &slirp->udb;
  92  } else if (so == slirp->icmp_last_so) {
  93      slirp->icmp_last_so = &slirp->icmp;
  94  }
  95  m_free(so->so_m);
  96
  97  if(so->so_next && so->so_prev)
  98    remque(so);  /* crashes if so is not in a queue */
  99
 100  if (so->so_tcpcb) {
 101      free(so->so_tcpcb);
 102  }
 103  g_free(so);
 104}
 105
 106size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
 107{
 108        int n, lss, total;
 109        struct sbuf *sb = &so->so_snd;
 110        int len = sb->sb_datalen - sb->sb_cc;
 111        int mss = so->so_tcpcb->t_maxseg;
 112
 113        DEBUG_CALL("sopreprbuf");
 114        DEBUG_ARG("so = %p", so);
 115
 116        if (len <= 0)
 117                return 0;
 118
 119        iov[0].iov_base = sb->sb_wptr;
 120        iov[1].iov_base = NULL;
 121        iov[1].iov_len = 0;
 122        if (sb->sb_wptr < sb->sb_rptr) {
 123                iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
 124                /* Should never succeed, but... */
 125                if (iov[0].iov_len > len)
 126                   iov[0].iov_len = len;
 127                if (iov[0].iov_len > mss)
 128                   iov[0].iov_len -= iov[0].iov_len%mss;
 129                n = 1;
 130        } else {
 131                iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
 132                /* Should never succeed, but... */
 133                if (iov[0].iov_len > len) iov[0].iov_len = len;
 134                len -= iov[0].iov_len;
 135                if (len) {
 136                        iov[1].iov_base = sb->sb_data;
 137                        iov[1].iov_len = sb->sb_rptr - sb->sb_data;
 138                        if(iov[1].iov_len > len)
 139                           iov[1].iov_len = len;
 140                        total = iov[0].iov_len + iov[1].iov_len;
 141                        if (total > mss) {
 142                                lss = total%mss;
 143                                if (iov[1].iov_len > lss) {
 144                                        iov[1].iov_len -= lss;
 145                                        n = 2;
 146                                } else {
 147                                        lss -= iov[1].iov_len;
 148                                        iov[0].iov_len -= lss;
 149                                        n = 1;
 150                                }
 151                        } else
 152                                n = 2;
 153                } else {
 154                        if (iov[0].iov_len > mss)
 155                           iov[0].iov_len -= iov[0].iov_len%mss;
 156                        n = 1;
 157                }
 158        }
 159        if (np)
 160                *np = n;
 161
 162        return iov[0].iov_len + (n - 1) * iov[1].iov_len;
 163}
 164
 165/*
 166 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 167 * NOTE: This will only be called if it is select()ed for reading, so
 168 * a read() of 0 (or less) means it's disconnected
 169 */
 170int
 171soread(struct socket *so)
 172{
 173        int n, nn;
 174        size_t buf_len;
 175        struct sbuf *sb = &so->so_snd;
 176        struct iovec iov[2];
 177
 178        DEBUG_CALL("soread");
 179        DEBUG_ARG("so = %p", so);
 180
 181        /*
 182         * No need to check if there's enough room to read.
 183         * soread wouldn't have been called if there weren't
 184         */
 185        buf_len = sopreprbuf(so, iov, &n);
 186        assert(buf_len != 0);
 187
 188        nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
 189        if (nn <= 0) {
 190                if (nn < 0 && (errno == EINTR || errno == EAGAIN))
 191                        return 0;
 192                else {
 193                        int err;
 194                        socklen_t elen = sizeof err;
 195                        struct sockaddr_storage addr;
 196                        struct sockaddr *paddr = (struct sockaddr *) &addr;
 197                        socklen_t alen = sizeof addr;
 198
 199                        err = errno;
 200                        if (nn == 0) {
 201                                if (getpeername(so->s, paddr, &alen) < 0) {
 202                                        err = errno;
 203                                } else {
 204                                        getsockopt(so->s, SOL_SOCKET, SO_ERROR,
 205                                                &err, &elen);
 206                                }
 207                        }
 208
 209                        DEBUG_MISC(" --- soread() disconnected, nn = %d, errno = %d-%s",
 210                       nn, errno,strerror(errno));
 211                        sofcantrcvmore(so);
 212
 213                        if (err == ECONNRESET || err == ECONNREFUSED
 214                            || err == ENOTCONN || err == EPIPE) {
 215                                tcp_drop(sototcpcb(so), err);
 216                        } else {
 217                                tcp_sockclosed(sototcpcb(so));
 218                        }
 219                        return -1;
 220                }
 221        }
 222
 223        /*
 224         * If there was no error, try and read the second time round
 225         * We read again if n = 2 (ie, there's another part of the buffer)
 226         * and we read as much as we could in the first read
 227         * We don't test for <= 0 this time, because there legitimately
 228         * might not be any more data (since the socket is non-blocking),
 229         * a close will be detected on next iteration.
 230         * A return of -1 won't (shouldn't) happen, since it didn't happen above
 231         */
 232        if (n == 2 && nn == iov[0].iov_len) {
 233            int ret;
 234            ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
 235            if (ret > 0)
 236                nn += ret;
 237        }
 238
 239        DEBUG_MISC(" ... read nn = %d bytes", nn);
 240
 241        /* Update fields */
 242        sb->sb_cc += nn;
 243        sb->sb_wptr += nn;
 244        if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
 245                sb->sb_wptr -= sb->sb_datalen;
 246        return nn;
 247}
 248
 249int soreadbuf(struct socket *so, const char *buf, int size)
 250{
 251    int n, nn, copy = size;
 252        struct sbuf *sb = &so->so_snd;
 253        struct iovec iov[2];
 254
 255        DEBUG_CALL("soreadbuf");
 256        DEBUG_ARG("so = %p", so);
 257
 258        /*
 259         * No need to check if there's enough room to read.
 260         * soread wouldn't have been called if there weren't
 261         */
 262        assert(size > 0);
 263        if (sopreprbuf(so, iov, &n) < size)
 264        goto err;
 265
 266    nn = MIN(iov[0].iov_len, copy);
 267    memcpy(iov[0].iov_base, buf, nn);
 268
 269    copy -= nn;
 270    buf += nn;
 271
 272    if (copy == 0)
 273        goto done;
 274
 275    memcpy(iov[1].iov_base, buf, copy);
 276
 277done:
 278    /* Update fields */
 279        sb->sb_cc += size;
 280        sb->sb_wptr += size;
 281        if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
 282                sb->sb_wptr -= sb->sb_datalen;
 283    return size;
 284err:
 285
 286    sofcantrcvmore(so);
 287    tcp_sockclosed(sototcpcb(so));
 288    g_critical("soreadbuf buffer too small");
 289    return -1;
 290}
 291
 292/*
 293 * Get urgent data
 294 *
 295 * When the socket is created, we set it SO_OOBINLINE,
 296 * so when OOB data arrives, we soread() it and everything
 297 * in the send buffer is sent as urgent data
 298 */
 299int
 300sorecvoob(struct socket *so)
 301{
 302        struct tcpcb *tp = sototcpcb(so);
 303        int ret;
 304
 305        DEBUG_CALL("sorecvoob");
 306        DEBUG_ARG("so = %p", so);
 307
 308        /*
 309         * We take a guess at how much urgent data has arrived.
 310         * In most situations, when urgent data arrives, the next
 311         * read() should get all the urgent data.  This guess will
 312         * be wrong however if more data arrives just after the
 313         * urgent data, or the read() doesn't return all the
 314         * urgent data.
 315         */
 316        ret = soread(so);
 317        if (ret > 0) {
 318            tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
 319            tp->t_force = 1;
 320            tcp_output(tp);
 321            tp->t_force = 0;
 322        }
 323
 324        return ret;
 325}
 326
 327/*
 328 * Send urgent data
 329 * There's a lot duplicated code here, but...
 330 */
 331int
 332sosendoob(struct socket *so)
 333{
 334        struct sbuf *sb = &so->so_rcv;
 335        char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
 336
 337        int n;
 338
 339        DEBUG_CALL("sosendoob");
 340        DEBUG_ARG("so = %p", so);
 341        DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
 342
 343        if (so->so_urgc > 2048)
 344           so->so_urgc = 2048; /* XXXX */
 345
 346        if (sb->sb_rptr < sb->sb_wptr) {
 347                /* We can send it directly */
 348                n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
 349        } else {
 350                /*
 351                 * Since there's no sendv or sendtov like writev,
 352                 * we must copy all data to a linear buffer then
 353                 * send it all
 354                 */
 355                uint32_t urgc = so->so_urgc;
 356                int len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
 357                if (len > urgc) {
 358                        len = urgc;
 359                }
 360                memcpy(buff, sb->sb_rptr, len);
 361                urgc -= len;
 362                if (urgc) {
 363                        n = sb->sb_wptr - sb->sb_data;
 364                        if (n > urgc) {
 365                                n = urgc;
 366                        }
 367                        memcpy((buff + len), sb->sb_data, n);
 368                        len += n;
 369                }
 370                n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
 371#ifdef DEBUG
 372                if (n != len) {
 373                        DEBUG_ERROR("Didn't send all data urgently XXXXX");
 374                }
 375#endif
 376        }
 377
 378        if (n < 0) {
 379                return n;
 380        }
 381        so->so_urgc -= n;
 382        DEBUG_MISC(" ---2 sent %d bytes urgent data, %d urgent bytes left", n, so->so_urgc);
 383
 384        sb->sb_cc -= n;
 385        sb->sb_rptr += n;
 386        if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
 387                sb->sb_rptr -= sb->sb_datalen;
 388
 389        return n;
 390}
 391
 392/*
 393 * Write data from so_rcv to so's socket,
 394 * updating all sbuf field as necessary
 395 */
 396int
 397sowrite(struct socket *so)
 398{
 399        int  n,nn;
 400        struct sbuf *sb = &so->so_rcv;
 401        int len = sb->sb_cc;
 402        struct iovec iov[2];
 403
 404        DEBUG_CALL("sowrite");
 405        DEBUG_ARG("so = %p", so);
 406
 407        if (so->so_urgc) {
 408                uint32_t expected = so->so_urgc;
 409                if (sosendoob(so) < expected) {
 410                        /* Treat a short write as a fatal error too,
 411                         * rather than continuing on and sending the urgent
 412                         * data as if it were non-urgent and leaving the
 413                         * so_urgc count wrong.
 414                         */
 415                        goto err_disconnected;
 416                }
 417                if (sb->sb_cc == 0)
 418                        return 0;
 419        }
 420
 421        /*
 422         * No need to check if there's something to write,
 423         * sowrite wouldn't have been called otherwise
 424         */
 425
 426        iov[0].iov_base = sb->sb_rptr;
 427        iov[1].iov_base = NULL;
 428        iov[1].iov_len = 0;
 429        if (sb->sb_rptr < sb->sb_wptr) {
 430                iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
 431                /* Should never succeed, but... */
 432                if (iov[0].iov_len > len) iov[0].iov_len = len;
 433                n = 1;
 434        } else {
 435                iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
 436                if (iov[0].iov_len > len) iov[0].iov_len = len;
 437                len -= iov[0].iov_len;
 438                if (len) {
 439                        iov[1].iov_base = sb->sb_data;
 440                        iov[1].iov_len = sb->sb_wptr - sb->sb_data;
 441                        if (iov[1].iov_len > len) iov[1].iov_len = len;
 442                        n = 2;
 443                } else
 444                        n = 1;
 445        }
 446        /* Check if there's urgent data to send, and if so, send it */
 447
 448        nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
 449        /* This should never happen, but people tell me it does *shrug* */
 450        if (nn < 0 && (errno == EAGAIN || errno == EINTR))
 451                return 0;
 452
 453        if (nn <= 0) {
 454                goto err_disconnected;
 455        }
 456
 457        if (n == 2 && nn == iov[0].iov_len) {
 458            int ret;
 459            ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
 460            if (ret > 0)
 461                nn += ret;
 462        }
 463        DEBUG_MISC("  ... wrote nn = %d bytes", nn);
 464
 465        /* Update sbuf */
 466        sb->sb_cc -= nn;
 467        sb->sb_rptr += nn;
 468        if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
 469                sb->sb_rptr -= sb->sb_datalen;
 470
 471        /*
 472         * If in DRAIN mode, and there's no more data, set
 473         * it CANTSENDMORE
 474         */
 475        if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
 476                sofcantsendmore(so);
 477
 478        return nn;
 479
 480err_disconnected:
 481        DEBUG_MISC(" --- sowrite disconnected, so->so_state = %x, errno = %d",
 482               so->so_state, errno);
 483        sofcantsendmore(so);
 484        tcp_sockclosed(sototcpcb(so));
 485        return -1;
 486}
 487
 488/*
 489 * recvfrom() a UDP socket
 490 */
 491void
 492sorecvfrom(struct socket *so)
 493{
 494        struct sockaddr_storage addr;
 495        struct sockaddr_storage saddr, daddr;
 496        socklen_t addrlen = sizeof(struct sockaddr_storage);
 497
 498        DEBUG_CALL("sorecvfrom");
 499        DEBUG_ARG("so = %p", so);
 500
 501        if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
 502          char buff[256];
 503          int len;
 504
 505          len = recvfrom(so->s, buff, 256, 0,
 506                         (struct sockaddr *)&addr, &addrlen);
 507          /* XXX Check if reply is "correct"? */
 508
 509          if(len == -1 || len == 0) {
 510            uint8_t code=ICMP_UNREACH_PORT;
 511
 512            if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
 513            else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
 514
 515            DEBUG_MISC(" udp icmp rx errno = %d-%s",
 516                   errno,strerror(errno));
 517            icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
 518          } else {
 519            icmp_reflect(so->so_m);
 520            so->so_m = NULL; /* Don't m_free() it again! */
 521          }
 522          /* No need for this socket anymore, udp_detach it */
 523          udp_detach(so);
 524        } else {                                /* A "normal" UDP packet */
 525          struct mbuf *m;
 526          int len;
 527#ifdef _WIN32
 528          unsigned long n;
 529#else
 530          int n;
 531#endif
 532
 533          if (ioctlsocket(so->s, FIONREAD, &n) != 0) {
 534              DEBUG_MISC(" ioctlsocket errno = %d-%s\n",
 535                         errno,strerror(errno));
 536              return;
 537          }
 538          if (n == 0) {
 539              return;
 540          }
 541
 542          m = m_get(so->slirp);
 543          if (!m) {
 544              return;
 545          }
 546          switch (so->so_ffamily) {
 547          case AF_INET:
 548              m->m_data += IF_MAXLINKHDR + sizeof(struct udpiphdr);
 549              break;
 550          case AF_INET6:
 551              m->m_data += IF_MAXLINKHDR + sizeof(struct ip6)
 552                                         + sizeof(struct udphdr);
 553              break;
 554          default:
 555              g_assert_not_reached();
 556              break;
 557          }
 558
 559          /*
 560           * XXX Shouldn't FIONREAD packets destined for port 53,
 561           * but I don't know the max packet size for DNS lookups
 562           */
 563          len = M_FREEROOM(m);
 564          /* if (so->so_fport != htons(53)) { */
 565
 566          if (n > len) {
 567            n = (m->m_data - m->m_dat) + m->m_len + n + 1;
 568            m_inc(m, n);
 569            len = M_FREEROOM(m);
 570          }
 571          /* } */
 572
 573          m->m_len = recvfrom(so->s, m->m_data, len, 0,
 574                              (struct sockaddr *)&addr, &addrlen);
 575          DEBUG_MISC(" did recvfrom %d, errno = %d-%s",
 576                 m->m_len, errno,strerror(errno));
 577          if(m->m_len<0) {
 578            /* Report error as ICMP */
 579            switch (so->so_lfamily) {
 580            uint8_t code;
 581            case AF_INET:
 582              code = ICMP_UNREACH_PORT;
 583
 584              if (errno == EHOSTUNREACH) {
 585                code = ICMP_UNREACH_HOST;
 586              } else if (errno == ENETUNREACH) {
 587                code = ICMP_UNREACH_NET;
 588              }
 589
 590              DEBUG_MISC(" rx error, tx icmp ICMP_UNREACH:%i", code);
 591              icmp_send_error(so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
 592              break;
 593            case AF_INET6:
 594              code = ICMP6_UNREACH_PORT;
 595
 596              if (errno == EHOSTUNREACH) {
 597                code = ICMP6_UNREACH_ADDRESS;
 598              } else if (errno == ENETUNREACH) {
 599                code = ICMP6_UNREACH_NO_ROUTE;
 600              }
 601
 602              DEBUG_MISC(" rx error, tx icmp6 ICMP_UNREACH:%i", code);
 603              icmp6_send_error(so->so_m, ICMP6_UNREACH, code);
 604              break;
 605            default:
 606              g_assert_not_reached();
 607              break;
 608            }
 609            m_free(m);
 610          } else {
 611          /*
 612           * Hack: domain name lookup will be used the most for UDP,
 613           * and since they'll only be used once there's no need
 614           * for the 4 minute (or whatever) timeout... So we time them
 615           * out much quicker (10 seconds  for now...)
 616           */
 617            if (so->so_expire) {
 618              if (so->so_fport == htons(53))
 619                so->so_expire = curtime + SO_EXPIREFAST;
 620              else
 621                so->so_expire = curtime + SO_EXPIRE;
 622            }
 623
 624            /*
 625             * If this packet was destined for CTL_ADDR,
 626             * make it look like that's where it came from
 627             */
 628            saddr = addr;
 629            sotranslate_in(so, &saddr);
 630            daddr = so->lhost.ss;
 631
 632            switch (so->so_ffamily) {
 633            case AF_INET:
 634                udp_output(so, m, (struct sockaddr_in *) &saddr,
 635                           (struct sockaddr_in *) &daddr,
 636                           so->so_iptos);
 637                break;
 638            case AF_INET6:
 639                udp6_output(so, m, (struct sockaddr_in6 *) &saddr,
 640                            (struct sockaddr_in6 *) &daddr);
 641                break;
 642            default:
 643                g_assert_not_reached();
 644                break;
 645            }
 646          } /* rx error */
 647        } /* if ping packet */
 648}
 649
 650/*
 651 * sendto() a socket
 652 */
 653int
 654sosendto(struct socket *so, struct mbuf *m)
 655{
 656        int ret;
 657        struct sockaddr_storage addr;
 658
 659        DEBUG_CALL("sosendto");
 660        DEBUG_ARG("so = %p", so);
 661        DEBUG_ARG("m = %p", m);
 662
 663        addr = so->fhost.ss;
 664        DEBUG_CALL(" sendto()ing)");
 665        sotranslate_out(so, &addr);
 666
 667        /* Don't care what port we get */
 668        ret = sendto(so->s, m->m_data, m->m_len, 0,
 669                     (struct sockaddr *)&addr, sockaddr_size(&addr));
 670        if (ret < 0)
 671                return -1;
 672
 673        /*
 674         * Kill the socket if there's no reply in 4 minutes,
 675         * but only if it's an expirable socket
 676         */
 677        if (so->so_expire)
 678                so->so_expire = curtime + SO_EXPIRE;
 679        so->so_state &= SS_PERSISTENT_MASK;
 680        so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
 681        return 0;
 682}
 683
 684/*
 685 * Listen for incoming TCP connections
 686 */
 687struct socket *
 688tcp_listen(Slirp *slirp, uint32_t haddr, unsigned hport, uint32_t laddr,
 689           unsigned lport, int flags)
 690{
 691        /* TODO: IPv6 */
 692        struct sockaddr_in addr;
 693        struct socket *so;
 694        int s, opt = 1;
 695        socklen_t addrlen = sizeof(addr);
 696        memset(&addr, 0, addrlen);
 697
 698        DEBUG_CALL("tcp_listen");
 699        DEBUG_ARG("haddr = %s", inet_ntoa((struct in_addr){.s_addr = haddr}));
 700        DEBUG_ARG("hport = %d", ntohs(hport));
 701        DEBUG_ARG("laddr = %s", inet_ntoa((struct in_addr){.s_addr = laddr}));
 702        DEBUG_ARG("lport = %d", ntohs(lport));
 703        DEBUG_ARG("flags = %x", flags);
 704
 705        so = socreate(slirp);
 706
 707        /* Don't tcp_attach... we don't need so_snd nor so_rcv */
 708        if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
 709            g_free(so);
 710            return NULL;
 711        }
 712        insque(so, &slirp->tcb);
 713
 714        /*
 715         * SS_FACCEPTONCE sockets must time out.
 716         */
 717        if (flags & SS_FACCEPTONCE)
 718           so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
 719
 720        so->so_state &= SS_PERSISTENT_MASK;
 721        so->so_state |= (SS_FACCEPTCONN | flags);
 722        so->so_lfamily = AF_INET;
 723        so->so_lport = lport; /* Kept in network format */
 724        so->so_laddr.s_addr = laddr; /* Ditto */
 725
 726        addr.sin_family = AF_INET;
 727        addr.sin_addr.s_addr = haddr;
 728        addr.sin_port = hport;
 729
 730        if (((s = slirp_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
 731            (slirp_socket_set_fast_reuse(s) < 0) ||
 732            (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
 733            (listen(s,1) < 0)) {
 734                int tmperrno = errno; /* Don't clobber the real reason we failed */
 735
 736                if (s >= 0) {
 737                    closesocket(s);
 738                }
 739                sofree(so);
 740                /* Restore the real errno */
 741#ifdef _WIN32
 742                WSASetLastError(tmperrno);
 743#else
 744                errno = tmperrno;
 745#endif
 746                return NULL;
 747        }
 748        setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
 749        opt = 1;
 750        setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
 751
 752        getsockname(s,(struct sockaddr *)&addr,&addrlen);
 753        so->so_ffamily = AF_INET;
 754        so->so_fport = addr.sin_port;
 755        if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
 756           so->so_faddr = slirp->vhost_addr;
 757        else
 758           so->so_faddr = addr.sin_addr;
 759
 760        so->s = s;
 761        return so;
 762}
 763
 764/*
 765 * Various session state calls
 766 * XXX Should be #define's
 767 * The socket state stuff needs work, these often get call 2 or 3
 768 * times each when only 1 was needed
 769 */
 770void
 771soisfconnecting(struct socket *so)
 772{
 773        so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
 774                          SS_FCANTSENDMORE|SS_FWDRAIN);
 775        so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
 776}
 777
 778void
 779soisfconnected(struct socket *so)
 780{
 781        so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
 782        so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
 783}
 784
 785static void
 786sofcantrcvmore(struct socket *so)
 787{
 788        if ((so->so_state & SS_NOFDREF) == 0) {
 789                shutdown(so->s,0);
 790        }
 791        so->so_state &= ~(SS_ISFCONNECTING);
 792        if (so->so_state & SS_FCANTSENDMORE) {
 793           so->so_state &= SS_PERSISTENT_MASK;
 794           so->so_state |= SS_NOFDREF; /* Don't select it */
 795        } else {
 796           so->so_state |= SS_FCANTRCVMORE;
 797        }
 798}
 799
 800static void
 801sofcantsendmore(struct socket *so)
 802{
 803        if ((so->so_state & SS_NOFDREF) == 0) {
 804            shutdown(so->s,1);           /* send FIN to fhost */
 805        }
 806        so->so_state &= ~(SS_ISFCONNECTING);
 807        if (so->so_state & SS_FCANTRCVMORE) {
 808           so->so_state &= SS_PERSISTENT_MASK;
 809           so->so_state |= SS_NOFDREF; /* as above */
 810        } else {
 811           so->so_state |= SS_FCANTSENDMORE;
 812        }
 813}
 814
 815/*
 816 * Set write drain mode
 817 * Set CANTSENDMORE once all data has been write()n
 818 */
 819void
 820sofwdrain(struct socket *so)
 821{
 822        if (so->so_rcv.sb_cc)
 823                so->so_state |= SS_FWDRAIN;
 824        else
 825                sofcantsendmore(so);
 826}
 827
 828/*
 829 * Translate addr in host addr when it is a virtual address
 830 */
 831void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
 832{
 833    Slirp *slirp = so->slirp;
 834    struct sockaddr_in *sin = (struct sockaddr_in *)addr;
 835    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
 836
 837    switch (addr->ss_family) {
 838    case AF_INET:
 839        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
 840                slirp->vnetwork_addr.s_addr) {
 841            /* It's an alias */
 842            if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
 843                if (get_dns_addr(&sin->sin_addr) < 0) {
 844                    sin->sin_addr = loopback_addr;
 845                }
 846            } else {
 847                sin->sin_addr = loopback_addr;
 848            }
 849        }
 850
 851        DEBUG_MISC(" addr.sin_port=%d, addr.sin_addr.s_addr=%.16s",
 852                   ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
 853        break;
 854
 855    case AF_INET6:
 856        if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
 857                    slirp->vprefix_len)) {
 858            if (in6_equal(&so->so_faddr6, &slirp->vnameserver_addr6)) {
 859                uint32_t scope_id;
 860                if (get_dns6_addr(&sin6->sin6_addr, &scope_id) >= 0) {
 861                    sin6->sin6_scope_id = scope_id;
 862                } else {
 863                    sin6->sin6_addr = in6addr_loopback;
 864                }
 865            } else {
 866                sin6->sin6_addr = in6addr_loopback;
 867            }
 868        }
 869        break;
 870
 871    default:
 872        break;
 873    }
 874}
 875
 876void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
 877{
 878    Slirp *slirp = so->slirp;
 879    struct sockaddr_in *sin = (struct sockaddr_in *)addr;
 880    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
 881
 882    switch (addr->ss_family) {
 883    case AF_INET:
 884        if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
 885            slirp->vnetwork_addr.s_addr) {
 886            uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
 887
 888            if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
 889                sin->sin_addr = slirp->vhost_addr;
 890            } else if (sin->sin_addr.s_addr == loopback_addr.s_addr ||
 891                       so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
 892                sin->sin_addr = so->so_faddr;
 893            }
 894        }
 895        break;
 896
 897    case AF_INET6:
 898        if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
 899                    slirp->vprefix_len)) {
 900            if (in6_equal(&sin6->sin6_addr, &in6addr_loopback)
 901                    || !in6_equal(&so->so_faddr6, &slirp->vhost_addr6)) {
 902                sin6->sin6_addr = so->so_faddr6;
 903            }
 904        }
 905        break;
 906
 907    default:
 908        break;
 909    }
 910}
 911
 912/*
 913 * Translate connections from localhost to the real hostname
 914 */
 915void sotranslate_accept(struct socket *so)
 916{
 917    Slirp *slirp = so->slirp;
 918
 919    switch (so->so_ffamily) {
 920    case AF_INET:
 921        if (so->so_faddr.s_addr == INADDR_ANY ||
 922            (so->so_faddr.s_addr & loopback_mask) ==
 923            (loopback_addr.s_addr & loopback_mask)) {
 924           so->so_faddr = slirp->vhost_addr;
 925        }
 926        break;
 927
 928   case AF_INET6:
 929        if (in6_equal(&so->so_faddr6, &in6addr_any) ||
 930                in6_equal(&so->so_faddr6, &in6addr_loopback)) {
 931           so->so_faddr6 = slirp->vhost_addr6;
 932        }
 933        break;
 934
 935    default:
 936        break;
 937    }
 938}
 939
 940void sodrop(struct socket *s, int num)
 941{
 942    if (sbdrop(&s->so_snd, num)) {
 943        s->slirp->cb->notify(s->slirp->opaque);
 944    }
 945}
 946