VirtualBox

Changeset 52256 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Aug 3, 2014 12:13:53 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
95347
Message:

NAT: preserve DF (if possible) and TOS when proxying outbound UDP
datagrams.

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

Legend:

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

    r52154 r52256  
    6868
    6969    u_int8_t        so_iptos;    /* Type of service */
     70
     71    uint8_t         so_sottl;    /* cached socket's IP_TTL option */
     72    uint8_t         so_sotos;    /* cached socket's IP_TOS option */
     73    int8_t          so_sodf;     /* cached socket's DF option */
    7074
    7175    u_char          so_type;     /* Type of socket, UDP or TCP */
  • trunk/src/VBox/Devices/Network/slirp/udp.c

    r52113 r52256  
    9393    struct socket *so;
    9494    int ret;
    95     int ttl;
     95    int ttl, tos;
    9696
    9797    LogFlowFunc(("ENTER: m = %p, iphlen = %d\n", m, iphlen));
     
    290290
    291291    ttl = ip->ip_ttl = save_ip.ip_ttl;
    292     ret = setsockopt(so->s, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl));
    293     if (ret < 0)
    294         LogRel(("NAT: Error (%s) occurred while setting TTL(%d) attribute "
    295                 "of IP packet to socket %R[natsock]\n", strerror(errno), ip->ip_ttl, so));
     292    if (ttl != so->so_sottl) {
     293        ret = setsockopt(so->s, IPPROTO_IP, IP_TTL,
     294                         (char *)&ttl, sizeof(ttl));
     295        LogRel(("NAT: IP_TTL: %d -> %d (%d)\n", so->so_sottl, ttl, ret));
     296        if (RT_LIKELY(ret == 0))
     297            so->so_sottl = ttl;
     298    }
     299
     300    tos = save_ip.ip_tos;
     301    if (tos != so->so_sotos) {
     302        ret = setsockopt(so->s, IPPROTO_IP, IP_TOS,
     303                         (char *)&tos, sizeof(tos));
     304        LogRel(("NAT: IP_TOS: %d -> %d (%d)\n", so->so_sotos, tos, ret));
     305        if (RT_LIKELY(ret == 0))
     306            so->so_sotos = tos;
     307    }
     308
     309    {
     310        /*
     311         * Different OSes have different socket options for DF.  We
     312         * can't use IP_HDRINCL here as it's only valid for SOCK_RAW.
     313         */
     314#     define USE_DF_OPTION(_Optname)                    \
     315        const int dfopt = _Optname;                     \
     316        const char * const dfoptname = #_Optname;
     317#if   defined(IP_MTU_DISCOVER)
     318        USE_DF_OPTION(IP_MTU_DISCOVER);
     319#elif defined(IP_DONTFRAG)      /* Solaris 11+, FreeBSD */
     320        USE_DF_OPTION(IP_DONTFRAG);
     321#elif defined(IP_DONTFRAGMENT)  /* Windows */
     322        USE_DF_OPTION(IP_DONTFRAGMENT);
     323#else
     324        USE_DF_OPTION(0);
     325#endif
     326        if (dfopt) {
     327            int df = (save_ip.ip_off & IP_DF) != 0;
     328#if defined(IP_MTU_DISCOVER)
     329            df = df ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
     330#endif
     331            if (df != so->so_sodf) {
     332                ret = setsockopt(so->s, IPPROTO_IP, dfopt,
     333                                 (char *)&df, sizeof(df));
     334                LogRel(("NAT: IP_DF: %d -> %d (%d)\n", so->so_sodf, df, ret));
     335                if (RT_LIKELY(ret == 0))
     336                    so->so_sodf = df;
     337            }
     338        }
     339    }
    296340
    297341    if (   sosendto(pData, so, m) == -1
     
    468512    if ((so->s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    469513        goto error;
     514    so->so_sottl = 0;
     515    so->so_sotos = 0;
     516    so->so_sodf = -1;
    470517    /*
    471518     * Here, we bind() the socket.  Although not really needed
     
    566613    so->so_type = IPPROTO_UDP;
    567614    fd_nonblock(so->s);
     615    so->so_sottl = 0;
     616    so->so_sotos = 0;
     617    so->so_sodf = -1;
    568618    SOCKET_LOCK_CREATE(so);
    569619    QSOCKET_LOCK(udb);
Note: See TracChangeset for help on using the changeset viewer.

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