2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

[master] add geoip support

3504.	[func]		Add support for ACLs based on geographic location,
			using MaxMind GeoIP databases. Based on code
			contributed by Ken Brownfield <kb@slide.com>.
			[RT #30681]
This commit is contained in:
Evan Hunt
2013-02-27 17:19:39 -08:00
parent dad65f7c93
commit 501941f0b6
66 changed files with 4337 additions and 47 deletions

View File

@@ -1,3 +1,8 @@
3504. [func] Add support for ACLs based on geographic location,
using MaxMind GeoIP databases. Based on code
contributed by Ken Brownfield <kb@slide.com>.
[RT #30681]
3503. [doc] Clarify size_spec syntax. [RT #32449]
3502. [func] zone-statistics: "no" is now a synonym for "none",

View File

@@ -82,7 +82,7 @@ SUBDIRS = unix
TARGETS = named@EXEEXT@ lwresd@EXEEXT@
OBJS = builtin.@O@ client.@O@ config.@O@ control.@O@ \
controlconf.@O@ interfacemgr.@O@ \
controlconf.@O@ geoip.@O@ interfacemgr.@O@ \
listenlist.@O@ log.@O@ logconf.@O@ main.@O@ notify.@O@ \
query.@O@ server.@O@ sortlist.@O@ statschannel.@O@ \
tkeyconf.@O@ tsigconf.@O@ update.@O@ xfrout.@O@ \
@@ -96,7 +96,7 @@ UOBJS = unix/os.@O@ unix/dlz_dlopen_driver.@O@
SYMOBJS = symtbl.@O@
SRCS = builtin.c client.c config.c control.c \
controlconf.c interfacemgr.c \
controlconf.c geoip.c interfacemgr.c \
listenlist.c log.c logconf.c main.c notify.c \
query.c server.c sortlist.c statschannel.c symtbl.c symtbl-empty.c \
tkeyconf.c tsigconf.c update.c xfrout.c \

161
bin/named/geoip.c Normal file
View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*! \file */
#include <config.h>
#ifdef HAVE_GEOIP
#include <named/log.h>
#include <named/geoip.h>
#include <dns/geoip.h>
#include <GeoIP.h>
static dns_geoip_databases_t geoip_table = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static void
init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
GeoIPOptions method, const char *name)
{
char *info;
GeoIP *db;
REQUIRE(dbp != NULL);
db = *dbp;
if (db != NULL) {
GeoIP_delete(db);
db = *dbp = NULL;
}
if (! GeoIP_db_avail(edition)) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"GeoIP %s DB not available", name);
return;
}
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"initializing GeoIP %s DB", name);
db = GeoIP_open_type(edition, method);
if (db == NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
"failed to initialize GeoIP %s DB; "
"geoip matches using this database will fail",
name);
return;
}
info = GeoIP_database_info(db);
if (info != NULL)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"%s", info);
*dbp = db;
}
static GeoIPDBTypes
choose_rev(GeoIPDBTypes primary, GeoIPDBTypes secondary, const char *name) {
if (GeoIP_db_avail(primary))
return (primary);
if (GeoIP_db_avail(secondary))
return (secondary);
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"GeoIP %s DB: neither revision available", name);
return (0);
}
#endif /* HAVE_GEOIP */
void
ns_geoip_init(void) {
#ifndef HAVE_GEOIP
return;
#else
if (ns_g_geoip == NULL)
ns_g_geoip = &geoip_table;
#endif
}
void
ns_geoip_load(char *dir) {
#ifndef HAVE_GEOIP
return;
#else
GeoIPOptions method;
GeoIPDBTypes edition;
#ifdef _WIN32
method = GEOIP_STANDARD;
#else
method = GEOIP_MMAP_CACHE;
#endif
ns_geoip_init();
if (dir != NULL) {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
"using \"%s\" as GeoIP directory", dir);
GeoIP_setup_custom_directory(dir);
}
init_geoip_db(&ns_g_geoip->country_v4, GEOIP_COUNTRY_EDITION,
method, "Country (IPv4)");
#ifdef HAVE_GEOIP_V6
init_geoip_db(&ns_g_geoip->country_v6, GEOIP_COUNTRY_EDITION_V6,
method, "Country (IPv6)");
#endif
edition = choose_rev(GEOIP_CITY_EDITION_REV0,
GEOIP_CITY_EDITION_REV1, "City (IPv4)");
if (edition != 0)
init_geoip_db(&ns_g_geoip->city_v4, edition,
method, "City (IPv4)");
#if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6)
edition = choose_rev(GEOIP_CITY_EDITION_REV0_V6,
GEOIP_CITY_EDITION_REV1_V6, "City (IPv6)");
if (edition != 0)
init_geoip_db(&ns_g_geoip->city_v6, edition,
method, "City (IPv6)");
#endif
edition = choose_rev(GEOIP_REGION_EDITION_REV0,
GEOIP_REGION_EDITION_REV1, "Region");
if (edition != 0)
init_geoip_db(&ns_g_geoip->region, edition, method, "Region");
init_geoip_db(&ns_g_geoip->isp, GEOIP_ISP_EDITION,
method, "ISP");
init_geoip_db(&ns_g_geoip->org, GEOIP_ORG_EDITION,
method, "Org");
init_geoip_db(&ns_g_geoip->as, GEOIP_ASNUM_EDITION,
method, "AS");
init_geoip_db(&ns_g_geoip->domain, GEOIP_DOMAIN_EDITION,
method, "Domain");
init_geoip_db(&ns_g_geoip->netspeed, GEOIP_NETSPEED_EDITION,
method, "NetSpeed");
#endif /* HAVE_GEOIP */
}

View File

@@ -0,0 +1,14 @@
#ifndef _GEOIP_H
#define _GEOIP_H
#ifdef HAVE_GEOIP
#include <GeoIP.h>
#include <GeoIPCity.h>
void ns_geoip_init(void);
void ns_geoip_load(char *dir);
extern dns_geoip_databases_t *ns_g_geoip;
#endif /* HAVE_GEOIP */
#endif

View File

@@ -29,6 +29,7 @@
#include <isccfg/aclconf.h>
#include <isccfg/cfg.h>
#include <dns/acl.h>
#include <dns/zone.h>
#include <dst/dst.h>
@@ -161,6 +162,10 @@ EXTERN isc_boolean_t ns_g_noaa INIT(ISC_FALSE);
EXTERN unsigned int ns_g_delay INIT(0);
EXTERN isc_boolean_t ns_g_nonearest INIT(ISC_FALSE);
#ifdef HAVE_GEOIP
EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL);
#endif
#undef EXTERN
#undef INIT

View File

@@ -106,6 +106,9 @@ ns_interfacemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
result = dns_aclenv_init(mctx, &mgr->aclenv);
if (result != ISC_R_SUCCESS)
goto cleanup_listenon;
#ifdef HAVE_GEOIP
mgr->aclenv.geoip = ns_g_geoip;
#endif
mgr->references = 1;
mgr->magic = IFMGR_MAGIC;

View File

