VirtualBox

Changeset 71982 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 23, 2018 2:04:04 PM (7 years ago)
Author:
vboxsync
Message:

NAT: (re)implement --nataliasmode sameports because the libalias
version never really worked.

Location:
trunk/src/VBox/Devices/Network/slirp
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r71945 r71982  
    3636#include <icmpapi.h>
    3737#endif
     38#include <alias.h>
    3839
    3940#if defined(DECLARE_IOVEC) && defined(RT_OS_WINDOWS)
     
    170171    LogFlowFuncLeave();
    171172}
     173
     174
     175int
     176sobind(PNATState pData, struct socket *so)
     177{
     178    bool fSamePorts = !!(pData->i32AliasMode & PKT_ALIAS_SAME_PORTS);
     179    struct sockaddr_in self;
     180    int opt;
     181    int binderr;
     182    int ret;
     183   
     184    /* do we need to bind the socket to specific host address/port? */
     185    if (pData->bindIP.s_addr == INADDR_ANY && !fSamePorts)
     186        return 0;
     187
     188    opt = 1;
     189    setsockopt(so->s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
     190
     191    RT_ZERO(self);
     192#ifdef RT_OS_DARWIN
     193    self.sin_len = sizeof(self);
     194#endif
     195    self.sin_family = AF_INET;
     196    self.sin_addr = pData->bindIP;
     197    self.sin_port = fSamePorts ? so->so_lport : 0;
     198   
     199    Log2(("NAT: binding guest %RTnaipv4:%d to host %RTnaipv4:%d\n",
     200          so->so_laddr.s_addr, ntohs(so->so_lport),
     201          self.sin_addr.s_addr, ntohs(self.sin_port)));
     202
     203    ret = bind(so->s, (struct sockaddr *)&self, sizeof(self));
     204    if (ret == 0)
     205    {
     206        Log2(("NAT: ... bind ok\n"));
     207        return 0;
     208    }
     209
     210    if (self.sin_port != 0)
     211    {
     212        if (pData->bindIP.s_addr != INADDR_ANY)
     213        {
     214            Log2(("NAT: failed to bind to %RTnaipv4:%d (bindip,sameports),"
     215                  " retrying with random port\n",
     216                  self.sin_addr.s_addr, self.sin_port));
     217
     218            /*
     219             * don't try to guess why bind() failed, retry without
     220             * requesting the same port port
     221             */
     222            self.sin_port = 0;
     223
     224            ret = bind(so->s, (struct sockaddr *)&self, sizeof(self));
     225            if (ret == 0)   /* bindIP ok (but port is not the same) */
     226            {
     227                Log2(("NAT: ... bind ok (without sameports)\n"));
     228                return 0;
     229            }
     230        }
     231        else
     232        {
     233            Log2(("NAT: failed to bind to 0.0.0.0:%d (sameports),"
     234                  " ignoring sameports\n",
     235                  self.sin_port));
     236
     237            /* it's ok if we failed to get the same port */
     238            return 0;
     239        }
     240    }
     241
     242    binderr = errno;
     243
     244    Log2(("NAT: failed to bind to %RTnaipv4 (bindip)\n",
     245          self.sin_addr.s_addr));
     246
     247    closesocket(so->s);
     248    so->s = -1;
     249#ifdef RT_OS_WINDOWS
     250    WSASetLastError(binderr);
     251#else
     252    errno = binderr;
     253#endif
     254    return -1;
     255}
     256
    172257
    173258/*
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r71945 r71982  
    167167struct socket * socreate (void);
    168168void sofree (PNATState, struct socket *);
     169int sobind(PNATState, struct socket *);
    169170int soread (PNATState, struct socket *);
    170171void sorecvoob (PNATState, struct socket *);
  • trunk/src/VBox/Devices/Network/slirp/tcp_subr.c

    r69500 r71982  
    413413
    414414        fd_nonblock(s);
    415         opt = 1;
    416         setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
     415
    417416        opt = 1;
    418417        setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(opt));
    419418
    420         if (pData->bindIP.s_addr != INADDR_ANY)
    421         {
    422             struct sockaddr_in self;
    423             self.sin_family = AF_INET;
    424             self.sin_addr = pData->bindIP;
    425             self.sin_port = 0;
    426 
    427             ret = bind(s, (struct sockaddr *)&self, sizeof(self));
    428             if (ret != 0)
    429             {
    430                 Log2(("NAT: bind(%RTnaipv4): %s\n", pData->bindIP.s_addr, strerror(errno)));
    431                 return ret;
    432             }
    433         }
     419        ret = sobind(pData, so);
     420        if (ret != 0)
     421            return ret;
    434422
    435423        addr.sin_family = AF_INET;
  • trunk/src/VBox/Devices/Network/slirp/udp.c

    r71945 r71982  
    271271            goto bad_free_mbuf;
    272272        }
     273
     274        /*
     275         * Setup fields
     276         */
     277        so->so_laddr = ip->ip_src;
     278        so->so_lport = uh->uh_sport;
     279        so->so_iptos = ip->ip_tos;
     280
    273281        if (udp_attach(pData, so) <= 0)
    274282        {
     
    279287        }
    280288
    281         /*
    282          * Setup fields
    283          */
    284289        /* udp_last_so = so; */
    285         so->so_laddr = ip->ip_src;
    286         so->so_lport = uh->uh_sport;
    287 
    288         so->so_iptos = ip->ip_tos;
    289 
    290290        /*
    291291         * XXXXX Here, check if it's in udpexec_list,
     
    526526udp_attach(PNATState pData, struct socket *so)
    527527{
    528     struct sockaddr_in *addr;
    529528    struct sockaddr sa_addr;
    530529    socklen_t socklen = sizeof(struct sockaddr);
     
    539538    so->so_sotos = 0;
    540539    so->so_sodf = -1;
    541     /*
    542      * Here, we bind() the socket.  Although not really needed
    543      * (sendto() on an unbound socket will bind it), it's done
    544      * here so that emulation of ytalk etc. don't have to do it
    545      */
    546     memset(&sa_addr, 0, sizeof(struct sockaddr));
    547     addr = (struct sockaddr_in *)&sa_addr;
    548 #ifdef RT_OS_DARWIN
    549     addr->sin_len = sizeof(struct sockaddr_in);
    550 #endif
    551     addr->sin_family = AF_INET;
    552     addr->sin_addr.s_addr = pData->bindIP.s_addr;
     540
    553541    fd_nonblock(so->s);
    554     if (bind(so->s, &sa_addr, sizeof(struct sockaddr_in)) < 0)
    555     {
    556         int lasterrno = errno;
    557         closesocket(so->s);
    558         so->s = -1;
    559 #ifdef RT_OS_WINDOWS
    560         WSASetLastError(lasterrno);
    561 #else
    562         errno = lasterrno;
    563 #endif
    564         goto error;
    565     }
     542
     543    status = sobind(pData, so);
     544    if (status != 0)
     545        return status;
     546
    566547    /* success, insert in queue */
    567548    so->so_expire = curtime + SO_EXPIRE;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette