tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rcnetdb.cpp (6026B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 /*
      7 ** Base class implementation for network access functions (ref: prnetdb.h)
      8 */
      9 
     10 #include "rclock.h"
     11 #include "rcnetdb.h"
     12 
     13 #include <prmem.h>
     14 #include <prlog.h>
     15 #include <string.h>
     16 
     17 RCNetAddr::RCNetAddr(const RCNetAddr& his): RCBase()
     18 {
     19    address = his.address;
     20 }
     21 
     22 RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase()
     23 {
     24    address = his.address;
     25    switch (address.raw.family)
     26    {
     27        case PR_AF_INET: address.inet.port = port; break;
     28        case PR_AF_INET6: address.ipv6.port = port; break;
     29        default: break;
     30    }
     31 }  /* RCNetAddr::RCNetAddr */
     32 
     33 RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase()
     34 {
     35    PRNetAddrValue how;
     36    switch (host)
     37    {
     38        case RCNetAddr::any: how = PR_IpAddrAny; break;
     39        case RCNetAddr::loopback: how = PR_IpAddrLoopback; break;
     40        default: PR_NOT_REACHED("This can't happen -- and did!");
     41    }
     42    (void)PR_InitializeNetAddr(how, port, &address);
     43 }  /* RCNetAddr::RCNetAddr */
     44 
     45 RCNetAddr::~RCNetAddr() { }
     46 
     47 void RCNetAddr::operator=(const RCNetAddr& his) {
     48    address = his.address;
     49 }
     50 
     51 PRStatus RCNetAddr::FromString(const char* string)
     52 {
     53    return PR_StringToNetAddr(string, &address);
     54 }
     55 
     56 void RCNetAddr::operator=(const PRNetAddr* addr) {
     57    address = *addr;
     58 }
     59 
     60 PRBool RCNetAddr::operator==(const RCNetAddr& his) const
     61 {
     62    PRBool rv = EqualHost(his);
     63    if (rv)
     64    {
     65        switch (address.raw.family)
     66        {
     67            case PR_AF_INET:
     68                rv = (address.inet.port == his.address.inet.port); break;
     69            case PR_AF_INET6:
     70                rv = (address.ipv6.port == his.address.ipv6.port); break;
     71            case PR_AF_LOCAL:
     72            default: break;
     73        }
     74    }
     75    return rv;
     76 }  /* RCNetAddr::operator== */
     77 
     78 PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const
     79 {
     80    PRBool rv;
     81    switch (address.raw.family)
     82    {
     83        case PR_AF_INET:
     84            rv = (address.inet.ip == his.address.inet.ip); break;
     85        case PR_AF_INET6:
     86            rv = (0 == memcmp(
     87                      &address.ipv6.ip, &his.address.ipv6.ip,
     88                      sizeof(address.ipv6.ip)));
     89            break;
     90 #if defined(XP_UNIX)
     91        case PR_AF_LOCAL:
     92            rv = (0 == strncmp(
     93                      address.local.path, his.address.local.path,
     94                      sizeof(address.local.path)));
     95            break;
     96 #endif
     97        default: break;
     98    }
     99    return rv;
    100 }  /* RCNetAddr::operator== */
    101 
    102 PRStatus RCNetAddr::ToString(char *string, PRSize size) const
    103 {
    104    return PR_NetAddrToString(&address, string, size);
    105 }
    106 
    107 /*
    108 ** RCHostLookup
    109 */
    110 
    111 RCHostLookup::~RCHostLookup()
    112 {
    113    if (NULL != address) {
    114        delete [] address;
    115    }
    116 }  /* RCHostLookup::~RCHostLookup */
    117 
    118 RCHostLookup::RCHostLookup(): RCBase()
    119 {
    120    address = NULL;
    121    max_index = 0;
    122 }  /* RCHostLookup::RCHostLookup */
    123 
    124 PRStatus RCHostLookup::ByName(const char* name)
    125 {
    126    PRStatus rv;
    127    PRNetAddr addr;
    128    PRHostEnt hostentry;
    129    PRIntn index = 0, max;
    130    RCNetAddr* vector = NULL;
    131    RCNetAddr* old_vector = NULL;
    132    void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE);
    133    if (NULL == buffer) {
    134        return PR_FAILURE;
    135    }
    136    rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry);
    137    if (PR_SUCCESS == rv)
    138    {
    139        for (max = 0, index = 0;; ++max)
    140        {
    141            index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
    142            if (0 == index) {
    143                break;
    144            }
    145        }
    146        if (max > 0)
    147        {
    148            vector = new RCNetAddr[max];
    149            while (--max > 0)
    150            {
    151                index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
    152                if (0 == index) {
    153                    break;
    154                }
    155                vector[index] = &addr;
    156            }
    157            {
    158                RCEnter entry(&ml);
    159                old_vector = address;
    160                address = vector;
    161                max_index = max;
    162            }
    163            if (NULL != old_vector) {
    164                delete [] old_vector;
    165            }
    166        }
    167    }
    168    if (NULL != buffer) {
    169        PR_DELETE(buffer);
    170    }
    171    return PR_SUCCESS;
    172 }  /* RCHostLookup::ByName */
    173 
    174 PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr)
    175 {
    176    PRStatus rv;
    177    PRNetAddr addr;
    178    PRHostEnt hostentry;
    179    PRIntn index = 0, max;
    180    RCNetAddr* vector = NULL;
    181    RCNetAddr* old_vector = NULL;
    182    char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE);
    183    if (NULL == buffer) {
    184        return PR_FAILURE;
    185    }
    186    rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry);
    187    if (PR_SUCCESS == rv)
    188    {
    189        for (max = 0, index = 0;; ++max)
    190        {
    191            index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
    192            if (0 == index) {
    193                break;
    194            }
    195        }
    196        if (max > 0)
    197        {
    198            vector = new RCNetAddr[max];
    199            while (--max > 0)
    200            {
    201                index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr);
    202                if (0 == index) {
    203                    break;
    204                }
    205                vector[index] = &addr;
    206            }
    207            {
    208                RCEnter entry(&ml);
    209                old_vector = address;
    210                address = vector;
    211                max_index = max;
    212            }
    213            if (NULL != old_vector) {
    214                delete [] old_vector;
    215            }
    216        }
    217    }
    218    if (NULL != buffer) {
    219        PR_DELETE(buffer);
    220    }
    221    return PR_SUCCESS;
    222 }  /* RCHostLookup::ByAddress */
    223 
    224 const RCNetAddr* RCHostLookup::operator[](PRUintn which)
    225 {
    226    RCNetAddr* addr = NULL;
    227    if (which < max_index) {
    228        addr = &address[which];
    229    }
    230    return addr;
    231 }  /* RCHostLookup::operator[] */
    232 
    233 /* RCNetdb.cpp */