@@ -95,6 +95,7 @@
#include <named/client.h>
#include <named/config.h>
#include <named/control.h>
#include <named/geoip.h>
#include <named/interfacemgr.h>
#include <named/log.h>
#include <named/logconf.h>
@@ -110,6 +111,9 @@
#include <named/ns_smf_globals.h>
#include <stdlib.h>
#endif
#ifdef HAVE_GEOIP
#include <named/geoip.h>
#endif /* HAVE_GEOIP */
#ifndef PATH_MAX
#define PATH_MAX 1024
@@ -3762,6 +3766,10 @@ create_view(const cfg_obj_t *vconfig, dns_viewlist_t *viewlist,
if (result != ISC_R_SUCCESS)
return (result);
#ifdef HAVE_GEOIP
view->aclenv.geoip = ns_g_geoip;
#endif
ISC_LIST_APPEND(*viewlist, view, link);
dns_view_attach(view, viewp);
return (ISC_R_SUCCESS);
@@ -5083,6 +5091,24 @@ load_configuration(const char *filename, ns_server_t *server,
}
isc__socketmgr_setreserved(ns_g_socketmgr, reserved);
#ifdef HAVE_GEOIP
/*
* Initialize GeoIP databases from the configured location.
* This should happen before configuring any ACLs, so that we
* know what databases are available and can reject any GeoIP
* ACLs that can't work.
*/
obj = NULL;
result = ns_config_get(maps, "geoip-directory", &obj);
if (result == ISC_R_SUCCESS && cfg_obj_isstring(obj)) {
char *dir;
DE_CONST(cfg_obj_asstring(obj), dir);
ns_geoip_load(dir);
} else
ns_geoip_load(NULL);
ns_g_aclconfctx->geoip = ns_g_geoip;
#endif /* HAVE_GEOIP */
/*
* Configure various server options.
*/
@@ -6069,6 +6095,10 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
if (server->blackholeacl != NULL)
dns_acl_detach(&server->blackholeacl);
#ifdef HAVE_GEOIP
dns_geoip_shutdown();
#endif
dns_db_detach(&server->in_roothints);
isc_task_endexclusive(server->task);
@@ -6090,7 +6120,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
server->task = NULL;
/* Initialize configuration data with default values. */
result = isc_quota_init(&server->xfroutquota, 10);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = isc_quota_init(&server->tcpquota, 10);
@@ -6098,9 +6127,16 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
result = isc_quota_init(&server->recursionquota, 100);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
result = dns_aclenv_init(mctx, &server->aclenv);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
#ifdef HAVE_GEOIP
/* Initialize GeoIP before using ACL environment */
ns_geoip_init();
server->aclenv.geoip = ns_g_geoip;
#endif
/* Initialize server data structures. */
server->zonemgr = NULL;
server->interfacemgr = NULL;

View File

@@ -21,7 +21,7 @@ top_srcdir = @top_srcdir@
@BIND9_MAKE_INCLUDES@
SUBDIRS = dlzexternal filter-aaaa lwresd rpz rsabigexponent tkey tsiggss
SUBDIRS = dlzexternal filter-aaaa geoip lwresd rpz rsabigexponent tkey tsiggss
TARGETS =
@BIND9_MAKE_RULES@

1
bin/tests/system/geoip/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
geoip

View File

@@ -0,0 +1,55 @@
# Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: Makefile.in,v 1.4 2011/07/28 23:47:58 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
CINCLUDES = ${ISC_INCLUDES}
CDEFINES =
CWARNINGS =
DNSLIBS =
ISCLIBS = .
DNSDEPLIBS =
ISCDEPLIBS =
DEPLIBS =
LIBS = @LIBS@
TARGETS = geoip@EXEEXT@
FILTEROBJS = geoip.@O@
SRCS = geoip.c
@BIND9_MAKE_RULES@
all: geoip@EXEEXT@
geoip@EXEEXT@: ${FILTEROBJS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${FILTEROBJS} ${LIBS}
clean distclean::
rm -f ${TARGETS}

View File

@@ -0,0 +1,19 @@
#!/bin/sh
#
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
rm -f ns2/named.conf
rm -f ns2/example[1234567].db
rm -f dig.out.*

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 AU
10.53.0.2/32 US
10.53.0.3/32 GB
10.53.0.4/32 CA
10.53.0.5/32 CL
10.53.0.6/32 DE
10.53.0.7/32 EH
1 10.53.0.1/32 AU
2 10.53.0.2/32 US
3 10.53.0.3/32 GB
4 10.53.0.4/32 CA
5 10.53.0.5/32 CL
6 10.53.0.6/32 DE
7 10.53.0.7/32 EH

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 AS100001 One Systems, Inc.
10.53.0.2/32 AS100002 Two Technology Ltd.
10.53.0.3/32 AS100003 Three Network Labs
10.53.0.4/32 AS100004 Four University
10.53.0.5/32 AS100005 Five Telecom
10.53.0.6/32 AS100006 Six Company
10.53.0.7/32 AS100007 Seven Communications
1 10.53.0.1/32 AS100001 One Systems, Inc.
2 10.53.0.2/32 AS100002 Two Technology Ltd.
3 10.53.0.3/32 AS100003 Three Network Labs
4 10.53.0.4/32 AS100004 Four University
5 10.53.0.5/32 AS100005 Five Telecom
6 10.53.0.6/32 AS100006 Six Company
7 10.53.0.7/32 AS100007 Seven Communications

Binary file not shown.

View File

@@ -0,0 +1,7 @@
fd92:7065:b8e:ffff::1/128,AS100001 One Systems, Inc.
fd92:7065:b8e:ffff::2/128,AS100002 Two Technology Ltd.
fd92:7065:b8e:ffff::3/128,AS100003 Three Network Labs
fd92:7065:b8e:ffff::4/128,AS100004 Four University
fd92:7065:b8e:ffff::5/128,AS100005 Five Telecom
fd92:7065:b8e:ffff::6/128,AS100006 Six Company
fd92:7065:b8e:ffff::7/128,AS100007 Seven Communications
1 fd92:7065:b8e:ffff::1/128,AS100001 One Systems, Inc.
2 fd92:7065:b8e:ffff::2/128,AS100002 Two Technology Ltd.
3 fd92:7065:b8e:ffff::3/128,AS100003 Three Network Labs
4 fd92:7065:b8e:ffff::4/128,AS100004 Four University
5 fd92:7065:b8e:ffff::5/128,AS100005 Five Telecom
6 fd92:7065:b8e:ffff::6/128,AS100006 Six Company
7 fd92:7065:b8e:ffff::7/128,AS100007 Seven Communications

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32,US,CA,"Redwood City",94063,37.4914,-122.2110,807,650
10.53.0.2/32,US,CA,"Santa Cruz",95060,37.0448,-122.1021,828,831
10.53.0.3/32,US,OK,"Oklahoma City",73120,35.5798,-97.5731,650,405
10.53.0.4/32,US,VA,Ashland,23005,37.7563,-77.4888,556,804
10.53.0.5/32,US,GA,Atlanta,30345,33.8477,-84.2814,524,404
10.53.0.6/32,US,CO,Morrison,80465,39.6081,-105.2072,751,303
10.53.0.7/32,US,AK,Ketchikan,99901,55.6153,-131.5848,747,907
1 10.53.0.1/32 US CA Redwood City 94063 37.4914 -122.2110 807 650
2 10.53.0.2/32 US CA Santa Cruz 95060 37.0448 -122.1021 828 831
3 10.53.0.3/32 US OK Oklahoma City 73120 35.5798 -97.5731 650 405
4 10.53.0.4/32 US VA Ashland 23005 37.7563 -77.4888 556 804
5 10.53.0.5/32 US GA Atlanta 30345 33.8477 -84.2814 524 404
6 10.53.0.6/32 US CO Morrison 80465 39.6081 -105.2072 751 303
7 10.53.0.7/32 US AK Ketchikan 99901 55.6153 -131.5848 747 907

Binary file not shown.

View File

@@ -0,0 +1,7 @@
"fd92:7065:b8e:ffff::1","fd92:7065:b8e:ffff::1","US","CA","Redwood City","94063",37.4914,-122.2110,807,650
"fd92:7065:b8e:ffff::2","fd92:7065:b8e:ffff::2","US","CA","Santa Cruz","95060",37.0448,-122.1021,828,831
"fd92:7065:b8e:ffff::3","fd92:7065:b8e:ffff::3","US","OK","Oklahoma City","73120",35.5798,-97.5731,650,405
"fd92:7065:b8e:ffff::4","fd92:7065:b8e:ffff::4","DE","07","Lotte","",52.2833,7.9167,0,0
"fd92:7065:b8e:ffff::5","fd92:7065:b8e:ffff::5","US","GA","Atlanta","30345",33.8477,-84.2814,524,404
"fd92:7065:b8e:ffff::6","fd92:7065:b8e:ffff::6","US","CO","Morrison","80465",39.6081,-105.2072,751,303
"fd92:7065:b8e:ffff::7","fd92:7065:b8e:ffff::7","US","AK","Ketchikan","99901",55.6153,-131.5848,747,907
1 fd92:7065:b8e:ffff::1 fd92:7065:b8e:ffff::1 US CA Redwood City 94063 37.4914 -122.2110 807 650
2 fd92:7065:b8e:ffff::2 fd92:7065:b8e:ffff::2 US CA Santa Cruz 95060 37.0448 -122.1021 828 831
3 fd92:7065:b8e:ffff::3 fd92:7065:b8e:ffff::3 US OK Oklahoma City 73120 35.5798 -97.5731 650 405
4 fd92:7065:b8e:ffff::4 fd92:7065:b8e:ffff::4 DE 07 Lotte 52.2833 7.9167 0 0
5 fd92:7065:b8e:ffff::5 fd92:7065:b8e:ffff::5 US GA Atlanta 30345 33.8477 -84.2814 524 404
6 fd92:7065:b8e:ffff::6 fd92:7065:b8e:ffff::6 US CO Morrison 80465 39.6081 -105.2072 751 303
7 fd92:7065:b8e:ffff::7 fd92:7065:b8e:ffff::7 US AK Ketchikan 99901 55.6153 -131.5848 747 907

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 one.de
10.53.0.2/32 two.com
10.53.0.3/32 three.com
10.53.0.4/32 four.com
10.53.0.5/32 five.es
10.53.0.6/32 six.it
10.53.0.7/32 seven.org
1 10.53.0.1/32 one.de
2 10.53.0.2/32 two.com
3 10.53.0.3/32 three.com
4 10.53.0.4/32 four.com
5 10.53.0.5/32 five.es
6 10.53.0.6/32 six.it
7 10.53.0.7/32 seven.org

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 One Systems, Inc.
10.53.0.2/32 Two Technology Ltd.
10.53.0.3/32 Three Network Labs
10.53.0.4/32 Four University
10.53.0.5/32 Five Telecom
10.53.0.6/32 Six Company
10.53.0.7/32 Seven Communications
1 10.53.0.1/32 One Systems, Inc.
2 10.53.0.2/32 Two Technology Ltd.
3 10.53.0.3/32 Three Network Labs
4 10.53.0.4/32 Four University
5 10.53.0.5/32 Five Telecom
6 10.53.0.6/32 Six Company
7 10.53.0.7/32 Seven Communications

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 0
10.53.0.2/32 1
10.53.0.3/32 2
10.53.0.4/32 3
10.53.0.5/32 0
10.53.0.6/32 1
10.53.0.7/32 2
1 10.53.0.1/32 0
2 10.53.0.2/32 1
3 10.53.0.3/32 2
4 10.53.0.4/32 3
5 10.53.0.5/32 0
6 10.53.0.6/32 1
7 10.53.0.7/32 2

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 One Systems, Inc.
10.53.0.2/32 Two Technology Ltd.
10.53.0.3/32 Three Network Labs
10.53.0.4/32 Four University
10.53.0.5/32 Five Telecom
10.53.0.6/32 Six Company
10.53.0.7/32 Seven Communications
1 10.53.0.1/32 One Systems, Inc.
2 10.53.0.2/32 Two Technology Ltd.
3 10.53.0.3/32 Three Network Labs
4 10.53.0.4/32 Four University
5 10.53.0.5/32 Five Telecom
6 10.53.0.6/32 Six Company
7 10.53.0.7/32 Seven Communications

Binary file not shown.

View File

@@ -0,0 +1,7 @@
10.53.0.1/32 US CA
10.53.0.2/32 CA BC
10.53.0.3/32 US OK
10.53.0.4/32 AU
10.53.0.5/32 US CO
10.53.0.6/32 CA ON
10.53.0.7/32 NL
1 10.53.0.1/32 US CA
2 10.53.0.2/32 CA BC
3 10.53.0.3/32 US OK
4 10.53.0.4/32 AU
5 10.53.0.5/32 US CO
6 10.53.0.6/32 CA ON
7 10.53.0.7/32 NL

Binary file not shown.

View File

@@ -0,0 +1,7 @@
"fd92:7065:b8e:ffff::1/128",AU
"fd92:7065:b8e:ffff::2/128",US
"fd92:7065:b8e:ffff::3/128",GB
"fd92:7065:b8e:ffff::4/128",CA
"fd92:7065:b8e:ffff::5/128",CL
"fd92:7065:b8e:ffff::6/128",DE
"fd92:7065:b8e:ffff::7/128",EH
1 fd92:7065:b8e:ffff::1/128 AU
2 fd92:7065:b8e:ffff::2/128 US
3 fd92:7065:b8e:ffff::3/128 GB
4 fd92:7065:b8e:ffff::4/128 CA
5 fd92:7065:b8e:ffff::5/128 CL
6 fd92:7065:b8e:ffff::6/128 DE
7 fd92:7065:b8e:ffff::7/128 EH

Binary file not shown.

View File

@@ -0,0 +1,29 @@
The data data files in this directory are sample GeoIP databases,
generated from the corresponding CSV files. Thanks to MaxMind, Inc.
for assitance with producing these files.
Unless otherwise noted, the databases only support IPv4:
GeoIP.dat: Country (IPv4)
GeoIPv6.dat: Country (IPv6)
GeoIPCity.dat: City (IPv4)
GeoIPCityv6.dat: City (IPv6)
GeoIPRegion.dat: Region
GeoIPISP.dat: ISP
GeoIPOrg.dat: Organization
GeoIPDoain.dat: Domain Name
GeoIPASNum.dat: AS Number
GeoIPNetSpeed.dat: Net Speed
GeoIP.dat can also be egenerated using the open source 'geoip-csv-to-dat'
utility:
$ geoip-csv-to-dat -i "BIND9 geoip test data v1" -o GeoIP.dat << EOF
"10.53.0.1","10.53.0.1","171245569","171245569","AU","Australia"
"10.53.0.2","10.53.0.2","171245570","171245570","US","United States"
"10.53.0.3","10.53.0.3","171245571","171245571","GB","United Kingdom"
"10.53.0.4","10.53.0.4","171245572","171245572","CA","Canada"
"10.53.0.5","10.53.0.5","171245573","171245573","CL","Chile"
"10.53.0.6","10.53.0.6","171245574","171245574","DE","Germany"
"10.53.0.7","10.53.0.7","171245575","171245575","EH","Western Sahara"
EOF

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <isc/util.h>
int
main(int argc, char **argv) {
UNUSED(argc);
UNUSED(argv);
#ifdef HAVE_GEOIP
return (0);
#else
return (1);
#endif
}

View File

@@ -0,0 +1,24 @@
; Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
;
; Permission to use, copy, modify, and/or distribute this software for any
; purpose with or without fee is hereby granted, provided that the above
; copyright notice and this permission notice appear in all copies.
;
; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
; PERFORMANCE OF THIS SOFTWARE.
$TTL 300 ; 5 minutes
@ IN SOA mname1. . (
2000042407 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns2
ns2 A 10.53.0.2

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip db country country AU; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip db country country US; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip db country country GB; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip db country country CA; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip db country country CL; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip db country country DE; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip db country country EH; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip domain one.de; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip domain two.com; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip domain three.com; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip domain four.com; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip domain five.es; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip domain six.it; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip domain seven.org; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip netspeed 0; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip netspeed 1; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip netspeed 2; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip netspeed 3; };
zone "example" {
type master;
file "example4.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip db country country AUS; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip db country country USA; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip db country country GBR; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip db country country CAN; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip db country country CHL; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip db country country DEU; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip db country country ESH; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip db country country Australia; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip db country country "United States"; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip db country country "United Kingdom"; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip db country country Canada; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip db country country Chile; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip db country country Germany; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip db country country "Western Sahara"; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip region CA; };
zone "example" {
type master;
file "example1.db";
};
};
view three {
match-clients { geoip region OK; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip region VA; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip region GA; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip region CO; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip region AK; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip db region region "California"; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip db region region "British Columbia"; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip db region region "Oklahoma"; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip db region country AU; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip db region region "Colorado"; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip db region region "Ontario"; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip db region country NL; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip city "Redwood City"; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip city "Santa Cruz"; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip city "Oklahoma City"; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip city "Ashland"; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip city "Atlanta"; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip city "Morrison"; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip city "Ketchikan"; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip isp "One Systems, Inc."; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip isp "Two Technology Ltd."; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip isp "Three Network Labs"; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip isp "Four University"; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip isp "Five Telecom"; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip isp "Six Company"; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip isp "Seven Communications"; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip org "One Systems, Inc."; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip org "Two Technology Ltd."; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip org "Three Network Labs"; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip org "Four University"; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip org "Five Telecom"; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip org "Six Company"; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip org "Seven Communications"; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
// NS2
controls { /* empty */ };
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port 5300;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
geoip-directory "../data";
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-md5;
};
controls {
inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; };
};
view one {
match-clients { geoip asnum "AS100001 One Systems, Inc."; };
zone "example" {
type master;
file "example1.db";
};
};
view two {
match-clients { geoip asnum "AS100002 Two Technology Ltd."; };
zone "example" {
type master;
file "example2.db";
};
};
view three {
match-clients { geoip asnum "AS100003 Three Network Labs"; };
zone "example" {
type master;
file "example3.db";
};
};
view four {
match-clients { geoip asnum "AS100004 Four University"; };
zone "example" {
type master;
file "example4.db";
};
};
view five {
match-clients { geoip asnum "AS100005 Five Telecom"; };
zone "example" {
type master;
file "example5.db";
};
};
view six {
match-clients { geoip asnum "AS100006 Six Company"; };
zone "example" {
type master;
file "example6.db";
};
};
view seven {
match-clients { geoip asnum "AS100007 Seven Communications"; };
zone "example" {
type master;
file "example7.db";
};
};
view none {
match-clients { any; };
zone "example" {
type master;
file "example.db.in";
};
};

View File

@@ -0,0 +1,23 @@
#!/bin/sh
#
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
if ./geoip
then
:
else
echo "I:This test requires GeoIP support." >&2
exit 1
fi

View File

@@ -0,0 +1,24 @@
#!/bin/sh
#
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
sh clean.sh
cp ns2/named1.conf ns2/named.conf
for i in 1 2 3 4 5 6 7; do
cp ns2/example.db.in ns2/example${i}.db
echo "@ IN TXT \"$i\"" >> ns2/example$i.db
done

View File

@@ -0,0 +1,233 @@
#!/bin/sh
#
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
status=0
n=0
rm -f dig.out.*
DIGOPTS="+tcp +short -p 5300 @10.53.0.2"
n=`expr $n + 1`
echo "I:checking GeoIP country database by code"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named2.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP country database by three-letter code"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named3.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP country database by name"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named4.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP region code, no specified database"
ret=0
lret=0
# skipping 2 on purpose here; it has the same region code as 1
for i in 1 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named5.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP region database by region name and country code"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named6.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP city database by city name"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named7.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP isp database"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named8.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP org database"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named9.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP asnum database"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named10.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP domain database"
ret=0
lret=0
for i in 1 2 3 4 5 6 7; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:reloading server"
cp -f ns2/named11.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reload 2>&1 | sed 's/^/I:ns2 /'
sleep 3
n=`expr $n + 1`
echo "I:checking GeoIP netspeed database"
ret=0
lret=0
for i in 1 2 3 4; do
$DIG $DIGOPTS txt example -b 10.53.0.$i > dig.out.ns2.test$n.$i || lret=1
j=`cat dig.out.ns2.test$n.$i | tr -d '"'`
[ "$i" = "$j" ] || lret=1
[ $lret -eq 1 ] && break
done
[ $lret -eq 1 ] && ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
echo "I:exit status: $status"
exit $status

View File

@@ -215,6 +215,15 @@ int sigwait(const unsigned int *set, int *sig);
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Build with GeoIP support */
#undef HAVE_GEOIP
/* Build with GeoIP City IPv6 support */
#undef HAVE_GEOIP_CITY_V6
/* Build with GeoIP Country IPv6 support */
#undef HAVE_GEOIP_V6
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
#undef HAVE_GSSAPI_GSSAPI_H

258
configure vendored
View File

@@ -1459,6 +1459,7 @@ with_ecdsa
with_gost
enable_openssl_hash
with_pkcs11
with_geoip
with_gssapi
with_randomdev
enable_threads
@@ -2169,6 +2170,7 @@ Optional Packages:
--with-gost OpenSSL GOST
--with-pkcs11=PATH Build with PKCS11 support yes|no|path
(PATH is for the PKCS11 provider)
--with-geoip=PATH Build with GeoIP support (yes|no|path)
--with-gssapi=PATH Specify path for system-supplied GSSAPI [default=yes]
--with-randomdev=PATH Specify path for random device
--with-libxml2=PATH Build with libxml2 library yes|no|path
@@ -14471,6 +14473,259 @@ $as_echo "PKCS11 provider is \"$use_pkcs11\"" >&6; }
esac
# Check whether --with-geoip was given.
if test "${with_geoip+set}" = set; then :
withval=$with_geoip; use_geoip="$withval"
else
use_geoip="no"
fi
if test "$use_geoip" = "yes"
then
for d in /usr /usr/local
do
if test -f $d/include/GeoIP.h
then
use_geoip=$d
break
fi
done
fi
case "$use_geoip" in
no|'')
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP support" >&5
$as_echo_n "checking for GeoIP support... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
$as_echo "disabled" >&6; }
;;
*)
if test -d "$use_geoip" -o -L "$use_geoip"
then
CFLAGS="$CFLAGS -I$use_geoip/include"
CPPFLAGS="$CPPFLAGS -I$use_geoip/include"
case "$host_os" in
netbsd*|openbsd*|solaris*)
LIBS="$LIBS -Wl,-rpath=$use_geoip/lib"
;;
*)
LIBS="$LIBS -L$use_geoip/lib"
esac
elif test "$use_geoip" = "yes"
then
as_fn_error $? "GeoIP path not found" "$LINENO" 5
else
as_fn_error $? "GeoIP path $use_geoip does not exist" "$LINENO" 5
fi
ac_fn_c_check_header_mongrel "$LINENO" "GeoIP.h" "ac_cv_header_GeoIP_h" "$ac_includes_default"
if test "x$ac_cv_header_GeoIP_h" = xyes; then :
else
as_fn_error $? "GeoIP header file not found" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing GeoIP_open" >&5
$as_echo_n "checking for library containing GeoIP_open... " >&6; }
if ${ac_cv_search_GeoIP_open+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char GeoIP_open ();
int
main ()
{
return GeoIP_open ();
;
return 0;
}
_ACEOF
for ac_lib in '' GeoIP; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_GeoIP_open=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_GeoIP_open+:} false; then :
break
fi
done
if ${ac_cv_search_GeoIP_open+:} false; then :
else
ac_cv_search_GeoIP_open=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_GeoIP_open" >&5
$as_echo "$ac_cv_search_GeoIP_open" >&6; }
ac_res=$ac_cv_search_GeoIP_open
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "GeoIP library not found" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fabsf" >&5
$as_echo_n "checking for library containing fabsf... " >&6; }
if ${ac_cv_search_fabsf+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char fabsf ();
int
main ()
{
return fabsf ();
;
return 0;
}
_ACEOF
for ac_lib in '' m; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_fabsf=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_fabsf+:} false; then :
break
fi
done
if ${ac_cv_search_fabsf+:} false; then :
else
ac_cv_search_fabsf=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fabsf" >&5
$as_echo "$ac_cv_search_fabsf" >&6; }
ac_res=$ac_cv_search_fabsf
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "Math library not found" "$LINENO" 5
fi
$as_echo "#define HAVE_GEOIP 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP support" >&5
$as_echo_n "checking for GeoIP support... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP Country IPv6 support" >&5
$as_echo_n "checking for GeoIP Country IPv6 support... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <GeoIP.h>
#include <netinet/in.h>
int
main ()
{
struct in6_addr in6;
GeoIP_country_name_by_ipnum_v6(NULL, in6);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_GEOIP_V6 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP City IPv6 support" >&5
$as_echo_n "checking for GeoIP City IPv6 support... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <GeoIP.h>
#include <GeoIPCity.h>
#include <netinet/in.h>
int
main ()
{
struct in6_addr in6;
int i = GEOIP_CITY_EDITION_REV0_V6;
GeoIP_record_by_ipnum_v6(NULL, in6);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_GEOIP_CITY_V6 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSSAPI library" >&5
$as_echo_n "checking for GSSAPI library... " >&6; }
@@ -20518,7 +20773,7 @@ ac_config_commands="$ac_config_commands chmod"
# elsewhere if there's a good reason for doing so.
#
ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/dsdigest/prereq.sh bin/tests/system/ecdsa/prereq.sh bin/tests/system/dlzredir/prereq.sh bin/tests/system/filter-aaaa/Makefile bin/tests/system/gost/prereq.sh bin/tests/system/lwresd/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/check-secure-delegation.pl contrib/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/export/Makefile lib/export/dns/Makefile lib/export/dns/include/Makefile lib/export/dns/include/dns/Makefile lib/export/dns/include/dst/Makefile lib/export/irs/Makefile lib/export/irs/include/Makefile lib/export/irs/include/irs/Makefile lib/export/isc/$thread_dir/Makefile lib/export/isc/$thread_dir/include/Makefile lib/export/isc/$thread_dir/include/isc/Makefile lib/export/isc/Makefile lib/export/isc/include/Makefile lib/export/isc/include/isc/Makefile lib/export/isc/nls/Makefile lib/export/isc/unix/Makefile lib/export/isc/unix/include/Makefile lib/export/isc/unix/include/isc/Makefile lib/export/isccfg/Makefile lib/export/isccfg/include/Makefile lib/export/isccfg/include/isccfg/Makefile lib/export/samples/Makefile lib/export/samples/Makefile-postinstall lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile unit/Makefile unit/unittest.sh"
ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/dsdigest/prereq.sh bin/tests/system/ecdsa/prereq.sh bin/tests/system/dlzredir/prereq.sh bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/gost/prereq.sh bin/tests/system/lwresd/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/check-secure-delegation.pl contrib/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/export/Makefile lib/export/dns/Makefile lib/export/dns/include/Makefile lib/export/dns/include/dns/Makefile lib/export/dns/include/dst/Makefile lib/export/irs/Makefile lib/export/irs/include/Makefile lib/export/irs/include/irs/Makefile lib/export/isc/$thread_dir/Makefile lib/export/isc/$thread_dir/include/Makefile lib/export/isc/$thread_dir/include/isc/Makefile lib/export/isc/Makefile lib/export/isc/include/Makefile lib/export/isc/include/isc/Makefile lib/export/isc/nls/Makefile lib/export/isc/unix/Makefile lib/export/isc/unix/include/Makefile lib/export/isc/unix/include/isc/Makefile lib/export/isccfg/Makefile lib/export/isccfg/include/Makefile lib/export/isccfg/include/isccfg/Makefile lib/export/samples/Makefile lib/export/samples/Makefile-postinstall lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile unit/Makefile unit/unittest.sh"
#
@@ -21549,6 +21804,7 @@ do
"bin/tests/system/ecdsa/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/ecdsa/prereq.sh" ;;
"bin/tests/system/dlzredir/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/dlzredir/prereq.sh" ;;
"bin/tests/system/filter-aaaa/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/filter-aaaa/Makefile" ;;
"bin/tests/system/geoip/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/geoip/Makefile" ;;
"bin/tests/system/gost/prereq.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/gost/prereq.sh" ;;
"bin/tests/system/lwresd/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/lwresd/Makefile" ;;
"bin/tests/system/rpz/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rpz/Makefile" ;;

View File

@@ -972,6 +972,94 @@ case "$use_pkcs11" in
esac
AC_SUBST(PKCS11_PROVIDER)
AC_ARG_WITH(geoip,
[ --with-geoip=PATH Build with GeoIP support (yes|no|path)],
use_geoip="$withval", use_geoip="no")
if test "$use_geoip" = "yes"
then
for d in /usr /usr/local
do
if test -f $d/include/GeoIP.h
then
use_geoip=$d
break
fi
done
fi
case "$use_geoip" in
no|'')
AC_MSG_CHECKING([for GeoIP support])
AC_MSG_RESULT([disabled])
;;
*)
if test -d "$use_geoip" -o -L "$use_geoip"
then
CFLAGS="$CFLAGS -I$use_geoip/include"
CPPFLAGS="$CPPFLAGS -I$use_geoip/include"
case "$host_os" in
netbsd*|openbsd*|solaris*)
LIBS="$LIBS -Wl,-rpath=$use_geoip/lib"
;;
*)
LIBS="$LIBS -L$use_geoip/lib"
esac
elif test "$use_geoip" = "yes"
then
AC_MSG_ERROR([GeoIP path not found])
else
AC_MSG_ERROR([GeoIP path $use_geoip does not exist])
fi
AC_CHECK_HEADER(GeoIP.h, [],
[AC_MSG_ERROR([GeoIP header file not found])]
)
AC_SEARCH_LIBS(GeoIP_open, GeoIP, [],
[AC_MSG_ERROR([GeoIP library not found])]
)
AC_SEARCH_LIBS(fabsf, m, [],
[AC_MSG_ERROR([Math library not found])]
)
AC_DEFINE(HAVE_GEOIP, 1, Build with GeoIP support)
AC_MSG_CHECKING([for GeoIP support])
AC_MSG_RESULT([yes])
AC_MSG_CHECKING([for GeoIP Country IPv6 support])
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([[
#include <GeoIP.h>
#include <netinet/in.h>
]], [[
struct in6_addr in6;
GeoIP_country_name_by_ipnum_v6(NULL, in6);
]]),
[
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_GEOIP_V6, 1, Build with GeoIP Country IPv6 support)
],
[AC_MSG_RESULT([no])]
)
AC_MSG_CHECKING([for GeoIP City IPv6 support])
AC_COMPILE_IFELSE(
AC_LANG_PROGRAM([[
#include <GeoIP.h>
#include <GeoIPCity.h>
#include <netinet/in.h>
]], [[
struct in6_addr in6;
int i = GEOIP_CITY_EDITION_REV0_V6;
GeoIP_record_by_ipnum_v6(NULL, in6);
]]),
[
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_GEOIP_CITY_V6, 1, Build with GeoIP City IPv6 support)
],
[AC_MSG_RESULT([no])]
)
;;
esac
AC_MSG_CHECKING(for GSSAPI library)
AC_ARG_WITH(gssapi,
[ --with-gssapi=PATH Specify path for system-supplied GSSAPI [[default=yes]]],
@@ -3663,6 +3751,7 @@ AC_CONFIG_FILES([
bin/tests/system/ecdsa/prereq.sh
bin/tests/system/dlzredir/prereq.sh
bin/tests/system/filter-aaaa/Makefile
bin/tests/system/geoip/Makefile
bin/tests/system/gost/prereq.sh
bin/tests/system/lwresd/Makefile
bin/tests/system/rpz/Makefile

View File

@@ -3957,6 +3957,62 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
</tgroup>
</informaltable>
<para>
When <acronym>BIND</acronym> 9 is built with GeoIP support,
ACLs can also be used for geographic access restrictions.
This is done by specifying an ACL element of the form:
<command>geoip <optional>db <replaceable>database</replaceable></optional> <replaceable>field</replaceable> <replaceable>value</replaceable></command>
</para>
<para>
The <replaceable>field</replaceable> indicates which field
to search for a match. Available fields are "country",
"region", "city", "continent", "postal" (postal code),
"metro" (metro code), "area" (area code), "tz" (timezone),
"isp", "org", "asnum", "domain" and "netspeed".
</para>
<para>
<replaceable>value</replaceable> is the value to searched for
within the database. A string may be quoted if it contains
spaces or other special characters. If this is a "country"
search and the string is two characters long, then it must be a
standard ISO-3166-1 two-letter country code, and if it is three
characters long then it must be an ISO-3166-1 three-letter
country code; otherwise it is the full name of the country.
Similarly, if this is a "region" search and the string is
two characters long, then it must be a standard two-letter state
or province abbreviation; otherwise it is the full name of the
state or province.
</para>
<para>
The <replaceable>database</replaceable> field indicates which
GeoIP database to search for a match. In most cases this is
unnecessary, because most search fields can only be found in
a single database. However, searches for country can be
answered from the "city", "region", or "country" databases,
and searches for region (i.e., state or provice) can be
answered from the "city" or "region" databases. For these
search types, specifying a <replaceable>database</replaceable>
will force the query to be answered from that database and no
other. If <replaceable>database</replaceable> is not
specified, then these queries will be answered from the "city",
database if it is installed, or the "region" database if it is
installed, or the "country" database, in that order.
</para>
<para>
Some example GeoIP ACLs:
</para>
<programlisting>geoip country US;
geoip country JAP;
geoip db country country Canada;
geoip db region region WA;
geoip city "San Francisco";
geoip region Oklahoma;
geoip postal 95062;
geoip tz "America/Los_Angeles";
geoip org "Internet Systems Consortium";
</programlisting>
</sect2>
<sect2>
<title><command>controls</command> Statement Grammar</title>

View File

@@ -62,8 +62,8 @@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
cache.@O@ callbacks.@O@ clientinfo.@O@ compress.@O@ \
db.@O@ dbiterator.@O@ dbtable.@O@ diff.@O@ dispatch.@O@ \
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ iptable.@O@ \
journal.@O@ keydata.@O@ keytable.@O@ \
dlz.@O@ dns64.@O@ dnssec.@O@ ds.@O@ forward.@O@ geoip.@O@\
iptable.@O@ journal.@O@ keydata.@O@ keytable.@O@ \
lib.@O@ log.@O@ lookup.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ order.@O@ peer.@O@ \
@@ -92,9 +92,9 @@ DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
DNSSRCS = acache.c acl.c adb.c byaddr.c \
cache.c callbacks.c clientinfo.c compress.c \
db.c dbiterator.c dbtable.c diff.c dispatch.c \
dlz.c dns64.c dnssec.c ds.c forward.c iptable.c journal.c \
keydata.c keytable.c lib.c log.c lookup.c \
master.c masterdump.c message.c \
dlz.c dns64.c dnssec.c ds.c forward.c geoip.c \
iptable.c journal.c keydata.c keytable.c lib.c log.c \
lookup.c master.c masterdump.c message.c \
name.c ncache.c nsec.c nsec3.c order.c peer.c portlist.c \
rbt.c rbtdb.c rbtdb64.c rcode.c rdata.c rdatalist.c \
rdataset.c rdatasetiter.c rdataslab.c request.c \

View File

@@ -29,6 +29,7 @@
#include <dns/acl.h>
#include <dns/iptable.h>
/*
* Create a new ACL, including an IP table and an array with room
* for 'n' ACL elements. The elements are uninitialized and the
@@ -386,9 +387,8 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr,
if (matchelt != NULL)
*matchelt = e;
return (ISC_TRUE);
} else {
} else
return (ISC_FALSE);
}
case dns_aclelementtype_nestedacl:
inner = e->nestedacl;
@@ -406,6 +406,10 @@ dns_aclelement_match(const isc_netaddr_t *reqaddr,
inner = env->localnets;
break;
#ifdef HAVE_GEOIP
case dns_aclelementtype_geoip:
return (dns_geoip_match(reqaddr, env->geoip, &e->geoip_elem));
#endif
default:
/* Should be impossible. */
INSIST(0);
@@ -560,7 +564,7 @@ dns_acl_isinsecure(const dns_acl_t *a) {
insecure = insecure_prefix_found;
UNLOCK(&insecure_prefix_lock);
if (insecure)
return(ISC_TRUE);
return (ISC_TRUE);
/* Now check non-radix elements */
for (i = 0; i < a->length; i++) {
@@ -609,6 +613,9 @@ dns_aclenv_init(isc_mem_t *mctx, dns_aclenv_t *env) {
if (result != ISC_R_SUCCESS)
goto cleanup_localhost;
env->match_mapped = ISC_FALSE;
#ifdef HAVE_GEOIP
env->geoip = NULL;
#endif
return (ISC_R_SUCCESS);
cleanup_localhost:

775
lib/dns/geoip.c Normal file
View File

@@ -0,0 +1,775 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*! \file */
#include <config.h>
#include <isc/util.h>
#include <isc/mem.h>
#include <isc/once.h>
#include <isc/string.h>
#include <dns/acl.h>
#include <dns/geoip.h>
#include <isc/thread.h>
#include <math.h>
#include <netinet/in.h>
#include <dns/log.h>
#ifdef HAVE_GEOIP
#include <GeoIP.h>
#include <GeoIPCity.h>
/*
* This structure preserves state from the previous GeoIP lookup,
* so that successive lookups for the same data from the same IP
* address will not require repeated calls into the GeoIP library
* to look up data in the database. This should improve performance
* somwhat.
*
* For lookups in the City and Region databases, we preserve pointers
* to the GeoIPRecord and GeoIPregion structures; these will need to be
* freed by GeoIPRecord_delete() and GeoIPRegion_delete().
*
* for lookups in ISP, AS, Org and Domain we prserve a pointer to
* the returned name; these must be freed by free().
*
* For lookups in Country we preserve a pointer to the text of
* the country code, name, etc (we use a different pointer for this
* than for the names returned by Org, ISP, etc, because those need
* to be freed but country lookups do not).
*
* For lookups in Netspeed we preserve the returned ID.
*
* XXX: Currently this mechanism is only used for IPv4 lookups; the
* family and addr6 fields are to be used IPv6 is added.
*/
typedef struct geoip_state {
isc_uint16_t subtype;
unsigned int family;
isc_uint32_t ipnum;
geoipv6_t ipnum6;
GeoIPRecord *record;
GeoIPRegion *region;
const char *text;
char *name;
int id;
isc_mem_t *mctx;
} geoip_state_t;
#ifdef ISC_PLATFORM_USETHREADS
static isc_mutex_t key_mutex;
static isc_boolean_t state_key_initialized = ISC_FALSE;
static isc_thread_key_t state_key;
static isc_once_t mutex_once = ISC_ONCE_INIT;
static isc_mem_t *state_mctx = NULL;
static void
key_mutex_init(void) {
RUNTIME_CHECK(isc_mutex_init(&key_mutex) == ISC_R_SUCCESS);
}
static void
free_state(void *arg) {
geoip_state_t *state = arg;
if (state != NULL && state->record != NULL)
GeoIPRecord_delete(state->record);
if (state != NULL)
isc_mem_putanddetach(&state->mctx,
state, sizeof(geoip_state_t));
isc_thread_key_setspecific(state_key, NULL);
}
static isc_result_t
state_key_init(void) {
isc_result_t result;
result = isc_once_do(&mutex_once, key_mutex_init);
if (result != ISC_R_SUCCESS)
return (result);
if (!state_key_initialized) {
LOCK(&key_mutex);
if (!state_key_initialized) {
if (state_mctx == NULL)
result = isc_mem_create2(0, 0, &state_mctx, 0);
if (result != ISC_R_SUCCESS)
goto unlock;
isc_mem_setname(state_mctx, "geoip_state", NULL);
isc_mem_setdestroycheck(state_mctx, ISC_FALSE);
int ret = isc_thread_key_create(&state_key, free_state);
if (ret == 0)
state_key_initialized = ISC_TRUE;
else
result = ISC_R_FAILURE;
}
unlock:
UNLOCK(&key_mutex);
}
return (result);
}
#else
geoip_state_t prev_state;
#endif
static void
clean_state(geoip_state_t *state) {
if (state == NULL)
return;
if (state->record != NULL)
GeoIPRecord_delete(state->record);
if (state->region != NULL)
GeoIPRegion_delete(state->region);
if (state->name != NULL)
free (state->name);
state->ipnum = 0;
state->text = NULL;
state->id = 0;
}
static isc_result_t
set_state(unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6,
dns_geoip_subtype_t subtype, GeoIPRecord *record,
GeoIPRegion *region, char *name, const char *text, int id)
{
isc_result_t result;
geoip_state_t *state = NULL;
#ifdef ISC_PLATFORM_USETHREADS
result = state_key_init();
if (result != ISC_R_SUCCESS)
return (result);
state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
if (state == NULL) {
state = (geoip_state_t *) isc_mem_get(state_mctx,
sizeof(geoip_state_t));
if (state == NULL)
return (ISC_R_NOMEMORY);
memset(state, 0, sizeof(*state));
result = isc_thread_key_setspecific(state_key, state);
if (result != ISC_R_SUCCESS) {
isc_mem_put(state_mctx, state, sizeof(geoip_state_t));
return (result);
}
isc_mem_attach(state_mctx, &state->mctx);
} else
clean_state(state);
#else
state = &prev_state;
if (state->ipnum != ipnum)
clean_state(state);
#endif
if (family == AF_INET)
state->ipnum = ipnum;
else
state->ipnum6 = *ipnum6;
state->family = family;
state->subtype = subtype;
state->record = record;
state->region = region;
state->name = name;
state->text = text;
state->id = id;
return (ISC_R_SUCCESS);
}
static geoip_state_t *
get_state() {
#ifdef ISC_PLATFORM_USETHREADS
isc_result_t result;
geoip_state_t *state;
result = state_key_init();
if (result != ISC_R_SUCCESS)
return (NULL);
state = (geoip_state_t *) isc_thread_key_getspecific(state_key);
return (state);
#else
return (&prev_state);
#endif
}
/*
* Country lookups are performed if the previous lookup was from a
* different IP address than the current, or was for a search of a
* different subtype.
*/
static const char *
country_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
unsigned int family,
isc_uint32_t ipnum, const geoipv6_t *ipnum6)
{
geoip_state_t *prev_state = NULL;
const char *text = NULL;
REQUIRE(db != NULL);
#ifndef HAVE_GEOIP_V6
/* no IPv6 support? give up now */
if (family == AF_INET6)
return (NULL);
#endif
prev_state = get_state();
if (prev_state != NULL &&
prev_state->subtype == subtype &&
((prev_state->family == AF_INET && prev_state->ipnum == ipnum) ||
(prev_state->family == AF_INET6 &&
memcmp(prev_state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0)))
text = prev_state->text;
if (text == NULL) {
switch (subtype) {
case dns_geoip_country_code:
if (family == AF_INET)
text = GeoIP_country_code_by_ipnum(db, ipnum);
#ifdef HAVE_GEOIP_V6
else
text = GeoIP_country_code_by_ipnum_v6(db,
*ipnum6);
#endif
break;
case dns_geoip_country_code3:
if (family == AF_INET)
text = GeoIP_country_code3_by_ipnum(db, ipnum);
#ifdef HAVE_GEOIP_V6
else
text = GeoIP_country_code3_by_ipnum_v6(db,
*ipnum6);
#endif
break;
case dns_geoip_country_name:
if (family == AF_INET)
text = GeoIP_country_name_by_ipnum(db, ipnum);
#ifdef HAVE_GEOIP_V6
else
text = GeoIP_country_name_by_ipnum_v6(db,
*ipnum6);
#endif
break;
default:
INSIST(0);
}
set_state(family, ipnum, ipnum6, subtype,
NULL, NULL, NULL, text, 0);
}
return (text);
}
static char *
city_string(GeoIPRecord *record, dns_geoip_subtype_t subtype, int *maxlen) {
const char *s;
char *deconst;
REQUIRE(record != NULL);
REQUIRE(maxlen != NULL);
/* Set '*maxlen' to the maximum length of this subtype, if any */
switch (subtype) {
case dns_geoip_city_countrycode:
case dns_geoip_city_region:
case dns_geoip_city_continentcode:
*maxlen = 2;
break;
case dns_geoip_city_countrycode3:
*maxlen = 3;
break;
default:
/* No fixed length; just use strcasecmp() for comparison */
*maxlen = 255;
}
switch (subtype) {
case dns_geoip_city_countrycode:
return (record->country_code);
case dns_geoip_city_countrycode3:
return (record->country_code3);
case dns_geoip_city_countryname:
return (record->country_name);
case dns_geoip_city_region:
return (record->region);
case dns_geoip_city_regionname:
s = GeoIP_region_name_by_code(record->country_code,
record->region);
DE_CONST(s, deconst);
return (deconst);
case dns_geoip_city_name:
return (record->city);
case dns_geoip_city_postalcode:
return (record->postal_code);
case dns_geoip_city_continentcode:
return (record->continent_code);
case dns_geoip_city_timezonecode:
s = GeoIP_time_zone_by_country_and_region(record->country_code,
record->region);
DE_CONST(s, deconst);
return (deconst);
default:
INSIST(0);
}
}
static isc_boolean_t
is_city(dns_geoip_subtype_t subtype) {
switch (subtype) {
case dns_geoip_city_countrycode:
case dns_geoip_city_countrycode3:
case dns_geoip_city_countryname:
case dns_geoip_city_region:
case dns_geoip_city_regionname:
case dns_geoip_city_name:
case dns_geoip_city_postalcode:
case dns_geoip_city_continentcode:
case dns_geoip_city_timezonecode:
case dns_geoip_city_metrocode:
case dns_geoip_city_areacode:
return (ISC_TRUE);
default:
return (ISC_FALSE);
}
}
/*
* GeoIPRecord lookups are performed if the previous lookup was
* from a different IP address than the current, or was for a search
* outside the City database.
*/
static GeoIPRecord *
city_lookup(GeoIP *db, dns_geoip_subtype_t subtype,
unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6)
{
GeoIPRecord *record = NULL;
geoip_state_t *prev_state = NULL;
REQUIRE(db != NULL);
#ifndef HAVE_GEOIP_V6
/* no IPv6 support? give up now */
if (family == AF_INET6)
return (NULL);
#endif
prev_state = get_state();
if (prev_state != NULL &&
is_city(prev_state->subtype) &&
((prev_state->family == AF_INET && prev_state->ipnum == ipnum) ||
(prev_state->family == AF_INET6 &&
memcmp(prev_state->ipnum6.s6_addr, ipnum6->s6_addr, 16) == 0)))
record = prev_state->record;
if (record == NULL) {
if (family == AF_INET)
record = GeoIP_record_by_ipnum(db, ipnum);
#ifdef HAVE_GEOIP_V6
else
record = GeoIP_record_by_ipnum_v6(db, *ipnum6);
#endif
if (record == NULL)
return (NULL);
set_state(family, ipnum, ipnum6, subtype,
record, NULL, NULL, NULL, 0);
}
return (record);
}
static char *
region_string(GeoIPRegion *region, dns_geoip_subtype_t subtype, int *maxlen) {
const char *s;
char *deconst;
REQUIRE(region != NULL);
REQUIRE(maxlen != NULL);
switch (subtype) {
case dns_geoip_region_countrycode:
*maxlen = 2;
return (region->country_code);
case dns_geoip_region_code:
*maxlen = 2;
return (region->region);
case dns_geoip_region_name:
*maxlen = 255;
s = GeoIP_region_name_by_code(region->country_code,
region->region);
DE_CONST(s, deconst);
return (deconst);
default:
INSIST(0);
}
}
static isc_boolean_t
is_region(dns_geoip_subtype_t subtype) {
switch (subtype) {
case dns_geoip_region_countrycode:
case dns_geoip_region_code:
return (ISC_TRUE);
default:
return (ISC_FALSE);
}
}
/*
* GeoIPRegion lookups are performed if the previous lookup was
* from a different IP address than the current, or was for a search
* outside the Region database.
*/
static GeoIPRegion *
region_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) {
GeoIPRegion *region = NULL;
geoip_state_t *prev_state = NULL;
REQUIRE(db != NULL);
prev_state = get_state();
if (prev_state != NULL && prev_state->ipnum == ipnum &&
is_region(prev_state->subtype))
region = prev_state->region;
if (region == NULL) {
region = GeoIP_region_by_ipnum(db, ipnum);
if (region == NULL)
return (NULL);
set_state(AF_INET, ipnum, NULL,
subtype, NULL, region, NULL, NULL, 0);
}
return (region);
}
/*
* ISP, Organization, AS Number and Domain lookups are performed if
* the previous lookup was from a different IP address than the current,
* or was for a search of a different subtype.
*/
static char *
name_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) {
char *name = NULL;
geoip_state_t *prev_state = NULL;
REQUIRE(db != NULL);
prev_state = get_state();
if (prev_state != NULL && prev_state->ipnum == ipnum &&
prev_state->subtype == subtype)
name = prev_state->name;
if (name == NULL) {
name = GeoIP_name_by_ipnum(db, ipnum);
if (name == NULL)
return (NULL);
set_state(AF_INET, ipnum, NULL,
subtype, NULL, NULL, name, NULL, 0);
}
return (name);
}
/*
* Netspeed lookups are performed if the previous lookup was from a
* different IP address than the current, or was for a search of a
* different subtype.
*/
static int
netspeed_lookup(GeoIP *db, dns_geoip_subtype_t subtype, isc_uint32_t ipnum) {
geoip_state_t *prev_state = NULL;
isc_boolean_t found = ISC_FALSE;
int id;
REQUIRE(db != NULL);
prev_state = get_state();
if (prev_state != NULL && prev_state->ipnum == ipnum &&
prev_state->subtype == subtype) {
id = prev_state->id;
found = ISC_TRUE;
}
if (!found) {
id = GeoIP_id_by_ipnum(db, ipnum);
set_state(AF_INET, ipnum, NULL,
subtype, NULL, NULL, NULL, NULL, id);
}
return (id);
}
#endif /* HAVE_GEOIP */
#define DB46(addr, geoip, name) \
((addr->family == AF_INET) ? (geoip->name##_v4) : (geoip->name##_v6))
/*
* Find the best database to answer a generic subtype
*/
static dns_geoip_subtype_t
fix_subtype(const isc_netaddr_t *reqaddr, const dns_geoip_databases_t *geoip,
dns_geoip_subtype_t subtype)
{
dns_geoip_subtype_t ret = subtype;
switch (subtype) {
case dns_geoip_countrycode:
if (DB46(reqaddr, geoip, city) != NULL)
ret = dns_geoip_city_countrycode;
else if (reqaddr->family == AF_INET && geoip->region != NULL)
ret = dns_geoip_region_countrycode;
else if (DB46(reqaddr, geoip, country) != NULL)
ret = dns_geoip_country_code;
break;
case dns_geoip_countrycode3:
if (DB46(reqaddr, geoip, city) != NULL)
ret = dns_geoip_city_countrycode3;
else if (DB46(reqaddr, geoip, country) != NULL)
ret = dns_geoip_country_code3;
break;
case dns_geoip_countryname:
if (DB46(reqaddr, geoip, city) != NULL)
ret = dns_geoip_city_countryname;
else if (DB46(reqaddr, geoip, country) != NULL)
ret = dns_geoip_country_name;
break;
case dns_geoip_region:
if (DB46(reqaddr, geoip, city) != NULL)
ret = dns_geoip_city_region;
else if (reqaddr->family == AF_INET && geoip->region != NULL)
ret = dns_geoip_region_code;
break;
case dns_geoip_regionname:
if (DB46(reqaddr, geoip, city) != NULL)
ret = dns_geoip_city_regionname;
else if (reqaddr->family == AF_INET && geoip->region != NULL)
ret = dns_geoip_region_name;
break;
default:
break;
}
return (ret);
}
isc_boolean_t
dns_geoip_match(const isc_netaddr_t *reqaddr,
const dns_geoip_databases_t *geoip,
const dns_geoip_elem_t *elt)
{
#ifndef HAVE_GEOIP
UNUSED(reqaddr);
UNUSED(geoip);
UNUSED(elt);
return (ISC_FALSE);
#else
GeoIP *db;
GeoIPRecord *record;
GeoIPRegion *region;
dns_geoip_subtype_t subtype;
isc_uint32_t ipnum = 0;
int maxlen = 0, id;
const char *cs;
char *s;
#ifdef HAVE_GEOIP_V6
const geoipv6_t *ipnum6 = NULL;
#else
const void *ipnum6 = NULL;
#endif
INSIST(geoip != NULL);
switch (reqaddr->family) {
case AF_INET:
ipnum = ntohl(reqaddr->type.in.s_addr);
break;
case AF_INET6:
#ifdef HAVE_GEOIP_V6
ipnum6 = &reqaddr->type.in6;
break;
#else
return (ISC_FALSE);
#endif
default:
return (ISC_FALSE);
}
subtype = fix_subtype(reqaddr, geoip, elt->subtype);
switch (subtype) {
case dns_geoip_country_code:
maxlen = 2;
goto getcountry;
case dns_geoip_country_code3:
maxlen = 3;
goto getcountry;
case dns_geoip_country_name:
maxlen = 255;
getcountry:
db = DB46(reqaddr, geoip, country);
INSIST(db != NULL);
INSIST(elt->as_string != NULL);
cs = country_lookup(db, subtype, reqaddr->family,
ipnum, ipnum6);
if (cs != NULL && strncasecmp(elt->as_string, cs, maxlen) == 0)
return (ISC_TRUE);
break;
case dns_geoip_city_countrycode:
case dns_geoip_city_countrycode3:
case dns_geoip_city_countryname:
case dns_geoip_city_region:
case dns_geoip_city_regionname:
case dns_geoip_city_name:
case dns_geoip_city_postalcode:
case dns_geoip_city_continentcode:
case dns_geoip_city_timezonecode:
INSIST(elt->as_string != NULL);
db = DB46(reqaddr, geoip, city);
record = city_lookup(db, subtype,
reqaddr->family, ipnum, ipnum6);
if (record == NULL)
break;
s = city_string(record, subtype, &maxlen);
INSIST(maxlen != 0);
if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0)
return (ISC_TRUE);
break;
case dns_geoip_city_metrocode:
db = DB46(reqaddr, geoip, city);
record = city_lookup(db, subtype,
reqaddr->family, ipnum, ipnum6);
if (record == NULL)
break;
if (elt->as_int == record->metro_code)
return (ISC_TRUE);
break;
case dns_geoip_city_areacode:
db = DB46(reqaddr, geoip, city);
record = city_lookup(db, subtype,
reqaddr->family, ipnum, ipnum6);
if (record == NULL)
break;
if (elt->as_int == record->area_code)
return (ISC_TRUE);
break;
case dns_geoip_region_countrycode:
case dns_geoip_region_code:
case dns_geoip_region_name:
INSIST(geoip->region != NULL);
INSIST(elt->as_string != NULL);
/* Region DB is not supported for IPv6 */
if (reqaddr->family == AF_INET6)
return (ISC_FALSE);
region = region_lookup(geoip->region, subtype, ipnum);
if (region == NULL)
break;
s = region_string(region, subtype, &maxlen);
INSIST(maxlen != 0);
if (s != NULL && strncasecmp(elt->as_string, s, maxlen) == 0)
return (ISC_TRUE);
break;
case dns_geoip_isp_name:
db = geoip->isp;
goto getname;
case dns_geoip_org_name:
db = geoip->org;
goto getname;
case dns_geoip_as_asnum:
db = geoip->as;
goto getname;
case dns_geoip_domain_name:
db = geoip->domain;
getname:
INSIST(db != NULL);
INSIST(elt->as_string != NULL);
/* ISP, Org, AS, and Domain are not supported for IPv6 */
if (reqaddr->family == AF_INET6)
return (ISC_FALSE);
s = name_lookup(db, subtype, ipnum);
if (s != NULL && strcasecmp(elt->as_string, s) == 0)
return (ISC_TRUE);
break;
case dns_geoip_netspeed_id:
INSIST(geoip->netspeed != NULL);
/* Netspeed DB is not supported for IPv6 */
if (reqaddr->family == AF_INET6)
return (ISC_FALSE);
id = netspeed_lookup(geoip->netspeed, subtype, ipnum);
if (id == elt->as_int)
return (ISC_TRUE);
break;
default:
INSIST(0);
}
return (ISC_FALSE);
#endif
}
void
dns_geoip_shutdown(void) {
#if defined(HAVE_GEOIP) && defined(ISC_PLATFORM_USETHREADS)
if (state_mctx != NULL)
isc_mem_detach(&state_mctx);
#else
return;
#endif
}

View File

@@ -23,13 +23,14 @@ top_srcdir = @top_srcdir@
HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h cert.h compress.h \
clientinfo.h db.h dbiterator.h dbtable.h diff.h dispatch.h \
dlz.h dnssec.h ds.h dsdigest.h events.h fixedname.h iptable.h \
journal.h keyflags.h keytable.h keyvalues.h lib.h log.h \
master.h masterdump.h message.h name.h ncache.h nsec.h \
peer.h portlist.h private.h rbt.h rcode.h \
rdata.h rdataclass.h rdatalist.h rdataset.h rdatasetiter.h \
rdataslab.h rdatatype.h request.h resolver.h result.h \
rootns.h rpz.h sdb.h sdlz.h secalg.h secproto.h soa.h ssu.h \
dlz.h dnssec.h ds.h dsdigest.h events.h fixedname.h geoip.h \
iptable.h journal.h keyflags.h keytable.h keyvalues.h \
lib.h log.h master.h masterdump.h message.h \
name.h ncache.h nsec.h peer.h portlist.h private.h \
rbt.h rcode.h rdata.h rdataclass.h rdatalist.h \
rdataset.h rdatasetiter.h rdataslab.h rdatatype.h \
request.h resolver.h result.h rootns.h rpz.h \
sdb.h sdlz.h secalg.h secproto.h soa.h ssu.h \
tcpmsg.h time.h tkey.h tsig.h ttl.h types.h \
validator.h version.h view.h xfrin.h zone.h zonekey.h zt.h

View File

@@ -38,10 +38,15 @@
#include <isc/netaddr.h>
#include <isc/refcount.h>
#include <dns/geoip.h>
#include <dns/name.h>
#include <dns/types.h>
#include <dns/iptable.h>
#ifdef HAVE_GEOIP
#include <GeoIP.h>
#endif
/***
*** Types
***/
@@ -52,8 +57,11 @@ typedef enum {
dns_aclelementtype_nestedacl,
dns_aclelementtype_localhost,
dns_aclelementtype_localnets,
#ifdef HAVE_GEOIP
dns_aclelementtype_geoip,
#endif /* HAVE_GEOIP */
dns_aclelementtype_any
} dns_aclelemettype_t;
} dns_aclelementtype_t;
typedef struct dns_aclipprefix dns_aclipprefix_t;
@@ -63,9 +71,12 @@ struct dns_aclipprefix {
};
struct dns_aclelement {
dns_aclelemettype_t type;
dns_aclelementtype_t type;
isc_boolean_t negative;
dns_name_t keyname;
#ifdef HAVE_GEOIP
dns_geoip_elem_t geoip_elem;
#endif /* HAVE_GEOIP */
dns_acl_t *nestedacl;
int node_num;
};
@@ -88,6 +99,9 @@ struct dns_aclenv {
dns_acl_t *localhost;
dns_acl_t *localnets;
isc_boolean_t match_mapped;
#ifdef HAVE_GEOIP
dns_geoip_databases_t *geoip;
#endif
};
#define DNS_ACL_MAGIC ISC_MAGIC('D','a','c','l')

119
lib/dns/include/dns/geoip.h Normal file
View File

@@ -0,0 +1,119 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef DNS_GEOIP_H
#define DNS_GEOIP_H 1
/*****
***** Module Info
*****/
/*! \file dns/acl.h
* \brief
* Address match list handling.
*/
/***
*** Imports
***/
#include <isc/lang.h>
#include <isc/magic.h>
#include <isc/netaddr.h>
#include <isc/refcount.h>
#include <dns/name.h>
#include <dns/types.h>
#include <dns/iptable.h>
#ifdef HAVE_GEOIP
#include <GeoIP.h>
#else
typedef void GeoIP;
#endif
/***
*** Types
***/
typedef enum {
dns_geoip_countrycode,
dns_geoip_countrycode3,
dns_geoip_countryname,
dns_geoip_region,
dns_geoip_regionname,
dns_geoip_country_code,
dns_geoip_country_code3,
dns_geoip_country_name,
dns_geoip_region_countrycode,
dns_geoip_region_code,
dns_geoip_region_name,
dns_geoip_city_countrycode,
dns_geoip_city_countrycode3,
dns_geoip_city_countryname,
dns_geoip_city_region,
dns_geoip_city_regionname,
dns_geoip_city_name,
dns_geoip_city_postalcode,
dns_geoip_city_metrocode,
dns_geoip_city_areacode,
dns_geoip_city_continentcode,
dns_geoip_city_timezonecode,
dns_geoip_isp_name,
dns_geoip_org_name,
dns_geoip_as_asnum,
dns_geoip_domain_name,
dns_geoip_netspeed_id
} dns_geoip_subtype_t;
typedef struct dns_geoip_elem {
dns_geoip_subtype_t subtype;
GeoIP *db;
union {
char as_string[256];
int as_int;
};
} dns_geoip_elem_t;
typedef struct dns_geoip_databases {
GeoIP *country_v4; /* DB 1 */
GeoIP *city_v4; /* DB 2 or 6 */
GeoIP *region; /* DB 3 or 7 */
GeoIP *isp; /* DB 4 */
GeoIP *org; /* DB 5 */
GeoIP *as; /* DB 9 */
GeoIP *netspeed; /* DB 10 */
GeoIP *domain; /* DB 11 */
GeoIP *country_v6; /* DB 12 */
GeoIP *city_v6; /* DB 30 or 31 */
} dns_geoip_databases_t;
/***
*** Functions
***/
ISC_LANG_BEGINDECLS
isc_boolean_t
dns_geoip_match(const isc_netaddr_t *reqaddr,
const dns_geoip_databases_t *geoip,
const dns_geoip_elem_t *elt);
void
dns_geoip_shutdown(void);
ISC_LANG_ENDDECLS
#endif /* DNS_GEOIP_H */

View File

@@ -39,15 +39,15 @@ LIBS = @LIBS@ @ATFLIBS@
OBJS = dnstest.@O@
SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \
private_test.c update_test.c zonemgr_test.c zt_test.c \
dbdiff_test.c nsec3_test.c dispatch_test.c rbt_test.c \
rdata_test.c rdataset_test.c rdatasetstats_test.c
dbdiff_test.c geoip_test.c nsec3_test.c dispatch_test.c \
rbt_test.c rdata_test.c rdataset_test.c rdatasetstats_test.c
SUBDIRS =
TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \
private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \
zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ \
nsec3_test@EXEEXT@ dispatch_test@EXEEXT@ rbt_test@EXEEXT@ \
rdata_test@EXEEXT@ rdataset_test@EXEEXT@ \
geoip_test@EXEEXT@ nsec3_test@EXEEXT@ dispatch_test@EXEEXT@ \
rbt_test@EXEEXT@ rdata_test@EXEEXT@ rdataset_test@EXEEXT@ \
rdatasetstats_test@EXEEXT@
@BIND9_MAKE_RULES@
@@ -134,6 +134,11 @@ rdata_test@EXEEXT@: rdata_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
rdata_test.@O@ ${DNSLIBS} ${ISCLIBS} ${LIBS}
geoip_test@EXEEXT@: geoip_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
geoip_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS}
unit::
sh ${top_srcdir}/unit/unittest.sh

703
lib/dns/tests/geoip_test.c Normal file
View File

@@ -0,0 +1,703 @@
/*
* Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id$ */
/*! \file */
#include <config.h>
#include <atf-c.h>
#include <unistd.h>
#include <isc/types.h>
#include <dns/geoip.h>
#include "dnstest.h"
#ifdef HAVE_GEOIP
#include <GeoIP.h>
/* We use GeoIP databases from the 'geoip' system test */
#define GEOIP_DATA "../../../bin/tests/system/geoip/data"
/*
* Helper functions
* (Mostly copied from bin/named/geoip.c)
*/
static dns_geoip_databases_t geoip = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static void
init_geoip_db(GeoIP **dbp, GeoIPDBTypes edition,
GeoIPOptions method, const char *name)
{
char *info;
GeoIP *db;
REQUIRE(dbp != NULL);
db = *dbp;
if (db != NULL) {
GeoIP_delete(db);
db = *dbp = NULL;
}
if (! GeoIP_db_avail(edition)) {
fprintf(stderr, "GeoIP %s DB not available\n", name);
return;
}
fprintf(stderr, "initializing GeoIP %s DB\n", name);
db = GeoIP_open_type(edition, method);
if (db == NULL) {
fprintf(stderr, "failed to initialize GeoIP %s DB; "
"geoip matches using this database will fail\n",
name);
return;
}
info = GeoIP_database_info(db);
if (info != NULL)
fprintf(stderr, "%s\n", info);
*dbp = db;
}
static GeoIPDBTypes
choose_rev(GeoIPDBTypes primary, GeoIPDBTypes secondary, const char *name) {
if (GeoIP_db_avail(primary))
return (primary);
if (GeoIP_db_avail(secondary))
return (secondary);
fprintf(stderr, "GeoIP %s DB: neither revision available\n", name);
return (0);
}
static void
load_geoip(const char *dir) {
GeoIPOptions method;
GeoIPDBTypes edition;
#ifdef _WIN32
method = GEOIP_STANDARD;
#else
method = GEOIP_MMAP_CACHE;
#endif
if (dir != NULL) {
char *p;
DE_CONST(dir, p);
GeoIP_setup_custom_directory(p);
}
init_geoip_db(&geoip.country_v4, GEOIP_COUNTRY_EDITION,
method, "Country (IPv4)");
#ifdef HAVE_GEOIP_V6
init_geoip_db(&geoip.country_v6, GEOIP_COUNTRY_EDITION_V6,
method, "Country (IPv6)");
#endif
edition = choose_rev(GEOIP_CITY_EDITION_REV0,
GEOIP_CITY_EDITION_REV1, "City (IPv4)");
if (edition != 0)
init_geoip_db(&geoip.city_v4, edition, method, "City (IPv4)");
#if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6)
edition = choose_rev(GEOIP_CITY_EDITION_REV0_V6,
GEOIP_CITY_EDITION_REV1_V6, "City (IPv6)");
if (edition != 0)
init_geoip_db(&geoip.city_v6, edition, method, "City (IPv6)");
#endif
edition = choose_rev(GEOIP_REGION_EDITION_REV0,
GEOIP_REGION_EDITION_REV1, "Region");
if (edition != 0)
init_geoip_db(&geoip.region, edition, method, "Region");
init_geoip_db(&geoip.isp, GEOIP_ISP_EDITION,
method, "ISP");
init_geoip_db(&geoip.org, GEOIP_ORG_EDITION,
method, "Org");
init_geoip_db(&geoip.as, GEOIP_ASNUM_EDITION,
method, "AS");
init_geoip_db(&geoip.domain, GEOIP_DOMAIN_EDITION,
method, "Domain");
init_geoip_db(&geoip.netspeed, GEOIP_NETSPEED_EDITION,
method, "NetSpeed");
}
static isc_boolean_t
do_lookup_string(const char *addr, dns_geoip_subtype_t subtype,
const char *string)
{
dns_geoip_elem_t elt;
struct in_addr in4;
isc_netaddr_t na;
inet_pton(AF_INET, addr, &in4);
isc_netaddr_fromin(&na, &in4);
elt.subtype = subtype;
strcpy(elt.as_string, string);
return (dns_geoip_match(&na, &geoip, &elt));
}
static isc_boolean_t
do_lookup_string_v6(const char *addr, dns_geoip_subtype_t subtype,
const char *string)
{
dns_geoip_elem_t elt;
struct in6_addr in6;
isc_netaddr_t na;
inet_pton(AF_INET6, addr, &in6);
isc_netaddr_fromin6(&na, &in6);
elt.subtype = subtype;
strcpy(elt.as_string, string);
return (dns_geoip_match(&na, &geoip, &elt));
}
static isc_boolean_t
do_lookup_int(const char *addr, dns_geoip_subtype_t subtype, int id) {
dns_geoip_elem_t elt;
struct in_addr in4;
isc_netaddr_t na;
inet_pton(AF_INET, addr, &in4);
isc_netaddr_fromin(&na, &in4);
elt.subtype = subtype;
elt.as_int = id;
return (dns_geoip_match(&na, &geoip, &elt));
}
/*
* Individual unit tests
*/
/* GeoIP country matching */
ATF_TC(country);
ATF_TC_HEAD(country, tc) {
atf_tc_set_md_var(tc, "descr", "test country database matching");
}
ATF_TC_BODY(country, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.country_v4 == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.1", dns_geoip_country_code, "AU");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_country_code3, "AUS");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_country_name, "Australia");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP country (ipv6) matching */
ATF_TC(country_v6);
ATF_TC_HEAD(country_v6, tc) {
atf_tc_set_md_var(tc, "descr", "test country (ipv6) database matching");
}
ATF_TC_BODY(country_v6, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.country_v6 == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_country_code, "AU");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_country_code3, "AUS");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_country_name, "Australia");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP city (ipv4) matching */
ATF_TC(city);
ATF_TC_HEAD(city, tc) {
atf_tc_set_md_var(tc, "descr", "test city database matching");
}
ATF_TC_BODY(city, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.city_v4 == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.1",
dns_geoip_city_continentcode, "NA");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_countrycode, "US");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_countrycode3, "USA");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_countryname, "United States");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_region, "CA");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_regionname, "California");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_name, "Redwood City");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_city_postalcode, "94063");
ATF_CHECK(match);
match = do_lookup_int("10.53.0.1", dns_geoip_city_areacode, 650);
ATF_CHECK(match);
match = do_lookup_int("10.53.0.1", dns_geoip_city_metrocode, 807);
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP city (ipv6) matching */
ATF_TC(city_v6);
ATF_TC_HEAD(city_v6, tc) {
atf_tc_set_md_var(tc, "descr", "test city (ipv6) database matching");
}
ATF_TC_BODY(city_v6, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.city_v6 == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_continentcode, "NA");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_countrycode, "US");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_countrycode3, "USA");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_countryname,
"United States");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_region, "CA");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_regionname, "California");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_name, "Redwood City");
ATF_CHECK(match);
match = do_lookup_string_v6("fd92:7065:b8e:ffff::1",
dns_geoip_city_postalcode, "94063");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP region matching */
ATF_TC(region);
ATF_TC_HEAD(region, tc) {
atf_tc_set_md_var(tc, "descr", "test region database matching");
}
ATF_TC_BODY(region, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.region == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.1",
dns_geoip_region_code, "CA");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_region_name, "California");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.1",
dns_geoip_region_countrycode, "US");
ATF_CHECK(match);
dns_test_end();
}
/*
* GeoIP best-database matching
* (With no specified databse and a city database available, answers
* should come from city database. With city database unavailable, region
* database. Region database unavailable, country database.)
*/
ATF_TC(best);
ATF_TC_HEAD(best, tc) {
atf_tc_set_md_var(tc, "descr", "test best database matching");
}
ATF_TC_BODY(best, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.region == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.4",
dns_geoip_countrycode, "US");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_countrycode3, "USA");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_countryname, "United States");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_regionname, "Virginia");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_region, "VA");
ATF_CHECK(match);
GeoIP_delete(geoip.city_v4);
geoip.city_v4 = NULL;
match = do_lookup_string("10.53.0.4",
dns_geoip_countrycode, "AU");
ATF_CHECK(match);
/*
* Note, region doesn't support code3 or countryname, so
* the next two would be answered from the country database instead
*/
match = do_lookup_string("10.53.0.4",
dns_geoip_countrycode3, "CAN");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_countryname, "Canada");
ATF_CHECK(match);
GeoIP_delete(geoip.region);
geoip.region = NULL;
match = do_lookup_string("10.53.0.4",
dns_geoip_countrycode, "CA");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_countrycode3, "CAN");
ATF_CHECK(match);
match = do_lookup_string("10.53.0.4",
dns_geoip_countryname, "Canada");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP asnum matching */
ATF_TC(asnum);
ATF_TC_HEAD(asnum, tc) {
atf_tc_set_md_var(tc, "descr", "test asnum database matching");
}
ATF_TC_BODY(asnum, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.as == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.3", dns_geoip_as_asnum,
"AS100003 Three Network Labs");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP isp matching */
ATF_TC(isp);
ATF_TC_HEAD(isp, tc) {
atf_tc_set_md_var(tc, "descr", "test isp database matching");
}
ATF_TC_BODY(isp, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.isp == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.1", dns_geoip_isp_name,
"One Systems, Inc.");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP org matching */
ATF_TC(org);
ATF_TC_HEAD(org, tc) {
atf_tc_set_md_var(tc, "descr", "test org database matching");
}
ATF_TC_BODY(org, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.org == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.2", dns_geoip_org_name,
"Two Technology Ltd.");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP domain matching */
ATF_TC(domain);
ATF_TC_HEAD(domain, tc) {
atf_tc_set_md_var(tc, "descr", "test domain database matching");
}
ATF_TC_BODY(domain, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.domain == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_string("10.53.0.4",
dns_geoip_domain_name, "four.com");
ATF_CHECK(match);
dns_test_end();
}
/* GeoIP netspeed matching */
ATF_TC(netspeed);
ATF_TC_HEAD(netspeed, tc) {
atf_tc_set_md_var(tc, "descr", "test netspeed database matching");
}
ATF_TC_BODY(netspeed, tc) {
isc_result_t result;
isc_boolean_t match;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_TRUE);
ATF_REQUIRE(result == ISC_R_SUCCESS);
/* Use databases from the geoip system test */
load_geoip(GEOIP_DATA);
if (geoip.netspeed == NULL) {
dns_test_end();
atf_tc_skip("Database not available");
}
match = do_lookup_int("10.53.0.1", dns_geoip_netspeed_id, 0);
ATF_CHECK(match);
match = do_lookup_int("10.53.0.2", dns_geoip_netspeed_id, 1);
ATF_CHECK(match);
match = do_lookup_int("10.53.0.3", dns_geoip_netspeed_id, 2);
ATF_CHECK(match);
match = do_lookup_int("10.53.0.4", dns_geoip_netspeed_id, 3);
ATF_CHECK(match);
dns_test_end();
}
#else
ATF_TC(untested);
ATF_TC_HEAD(untested, tc) {
atf_tc_set_md_var(tc, "descr", "skipping geoip test");
}
ATF_TC_BODY(untested, tc) {
UNUSED(tc);
atf_tc_skip("GeoIP not available");
}
#endif
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
#ifdef HAVE_GEOIP
ATF_TP_ADD_TC(tp, country);
ATF_TP_ADD_TC(tp, country_v6);
ATF_TP_ADD_TC(tp, city);
ATF_TP_ADD_TC(tp, city_v6);
ATF_TP_ADD_TC(tp, region);
ATF_TP_ADD_TC(tp, best);
ATF_TP_ADD_TC(tp, asnum);
ATF_TP_ADD_TC(tp, isp);
ATF_TP_ADD_TC(tp, org);
ATF_TP_ADD_TC(tp, domain);
ATF_TP_ADD_TC(tp, netspeed);
#else
ATF_TP_ADD_TC(tp, untested);
#endif
return (atf_no_error());
}

