VirtualBox

忽略:
時間撮記:
2012-1-18 下午06:01:11 (13 年 以前)
作者:
vboxsync
訊息:

IPRT: socket / address resolving fixes.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r39032 r39801  
    5555#include <iprt/asm.h>
    5656#include <iprt/assert.h>
     57#include <iprt/ctype.h>
    5758#include <iprt/err.h>
    5859#include <iprt/mempool.h>
     
    157158{
    158159    struct sockaddr     Addr;
    159     struct sockaddr_in  Ipv4;
     160    struct sockaddr_in  IPv4;
    160161#ifdef IPRT_WITH_TCPIP_V6
    161     struct sockaddr_in6 Ipv6;
     162    struct sockaddr_in6 IPv6;
    162163#endif
    163164} RTSOCKADDRUNION;
     
    239240        RT_ZERO(*pAddr);
    240241        pAddr->enmType      = RTNETADDRTYPE_IPV4;
    241         pAddr->uPort        = RT_N2H_U16(pSrc->Ipv4.sin_port);
    242         pAddr->uAddr.IPv4.u = pSrc->Ipv4.sin_addr.s_addr;
     242        pAddr->uPort        = RT_N2H_U16(pSrc->IPv4.sin_port);
     243        pAddr->uAddr.IPv4.u = pSrc->IPv4.sin_addr.s_addr;
    243244    }
    244245#ifdef IPRT_WITH_TCPIP_V6
     
    248249        RT_ZERO(*pAddr);
    249250        pAddr->enmType            = RTNETADDRTYPE_IPV6;
    250         pAddr->uPort              = RT_N2H_U16(pSrc->Ipv6.sin6_port);
    251         pAddr->uAddr.IPv6.au32[0] = pSrc->Ipv6.sin6_addr.s6_addr32[0];
    252         pAddr->uAddr.IPv6.au32[1] = pSrc->Ipv6.sin6_addr.s6_addr32[1];
    253         pAddr->uAddr.IPv6.au32[2] = pSrc->Ipv6.sin6_addr.s6_addr32[2];
    254         pAddr->uAddr.IPv6.au32[3] = pSrc->Ipv6.sin6_addr.s6_addr32[3];
     251        pAddr->uPort              = RT_N2H_U16(pSrc->IPv6.sin6_port);
     252        pAddr->uAddr.IPv6.au32[0] = pSrc->IPv6.sin6_addr.s6_addr32[0];
     253        pAddr->uAddr.IPv6.au32[1] = pSrc->IPv6.sin6_addr.s6_addr32[1];
     254        pAddr->uAddr.IPv6.au32[2] = pSrc->IPv6.sin6_addr.s6_addr32[2];
     255        pAddr->uAddr.IPv6.au32[3] = pSrc->IPv6.sin6_addr.s6_addr32[3];
    255256    }
    256257#endif
     
    268269 * @param   pDst                The source address.
    269270 * @param   cbSrc               The size of the source address.
    270  */
    271 static int rtSocketAddrFromNetAddr(PCRTNETADDR pAddr, RTSOCKADDRUNION *pDst, size_t cbDst)
     271 * @param   pcbAddr             Where to store the size of the returned address.
     272 *                              Optional
     273 */
     274static int rtSocketAddrFromNetAddr(PCRTNETADDR pAddr, RTSOCKADDRUNION *pDst, size_t cbDst, int *pcbAddr)
    272275{
    273276    RT_BZERO(pDst, cbDst);
     
    276279    {
    277280        pDst->Addr.sa_family       = AF_INET;
    278         pDst->Ipv4.sin_port        = RT_H2N_U16(pAddr->uPort);
    279         pDst->Ipv4.sin_addr.s_addr = pAddr->uAddr.IPv4.u;
     281        pDst->IPv4.sin_port        = RT_H2N_U16(pAddr->uPort);
     282        pDst->IPv4.sin_addr.s_addr = pAddr->uAddr.IPv4.u;
     283        if (pcbAddr)
     284            *pcbAddr = sizeof(pDst->IPv4);
    280285    }
    281286#ifdef IPRT_WITH_TCPIP_V6
     
    284289    {
    285290        pDst->Addr.sa_family              = AF_INET6;
    286         pDst->Ipv6.sin6_port              = RT_H2N_U16(pAddr->uPort);
    287         pSrc->Ipv6.sin6_addr.s6_addr32[0] = pAddr->uAddr.IPv6.au32[0];
    288         pSrc->Ipv6.sin6_addr.s6_addr32[1] = pAddr->uAddr.IPv6.au32[1];
    289         pSrc->Ipv6.sin6_addr.s6_addr32[2] = pAddr->uAddr.IPv6.au32[2];
    290         pSrc->Ipv6.sin6_addr.s6_addr32[3] = pAddr->uAddr.IPv6.au32[3];
     291        pDst->IPv6.sin6_port              = RT_H2N_U16(pAddr->uPort);
     292        pSrc->IPv6.sin6_addr.s6_addr32[0] = pAddr->uAddr.IPv6.au32[0];
     293        pSrc->IPv6.sin6_addr.s6_addr32[1] = pAddr->uAddr.IPv6.au32[1];
     294        pSrc->IPv6.sin6_addr.s6_addr32[2] = pAddr->uAddr.IPv6.au32[2];
     295        pSrc->IPv6.sin6_addr.s6_addr32[3] = pAddr->uAddr.IPv6.au32[3];
     296        if (pcbAddr)
     297            *pcbAddr = sizeof(pDst->IPv6);
    291298    }
    292299#endif
     
    580587}
    581588
     589static bool rtSocketIsIPv4Numerical(const char *pszAddress, PRTNETADDRIPV4 pAddr)
     590{
     591
     592    /* Empty address resolves to the INADDR_ANY address (good for bind). */
     593    if (!*pszAddress)
     594    {
     595        pAddr->u = INADDR_ANY;
     596        return true;
     597    }
     598
     599    /* Four quads? */
     600    char *psz = (char *)pszAddress;
     601    for (int i = 0; i < 4; i++)
     602    {
     603        uint8_t u8;
     604        int rc = RTStrToUInt8Ex(psz, &psz, 0, &u8);
     605        if (rc != VINF_SUCCESS)
     606            return false;
     607        if (*psz != (i < 3 ? '.' : '\0'))
     608            return false;
     609        psz++;
     610
     611        pAddr->au8[i] = u8;             /* big endian */
     612    }
     613
     614    return true;
     615}
    582616
    583617RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRTNETADDR pAddr)
     
    606640
    607641    /*
    608      * Resolve the address.
     642     * Resolve the address. Pretty crude at the moment, but we have to make
     643     * sure to not ask the NT 4 gethostbyname about an IPv4 address as it may
     644     * give a wrong answer.
    609645     */
    610646    /** @todo this only supports IPv4, and IPv6 support needs to be added.
    611      * It probably needs to be converted to getnameinfo(). */
    612     struct hostent *pHostEnt = NULL;
     647     * It probably needs to be converted to getaddrinfo(). */
     648    RTNETADDRIPV4 IPv4Quad;
     649    if (rtSocketIsIPv4Numerical(pszAddress, &IPv4Quad))
     650    {
     651        RT_ZERO(*pAddr);
     652        pAddr->enmType      = RTNETADDRTYPE_IPV4;
     653        pAddr->uPort        = uPort;
     654        pAddr->uAddr.IPv4   = IPv4Quad;
     655        return VINF_SUCCESS;
     656    }
     657
     658    struct hostent *pHostEnt;
    613659    pHostEnt = gethostbyname(pszAddress);
    614660    if (!pHostEnt)
    615661    {
    616         struct in_addr InAddr;
    617         InAddr.s_addr = inet_addr(pszAddress);
    618         pHostEnt = gethostbyaddr((char *)&InAddr, 4, AF_INET);
    619         if (!pHostEnt)
    620         {
    621             rc = rtSocketResolverError();
    622             AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
    623             return rc;
    624         }
     662        rc = rtSocketResolverError();
     663        AssertMsgFailed(("Could not resolve '%s', rc=%Rrc\n", pszAddress, rc));
     664        return rc;
    625665    }
    626666
     
    857897    if (pAddr)
    858898    {
    859         rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u));
     899        rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), NULL);
    860900        if (RT_FAILURE(rc))
    861901            return rc;
     
    13931433 * @returns IPRT status code.
    13941434 * @param   hSocket             The socket handle.
    1395  * @param   pAddr               The socket address to bind to.
    1396  * @param   cbAddr              The size of the address structure @a pAddr
    1397  *                              points to.
    1398  */
    1399 int rtSocketBind(RTSOCKET hSocket, const struct sockaddr *pAddr, int cbAddr)
     1435 * @param   pAddr               The address to bind to.
     1436 */
     1437int rtSocketBind(RTSOCKET hSocket, PCRTNETADDR pAddr)
    14001438{
    14011439    /*
     
    14071445    AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
    14081446
    1409     int rc = VINF_SUCCESS;
    1410     if (bind(pThis->hNative, pAddr, cbAddr) != 0)
    1411         rc = rtSocketError();
     1447    RTSOCKADDRUNION u;
     1448    int             cbAddr;
     1449    int rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), &cbAddr);
     1450    if (RT_SUCCESS(rc))
     1451    {
     1452        if (bind(pThis->hNative, &u.Addr, cbAddr) != 0)
     1453            rc = rtSocketError();
     1454    }
    14121455
    14131456    rtSocketUnlock(pThis);
     
    15081551 * @param   hSocket             The socket handle.
    15091552 * @param   pAddr               The socket address to connect to.
    1510  * @param   cbAddr              The size of the address structure @a pAddr
    1511  *                              points to.
    1512  */
    1513 int rtSocketConnect(RTSOCKET hSocket, const struct sockaddr *pAddr, int cbAddr)
     1553 */
     1554int rtSocketConnect(RTSOCKET hSocket, PCRTNETADDR pAddr)
    15141555{
    15151556    /*
     
    15211562    AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS);
    15221563
    1523     int rc = VINF_SUCCESS;
    1524     if (connect(pThis->hNative, pAddr, cbAddr) != 0)
    1525         rc = rtSocketError();
     1564    RTSOCKADDRUNION u;
     1565    int             cbAddr;
     1566    int rc = rtSocketAddrFromNetAddr(pAddr, &u, sizeof(u), &cbAddr);
     1567    if (RT_SUCCESS(rc))
     1568    {
     1569Log(("Calling connect()...\n%.*Rhxs\n", cbAddr, &u));
     1570        if (connect(pThis->hNative, &u.Addr, cbAddr) != 0)
     1571            rc = rtSocketError();
     1572    }
    15261573
    15271574    rtSocketUnlock(pThis);
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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