|
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 { address = his.address; } |
|
19 |
|
20 RCNetAddr::RCNetAddr(const RCNetAddr& his, PRUint16 port): RCBase() |
|
21 { |
|
22 address = his.address; |
|
23 switch (address.raw.family) |
|
24 { |
|
25 case PR_AF_INET: address.inet.port = port; break; |
|
26 case PR_AF_INET6: address.ipv6.port = port; break; |
|
27 default: break; |
|
28 } |
|
29 } /* RCNetAddr::RCNetAddr */ |
|
30 |
|
31 RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase() |
|
32 { |
|
33 PRNetAddrValue how; |
|
34 switch (host) |
|
35 { |
|
36 case RCNetAddr::any: how = PR_IpAddrAny; break; |
|
37 case RCNetAddr::loopback: how = PR_IpAddrLoopback; break; |
|
38 default: PR_ASSERT(!"This can't happen -- and did!"); |
|
39 } |
|
40 (void)PR_InitializeNetAddr(how, port, &address); |
|
41 } /* RCNetAddr::RCNetAddr */ |
|
42 |
|
43 RCNetAddr::~RCNetAddr() { } |
|
44 |
|
45 void RCNetAddr::operator=(const RCNetAddr& his) { address = his.address; } |
|
46 |
|
47 PRStatus RCNetAddr::FromString(const char* string) |
|
48 { return PR_StringToNetAddr(string, &address); } |
|
49 |
|
50 void RCNetAddr::operator=(const PRNetAddr* addr) { address = *addr; } |
|
51 |
|
52 PRBool RCNetAddr::operator==(const RCNetAddr& his) const |
|
53 { |
|
54 PRBool rv = EqualHost(his); |
|
55 if (rv) |
|
56 { |
|
57 switch (address.raw.family) |
|
58 { |
|
59 case PR_AF_INET: |
|
60 rv = (address.inet.port == his.address.inet.port); break; |
|
61 case PR_AF_INET6: |
|
62 rv = (address.ipv6.port == his.address.ipv6.port); break; |
|
63 case PR_AF_LOCAL: |
|
64 default: break; |
|
65 } |
|
66 } |
|
67 return rv; |
|
68 } /* RCNetAddr::operator== */ |
|
69 |
|
70 PRBool RCNetAddr::EqualHost(const RCNetAddr& his) const |
|
71 { |
|
72 PRBool rv; |
|
73 switch (address.raw.family) |
|
74 { |
|
75 case PR_AF_INET: |
|
76 rv = (address.inet.ip == his.address.inet.ip); break; |
|
77 case PR_AF_INET6: |
|
78 rv = (0 == memcmp( |
|
79 &address.ipv6.ip, &his.address.ipv6.ip, |
|
80 sizeof(address.ipv6.ip))); |
|
81 break; |
|
82 #if defined(XP_UNIX) |
|
83 case PR_AF_LOCAL: |
|
84 rv = (0 == strncmp( |
|
85 address.local.path, his.address.local.path, |
|
86 sizeof(address.local.path))); |
|
87 break; |
|
88 #endif |
|
89 default: break; |
|
90 } |
|
91 return rv; |
|
92 } /* RCNetAddr::operator== */ |
|
93 |
|
94 PRStatus RCNetAddr::ToString(char *string, PRSize size) const |
|
95 { return PR_NetAddrToString(&address, string, size); } |
|
96 |
|
97 /* |
|
98 ** RCHostLookup |
|
99 */ |
|
100 |
|
101 RCHostLookup::~RCHostLookup() |
|
102 { |
|
103 if (NULL != address) delete [] address; |
|
104 } /* RCHostLookup::~RCHostLookup */ |
|
105 |
|
106 RCHostLookup::RCHostLookup(): RCBase() |
|
107 { |
|
108 address = NULL; |
|
109 max_index = 0; |
|
110 } /* RCHostLookup::RCHostLookup */ |
|
111 |
|
112 PRStatus RCHostLookup::ByName(const char* name) |
|
113 { |
|
114 PRStatus rv; |
|
115 PRNetAddr addr; |
|
116 PRHostEnt hostentry; |
|
117 PRIntn index = 0, max; |
|
118 RCNetAddr* vector = NULL; |
|
119 RCNetAddr* old_vector = NULL; |
|
120 void* buffer = PR_Malloc(PR_NETDB_BUF_SIZE); |
|
121 if (NULL == buffer) return PR_FAILURE; |
|
122 rv = PR_GetHostByName(name, (char*)buffer, PR_NETDB_BUF_SIZE, &hostentry); |
|
123 if (PR_SUCCESS == rv) |
|
124 { |
|
125 for (max = 0, index = 0;; ++max) |
|
126 { |
|
127 index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); |
|
128 if (0 == index) break; |
|
129 } |
|
130 if (max > 0) |
|
131 { |
|
132 vector = new RCNetAddr[max]; |
|
133 while (--max > 0) |
|
134 { |
|
135 index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); |
|
136 if (0 == index) break; |
|
137 vector[index] = &addr; |
|
138 } |
|
139 { |
|
140 RCEnter entry(&ml); |
|
141 old_vector = address; |
|
142 address = vector; |
|
143 max_index = max; |
|
144 } |
|
145 if (NULL != old_vector) delete [] old_vector; |
|
146 } |
|
147 } |
|
148 if (NULL != buffer) PR_DELETE(buffer); |
|
149 return PR_SUCCESS; |
|
150 } /* RCHostLookup::ByName */ |
|
151 |
|
152 PRStatus RCHostLookup::ByAddress(const RCNetAddr& host_addr) |
|
153 { |
|
154 PRStatus rv; |
|
155 PRNetAddr addr; |
|
156 PRHostEnt hostentry; |
|
157 PRIntn index = 0, max; |
|
158 RCNetAddr* vector = NULL; |
|
159 RCNetAddr* old_vector = NULL; |
|
160 char *buffer = (char*)PR_Malloc(PR_NETDB_BUF_SIZE); |
|
161 if (NULL == buffer) return PR_FAILURE; |
|
162 rv = PR_GetHostByAddr(host_addr, buffer, PR_NETDB_BUF_SIZE, &hostentry); |
|
163 if (PR_SUCCESS == rv) |
|
164 { |
|
165 for (max = 0, index = 0;; ++max) |
|
166 { |
|
167 index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); |
|
168 if (0 == index) break; |
|
169 } |
|
170 if (max > 0) |
|
171 { |
|
172 vector = new RCNetAddr[max]; |
|
173 while (--max > 0) |
|
174 { |
|
175 index = PR_EnumerateHostEnt(index, &hostentry, 0, &addr); |
|
176 if (0 == index) break; |
|
177 vector[index] = &addr; |
|
178 } |
|
179 { |
|
180 RCEnter entry(&ml); |
|
181 old_vector = address; |
|
182 address = vector; |
|
183 max_index = max; |
|
184 } |
|
185 if (NULL != old_vector) delete [] old_vector; |
|
186 } |
|
187 } |
|
188 if (NULL != buffer) PR_DELETE(buffer); |
|
189 return PR_SUCCESS; |
|
190 } /* RCHostLookup::ByAddress */ |
|
191 |
|
192 const RCNetAddr* RCHostLookup::operator[](PRUintn which) |
|
193 { |
|
194 RCNetAddr* addr = NULL; |
|
195 if (which < max_index) |
|
196 addr = &address[which]; |
|
197 return addr; |
|
198 } /* RCHostLookup::operator[] */ |
|
199 |
|
200 /* RCNetdb.cpp */ |