View File

@@ -58,10 +58,8 @@ DNSOBJS = acl.@O@ adb.@O@ byaddr.@O@ \
cache.@O@ callbacks.@O@ client.@O@ compress.@O@ \
db.@O@ dbiterator.@O@ diff.@O@ dispatch.@O@ dlz.@O@ dnssec.@O@ \
ds.@O@ \
forward.@O@ iptable.@O@ \
keytable.@O@ \
lib.@O@ log.@O@ \
master.@O@ masterdump.@O@ message.@O@ \
forward.@O@ geoip.@O@ iptable.@O@ keytable.@O@ \
lib.@O@ log.@O@ master.@O@ masterdump.@O@ message.@O@ \
name.@O@ ncache.@O@ nsec.@O@ nsec3.@O@ \
peer.@O@ portlist.@O@ \
rbt.@O@ rbtdb.@O@ rcode.@O@ rdata.@O@ \
@@ -87,10 +85,8 @@ DSTSRCS = @OPENSSLLINKSRCS@ \
DNSSRCS = acl.c adb.c byaddr.c \
cache.c callbacks.c client.c compress.c \
db.c dbiterator.c diff.c dispatch.c dlz.c dnssec.c ds.c \
forward.c iptable.c \
keytable.c \
lib.c log.c \
master.c masterdump.c message.c \
forward.c geoip.c iptable.c keytable.c \
lib.c log.c master.c masterdump.c message.c \
name.c ncache.c nsec.c nsec3.c \
peer.c portlist.c \
rbt.c rbtdb.c rcode.c rdata.c \

