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 */