VirtualBox

Ignore:
Timestamp:
Jun 9, 2014 10:32:05 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
94286
Message:

NAT/Net: Start untangling errno vs. winsock mess. Don't refer errno
directly, while here convert some perror() calls to DPRINTFs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/NetworkServices/NAT/proxy.c

    r51576 r51581  
    3535#endif
    3636
     37static FNRTSTRFORMATTYPE proxy_sockerr_rtstrfmt;
     38
    3739static SOCKET proxy_create_socket(int, int);
    3840
     
    4244/* XXX: for mapping loopbacks to addresses in our network (ip4) */
    4345struct netif *g_proxy_netif;
     46
     47
    4448/*
    4549 * Called on the lwip thread (aka tcpip thread) from tcpip_init() via
     
    5559    LWIP_UNUSED_ARG(proxy_netif);
    5660
     61    status = RTStrFormatTypeRegister("sockerr", proxy_sockerr_rtstrfmt, NULL);
     62    AssertRC(status);
     63
    5764    g_proxy_options = opts;
    5865    g_proxy_netif = proxy_netif;
     
    99106    }
    100107}
     108
     109
     110#if !defined(RT_OS_WINDOWS)
     111/**
     112 * Formatter for %R[sockerr] - unix strerror_r() version.
     113 */
     114static DECLCALLBACK(size_t)
     115proxy_sockerr_rtstrfmt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
     116                       const char *pszType, const void *pvValue,
     117                       int cchWidth, int cchPrecision, unsigned int fFlags,
     118                       void *pvUser)
     119{
     120    const int error = (int)(intptr_t)pvValue;
     121    size_t cb = 0;
     122
     123    const char *msg = NULL;
     124    char buf[128];
     125
     126    NOREF(cchWidth);
     127    NOREF(cchPrecision);
     128    NOREF(fFlags);
     129    NOREF(pvUser);
     130
     131    AssertReturn(strcmp(pszType, "sockerr") == 0, 0);
     132
     133    /* make sure return type mismatch is caught */
     134#if defined(RT_OS_LINUX) && defined(_GNU_SOURCE)
     135    msg = strerror_r(error, buf, sizeof(buf));
     136#else
     137    {
     138        int status = strerror_r(error, buf, sizeof(buf));
     139        msg = buf;
     140    }
     141#endif
     142    return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%s", msg);
     143}
     144
     145#else /* RT_OS_WINDOWS */
     146
     147/**
     148 * Formatter for %R[sockerr] - windows FormatMessage() version.
     149 */
     150static DECLCALLBACK(size_t)
     151proxy_sockerr_rtstrfmt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
     152                       const char *pszType, const void *pvValue,
     153                       int cchWidth, int cchPrecision, unsigned int fFlags,
     154                       void *pvUser)
     155{
     156    const int error = (int)(intptr_t)pvValue;
     157    size_t cb = 0;
     158
     159    NOREF(cchWidth);
     160    NOREF(cchPrecision);
     161    NOREF(fFlags);
     162    NOREF(pvUser);
     163
     164    AssertReturn(strcmp(pszType, "sockerr") == 0, 0);
     165
     166    /*
     167     * XXX: Windows strerror() doesn't handle posix error codes, but
     168     * since winsock uses its own, it shouldn't be much of a problem.
     169     * If you see a strange error message, it's probably from
     170     * FormatMessage() for an error from <WinError.h> that has the
     171     * same numeric value.
     172     */
     173    if (error < _sys_nerr) {
     174        char buf[128] = "";
     175        int status;
     176
     177        status = strerror_s(buf, sizeof(buf), error);
     178        if (status == 0) {
     179            if (strcmp(buf, "Unknown error") == 0) {
     180                /* windows strerror() doesn't add the numeric value */
     181                cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL,
     182                                  "Unknown error: %d", error);
     183            }
     184            else {
     185                cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL,
     186                                  "%s", buf);
     187            }
     188        }
     189        else {
     190            cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL,
     191                              "Unknown error: %d", error);
     192        }
     193    }
     194    else {
     195        DWORD nchars;
     196        char *msg = NULL;
     197
     198        nchars = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
     199                                | FORMAT_MESSAGE_ALLOCATE_BUFFER,
     200                                NULL, error, LANG_NEUTRAL,
     201                                (LPSTR)&msg, 0,
     202                                NULL);
     203        if (nchars <= 0 || msg == NULL) {
     204            cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL,
     205                              "Unknown error: %d", error);
     206        }
     207        else {
     208            /* FormatMessage() "helpfully" adds newline; get rid of it */
     209            char *crpos = strchr(msg, '\r');
     210            if (crpos != NULL) {
     211                *crpos = '\0';
     212            }
     213
     214            cb += RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL,
     215                              "%s", msg);
     216        }
     217
     218        if (msg != NULL) {
     219            LocalFree(msg);
     220        }
     221    }
     222
     223    return cb;
     224}
     225#endif /* RT_OS_WINDOWS */
    101226
    102227
     
    300425        status = bind(s, psrc_sa, src_sa_len);
    301426        if (status == SOCKET_ERROR) {
    302             DPRINTF(("socket %d: bind: %s\n", s, strerror(errno)));
     427            DPRINTF(("socket %d: bind: %R[sockerr]\n", s, SOCKERRNO()));
    303428            closesocket(s);
    304429            return INVALID_SOCKET;
     
    307432
    308433    status = connect(s, pdst_sa, dst_sa_len);
    309     if (status == SOCKET_ERROR && errno != EINPROGRESS) {
    310         DPRINTF(("socket %d: connect: %s\n", s, strerror(errno)));
     434    if (status == SOCKET_ERROR && SOCKERRNO() != EINPROGRESS) {
     435        DPRINTF(("socket %d: connect: %R[sockerr]\n", s, SOCKERRNO()));
    311436        closesocket(s);
    312437        return INVALID_SOCKET;
     
    421546        dyniov = (IOVEC *)malloc(clen * sizeof(*dyniov));
    422547        if (dyniov == NULL) {
    423             error = -errno;
     548            error = -errno;     /* sic: not a socket error */
    424549            goto out;
    425550        }
     
    447572
    448573    nsent = sendmsg(sock, &mh, 0);
    449     if (nsent < 0) {
    450         error = -errno;
    451         DPRINTF(("%s: fd %d: sendmsg errno %d\n",
    452                  __func__, sock, errno));
    453     }
    454574#else
    455575    rc = WSASendTo(sock, iov, (DWORD)clen, &nsent, 0,
    456576                   name, (int)namelen, NULL, NULL);
    457577    if (rc == SOCKET_ERROR) {
    458          DPRINTF(("%s: fd %d: sendmsg errno %d\n",
    459                   __func__, sock, WSAGetLastError()));
    460          error = -WSAGetLastError();
    461     }
    462 #endif
     578        nsent = -1;
     579    }
     580#endif
     581    if (nsent < 0) {
     582        error = SOCKERRNO();
     583        DPRINTF(("%s: socket %d: sendmsg: %R[sockerr]\n",
     584                 __func__, sock, error));
     585        error = -error;
     586    }
    463587
    464588  out:
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