View File

@@ -31,6 +31,11 @@
#include <dns/fixedname.h>
#include <dns/log.h>
#ifdef HAVE_GEOIP
#include <stdlib.h>
#include <math.h>
#endif /* HAVE_GEOIP */
#define LOOP_MAGIC ISC_MAGIC('L','O','O','P')
isc_result_t
@@ -53,6 +58,8 @@ cfg_aclconfctx_create(isc_mem_t *mctx, cfg_aclconfctx_t **ret) {
isc_mem_attach(mctx, &actx->mctx);
ISC_LIST_INIT(actx->named_acl_cache);
actx->geoip = NULL;
*ret = actx;
return (ISC_R_SUCCESS);
@@ -230,12 +237,16 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx,
elt = cfg_list_next(elt)) {
const cfg_obj_t *ce = cfg_listelt_value(elt);
/* negated element; just get the value. */
/* might be a negated element, in which case get the value. */
if (cfg_obj_istuple(ce)) {
ce = cfg_tuple_get(ce, "value");
const cfg_obj_t *negated =
cfg_tuple_get(ce, "negated");
if (! cfg_obj_isvoid(negated)) {
ce = negated;
if (has_negative != NULL)
*has_negative = ISC_TRUE;
}
}
if (cfg_obj_istype(ce, &cfg_type_keyref)) {
n++;
@@ -244,6 +255,12 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx,
n += count_acl_elements(ce, cctx, &negative);
if (negative)
n++;
#ifdef HAVE_GEOIP
} else if (cfg_obj_istuple(ce) &&
cfg_obj_isvoid(cfg_tuple_get(ce, "negated")))
{
n++;
#endif /* HAVE_GEOIP */
} else if (cfg_obj_isstring(ce)) {
const char *name = cfg_obj_asstring(ce);
if (strcasecmp(name, "localhost") == 0 ||
@@ -262,6 +279,267 @@ count_acl_elements(const cfg_obj_t *caml, const cfg_obj_t *cctx,
return n;
}
#ifdef HAVE_GEOIP
static dns_geoip_subtype_t
get_subtype(const cfg_obj_t *obj, isc_log_t *lctx,
dns_geoip_subtype_t subtype, const char *dbname)
{
if (dbname == NULL)
return (subtype);
switch (subtype) {
case dns_geoip_countrycode:
if (strcasecmp(dbname, "city") == 0)
return (dns_geoip_city_countrycode);
else if (strcasecmp(dbname, "region") == 0)
return (dns_geoip_region_countrycode);
else if (strcasecmp(dbname, "country") == 0)
return (dns_geoip_country_code);
cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
"invalid GeoIP DB specified for "
"country search: ignored");
return (subtype);
case dns_geoip_countrycode3:
if (strcasecmp(dbname, "city") == 0)
return (dns_geoip_city_countrycode3);
else if (strcasecmp(dbname, "country") == 0)
return (dns_geoip_country_code3);
cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
"invalid GeoIP DB specified for "
"country search: ignored");
return (subtype);
case dns_geoip_countryname:
if (strcasecmp(dbname, "city") == 0)
return (dns_geoip_city_countryname);
else if (strcasecmp(dbname, "country") == 0)
return (dns_geoip_country_name);
cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
"invalid GeoIP DB specified for "
"country search: ignored");
return (subtype);
case dns_geoip_region:
if (strcasecmp(dbname, "city") == 0)
return (dns_geoip_city_region);
else if (strcasecmp(dbname, "region") == 0)
return (dns_geoip_region_code);
cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
"invalid GeoIP DB specified for "
"region search: ignored");
return (subtype);
case dns_geoip_regionname:
if (strcasecmp(dbname, "city") == 0)
return (dns_geoip_city_region);
else if (strcasecmp(dbname, "region") == 0)
return (dns_geoip_region_name);
cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
"invalid GeoIP DB specified for "
"region search: ignored");
return (subtype);
/*
* Log a warning if the wrong database was specified
* on an unambiguous query
*/
case dns_geoip_city_name:
case dns_geoip_city_postalcode:
case dns_geoip_city_metrocode:
case dns_geoip_city_areacode:
case dns_geoip_city_continentcode:
case dns_geoip_city_timezonecode:
if (strcasecmp(dbname, "city") != 0)
cfg_obj_log(obj, lctx, ISC_LOG_WARNING,
"invalid GeoIP DB specified for "
"a 'city'-only search type: ignoring");
return (subtype);
case dns_geoip_isp_name:
if (strcasecmp(dbname, "isp") != 0)
cfg_obj_log(obj, lctx, ISC_LOG_WARNING,
"invalid GeoIP DB specified for "
"an 'isp' search: ignoring");
return (subtype);
case dns_geoip_org_name:
if (strcasecmp(dbname, "org") != 0)
cfg_obj_log(obj, lctx, ISC_LOG_WARNING,
"invalid GeoIP DB specified for "
"an 'org' search: ignoring");
return (subtype);
case dns_geoip_as_asnum:
if (strcasecmp(dbname, "asnum") != 0)
cfg_obj_log(obj, lctx, ISC_LOG_WARNING,
"invalid GeoIP DB specified for "
"an 'asnum' search: ignoring");
return (subtype);
case dns_geoip_domain_name:
if (strcasecmp(dbname, "domain") != 0)
cfg_obj_log(obj, lctx, ISC_LOG_WARNING,
"invalid GeoIP DB specified for "
"a 'domain' search: ignoring");
return (subtype);
case dns_geoip_netspeed_id:
if (strcasecmp(dbname, "netspeed") != 0)
cfg_obj_log(obj, lctx, ISC_LOG_WARNING,
"invalid GeoIP DB specified for "
"a 'netspeed' search: ignoring");
return (subtype);
default:
INSIST(0);
}
}
static isc_boolean_t
geoip_can_answer(dns_aclelement_t *elt, cfg_aclconfctx_t *ctx) {
if (ctx->geoip == NULL)
return (ISC_TRUE);
switch (elt->geoip_elem.subtype) {
case dns_geoip_countrycode:
case dns_geoip_countrycode3:
case dns_geoip_countryname:
if (ctx->geoip->city_v4 != NULL ||
ctx->geoip->city_v6 != NULL ||
ctx->geoip->country_v4 != NULL ||
ctx->geoip->country_v6 != NULL ||
ctx->geoip->region != NULL)
return (ISC_TRUE);
case dns_geoip_region:
case dns_geoip_regionname:
if (ctx->geoip->city_v4 != NULL ||
ctx->geoip->city_v6 != NULL ||
ctx->geoip->region != NULL)
return (ISC_TRUE);
case dns_geoip_country_code:
case dns_geoip_country_code3:
case dns_geoip_country_name:
if (ctx->geoip->country_v4 != NULL ||
ctx->geoip->country_v6 != NULL)
return (ISC_TRUE);
case dns_geoip_region_countrycode:
case dns_geoip_region_code:
case dns_geoip_region_name:
if (ctx->geoip->region != NULL)
return (ISC_TRUE);
case dns_geoip_city_countrycode:
case dns_geoip_city_countrycode3:
case dns_geoip_city_countryname:
case dns_geoip_city_region:
case dns_geoip_city_regionname:
case dns_geoip_city_name:
case dns_geoip_city_postalcode:
case dns_geoip_city_metrocode:
case dns_geoip_city_areacode:
case dns_geoip_city_continentcode:
case dns_geoip_city_timezonecode:
if (ctx->geoip->city_v4 != NULL ||
ctx->geoip->city_v6 != NULL)
return (ISC_TRUE);
case dns_geoip_isp_name:
if (ctx->geoip->isp != NULL)
return (ISC_TRUE);
case dns_geoip_org_name:
if (ctx->geoip->org != NULL)
return (ISC_TRUE);
case dns_geoip_as_asnum:
if (ctx->geoip->as != NULL)
return (ISC_TRUE);
case dns_geoip_domain_name:
if (ctx->geoip->domain != NULL)
return (ISC_TRUE);
case dns_geoip_netspeed_id:
if (ctx->geoip->netspeed != NULL)
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static isc_result_t
parse_geoip_element(const cfg_obj_t *obj, isc_log_t *lctx,
cfg_aclconfctx_t *ctx, dns_aclelement_t *de)
{
const cfg_obj_t *ge;
const char *dbname = NULL;
const char *stype, *search;
dns_geoip_subtype_t subtype;
ge = cfg_tuple_get(obj, "db");
if (!cfg_obj_isvoid(ge))
dbname = cfg_obj_asstring(ge);
stype = cfg_obj_asstring(cfg_tuple_get(obj, "subtype"));
search = cfg_obj_asstring(cfg_tuple_get(obj, "search"));
if (strcasecmp(stype, "country") == 0 && strlen(search) == 2) {
/* Two-letter country code */
subtype = dns_geoip_countrycode;
strncpy(de->geoip_elem.as_string, search, 2);
} else if (strcasecmp(stype, "country") == 0 && strlen(search) == 3) {
/* Three-letter country code */
subtype = dns_geoip_countrycode3;
strncpy(de->geoip_elem.as_string, search, 3);
} else if (strcasecmp(stype, "country") == 0) {
/* Country name */
subtype = dns_geoip_countryname;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "region") == 0 && strlen(search) == 2) {
/* Two-letter region code */
subtype = dns_geoip_region;
strncpy(de->geoip_elem.as_string, search, 2);
} else if (strcasecmp(stype, "region") == 0) {
/* Region name */
subtype = dns_geoip_regionname;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "city") == 0) {
/* City name */
subtype = dns_geoip_city_name;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "postal") == 0 && strlen(search) < 7) {
subtype = dns_geoip_city_postalcode;
strncpy(de->geoip_elem.as_string, search, 6);
de->geoip_elem.as_string[6] = '\0';
} else if (strcasecmp(stype, "metro") == 0) {
subtype = dns_geoip_city_metrocode;
de->geoip_elem.as_int = atoi(search);
} else if (strcasecmp(stype, "area") == 0) {
subtype = dns_geoip_city_areacode;
de->geoip_elem.as_int = atoi(search);
} else if (strcasecmp(stype, "tz") == 0) {
subtype = dns_geoip_city_timezonecode;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "continent") == 0 && strlen(search) == 2) {
/* Two-letter continent code */
subtype = dns_geoip_city_continentcode;
strncpy(de->geoip_elem.as_string, search, 2);
} else if (strcasecmp(stype, "isp") == 0) {
subtype = dns_geoip_isp_name;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "asnum") == 0) {
subtype = dns_geoip_as_asnum;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "org") == 0) {
subtype = dns_geoip_org_name;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "domain") == 0) {
subtype = dns_geoip_domain_name;
strncpy(de->geoip_elem.as_string, search, 255);
} else if (strcasecmp(stype, "netspeed") == 0) {
subtype = dns_geoip_netspeed_id;
de->geoip_elem.as_int = atoi(search);
} else
INSIST(0);
de->geoip_elem.subtype = get_subtype(obj, lctx, subtype, dbname);
if (! geoip_can_answer(de, ctx)) {
cfg_obj_log(obj, lctx, ISC_LOG_ERROR,
"no GeoIP database installed which can answer "
"queries of type '%s'", stype);
return (ISC_R_FAILURE);
}
return (ISC_R_SUCCESS);
}
#endif
isc_result_t
cfg_acl_fromconfig(const cfg_obj_t *caml,
const cfg_obj_t *cctx,
@@ -317,15 +595,18 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
elt != NULL;
elt = cfg_list_next(elt)) {
const cfg_obj_t *ce = cfg_listelt_value(elt);
isc_boolean_t neg;
isc_boolean_t neg = ISC_FALSE;
if (cfg_obj_istuple(ce)) {
/* This must be a negated element. */
ce = cfg_tuple_get(ce, "value");
/* Might be a negated element */
const cfg_obj_t *negated =
cfg_tuple_get(ce, "negated");
if (! cfg_obj_isvoid(negated)) {
neg = ISC_TRUE;
dacl->has_negatives = ISC_TRUE;
} else
neg = ISC_FALSE;
ce = negated;
}
}
/*
* If nest_level is nonzero, then every element is
@@ -405,6 +686,16 @@ nested_acl:
&de->keyname);
if (result != ISC_R_SUCCESS)
goto cleanup;
#ifdef HAVE_GEOIP
} else if (cfg_obj_istuple(ce) &&
cfg_obj_isvoid(cfg_tuple_get(ce, "negated")))
{
result = parse_geoip_element(ce, lctx, ctx, de);
if (result != ISC_R_SUCCESS)
goto cleanup;
de->type = dns_aclelementtype_geoip;
de->negative = neg;
#endif /* HAVE_GEOIP */
} else if (cfg_obj_isstring(ce)) {
/* ACL name. */
const char *name = cfg_obj_asstring(ce);

View File

@@ -24,11 +24,13 @@
#include <isccfg/cfg.h>
#include <dns/geoip.h>
#include <dns/types.h>
typedef struct cfg_aclconfctx {
ISC_LIST(dns_acl_t) named_acl_cache;
isc_mem_t *mctx;
dns_geoip_databases_t *geoip;
isc_refcount_t references;
} cfg_aclconfctx_t;

View File

@@ -82,6 +82,15 @@ doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type);
static void
doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type);
static isc_result_t
parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
static void
print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj);
static void
doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type);
static cfg_type_t cfg_type_acl;
static cfg_type_t cfg_type_addrmatchelt;
static cfg_type_t cfg_type_bracketed_aml;
@@ -927,6 +936,7 @@ options_clauses[] = {
{ "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "files", &cfg_type_size, 0 },
{ "flush-zones-on-shutdown", &cfg_type_boolean, 0 },
{ "geoip-directory", &cfg_type_qstringornone, 0 },
{ "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "heartbeat-interval", &cfg_type_uint32, 0 },
{ "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP },
@@ -2103,6 +2113,99 @@ static cfg_type_t cfg_type_optional_keyref = {
doc_optional_keyvalue, &cfg_rep_string, &key_kw
};
/*
* "geoip" ACL element:
* geoip [ db <database> ] search-type <string>
*/
static const char *geoiptype_enums[] = {
"country", "country3", "countryname", "region", "regionname",
"city", "postal", "metrocode", "areacode", "timezone", "continent",
"isp", "domain", "asnum", "org", "netspeed", NULL
};
static cfg_type_t cfg_type_geoiptype = {
"geoiptype", cfg_parse_enum, cfg_print_ustring,
cfg_doc_enum, &cfg_rep_string, &geoiptype_enums
};
static const char *geoipdb_enums[] = {
"country", "region", "city",
"isp", "domain", "asnum", "org", "netspeed", NULL
};
static cfg_type_t cfg_type_geoipdb = {
"geoipdb", cfg_parse_enum, cfg_print_ustring,
cfg_doc_enum, &cfg_rep_string, &geoipdb_enums
};
static cfg_tuplefielddef_t geoip_fields[] = {
{ "negated", &cfg_type_void, 0},
{ "db", &cfg_type_geoipdb, 0},
{ "subtype", &cfg_type_geoiptype, 0 },
{ "search", &cfg_type_astring, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_geoip = {
"geoip", parse_geoip, print_geoip, doc_geoip,
&cfg_rep_tuple, geoip_fields
};
static isc_result_t
parse_geoip(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
isc_result_t result;
cfg_obj_t *obj = NULL;
const cfg_tuplefielddef_t *fields = type->of;
CHECK(cfg_create_tuple(pctx, type, &obj));
CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[0]));
/* Parse the optional "db" field. */
CHECK(cfg_peektoken(pctx, 0));
if (pctx->token.type == isc_tokentype_string) {
CHECK(cfg_gettoken(pctx, 0));
if (strcasecmp(TOKEN_STRING(pctx), "db") == 0 &&
obj->value.tuple[1] == NULL) {
CHECK(cfg_parse_obj(pctx, fields[1].type,
&obj->value.tuple[1]));
} else {
CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
cfg_ungettoken(pctx);
}
}
CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2]));
CHECK(cfg_parse_obj(pctx, fields[3].type, &obj->value.tuple[3]));
*ret = obj;
return (ISC_R_SUCCESS);
cleanup:
CLEANUP_OBJ(obj);
return (result);
}
static void
print_geoip(cfg_printer_t *pctx, const cfg_obj_t *obj) {
if (obj->value.tuple[1]->type->print != cfg_print_void) {
cfg_print_cstr(pctx, " db ");
cfg_print_obj(pctx, obj->value.tuple[1]);
}
cfg_print_obj(pctx, obj->value.tuple[2]);
cfg_print_obj(pctx, obj->value.tuple[3]);
}
static void
doc_geoip(cfg_printer_t *pctx, const cfg_type_t *type) {
UNUSED(type);
cfg_print_cstr(pctx, "[ db ");
cfg_doc_enum(pctx, &cfg_type_geoipdb);
cfg_print_cstr(pctx, " ]");
cfg_print_chars(pctx, " ", 1);
cfg_doc_enum(pctx, &cfg_type_geoiptype);
cfg_print_chars(pctx, " ", 1);
cfg_print_cstr(pctx, "<quoted_string>");
}
/*%
* A "controls" statement is represented as a map with the multivalued
* "inet" and "unix" clauses.
@@ -2246,7 +2349,9 @@ static cfg_type_t cfg_type_statschannels = {
* An optional class, as used in view and zone statements.
*/
static isc_result_t
parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type,
cfg_obj_t **ret)
{
isc_result_t result;
UNUSED(type);
CHECK(cfg_peektoken(pctx, 0));
@@ -2369,6 +2474,16 @@ parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
if (pctx->token.type == isc_tokentype_string &&
(strcasecmp(TOKEN_STRING(pctx), "key") == 0)) {
CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret));
} else if (pctx->token.type == isc_tokentype_string &&
(strcasecmp(TOKEN_STRING(pctx), "geoip") == 0)) {
#ifdef HAVE_GEOIP
CHECK(cfg_gettoken(pctx, 0));
CHECK(cfg_parse_obj(pctx, &cfg_type_geoip, ret));
#else
cfg_parser_error(pctx, CFG_LOG_NEAR,
"'geoip' not supported in this build");
return (ISC_R_UNEXPECTEDTOKEN);
#endif
} else {
if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK |
CFG_ADDR_V4PREFIXOK |
@@ -2406,7 +2521,7 @@ parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret)
*/
static cfg_tuplefielddef_t negated_fields[] = {
{ "value", &cfg_type_addrmatchelt, 0 },
{ "negated", &cfg_type_addrmatchelt, 0 },
{ NULL, NULL, 0 }
};