~ubuntu-branches/ubuntu/vivid/virtualbox-ose/vivid

« back to all changes in this revision

Viewing changes to src/VBox/Devices/Network/slirp/socket.c

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-10-13 23:06:00 UTC
  • mfrom: (0.3.2 upstream) (0.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20091013230600-xhu2pwizq0wo63l9
Tags: 3.0.8-dfsg-1ubuntu1
* Merge from debian unstable (LP: #444812), remaining changes:
  - Enable DKMS support on virtualbox host and guest modules (LP: #267097)
    - Drop virtualbox-ose{-guest,}-modules-* package templates
    - Recommend *-source instead of *-modules packages
    - Replace error messages related to missing/mismatched
      kernel module accordingly
  - Autoload kernel module
    - LOAD_VBOXDRV_MODULE=1 in virtualbox-ose.default
  - Disable update action
    - patches/u01-disable-update-action.dpatch
  - Virtualbox should go in Accessories, not in System tools (LP: #288590)
    - virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add apport hook
    - virtualbox-ose.files/source_virtualbox-ose.py
    - virtualbox-ose.install
  - Add launchpad integration
    - control
    - lpi-bug.xpm
    - patches/u02-lp-integration.dpatch
* Try to remove existing dkms modules before adding the new modules
  (LP: #434503)
  - debian/virtualbox-ose-source.postinst
  - debian/virtualbox-ose-guest-source.postinst
* Don't fail if dkms modules have already been removed
  - debian/virtualbox-ose-source.prerm
  - debian/virtualbox-ose-guest-source.prerm

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
    struct socket *so;
62
62
 
63
63
    so = (struct socket *)RTMemAllocZ(sizeof(struct socket));
64
 
    if(so)
 
64
    if (so)
65
65
    {
66
66
        so->so_state = SS_NOFDREF;
67
67
        so->s = -1;
90
90
    if (so->so_m != NULL)
91
91
        m_free(pData, so->so_m);
92
92
#ifndef VBOX_WITH_SLIRP_MT
93
 
    if(so->so_next && so->so_prev)
 
93
    if (so->so_next && so->so_prev)
94
94
    {
95
95
        remque(pData, so);  /* crashes if so is not in a queue */
96
96
        NSOCK_DEC();
166
166
        {
167
167
            iov[1].iov_base = sb->sb_data;
168
168
            iov[1].iov_len = sb->sb_rptr - sb->sb_data;
169
 
            if(iov[1].iov_len > len)
 
169
            if (iov[1].iov_len > len)
170
170
                iov[1].iov_len = len;
171
171
            total = iov[0].iov_len + iov[1].iov_len;
172
172
            if (total > mss)
223
223
            return 0;
224
224
        }
225
225
#endif
226
 
        if (nn < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
 
226
        if (   nn < 0
 
227
            && (   errno == EINTR
 
228
                || errno == EAGAIN
 
229
                || errno == EWOULDBLOCK))
227
230
        {
228
231
            SOCKET_UNLOCK(so);
229
232
            STAM_PROFILE_STOP(&pData->StatIOread, a);
271
274
        if (ret > 0)
272
275
            nn += ret;
273
276
        STAM_STATS(
274
 
            if(ret > 0)
 
277
            if (ret > 0)
275
278
            {
276
279
                STAM_COUNTER_INC(&pData->StatIORead_in_2);
277
280
                STAM_COUNTER_ADD(&pData->StatIORead_in_2_2nd_bytes, ret);
481
484
    nn = send(so->s, iov[0].iov_base, iov[0].iov_len, 0);
482
485
#endif
483
486
    /* This should never happen, but people tell me it does *shrug* */
484
 
    if (nn < 0 && (errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
 
487
    if (   nn < 0
 
488
        && (   errno == EAGAIN
 
489
            || errno == EINTR
 
490
            || errno == EWOULDBLOCK))
485
491
    {
486
492
        SOCKET_UNLOCK(so);
487
493
        STAM_PROFILE_STOP(&pData->StatIOwrite, a);
541
547
void
542
548
sorecvfrom(PNATState pData, struct socket *so)
543
549
{
 
550
    ssize_t ret = 0;
544
551
    struct sockaddr_in addr;
545
552
    socklen_t addrlen = sizeof(struct sockaddr_in);
546
553
 
563
570
        struct mbuf *m;
564
571
        struct ethhdr *eh;
565
572
        size_t len;
566
 
        u_long n;
 
573
        u_long n = 0;
567
574
 
568
575
        QSOCKET_LOCK(udb);
569
576
        SOCKET_LOCK(so);
584
591
        len = M_FREEROOM(m);
585
592
        /* if (so->so_fport != htons(53)) */
586
593
        {
587
 
            ioctlsocket(so->s, FIONREAD, &n);
588
 
 
589
 
            if (n > len)
 
594
            int rc = 0;
 
595
            static int signaled = 0;
 
596
            rc = ioctlsocket(so->s, FIONREAD, &n);
 
597
            if (   rc == -1
 
598
                && (   errno == EAGAIN
 
599
                    || errno == EWOULDBLOCK
 
600
                    || errno == EINPROGRESS
 
601
                    || errno == ENOTCONN))
 
602
            {
 
603
                m_free(pData, m);
 
604
                return;
 
605
            }
 
606
 
 
607
            if (rc == -1 && signaled == 0)
 
608
            {
 
609
                LogRel(("NAT: can't fetch amount of bytes on socket %R[natsock], so message will be truncated.\n", so));
 
610
                signaled = 1;
 
611
                m_free(pData, m);
 
612
                return;
 
613
            }
 
614
 
 
615
            if (rc != -1 && n > len)
590
616
            {
591
617
                n = (m->m_data - m->m_dat) + m->m_len + n + 1;
592
618
                m_inc(m, n);
594
620
            }
595
621
        }
596
622
 
597
 
        m->m_len = recvfrom(so->s, m->m_data, len, 0,
 
623
        ret = recvfrom(so->s, m->m_data, len, 0,
598
624
                            (struct sockaddr *)&addr, &addrlen);
599
625
        Log2((" did recvfrom %d, errno = %d-%s\n",
600
626
                    m->m_len, errno, strerror(errno)));
601
 
        if(m->m_len < 0)
 
627
        m->m_len = ret;
 
628
        if (ret < 0)
602
629
        {
603
630
            u_char code = ICMP_UNREACH_PORT;
604
631
 
605
632
            if (errno == EHOSTUNREACH)
606
633
                code = ICMP_UNREACH_HOST;
607
 
            else if(errno == ENETUNREACH)
 
634
            else if (errno == ENETUNREACH)
608
635
                code = ICMP_UNREACH_NET;
609
636
 
610
 
            Log2((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
 
637
            m_free(pData, m);
 
638
            if (   errno == EAGAIN
 
639
                || errno == EWOULDBLOCK
 
640
                || errno == EINPROGRESS
 
641
                || errno == ENOTCONN)
 
642
            {
 
643
                return;
 
644
            }
 
645
 
 
646
            Log2((" rx error, tx icmp ICMP_UNREACH:%i\n", code));
611
647
            icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
612
648
            so->so_m = NULL;
613
 
            m_free(pData, m);
614
649
        }
615
650
        else
616
651
        {
1150
1185
{
1151
1186
    struct sockaddr_in addr;
1152
1187
    socklen_t addrlen = sizeof(struct sockaddr_in);
1153
 
    char buff[1500];
1154
 
    int len;
1155
 
    len = recvfrom(so->s, buff, 1500, 0,
 
1188
    char *buff;
 
1189
    int len = 0;
 
1190
    int rc = 0;
 
1191
    static int signalled = 0;
 
1192
    rc = ioctlsocket(so->s, FIONREAD, &len);
 
1193
    if (   rc == -1
 
1194
        && (errno == EAGAIN
 
1195
        || errno == EWOULDBLOCK
 
1196
        || errno == EINPROGRESS
 
1197
        || errno == ENOTCONN))
 
1198
    {
 
1199
        return;
 
1200
    }
 
1201
    if (rc == -1 && signalled == 0)
 
1202
    {
 
1203
        signalled = 1;
 
1204
        LogRel(("NAT: fetching number of bits has been failed for ICMP socket (%d: %s)\n",
 
1205
            errno, strerror(errno)));
 
1206
        return;
 
1207
    }
 
1208
    len = (len != 0 && rc != -1 ? len : 1500);
 
1209
    buff = RTMemAlloc(len);
 
1210
    len = recvfrom(so->s, buff, len, 0,
1156
1211
                   (struct sockaddr *)&addr, &addrlen);
1157
1212
    /* XXX Check if reply is "correct"? */
1158
1213
 
1159
1214
    if (len == -1 || len == 0)
1160
1215
    {
1161
 
        u_char code = ICMP_UNREACH_PORT;
 
1216
        u_char code;
 
1217
        if (   len == -1
 
1218
            && (   errno == EAGAIN
 
1219
                || errno == EWOULDBLOCK
 
1220
                || errno == EINPROGRESS
 
1221
                || errno == ENOTCONN))
 
1222
        {
 
1223
            return;
 
1224
        }
 
1225
        code = ICMP_UNREACH_PORT;
1162
1226
 
1163
1227
        if (errno == EHOSTUNREACH)
1164
1228
            code = ICMP_UNREACH_HOST;
1165
 
        else if(errno == ENETUNREACH)
 
1229
        else if (errno == ENETUNREACH)
1166
1230
            code = ICMP_UNREACH_NET;
1167
1231
 
1168
 
        DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
 
1232
        LogRel((" udp icmp rx errno = %d-%s\n",
1169
1233
                    errno, strerror(errno)));
1170
1234
        icmp_error(pData, so->so_m, ICMP_UNREACH, code, 0, strerror(errno));
1171
1235
        so->so_m = NULL;
1174
1238
    {
1175
1239
        send_icmp_to_guest(pData, buff, len, so, &addr);
1176
1240
    }
 
1241
    RTMemFree(buff);
1177
1242
}
1178
1243
#endif /* !RT_OS_WINDOWS */