]>
Commit | Line | Data |
---|---|---|
2923e03f AT |
1 | /* |
2 | * This file is part of PowerDNS or dnsdist. | |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
22 | #ifdef HAVE_CONFIG_H | |
23 | #include "config.h" | |
24 | #endif | |
25 | #include "geoipbackend.hh" | |
26 | #include "geoipinterface.hh" | |
e3808f5e | 27 | #ifdef HAVE_GEOIP |
2923e03f | 28 | #include "GeoIPCity.h" |
68917ab7 | 29 | #include "GeoIP.h" |
2923e03f | 30 | |
ff05c7e1 O |
31 | struct geoip_deleter |
32 | { | |
33 | void operator()(GeoIP* ptr) | |
34 | { | |
68917ab7 CHB |
35 | if (ptr) { |
36 | GeoIP_delete(ptr); | |
37 | } | |
2923e03f AT |
38 | }; |
39 | }; | |
40 | ||
ff05c7e1 O |
41 | struct geoiprecord_deleter |
42 | { | |
43 | void operator()(GeoIPRecord* ptr) | |
44 | { | |
68917ab7 CHB |
45 | if (ptr) { |
46 | GeoIPRecord_delete(ptr); | |
47 | } | |
48 | } | |
49 | }; | |
50 | ||
ff05c7e1 O |
51 | struct geoipregion_deleter |
52 | { | |
53 | void operator()(GeoIPRegion* ptr) | |
54 | { | |
68917ab7 CHB |
55 | if (ptr) { |
56 | GeoIPRegion_delete(ptr); | |
57 | } | |
58 | } | |
59 | }; | |
60 | ||
ff05c7e1 O |
61 | class GeoIPInterfaceDAT : public GeoIPInterface |
62 | { | |
2923e03f | 63 | public: |
ff05c7e1 O |
64 | GeoIPInterfaceDAT(const string& fname, const string& modeStr) |
65 | { | |
2923e03f AT |
66 | int flags; |
67 | if (modeStr == "standard") | |
68 | flags = GEOIP_STANDARD; | |
69 | else if (modeStr == "memory") | |
70 | flags = GEOIP_MEMORY_CACHE; | |
71 | else if (modeStr == "index") | |
72 | flags = GEOIP_INDEX_CACHE; | |
68917ab7 | 73 | #ifdef HAVE_MMAP |
2923e03f AT |
74 | else if (modeStr == "mmap") |
75 | flags = GEOIP_MMAP_CACHE; | |
68917ab7 | 76 | #endif |
2923e03f AT |
77 | else |
78 | throw PDNSException("Invalid cache mode " + modeStr + " for GeoIP backend"); | |
79 | ||
68917ab7 CHB |
80 | d_gi = std::unique_ptr<GeoIP, geoip_deleter>(GeoIP_open(fname.c_str(), flags)); |
81 | if (d_gi.get() == nullptr) | |
2923e03f AT |
82 | throw PDNSException("Cannot open GeoIP database " + fname); |
83 | d_db_type = GeoIP_database_edition(d_gi.get()); | |
84 | } | |
85 | ||
ff05c7e1 O |
86 | bool queryCountry(string& ret, GeoIPNetmask& gl, const string& ip) override |
87 | { | |
23c4de63 AT |
88 | GeoIPLookup tmp_gl = { |
89 | .netmask = gl.netmask, | |
90 | }; | |
ff05c7e1 | 91 | if (d_db_type == GEOIP_COUNTRY_EDITION || d_db_type == GEOIP_LARGE_COUNTRY_EDITION) { |
bf082a1e AT |
92 | int id; |
93 | if ((id = GeoIP_id_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) { | |
94 | ret = GeoIP_code3_by_id(id); | |
95 | gl.netmask = tmp_gl.netmask; | |
96 | return true; | |
97 | } | |
ff05c7e1 O |
98 | } |
99 | else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { | |
68917ab7 | 100 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 101 | if (gir) { |
23c4de63 | 102 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
103 | ret = GeoIP_code3_by_id(GeoIP_id_by_code(gir->country_code)); |
104 | return true; | |
105 | } | |
ff05c7e1 O |
106 | } |
107 | else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) { | |
68917ab7 | 108 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str())); |
2923e03f AT |
109 | if (gir) { |
110 | ret = gir->country_code3; | |
23c4de63 | 111 | gl.netmask = gir->netmask; |
2923e03f AT |
112 | return true; |
113 | } | |
114 | } | |
115 | return false; | |
116 | } | |
117 | ||
ff05c7e1 O |
118 | bool queryCountryV6(string& ret, GeoIPNetmask& gl, const string& ip) override |
119 | { | |
23c4de63 AT |
120 | GeoIPLookup tmp_gl = { |
121 | .netmask = gl.netmask, | |
122 | }; | |
ff05c7e1 | 123 | if (d_db_type == GEOIP_COUNTRY_EDITION_V6 || d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) { |
bf082a1e AT |
124 | int id; |
125 | if ((id = GeoIP_id_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) { | |
126 | ret = GeoIP_code3_by_id(id); | |
127 | gl.netmask = tmp_gl.netmask; | |
128 | return true; | |
129 | } | |
ff05c7e1 O |
130 | } |
131 | else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { | |
68917ab7 | 132 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 133 | if (gir) { |
23c4de63 | 134 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
135 | ret = GeoIP_code3_by_id(GeoIP_id_by_code(gir->country_code)); |
136 | return true; | |
137 | } | |
ff05c7e1 O |
138 | } |
139 | else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) { | |
68917ab7 | 140 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str())); |
2923e03f AT |
141 | if (gir) { |
142 | ret = gir->country_code3; | |
23c4de63 | 143 | gl.netmask = gir->netmask; |
2923e03f AT |
144 | return true; |
145 | } | |
146 | } | |
147 | return false; | |
148 | } | |
149 | ||
ff05c7e1 O |
150 | bool queryCountry2(string& ret, GeoIPNetmask& gl, const string& ip) override |
151 | { | |
23c4de63 AT |
152 | GeoIPLookup tmp_gl = { |
153 | .netmask = gl.netmask, | |
154 | }; | |
ff05c7e1 | 155 | if (d_db_type == GEOIP_COUNTRY_EDITION || d_db_type == GEOIP_LARGE_COUNTRY_EDITION) { |
bf082a1e AT |
156 | int id; |
157 | if ((id = GeoIP_id_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) { | |
158 | ret = GeoIP_code_by_id(id); | |
159 | gl.netmask = tmp_gl.netmask; | |
160 | return true; | |
161 | } | |
ff05c7e1 O |
162 | } |
163 | else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { | |
164 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)); | |
2923e03f | 165 | if (gir) { |
23c4de63 | 166 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
167 | ret = GeoIP_code_by_id(GeoIP_id_by_code(gir->country_code)); |
168 | return true; | |
169 | } | |
ff05c7e1 O |
170 | } |
171 | else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) { | |
68917ab7 | 172 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str())); |
2923e03f AT |
173 | if (gir) { |
174 | ret = gir->country_code; | |
23c4de63 | 175 | gl.netmask = gir->netmask; |
2923e03f AT |
176 | return true; |
177 | } | |
178 | } | |
179 | return false; | |
180 | } | |
181 | ||
ff05c7e1 O |
182 | bool queryCountry2V6(string& ret, GeoIPNetmask& gl, const string& ip) override |
183 | { | |
23c4de63 AT |
184 | GeoIPLookup tmp_gl = { |
185 | .netmask = gl.netmask, | |
186 | }; | |
ff05c7e1 | 187 | if (d_db_type == GEOIP_COUNTRY_EDITION_V6 || d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) { |
bf082a1e AT |
188 | int id; |
189 | if ((id = GeoIP_id_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) { | |
190 | ret = GeoIP_code_by_id(id); | |
191 | gl.netmask = tmp_gl.netmask; | |
192 | return true; | |
193 | } | |
ff05c7e1 O |
194 | } |
195 | else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { | |
68917ab7 | 196 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 197 | if (gir) { |
23c4de63 | 198 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
199 | ret = GeoIP_code_by_id(GeoIP_id_by_code(gir->country_code)); |
200 | return true; | |
201 | } | |
ff05c7e1 O |
202 | } |
203 | else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) { | |
68917ab7 | 204 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str())); |
2923e03f AT |
205 | if (gir) { |
206 | ret = gir->country_code; | |
23c4de63 | 207 | gl.netmask = gir->netmask; |
2923e03f AT |
208 | return true; |
209 | } | |
210 | } | |
211 | return false; | |
212 | } | |
213 | ||
ff05c7e1 O |
214 | bool queryContinent(string& ret, GeoIPNetmask& gl, const string& ip) override |
215 | { | |
23c4de63 AT |
216 | GeoIPLookup tmp_gl = { |
217 | .netmask = gl.netmask, | |
218 | }; | |
ff05c7e1 | 219 | if (d_db_type == GEOIP_COUNTRY_EDITION || d_db_type == GEOIP_LARGE_COUNTRY_EDITION) { |
bf082a1e AT |
220 | int id; |
221 | if ((id = GeoIP_id_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) { | |
222 | ret = GeoIP_continent_by_id(id); | |
223 | gl.netmask = tmp_gl.netmask; | |
224 | return true; | |
225 | } | |
ff05c7e1 O |
226 | } |
227 | else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { | |
68917ab7 | 228 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 229 | if (gir) { |
23c4de63 | 230 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
231 | ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code)); |
232 | return true; | |
233 | } | |
ff05c7e1 O |
234 | } |
235 | else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) { | |
68917ab7 | 236 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str())); |
2923e03f | 237 | if (gir) { |
ff05c7e1 | 238 | ret = ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code)); |
23c4de63 | 239 | gl.netmask = gir->netmask; |
2923e03f AT |
240 | return true; |
241 | } | |
242 | } | |
243 | return false; | |
244 | } | |
245 | ||
ff05c7e1 O |
246 | bool queryContinentV6(string& ret, GeoIPNetmask& gl, const string& ip) override |
247 | { | |
23c4de63 AT |
248 | GeoIPLookup tmp_gl = { |
249 | .netmask = gl.netmask, | |
250 | }; | |
ff05c7e1 | 251 | if (d_db_type == GEOIP_COUNTRY_EDITION_V6 || d_db_type == GEOIP_LARGE_COUNTRY_EDITION_V6) { |
bf082a1e AT |
252 | int id; |
253 | if ((id = GeoIP_id_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)) > 0) { | |
254 | ret = GeoIP_continent_by_id(id); | |
255 | gl.netmask = tmp_gl.netmask; | |
256 | return true; | |
257 | } | |
ff05c7e1 O |
258 | } |
259 | else if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { | |
68917ab7 | 260 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 261 | if (gir) { |
23c4de63 | 262 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
263 | ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code)); |
264 | return true; | |
265 | } | |
ff05c7e1 O |
266 | } |
267 | else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) { | |
68917ab7 | 268 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str())); |
2923e03f AT |
269 | if (gir) { |
270 | ret = GeoIP_continent_by_id(GeoIP_id_by_code(gir->country_code)); | |
23c4de63 | 271 | gl.netmask = gir->netmask; |
2923e03f AT |
272 | return true; |
273 | } | |
274 | } | |
275 | return false; | |
276 | } | |
277 | ||
ff05c7e1 O |
278 | bool queryName(string& ret, GeoIPNetmask& gl, const string& ip) override |
279 | { | |
23c4de63 AT |
280 | GeoIPLookup tmp_gl = { |
281 | .netmask = gl.netmask, | |
282 | }; | |
ff05c7e1 | 283 | if (d_db_type == GEOIP_ISP_EDITION || d_db_type == GEOIP_ORG_EDITION) { |
68917ab7 CHB |
284 | char* result = GeoIP_name_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl); |
285 | if (result != nullptr) { | |
286 | ret = result; | |
287 | free(result); | |
23c4de63 | 288 | gl.netmask = tmp_gl.netmask; |
2923e03f | 289 | // reduce space to dash |
68917ab7 | 290 | ret = boost::replace_all_copy(ret, " ", "-"); |
2923e03f AT |
291 | return true; |
292 | } | |
293 | } | |
294 | return false; | |
295 | } | |
296 | ||
ff05c7e1 O |
297 | bool queryNameV6(string& ret, GeoIPNetmask& gl, const string& ip) override |
298 | { | |
23c4de63 AT |
299 | GeoIPLookup tmp_gl = { |
300 | .netmask = gl.netmask, | |
301 | }; | |
ff05c7e1 | 302 | if (d_db_type == GEOIP_ISP_EDITION_V6 || d_db_type == GEOIP_ORG_EDITION_V6) { |
68917ab7 CHB |
303 | char* result = GeoIP_name_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl); |
304 | if (result != nullptr) { | |
305 | ret = result; | |
306 | free(result); | |
23c4de63 | 307 | gl.netmask = tmp_gl.netmask; |
2923e03f | 308 | // reduce space to dash |
68917ab7 | 309 | ret = boost::replace_all_copy(ret, " ", "-"); |
2923e03f AT |
310 | return true; |
311 | } | |
312 | } | |
313 | return false; | |
314 | } | |
315 | ||
ff05c7e1 O |
316 | bool queryASnum(string& ret, GeoIPNetmask& gl, const string& ip) override |
317 | { | |
23c4de63 AT |
318 | GeoIPLookup tmp_gl = { |
319 | .netmask = gl.netmask, | |
320 | }; | |
2923e03f | 321 | if (d_db_type == GEOIP_ASNUM_EDITION) { |
68917ab7 CHB |
322 | char* result = GeoIP_name_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl); |
323 | if (result != nullptr) { | |
324 | std::string val(result); | |
2923e03f | 325 | vector<string> asnr; |
68917ab7 | 326 | free(result); |
2923e03f | 327 | stringtok(asnr, val); |
ff05c7e1 | 328 | if (asnr.size() > 0) { |
23c4de63 | 329 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
330 | ret = asnr[0]; |
331 | return true; | |
332 | } | |
333 | } | |
334 | } | |
335 | return false; | |
336 | } | |
337 | ||
ff05c7e1 O |
338 | bool queryASnumV6(string& ret, GeoIPNetmask& gl, const string& ip) override |
339 | { | |
23c4de63 AT |
340 | GeoIPLookup tmp_gl = { |
341 | .netmask = gl.netmask, | |
342 | }; | |
2923e03f | 343 | if (d_db_type == GEOIP_ASNUM_EDITION_V6) { |
68917ab7 CHB |
344 | char* result = GeoIP_name_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl); |
345 | if (result != nullptr) { | |
346 | std::string val(result); | |
2923e03f | 347 | vector<string> asnr; |
68917ab7 | 348 | free(result); |
2923e03f | 349 | stringtok(asnr, val); |
ff05c7e1 | 350 | if (asnr.size() > 0) { |
23c4de63 | 351 | gl.netmask = tmp_gl.netmask; |
2923e03f AT |
352 | ret = asnr[0]; |
353 | return true; | |
354 | } | |
355 | } | |
356 | } | |
357 | return false; | |
358 | } | |
359 | ||
ff05c7e1 O |
360 | bool queryRegion(string& ret, GeoIPNetmask& gl, const string& ip) override |
361 | { | |
23c4de63 AT |
362 | GeoIPLookup tmp_gl = { |
363 | .netmask = gl.netmask, | |
364 | }; | |
ff05c7e1 | 365 | if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { |
68917ab7 | 366 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 367 | if (gir) { |
23c4de63 | 368 | gl.netmask = tmp_gl.netmask; |
ff05c7e1 | 369 | ret = valueOrEmpty<char*, string>(gir->region); |
2923e03f AT |
370 | return true; |
371 | } | |
ff05c7e1 O |
372 | } |
373 | else if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) { | |
68917ab7 | 374 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str())); |
2923e03f | 375 | if (gir) { |
ff05c7e1 | 376 | ret = valueOrEmpty<char*, string>(gir->region); |
23c4de63 | 377 | gl.netmask = gir->netmask; |
2923e03f AT |
378 | return true; |
379 | } | |
380 | } | |
381 | return false; | |
382 | } | |
383 | ||
ff05c7e1 O |
384 | bool queryRegionV6(string& ret, GeoIPNetmask& gl, const string& ip) override |
385 | { | |
23c4de63 AT |
386 | GeoIPLookup tmp_gl = { |
387 | .netmask = gl.netmask, | |
388 | }; | |
ff05c7e1 | 389 | if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1) { |
68917ab7 | 390 | std::unique_ptr<GeoIPRegion, geoipregion_deleter> gir(GeoIP_region_by_addr_v6_gl(d_gi.get(), ip.c_str(), &tmp_gl)); |
2923e03f | 391 | if (gir) { |
23c4de63 | 392 | gl.netmask = tmp_gl.netmask; |
ff05c7e1 | 393 | ret = valueOrEmpty<char*, string>(gir->region); |
2923e03f AT |
394 | return true; |
395 | } | |
ff05c7e1 O |
396 | } |
397 | else if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) { | |
68917ab7 | 398 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str())); |
2923e03f | 399 | if (gir) { |
ff05c7e1 | 400 | ret = valueOrEmpty<char*, string>(gir->region); |
23c4de63 | 401 | gl.netmask = gir->netmask; |
2923e03f AT |
402 | return true; |
403 | } | |
404 | } | |
405 | return false; | |
406 | } | |
407 | ||
ff05c7e1 O |
408 | bool queryCity(string& ret, GeoIPNetmask& gl, const string& ip) override |
409 | { | |
410 | if (d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) { | |
68917ab7 | 411 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str())); |
2923e03f | 412 | if (gir) { |
ff05c7e1 | 413 | ret = valueOrEmpty<char*, string>(gir->city); |
23c4de63 | 414 | gl.netmask = gir->netmask; |
2923e03f AT |
415 | return true; |
416 | } | |
417 | } | |
418 | return false; | |
419 | } | |
420 | ||
ff05c7e1 O |
421 | bool queryCityV6(string& ret, GeoIPNetmask& gl, const string& ip) override |
422 | { | |
423 | if (d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) { | |
68917ab7 | 424 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str())); |
2923e03f | 425 | if (gir) { |
ff05c7e1 | 426 | ret = valueOrEmpty<char*, string>(gir->city); |
23c4de63 | 427 | gl.netmask = gir->netmask; |
2923e03f AT |
428 | return true; |
429 | } | |
430 | } | |
431 | return false; | |
432 | } | |
433 | ||
ff05c7e1 | 434 | bool queryLocationV6(GeoIPNetmask& gl, const string& ip, |
7ca490f0 | 435 | double& latitude, double& longitude, |
d73de874 | 436 | boost::optional<int>& /* alt */, boost::optional<int>& /* prec */) override |
ff05c7e1 O |
437 | { |
438 | if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1 || d_db_type == GEOIP_CITY_EDITION_REV0_V6 || d_db_type == GEOIP_CITY_EDITION_REV1_V6) { | |
68917ab7 | 439 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr_v6(d_gi.get(), ip.c_str())); |
5175e0dd AT |
440 | if (gir) { |
441 | latitude = gir->latitude; | |
442 | longitude = gir->longitude; | |
443 | gl.netmask = gir->netmask; | |
444 | return true; | |
445 | } | |
446 | } | |
447 | return false; | |
448 | } | |
449 | ||
ff05c7e1 | 450 | bool queryLocation(GeoIPNetmask& gl, const string& ip, |
7ca490f0 | 451 | double& latitude, double& longitude, |
d73de874 | 452 | boost::optional<int>& /* alt */, boost::optional<int>& /* prec */) override |
ff05c7e1 O |
453 | { |
454 | if (d_db_type == GEOIP_REGION_EDITION_REV0 || d_db_type == GEOIP_REGION_EDITION_REV1 || d_db_type == GEOIP_CITY_EDITION_REV0 || d_db_type == GEOIP_CITY_EDITION_REV1) { | |
68917ab7 | 455 | std::unique_ptr<GeoIPRecord, geoiprecord_deleter> gir(GeoIP_record_by_addr(d_gi.get(), ip.c_str())); |
5175e0dd AT |
456 | if (gir) { |
457 | latitude = gir->latitude; | |
458 | longitude = gir->longitude; | |
459 | gl.netmask = gir->netmask; | |
460 | return true; | |
461 | } | |
462 | } | |
463 | return false; | |
464 | } | |
465 | ||
9a315393 | 466 | ~GeoIPInterfaceDAT() override = default; |
ff05c7e1 | 467 | |
2923e03f AT |
468 | private: |
469 | unsigned int d_db_type; | |
68917ab7 | 470 | unique_ptr<GeoIP, geoip_deleter> d_gi; |
2923e03f AT |
471 | }; |
472 | ||
ff05c7e1 O |
473 | unique_ptr<GeoIPInterface> GeoIPInterface::makeDATInterface(const string& fname, const map<string, string>& opts) |
474 | { | |
2923e03f | 475 | string mode = "standard"; |
ff05c7e1 | 476 | const auto& opt = opts.find("mode"); |
2923e03f AT |
477 | if (opt != opts.end()) |
478 | mode = opt->second; | |
2bbc9eb0 | 479 | return std::make_unique<GeoIPInterfaceDAT>(fname, mode); |
2923e03f | 480 | } |
e3808f5e AT |
481 | |
482 | #else | |
483 | ||
aa87b287 | 484 | unique_ptr<GeoIPInterface> GeoIPInterface::makeDATInterface([[maybe_unused]] const string& fname, [[maybe_unused]] const map<string, string>& opts) |
ff05c7e1 | 485 | { |
e3808f5e AT |
486 | throw PDNSException("libGeoIP support not compiled in"); |
487 | } | |
488 | ||
489 | #endif |