Commit Diff
Diff:
9555334803a67cecad9c69ececf48e8ab1b9961d
ed247332c5c765e1d37d2af2b08476d8db206fd3
Commit:
ed247332c5c765e1d37d2af2b08476d8db206fd3
Tree:
da1c5fb87609f27e5f3e9b8f3cd5f5d76cd2d380
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Tue Mar 9 15:38:22 2010 UTC
Message:
* part 1 of merging TTLPATCH branch to HEAD
blob - 460f5d5dbb52a3ce9e14f8a94c8d6eca0af662c6
blob + e8e0470de62d931df68a6b8df95f0bb2e0c174dc
--- Makefile
+++ Makefile
@@ -1,8 +1,9 @@
PROG=wildcarddnsd
-SRCS=main.c parse.c reply.c additional.c
+SRCS=main.c parse.c reply.c additional.c region.c
#CFLAGS= -DDEBUG -g -Wall
CFLAGS= -Wall -g
+#LDADD= -lcrypto -lssl
OBJDIR=.
BINDIR=/usr/local/sbin
blob - ef23d35e029c94e2f46694c923d23d15a11d0a5a
blob + 2692e1d88aef8a2885a0521dec4fc2234bfb8512
--- Makefile.linux
+++ Makefile.linux
@@ -1,6 +1,7 @@
CC=gcc
#CFLAGS=-DDEBUG
CFLAGS=
+LDADD= -ldb
build:
@@ -8,7 +9,8 @@ build:
$(CC) $(CFLAGS) -c main.c
$(CC) $(CFLAGS) -c parse.c
$(CC) $(CFLAGS) -c reply.c
- $(CC) $(CFLAGS) -o wildcarddnsd additional.o main.o parse.o reply.o -ldb
+ $(CC) $(CFLAGS) -c region.c
+ $(CC) $(CFLAGS) -o wildcarddnsd additional.o main.o parse.o reply.o region.o $(LDADD)
clean:
rm -f *.o wildcarddnsd
blob - 4211982dc473e3100c6d0899e6702f0aeab11866
blob + b359f895ee6f2d559fd9419a307da98fe52a8a19
--- additional.c
+++ additional.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2009 Peter J. Philipp
+ * Copyright (c) 2005-2010 Peter J. Philipp
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@ int additional_ptr(char *, int, struct domain *, char
extern int compress_label(char *, int, int);
-static const char rcsid[] = "$Id: additional.c,v 1.6 2009/03/25 12:15:55 pbug Exp $";
+static const char rcsid[] = "$Id: additional.c,v 1.7 2010/03/09 15:38:22 pbug Exp $";
/*
blob - ef3237c1992db2abadf0ad1b7acb3f3d7c04f23f
blob + fd5295d913818ed2f123c976a0775d42a354f1e1
--- db.h
+++ db.h
@@ -74,6 +74,7 @@ struct domain {
struct soa soa; /* start of authority */
u_int32_t ttl; /* time to live */
in_addr_t a[10]; /* IP addresses */
+ u_int8_t region[10]; /* region of IP address */
int a_count; /* IP address count (max 10) */
int a_ptr; /* pointer to last used address */
struct in6_addr aaaa[10]; /* IPv6 addresses */
@@ -100,6 +101,7 @@ struct sreply {
int salen; /* length of struct sockaddr */
struct domain *sd1; /* first resolved domain */
struct domain *sd2; /* CNAME to second resolved domain */
+ u_int8_t region; /* region of question */
};
/*
@@ -109,7 +111,7 @@ struct sreply {
* (hopefully the only macro in the program !!!!)
*/
-#define BUILD_REPLY(reply, so0, buf0, len0, q0, sa0, salen0, sd10, sd20) \
+#define BUILD_REPLY(reply, so0, buf0, len0, q0, sa0, salen0, sd10, sd20, aregion) \
do { \
reply.so = so0; \
reply.buf = buf0; \
@@ -119,6 +121,7 @@ struct sreply {
reply.salen = salen0; \
reply.sd1 = sd10; \
reply.sd2 = sd20; \
+ reply.region = aregion; \
} while (0);
int parse_file(DB *db, char *);
blob - 946a1e327c267370a1c76ca0d0b8ae0e94090bcd
blob + 6fe82e4e326e321dc33d39b20118bd5211a09c64
--- dns.h
+++ dns.h
@@ -122,6 +122,10 @@ struct dns_question_hdr {
#define DNS_TYPE_MX 15
#define DNS_TYPE_TXT 16
+/* DNS types 0xff00 -> 0xfffe (private use) RFC 5395, page 8 */
+
+#define DNS_TYPE_BALANCE 0xfffe
+
/* quad A - RFC 3596 */
#define DNS_TYPE_AAAA 28
blob - 9bb786d07893eb4183028dce3adfbeaf63905b82
blob + 686033a72152a53460c42c1b8c5fbf57aff48721
--- example1.conf
+++ example1.conf
@@ -3,56 +3,62 @@
# wildcarddns - RR configuration file
#
#
-;
-; comments must be at the beginning of a new line, # and ; is allowed
-;
-;
-; ALL RR's begine with: zone,RR,time to live, ...
-;
-; names can be expressed with no trailing . or with trailing dot either way
-; they'll be modified to have a trailing dot.
-; example: www.google.com or www.google.com. becomes www.google.com.
-;
-# soa RR consists of: zone, SOA, ttl of RR, nameserver, responsible person,
-# serial, refresh, retry, expire, zone time to live (no spaces)
-;
-*,soa,3600,neptune.ATLAS.,pbug.neptune.ATLAS,1,3600,1800,7200,3600
-;
-# a RR consists of: zone, A, ttl of RR, IP (no spaces)
-# up to 10 addresses allowed
-;
-*,a,3600,10.0.0.2
-*,a,3600,10.0.0.1
-;
-# MX RR consists of: zone, MX, ttl of RR, priority, name of MX (no spaces)
-# up to 10 addresses allowed
-;
-*,mx,3600,1,atlas.local
-*,mx,3600,1,neptune.local
-;
-# AAAA RR consists of: zone, AAAA, ttl of RR, IPv6 address (no spaces)
-# up to 10 addresses allowed
-;
-*,aaaa,3600,::1
-*,aaaa,3600,3ffe:b00:1022::
-;
-# all of *.com looks like this:
-;
-com,soa,3600,a.com,b.com,1,3600,1800,300000,3600
-;
-# CNAME RR consists of: zone, CNAME, ttl of RR, name (no spaces)
-; CNAME support is currently not complete since a CNAME must attach the
-; records it is pointing to... something to be done in the future I guess..
-;
-*,cname,3600,neptune.local
-;
-#
-# PTR RR consists of: zone, PTR, ttl of RR, name (no spaces)
-;
-arpa.,ptr,3600,neptune.local.
-;
-# NS RR consists of: zone, NS, ttl of RR, name (no spaces)
-;
-*,ns,3600,ns.neptune.local.
-;
-; Got it? good.
+
+version "2";
+
+zone "default" {
+ ; comments must be at the beginning of a new line, # and ; is allowed
+ ;
+ ;
+ ; ALL RR's begine with: zone,RR,time to live, ...
+ ;
+ ; names can be expressed with no trailing . or with trailing dot either way
+ ; they'll be modified to have a trailing dot.
+ ; example: www.google.com or www.google.com. becomes www.google.com.
+ ;
+ ; soa RR consists of: zone, SOA, ttl of RR, nameserver, responsible person,
+ ; serial, refresh, retry, expire, zone time to live (no spaces)
+ ;
+ *,soa,3600,neptune.ATLAS.,pbug.neptune.ATLAS,1,3600,1800,7200,3600
+ ;
+ ; a RR consists of: zone, A, ttl of RR, IP (no spaces)
+ ; up to 10 addresses allowed
+ ;
+ *,a,3600,10.0.0.2
+ *,a,3600,10.0.0.1
+ ;
+ ; MX RR consists of: zone, MX, ttl of RR, priority, name of MX (no spaces)
+ ; up to 10 addresses allowed
+ ;
+ *,mx,3600,1,atlas.local
+ *,mx,3600,1,neptune.local
+ ;
+ ; AAAA RR consists of: zone, AAAA, ttl of RR, IPv6 address (no spaces)
+ ; up to 10 addresses allowed
+ ;
+ *,aaaa,3600,::1
+ *,aaaa,3600,3ffe:b00:1022::
+ ;
+ ; all of *.com looks like this:
+ ;
+ com,soa,3600,a.com,b.com,1,3600,1800,300000,3600
+ ;
+ ; CNAME RR consists of: zone, CNAME, ttl of RR, name (no spaces)
+ ; CNAME support is currently not complete since a CNAME must attach the
+ ; records it is pointing to... something to be done in the future I guess..
+ ;
+ *,cname,3600,neptune.local
+ ;
+ ;
+ ; PTR RR consists of: zone, PTR, ttl of RR, name (no spaces)
+ ;
+ arpa.,ptr,3600,neptune.local.
+ ;
+ ; NS RR consists of: zone, NS, ttl of RR, name (no spaces)
+ ;
+ *,ns,3600,ns.neptune.local.
+
+; close zone
+}
+
+; pretty straight forward
blob - 8981fd9136b0632c3e19085b696566d6290d9501
blob + 8ec1156b9365337b94f7edd87bfe94c7f907985b
--- example2.conf
+++ example2.conf
@@ -3,79 +3,86 @@
# wildcarddns - RR configuration file
#
#
-;
-; comments must be at the beginning of a new line, # and ; is allowed
-;
-;
-; ALL RR's begine with: zone,RR,time to live, ...
-;
-; names can be expressed with no trailing . or with trailing dot either way
-; they'll be modified to have a trailing dot.
-; example: www.google.com or www.google.com. becomes www.google.com.
-;
-# soa RR consists of: zone, SOA, ttl of RR, nameserver, responsible person,
-# serial, refresh, retry, expire, zone time to live (no spaces)
-;
-*,soa,3600,miranda.solarscale.de.,pjp.solarscale.de.,1,3600,1800,7200,3600
-;
-# a RR consists of: zone, A, ttl of RR, IP (no spaces)
-# up to 10 addresses allowed
-;
-; miranda.solarscale.de
-*,a,3600,192.168.0.20
-;
-# MX RR consists of: zone, MX, ttl of RR, priority, name of MX (no spaces)
-# up to 10 addresses allowed
-;
-*,mx,3600,1,miranda.solarscale.de.
-;
-# AAAA RR consists of: zone, AAAA, ttl of RR, IPv6 address (no spaces)
-# up to 10 addresses allowed
-;
-;*,aaaa,3600,::1
-;*,aaaa,3600,3ffe:b00:1022::
-;
-# all of *.com looks like this:
-;
-;com,soa,3600,a.com,b.com,1,3600,1800,300000,3600
-;
-# CNAME RR consists of: zone, CNAME, ttl of RR, name (no spaces)
-; CNAME support is currently not complete since a CNAME must attach the
-; records it is pointing to... something to be done in the future I guess..
-;
-;*,cname,3600,neptune.local
-;
-#
-# PTR RR consists of: zone, PTR, ttl of RR, name (no spaces)
-;
-arpa.,ptr,3600,miranda.solarscale.de.
-;
-# NS RR consists of: zone, NS, ttl of RR, name (no spaces)
-;
-*,ns,3600,miranda.solarscale.de.
-;
-; Got it? good.
-ferdinand.solarscale.de,a,3600,192.168.0.21
-21.0.168.192.in-addr.arpa.,ptr,3600,ferdinand.solarscale.de.
-ariel.solarscale.de,a,3600,192.168.0.17
-17.0.168.192.in-addr.arpa.,ptr,3600,ariel.solarscale.de.
-uranus.solarscale.de,a,3600,192.168.0.1
-1.0.168.192.in-addr.arpa.,ptr,3600,uranus.solarscale.de.
-area5.solarscale.de,a,3600,192.168.0.11
-11.0.168.192.in-addr.arpa.,ptr,3600,area5.solarscale.de.
-perdita.solarscale.de,a,3600,192.168.0.23
-23.0.168.192.in-addr.arpa,ptr,3600,perdita.solarscale.de.
-itojun.solarscale.de,cname,3600,perdita.solarscale.de.
-desdemona.solarscale.de,a,3600,192.168.0.15
-15.0.168.192.in-addr.arpa,ptr,3600,desdemona.solarscale.de.
-rosalind.solarscale.de,a,3600,192.168.0.19
-19.0.168.192.in-addr.arpa,ptr,3600,rosalind.solarscale.de.
-titania.solarscale.de,a,3600,192.168.0.16
-16.0.168.192.in-addr.arpa,ptr,3600,titania.solarscale.de.
-cupid.solarscale.de,a,3600,192.168.0.12
-12.0.168.192.in-addr.arpa,ptr,3600,cupid.solarscale.de.
-;
-; cvs
-cvs.solarscale.de,cname,3600,miranda.solarscale.de.
-; irc
-irc.solarscale.de,cnam,3600,ariel.solarscale.de.
+
+version "2";
+
+
+zone "default" {
+ ;
+ ; comments must be at the beginning of a new line, # and ; is allowed
+ ;
+ ;
+ ; ALL RR's begine with: zone,RR,time to live, ...
+ ;
+ ; names can be expressed with no trailing . or with trailing dot either way
+ ; they'll be modified to have a trailing dot.
+ ; example: www.google.com or www.google.com. becomes www.google.com.
+ ;
+ ; soa RR consists of: zone, SOA, ttl of RR, nameserver, responsible person,
+ ; serial, refresh, retry, expire, zone time to live (no spaces)
+ ;
+ *,soa,3600,miranda.solarscale.de.,pjp.solarscale.de.,1,3600,1800,7200,3600
+ ;
+ ; a RR consists of: zone, A, ttl of RR, IP (no spaces)
+ ; up to 10 addresses allowed
+ ;
+ ; miranda.solarscale.de
+ *,a,3600,192.168.0.20
+ ;
+ ; MX RR consists of: zone, MX, ttl of RR, priority, name of MX (no spaces)
+ ; up to 10 addresses allowed
+ ;
+ *,mx,3600,1,miranda.solarscale.de.
+ ;
+ ; AAAA RR consists of: zone, AAAA, ttl of RR, IPv6 address (no spaces)
+ ; up to 10 addresses allowed
+ ;
+ ;*,aaaa,3600,::1
+ ;*,aaaa,3600,3ffe:b00:1022::
+ ;
+ ; all of *.com looks like this:
+ ;
+ ;com,soa,3600,a.com,b.com,1,3600,1800,300000,3600
+ ;
+ ; CNAME RR consists of: zone, CNAME, ttl of RR, name (no spaces)
+ ; CNAME support is currently not complete since a CNAME must attach the
+ ; records it is pointing to... something to be done in the future I guess..
+ ;
+ ;*,cname,3600,neptune.local
+ ;
+ ;
+ ; PTR RR consists of: zone, PTR, ttl of RR, name (no spaces)
+ ;
+ arpa.,ptr,3600,miranda.solarscale.de.
+ ;
+ ; NS RR consists of: zone, NS, ttl of RR, name (no spaces)
+ ;
+ *,ns,3600,miranda.solarscale.de.
+ ;
+ ; Got it? good.
+ ferdinand.solarscale.de,a,3600,192.168.0.21
+ 21.0.168.192.in-addr.arpa.,ptr,3600,ferdinand.solarscale.de.
+ ariel.solarscale.de,a,3600,192.168.0.17
+ 17.0.168.192.in-addr.arpa.,ptr,3600,ariel.solarscale.de.
+ uranus.solarscale.de,a,3600,192.168.0.1
+ 1.0.168.192.in-addr.arpa.,ptr,3600,uranus.solarscale.de.
+ area5.solarscale.de,a,3600,192.168.0.11
+ 11.0.168.192.in-addr.arpa.,ptr,3600,area5.solarscale.de.
+ perdita.solarscale.de,a,3600,192.168.0.23
+ 23.0.168.192.in-addr.arpa,ptr,3600,perdita.solarscale.de.
+ itojun.solarscale.de,cname,3600,perdita.solarscale.de.
+ desdemona.solarscale.de,a,3600,192.168.0.15
+ 15.0.168.192.in-addr.arpa,ptr,3600,desdemona.solarscale.de.
+ rosalind.solarscale.de,a,3600,192.168.0.19
+ 19.0.168.192.in-addr.arpa,ptr,3600,rosalind.solarscale.de.
+ titania.solarscale.de,a,3600,192.168.0.16
+ 16.0.168.192.in-addr.arpa,ptr,3600,titania.solarscale.de.
+ cupid.solarscale.de,a,3600,192.168.0.12
+ 12.0.168.192.in-addr.arpa,ptr,3600,cupid.solarscale.de.
+ ;
+ ; cvs
+ cvs.solarscale.de,cname,3600,miranda.solarscale.de.
+ ; irc
+ irc.solarscale.de,cnam,3600,ariel.solarscale.de.
+}
+; end
blob - 62f2f02779d6881312336e033aff4f99fa3314c1
blob + ff2f15959b036958e7bccfde052855a40359088d
--- example3.conf
+++ example3.conf
@@ -1,41 +1,46 @@
# wildcarddns - RR configuration file
-#
-# This doesn't have any wildcards which prevents other people pointing their
-# domains at your wildcarded top domain. Answer will look like this in the
-# logs: (daemon with -l flag)
-# Feb 18 10:05:33 proteus wildcarddnsd[15843]: don't have wildcard answer
-# Feb 18 10:05:33 proteus wildcarddnsd[15843]: request on descriptor 4
-# interface "62.75.160.180" from xxx.xxx.xxx.xxx for "flavair.com." type=1
-# class=1, answering "NXDOMAIN"
-#
-#
-# serial, refresh, retry, expire, zone time to live (no spaces)
-margaret.centroid.eu,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
-margaret.centroid.eu,ns,3600,proteus.solarscale.de.
-margaret.centroid.eu,ns,3600,uranus.centroid.eu.
-;
-margaret.centroid.eu,a,3600,212.114.251.91
-margaret.centroid.eu,aaaa,3600,2001:a60:f074::2
-;
-ipv6.solarscale.de,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
-ipv6.solarscale.de,ns,3600,proteus.solarscale.de.
-ipv6.solarscale.de,ns,3600,uranus.centroid.eu.
-ipv6.solarscale.de,ns,3600,margaret.centroid.eu.
-;
-ipv6.solarscale.de,aaaa,3600,2001:a60:f074::2
-www.ipv6.solarscale.de,aaaa,3600,2001:a60:f074::2
-;
-ipv6.centroid.eu,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
-ipv6.centroid.eu,ns,3600,proteus.solarscale.de.
-ipv6.centroid.eu,ns,3600,uranus.centroid.eu.
-ipv6.centroid.eu,ns,3600,margaret.centroid.eu.
-;
-ipv6.centroid.eu,aaaa,3600,2001:a60:f074::2
-www.ipv6.centroid.eu,aaaa,3600,2001:a60:f074::2
-;
-;
-# reverse dns for IPv6
-0.4.7.0.f.0.6.a.0.1.0.0.2.ip6.arpa.,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
-;
-1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.7.0.f.0.6.a.0.1.0.0.2.ip6.arpa.,ptr,3600,uranus.centroid.eu.
-2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.7.0.f.0.6.a.0.1.0.0.2.ip6.arpa.,ptr,3600,margaret.centroid.eu.
+version "2";
+
+zone "centroid.eu" {
+ # serial, refresh, retry, expire, zone time to live (no spaces)
+ margaret.centroid.eu,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
+ margaret.centroid.eu,ns,3600,proteus.solarscale.de.
+ margaret.centroid.eu,ns,3600,uranus.centroid.eu.
+ ;
+ margaret.centroid.eu,a,3600,212.114.251.91
+ margaret.centroid.eu,aaaa,3600,2001:a60:f074::2
+ ;
+}
+
+zone "ipv6.solarscale.de" {
+ ipv6.solarscale.de,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
+ ipv6.solarscale.de,ns,3600,proteus.solarscale.de.
+ ipv6.solarscale.de,ns,3600,uranus.centroid.eu.
+ ipv6.solarscale.de,ns,3600,margaret.centroid.eu.
+ ;
+ ipv6.solarscale.de,aaaa,3600,2001:a60:f074::2
+ www.ipv6.solarscale.de,aaaa,3600,2001:a60:f074::2
+ ;
+}
+
+zone "ipv6.centroid.eu" {
+ ipv6.centroid.eu,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
+ ipv6.centroid.eu,ns,3600,proteus.solarscale.de.
+ ipv6.centroid.eu,ns,3600,uranus.centroid.eu.
+ ipv6.centroid.eu,ns,3600,margaret.centroid.eu.
+ ;
+ ipv6.centroid.eu,aaaa,3600,2001:a60:f074::2
+ www.ipv6.centroid.eu,aaaa,3600,2001:a60:f074::2
+ ;
+ ;
+}
+
+zone "ip6.arpa" {
+ # reverse dns for IPv6
+ 0.4.7.0.f.0.6.a.0.1.0.0.2.ip6.arpa.,soa,3600,proteus.solarscale.de.,pjp.solarscale.de.,1234896561,3600,1800,7200,3600
+ ;
+ 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.7.0.f.0.6.a.0.1.0.0.2.ip6.arpa.,ptr,3600,uranus.centroid.eu.
+ 2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.4.7.0.f.0.6.a.0.1.0.0.2.ip6.arpa.,ptr,3600,margaret.centroid.eu.
+}
+
+; end
blob - e2500a14237e93897638559b3e3f763c4ac053d6
blob + ba057fe2148a67699132ab35797c9f36783805eb
--- include.h
+++ include.h
@@ -33,6 +33,7 @@
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/uio.h>
+#include <sys/queue.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -58,3 +59,5 @@
#endif
#endif
+
+#include <openssl/md5.h>
blob - /dev/null
blob + e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (mode 644)
blob - c8936bd83f9e37dfcd4bbd5271f2871e6c0d4055
blob + 801c618c8b58118bf9c98cd81155363a125978b5
--- main.c
+++ main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2009 Peter J. Philipp
+ * Copyright (c) 2002-2010 Peter J. Philipp
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,6 +49,7 @@ extern void reply_ptr(struct sreply *);
extern void reply_cname(struct sreply *);
extern void reply_mx(struct sreply *);
extern void reply_ns(struct sreply *, DB *);
+extern u_int8_t find_region(in_addr_t);
char * dns_label(char *, int *);
int compress_label(char *, int, int);
int memcasecmp(char *, char *, int);
@@ -82,7 +83,7 @@ extern char *__progname;
static int Wflag = 0;
static int lflag = 0;
-static const char rcsid[] = "$Id: main.c,v 1.32 2009/11/20 10:34:42 pbug Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.33 2010/03/09 15:38:22 pbug Exp $";
/*
* MAIN - set up arguments, set up database, set up sockets, call mainloop
@@ -305,7 +306,7 @@ main(int argc, char *argv[])
}
} else if (pifap->ifa_addr->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)pifap->ifa_addr;
- sin6->sin6_port = htons(53);
+ sin6->sin6_port = htons(port);
/* no address bound to this interface */
salen = sizeof(struct sockaddr_in6);
@@ -428,7 +429,8 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
int so;
int type0, type1;
int lzerrno;
- u_int32_t received_ttl;
+
+ u_int32_t received_ttl;
#ifdef __FreeBSD__
u_char *ttlptr;
#elif __OpenBSD__
@@ -437,6 +439,8 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
int *ttlptr;
#endif
+ u_int8_t aregion; /* region where the address comes from */
+
char buf[2048];
char address[INET6_ADDRSTRLEN];
char replystring[DNS_MAXNAME + 1];
@@ -553,6 +557,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
fromlen = sizeof(struct sockaddr_in);
sin = (struct sockaddr_in *)from;
inet_ntop(AF_INET, (void *)&sin->sin_addr, (char *)&address, sizeof(address));
+ aregion = find_region(sin->sin_addr.s_addr);
} else {
syslog(LOG_INFO, "packet received on descriptor %u interface \"%s\" had weird address family (%u), drop", so, ident[i], from->sa_family);
goto drop;
@@ -580,7 +585,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
syslog(LOG_INFO, "on descriptor %u interface \"%s\" header from %s has no question, drop", so, ident[i], address);
/* format error */
- BUILD_REPLY(sreply, so, buf, len, NULL, from, fromlen, NULL, NULL);
+ BUILD_REPLY(sreply, so, buf, len, NULL, from, fromlen, NULL, NULL, aregion);
reply_fmterror(&sreply);
syslog(LOG_INFO, "question on descriptor %d interface \"%s\" from %s, did not have question of 1 replying format error", so, ident[i], address);
goto drop;
@@ -621,7 +626,7 @@ mainloop(int *udp, int *tcp, int sockcount, char **ide
(void)get_soa(db, question, &sd0);
BUILD_REPLY(sreply, so, buf, len, question, from, \
- fromlen, &sd0, NULL);
+ fromlen, &sd0, NULL, aregion);
reply_noerror(&sreply);
goto out;
@@ -646,7 +651,8 @@ nxdomain:
memset(&sd0, 0, sizeof(sd0));
(void)get_soa(db, question, &sd0);
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion);
reply_nxdomain(&sreply);
goto out;
case DNS_TYPE_CNAME:
@@ -677,7 +683,8 @@ nxdomain:
case DNS_CLASS_IN:
break;
default:
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, NULL, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, NULL, NULL, aregion);
reply_notimpl(&sreply);
snprintf(replystring, DNS_MAXNAME, "NOTIMPL");
goto out;
@@ -686,10 +693,13 @@ nxdomain:
switch (ntohs(question->hdr->qtype)) {
case DNS_TYPE_A:
if (type0 == DNS_TYPE_CNAME) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL));
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
+ aregion);
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_A) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion);
reply_a(&sreply, db);
break; /* must break here */
}
@@ -698,10 +708,13 @@ nxdomain:
case DNS_TYPE_AAAA:
if (type0 == DNS_TYPE_CNAME) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL));
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
+ aregion );
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_AAAA) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from,
+ fromlen, &sd0, NULL, aregion);
reply_aaaa(&sreply, db);
break; /* must break here */
}
@@ -710,10 +723,13 @@ nxdomain:
case DNS_TYPE_MX:
if (type0 == DNS_TYPE_CNAME) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL));
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL), \
+ aregion );
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_MX) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion);
reply_mx(&sreply);
break; /* must break here */
}
@@ -721,13 +737,15 @@ nxdomain:
break;
case DNS_TYPE_SOA:
if (type0 == DNS_TYPE_SOA) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion);
reply_soa(&sreply);
}
break;
case DNS_TYPE_NS:
if (type0 == DNS_TYPE_NS) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion);
reply_ns(&sreply, db);
}
break;
@@ -735,17 +753,21 @@ nxdomain:
case DNS_TYPE_CNAME:
if (type0 == DNS_TYPE_CNAME) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, NULL, aregion);
reply_cname(&sreply);
}
break;
case DNS_TYPE_PTR:
if (type0 == DNS_TYPE_CNAME) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL));
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, &sd0, ((type1 > 0) ? &sd1 : NULL) \
+ , aregion );
reply_cname(&sreply);
} else if (type0 == DNS_TYPE_PTR) {
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, &sd0, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from,
+ fromlen, &sd0, NULL, aregion);
reply_ptr(&sreply);
break; /* must break here */
}
@@ -757,7 +779,8 @@ nxdomain:
* ANY unkown RR TYPE gets a NOTIMPL
*/
- BUILD_REPLY(sreply, so, buf, len, question, from, fromlen, NULL, NULL);
+ BUILD_REPLY(sreply, so, buf, len, question, from, \
+ fromlen, NULL, NULL, aregion);
reply_notimpl(&sreply);
snprintf(replystring, DNS_MAXNAME, "NOTIMPL");
break;
@@ -765,7 +788,7 @@ nxdomain:
out:
if (lflag)
- syslog(LOG_INFO, "request on descriptor %u interface \"%s\" from %s (ttl=%u) for \"%s\" type=%s class=%u, answering \"%s\"", so, ident[i], address, received_ttl, question->converted_name, get_dns_type(ntohs(question->hdr->qtype)), ntohs(question->hdr->qclass), replystring);
+ syslog(LOG_INFO, "request on descriptor %u interface \"%s\" from %s (ttl=%u, region=%d) for \"%s\" type=%s class=%u, answering \"%s\"", so, ident[i], address, received_ttl, aregion, question->converted_name, get_dns_type(ntohs(question->hdr->qtype)), ntohs(question->hdr->qclass), replystring);
if (fakequestion != NULL) {
blob - ef1bd4e3ae7ae91d5f0fb52c5773e9bbad9bc4ac
blob + 1bb90761732cb08e0c26778ee7321ce008e43396
--- parse.c
+++ parse.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2009 Peter J. Philipp
+ * Copyright (c) 2005-2010 Peter J. Philipp
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,12 +30,16 @@
#include "db.h"
extern char * dns_label(char *, int *);
+extern u_int8_t find_region(in_addr_t *);
+extern void init_region(void);
+extern void insert_region(char *address, char *prefix, u_int8_t region);
struct myrr_lookup {
char *name;
u_int16_t type;
} mysrr_lookup[] = {
{ "a", DNS_TYPE_A } ,
+ { "balance", DNS_TYPE_BALANCE },
{ "soa", DNS_TYPE_SOA },
{ "cname", DNS_TYPE_CNAME },
{ "ptr", DNS_TYPE_PTR },
@@ -45,8 +49,31 @@ struct myrr_lookup {
{ NULL, 0 },
};
-static const char rcsid[] = "$Id: parse.c,v 1.16 2009/11/03 17:03:54 pbug Exp $";
+enum { CMD_TYPE_VERSION = 1, CMD_TYPE_REGION, CMD_TYPE_ZONE, CMD_TYPE_INCLUDE };
+struct cmd_lookup {
+ char *name;
+ u_int16_t type;
+} CMD_lookup[] = {
+ { "version ", CMD_TYPE_VERSION },
+ { "region ", CMD_TYPE_REGION },
+ { "zone ", CMD_TYPE_ZONE },
+ { "include ", CMD_TYPE_INCLUDE },
+ { NULL, 0},
+};
+
+#define CONFIG_START 0x1
+#define CONFIG_VERSION 0x2
+#define CONFIG_REGION 0x4
+#define CONFIG_ZONE 0x8
+#define CONFIG_INCLUDE 0x10
+
+#define WILDCARDVERSION 2
+
+static u_int32_t config = 0;
+
+static const char rcsid[] = "$Id: parse.c,v 1.17 2010/03/09 15:38:22 pbug Exp $";
+
/*
* PARSE_FILE - parse the configfile XXX rewrite me in yacc :(
*
@@ -62,6 +89,9 @@ parse_file(DB *db, char *file)
u_int32_t ttl;
int converted_namelen;
int line = 0;
+ u_int8_t region = 0;
+ int confstatus = CONFIG_START;
+ int version;
#if DB_VERSION_MAJOR > 3
int ret;
#endif
@@ -70,6 +100,7 @@ parse_file(DB *db, char *file)
char domainname[DNS_MAXNAME + 1];
char *converted_name;
char *p, *endline, *start, *starttoken;
+ char *address;
char save;
DBT key, data;
@@ -77,6 +108,7 @@ parse_file(DB *db, char *file)
DIR *dir;
in_addr_t *ia;
+
struct domain sdomain;
struct in6_addr *ia6;
struct stat sb, sb0;
@@ -127,11 +159,18 @@ parse_file(DB *db, char *file)
return -1;
}
+ /* XXX */
+ init_region();
+
while (fgets(buf, sizeof(buf), f) != NULL) {
converted_name = NULL;
len = strlen(buf);
start = &buf[0];
+
+ while (*start != '\n' && isspace(*start))
+ start++;
+
starttoken = p = start; /* XXX */
endline = NULL;
for (i = 0; i < len; i++, p++) {
@@ -143,7 +182,7 @@ parse_file(DB *db, char *file)
}
if (endline == NULL) {
- fprintf(stderr, "line too long line %d\n", line);
+ syslog(LOG_INFO, "line too long line %d", line);
fclose(f);
return -1;
}
@@ -153,298 +192,191 @@ parse_file(DB *db, char *file)
#ifdef DEBUG
printf("hash mark skipping line %d\n", line);
#endif
- goto skip;
- }
+ goto loop;
+ }
+
+ if (confstatus & CONFIG_START) {
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(1) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
+ for (p = start; *p && *p != '"'; p++);
+ if (*p == '"')
+ tokenlen = p - start;
+ else {
+ if (*start == '\n')
+ goto loop;
- tokenlen = (p - starttoken);
- if (tokenlen > (DNS_MAXNAME - 2)) {
- fprintf(stderr, "domain name is too long\n");
- fclose(f);
- return -1;
- }
+ syslog(LOG_INFO, "(33) malformed line %d", line);
+ fclose(f);
+ return (-1);
+ }
- /* write out our domain name all in lowercase and append a
- * terminating '.' if necessary.
- */
-
- {
- char *c;
- int i;
-
- c = starttoken;
- for (i = 0; i < tokenlen; i++) {
- int c0;
- c0 = *c++;
- domainname[i] = tolower(c0);
- }
-
- if (domainname[tokenlen - 1] != '.' &&
- !(tokenlen == 1 && domainname[tokenlen - 1] == '*')) {
- domainname[tokenlen] = '.';
- tokenlen++;
- }
-
- domainname[tokenlen] = '\0';
+ for (i = 0; CMD_lookup[i].name != NULL; i++) {
+ if (strncasecmp(starttoken, CMD_lookup[i].name , tokenlen) == 0) {
+ switch (CMD_lookup[i].type) {
+ case CMD_TYPE_VERSION:
+ confstatus |= CONFIG_VERSION;
+ confstatus &= ~CONFIG_START;
+ break;
+ case CMD_TYPE_ZONE:
+ if ((config & CONFIG_VERSION) != CONFIG_VERSION) {
+ syslog(LOG_INFO, "must have version at top of config\n");
+ fclose(f);
+ return (-1);
+ }
+ if (strchr(starttoken, '{') == NULL) {
+ syslog(LOG_INFO, "must have opening brace ('{') in zone entry on line %d", line);
+ fclose(f);
+ return (-1);
+ }
- }
+ confstatus |= CONFIG_ZONE;
+ confstatus &= ~CONFIG_START;
+ goto loop;
+ case CMD_TYPE_INCLUDE:
+ if ((config & CONFIG_VERSION) != CONFIG_VERSION) {
+ syslog(LOG_INFO, "must have version at top of config\n");
+ fclose(f);
+ return (-1);
+ }
+ confstatus |= CONFIG_INCLUDE;
+ confstatus &= ~CONFIG_START;
+ break;
+ case CMD_TYPE_REGION:
+ if ((config & CONFIG_VERSION) != CONFIG_VERSION) {
+ syslog(LOG_INFO, "must have version at top of config\n");
+ fclose(f);
+ return (-1);
+ }
+ if (strchr(starttoken, '{') == NULL) {
+ syslog(LOG_INFO, "must have opening brace ('{') in region entry on line %d", line);
+ fclose(f);
+ return (-1);
+ }
+ config |= CONFIG_REGION;
+
+ confstatus |= CONFIG_REGION;
+ confstatus &= ~CONFIG_START;
+ goto loop;
+ } /* switch */
- if (tokenlen == 1 && domainname[0] == '*') {
- converted_name = (char *)malloc(1);
- if (converted_name == NULL) {
- syslog(LOG_INFO, "malloc: %m");
- exit(1);
- }
- *converted_name = '*';
- converted_namelen = 1;
- } else {
- converted_name = dns_label(domainname, &converted_namelen);
- if (converted_name == NULL) {
- fprintf(stderr, "(XXX) illegal domain name line %d\n", line);
- exit(1);
- }
- }
-
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
-
- key.data = (char *)converted_name;
- key.size = converted_namelen;
-
- data.data = NULL;
- data.size = 0;
-
- memset((char *)&sdomain, 0, sizeof(struct domain));
-#if DB_VERSION_MAJOR > 3
- if (db->get(db, NULL, &key, &data, 0) == 0) {
-#else
- if (db->get(db, &key, &data, 0) == 0) {
-#endif
- if (data.size != sizeof(struct domain)) {
- fprintf(stderr, "damaged btree database\n");
+ break;
+ } /* if */
+ } /* for()*/
+
+ if (CMD_lookup[i].name == NULL) {
+ syslog(LOG_INFO, "unknown command, line %d", line);
fclose(f);
- return -1;
+ return (-1);
}
-
- memcpy((char *)&sdomain, (char *)data.data, data.size);
- } else {
-#if 0
- syslog(LOG_INFO, "db->get: %m");
-#endif
+
}
-#if __linux__
- strncpy((char *)&sdomain.zonename[0], (char *)&domainname[0],
- sizeof(sdomain.zonename));
- sdomain.zonename[sizeof(sdomain.zonename) - 1] = 0;
-#else
- strlcpy((char *)&sdomain.zonename[0], (char *)&domainname[0], sizeof(sdomain.zonename));
-#endif
+ /*
+ * read the old config format, when done go
+ * back to CONFIG_START
+ */
- if (++p >= endline) {
- fprintf(stderr, "(2) malformed line %d", line);
- fclose(f);
- return -1;
- }
-
- starttoken = p;
-
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(3) malformed line %d", line);
- fclose(f);
- return -1;
- }
-
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
-
- type = 0;
- for (i = 0; mysrr_lookup[i].name != NULL; i++) {
- if (strncasecmp(starttoken, mysrr_lookup[i].name, tokenlen) == 0) {
- type = mysrr_lookup[i].type;
- break;
+ if (confstatus & CONFIG_ZONE) {
+ if (*starttoken == '}') {
+ confstatus &= ~CONFIG_ZONE;
+ confstatus |= CONFIG_START;
+ goto loop;
}
- }
-
- if (type == 0) {
- fprintf(stderr, "unknown rr line %d\n", line);
- fclose(f);
- return -1;
- }
-
- *p = save;
-
- if (++p >= endline) {
- fprintf(stderr, "(4) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
-
- starttoken = p;
-
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(5) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
-
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
-
- ttl = atoi(starttoken);
-
- sdomain.ttl = ttl;
-
- *p = save;
-
- if (++p >= endline) {
- fprintf(stderr, "(6) malformed line %d\n", line );
- fclose(f);
- return -1;
- }
-
- starttoken = p;
-
-
- switch (type) {
- case DNS_TYPE_A:
- p = endline;
- save = *p;
- *p = '\0';
- if (sdomain.a_count < 10) {
- ia = (in_addr_t *) &sdomain.a[sdomain.a_count];
- sdomain.a_count++;
- } else {
- fprintf(stderr, "too many a records for zone \"%s\", skipping line %d\n", domainname, line);
- break;
- }
-
- /* don't allow 0.0.0.0 skip take this entry back */
- if ((*ia = inet_addr(starttoken)) == INADDR_ANY)
- sdomain.a_count--;
-
- *p = save;
-
- sdomain.a_ptr = 0;
- sdomain.flags |= DOMAIN_HAVE_A;
- break;
- case DNS_TYPE_AAAA:
- p = endline;
- save = *p;
- *p = 0;
- if (sdomain.aaaa_count < 10) {
- ia6 = (struct in6_addr *) &sdomain.aaaa[sdomain.aaaa_count];
- sdomain.aaaa_count++;
- } else {
- fprintf(stderr, "too many aaaa records for zone \"%s\", skipping line %d\n", domainname, line);
- break;
- }
-
-#ifdef DEBUG
- printf("starttoken = %s\n", starttoken);
-#endif
-
- if (inet_pton(AF_INET6, (char *)starttoken, (char *)ia6) != 1) {
- sdomain.aaaa_count--;
- fprintf(stderr, "aaaa \"%s\" unparseable line %d\n", starttoken, line);
- }
-
- *p = save;
-
- sdomain.aaaa_ptr = 0;
- sdomain.flags |= DOMAIN_HAVE_AAAA;
- break;
- case DNS_TYPE_MX:
-
for (p = starttoken; p < endline && *p != ','; p++);
if (p >= endline || *p != ',') {
- fprintf(stderr, "(7) malformed line %d\n", line);
+ if (*starttoken == '\n')
+ goto loop;
+ syslog(LOG_INFO, "(1) malformed line %d", line);
fclose(f);
return -1;
}
tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
-
- if (sdomain.mx_count < 10) {
- sdomain.mx[sdomain.mx_count].preference = atoi(starttoken);
- } else {
- fprintf(stderr, "too many mx records for zone \"%s\", skipping line %d\n", domainname, line);
- break;
+ if (tokenlen > (DNS_MAXNAME - 2)) {
+ syslog(LOG_INFO, "domain name is too long, on line %d", line);
+ fclose(f);
+ return -1;
}
-
- *p = save;
- if (++p >= endline) {
- fprintf(stderr, "(XX) malformed line %d", line);
- break;
- }
+ /*
+ * write out our domain name all in lowercase and append a
+ * terminating '.' if necessary.
+ */
- starttoken = p;
+ {
+ char *c;
+ int i;
- p = endline;
- save = *p;
- *p = 0;
+ c = starttoken;
+ for (i = 0; i < tokenlen; i++) {
+ int c0;
+ c0 = *c++;
+ domainname[i] = tolower(c0);
+ }
-
- {
- char *name;
- char *n;
-
- if ((name = dns_label(starttoken, (int *)&sdomain.mx[sdomain.mx_count].exchangelen)) == NULL) {
- fprintf(stderr, "illegal mx server, skipping line %d\n", line);
- goto skip;
+ if (domainname[tokenlen - 1] != '.' &&
+ !(tokenlen == 1 && domainname[tokenlen - 1] == '*')) {
+ domainname[tokenlen] = '.';
+ tokenlen++;
}
- n = (char *)sdomain.mx[sdomain.mx_count].exchange;
- memcpy((char *)n, name, sdomain.mx[sdomain.mx_count].exchangelen);
- free (name);
+ domainname[tokenlen] = '\0';
+
}
-
- sdomain.mx_count++;
- *p = save;
- sdomain.flags |= DOMAIN_HAVE_MX;
- break;
- case DNS_TYPE_SOA:
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(7) malformed line %d\n", line);
- fclose(f);
- return -1;
+ if (tokenlen == 1 && domainname[0] == '*') {
+ converted_name = (char *)malloc(1);
+ if (converted_name == NULL) {
+ syslog(LOG_INFO, "malloc: %m");
+ exit(1);
+ }
+ *converted_name = '*';
+ converted_namelen = 1;
+ } else {
+ converted_name = dns_label(domainname, &converted_namelen);
+ if (converted_name == NULL) {
+ fprintf(stderr, "(XXX) illegal domain name line %d\n", line);
+ exit(1);
+ }
}
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
+ key.data = (char *)converted_name;
+ key.size = converted_namelen;
- {
- char *name;
+ data.data = NULL;
+ data.size = 0;
- if ((name = dns_label(starttoken, (int *)&sdomain.soa.nsserver_len)) == NULL) {
- fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
- goto skip;
+ memset((char *)&sdomain, 0, sizeof(struct domain));
+ #if DB_VERSION_MAJOR > 3
+ if (db->get(db, NULL, &key, &data, 0) == 0) {
+ #else
+ if (db->get(db, &key, &data, 0) == 0) {
+ #endif
+ if (data.size != sizeof(struct domain)) {
+ syslog(LOG_INFO, "damaged btree database");
+ fclose(f);
+ return -1;
}
- memcpy((char *)&sdomain.soa.nsserver[0], name, sdomain.soa.nsserver_len);
- free (name);
+ memcpy((char *)&sdomain, (char *)data.data, data.size);
+ } else {
+ #if 0
+ syslog(LOG_INFO, "db->get: %m");
+ #endif
}
-
- *p = save;
+ #if __linux__
+ strncpy((char *)&sdomain.zonename[0], (char *)&domainname[0],
+ sizeof(sdomain.zonename));
+ sdomain.zonename[sizeof(sdomain.zonename) - 1] = 0;
+ #else
+ strlcpy((char *)&sdomain.zonename[0], (char *)&domainname[0], sizeof(sdomain.zonename));
+ #endif
+
if (++p >= endline) {
- fprintf(stderr, "(8) malformed line %d\n", line);
+ syslog(LOG_INFO, "(2) malformed line %d", line);
fclose(f);
return -1;
}
@@ -453,7 +385,7 @@ parse_file(DB *db, char *file)
for (p = starttoken; p < endline && *p != ','; p++);
if (p >= endline || *p != ',') {
- fprintf(stderr, "(9) malformed line %d\n", line);
+ syslog(LOG_INFO, "(3) malformed line %d", line);
fclose(f);
return -1;
}
@@ -462,22 +394,24 @@ parse_file(DB *db, char *file)
save = *p;
*p = 0;
- {
- char *name;
-
- if ((name = dns_label(starttoken, (int *)&sdomain.soa.rp_len)) == NULL) {
- fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
- goto skip;
+ type = 0;
+ for (i = 0; mysrr_lookup[i].name != NULL; i++) {
+ if (strncasecmp(starttoken, mysrr_lookup[i].name, tokenlen) == 0) {
+ type = mysrr_lookup[i].type;
+ break;
}
+ }
- memcpy((char *)&sdomain.soa.responsible_person[0], name, sdomain.soa.rp_len);
- free (name);
+ if (type == 0) {
+ syslog(LOG_INFO, "unknown rr line %d", line);
+ fclose(f);
+ return -1;
}
-
+
*p = save;
if (++p >= endline) {
- fprintf(stderr, "(10) malformed line %d\n", line);
+ syslog(LOG_INFO, "(4) malformed line %d", line);
fclose(f);
return -1;
}
@@ -486,7 +420,7 @@ parse_file(DB *db, char *file)
for (p = starttoken; p < endline && *p != ','; p++);
if (p >= endline || *p != ',') {
- fprintf(stderr, "(11) malformed line %d\n", line);
+ syslog(LOG_INFO, "(5) malformed line %d", line);
fclose(f);
return -1;
}
@@ -495,219 +429,526 @@ parse_file(DB *db, char *file)
save = *p;
*p = 0;
- sdomain.soa.serial = atoi(starttoken);
-
+ ttl = atoi(starttoken);
+
+ sdomain.ttl = ttl;
+
*p = save;
if (++p >= endline) {
- fprintf(stderr, "(12) malformed line %d\n", line);
+ syslog(LOG_INFO, "(6) malformed line %d", line );
fclose(f);
return -1;
}
starttoken = p;
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(13) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
+ switch (type) {
+ case DNS_TYPE_A:
+ p = endline;
+ save = *p;
+ *p = '\0';
+ if (sdomain.a_count < 10) {
+ ia = (in_addr_t *) &sdomain.a[sdomain.a_count];
+ sdomain.a_count++;
+ } else {
+ fprintf(stderr, "too many a records for zone \"%s\", skipping line %d\n", domainname, line);
+ break;
+ }
- sdomain.soa.refresh = atoi(starttoken);
+
+ /* don't allow 0.0.0.0 skip take this entry back */
+ if ((*ia = inet_addr(starttoken)) == INADDR_ANY)
+ sdomain.a_count--;
+
+ *p = save;
+ sdomain.region[sdomain.a_count - 1] = 0xff;
+
+ sdomain.a_ptr = 0;
+ sdomain.flags |= DOMAIN_HAVE_A;
+ break;
+
+ case DNS_TYPE_BALANCE:
+ if ((config & CONFIG_REGION) != CONFIG_REGION) {
+ syslog(LOG_INFO, "must have region before zone in config\n");
+ fclose(f);
+ return -1;
+ }
- *p = save;
+ type = DNS_TYPE_A;
- if (++p >= endline) {
- fprintf(stderr, "(14) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
+ p = endline;
+ save = *p;
+ *p = '\0';
+ if (sdomain.a_count < 10) {
+ ia = (in_addr_t *) &sdomain.a[sdomain.a_count];
+ sdomain.a_count++;
+ } else {
+ fprintf(stderr, "too many a records for zone \"%s\", skipping line %d\n", domainname, line);
+ break;
+ }
- starttoken = p;
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(15) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
+ /* don't allow 0.0.0.0 skip take this entry back */
+ if ((*ia = inet_addr(starttoken)) == INADDR_ANY)
+ sdomain.a_count--;
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
+ region = find_region((in_addr_t *)*ia);
+ sdomain.region[sdomain.a_count - 1] = region;
- sdomain.soa.retry = atoi(starttoken);
-
- *p = save;
- if (++p >= endline) {
- fprintf(stderr, "(16) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
+ *p = save;
- starttoken = p;
+ sdomain.a_ptr = 0;
+ sdomain.flags |= DOMAIN_HAVE_A;
+ break;
- for (p = starttoken; p < endline && *p != ','; p++);
- if (p >= endline || *p != ',') {
- fprintf(stderr, "(17) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
+ case DNS_TYPE_AAAA:
+ p = endline;
+ save = *p;
+ *p = 0;
+ if (sdomain.aaaa_count < 10) {
+ ia6 = (struct in6_addr *) &sdomain.aaaa[sdomain.aaaa_count];
+ sdomain.aaaa_count++;
+ } else {
+ fprintf(stderr, "too many aaaa records for zone \"%s\", skipping line %d\n", domainname, line);
+ break;
+ }
+
+ #ifdef DEBUG
+ printf("starttoken = %s\n", starttoken);
+ #endif
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
+ if (inet_pton(AF_INET6, (char *)starttoken, (char *)ia6) != 1) {
+ sdomain.aaaa_count--;
+ fprintf(stderr, "aaaa \"%s\" unparseable line %d\n", starttoken, line);
+ }
+
+ *p = save;
- sdomain.soa.expire = atoi(starttoken);
-
- *p = save;
+ sdomain.aaaa_ptr = 0;
+ sdomain.flags |= DOMAIN_HAVE_AAAA;
+ break;
+ case DNS_TYPE_MX:
+
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(7) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
- if (++p >= endline) {
- fprintf(stderr, "(18) malformed line %d\n", line);
- fclose(f);
- return -1;
- }
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
- starttoken = p;
- p = endline;
+ if (sdomain.mx_count < 10) {
+ sdomain.mx[sdomain.mx_count].preference = atoi(starttoken);
+ } else {
+ fprintf(stderr, "too many mx records for zone \"%s\", skipping line %d\n", domainname, line);
+ break;
+ }
+
+ *p = save;
- tokenlen = (p - starttoken);
- save = *p;
- *p = 0;
+ if (++p >= endline) {
+ fprintf(stderr, "(XX) malformed line %d", line);
+ break;
+ }
- sdomain.soa.minttl = atoi(starttoken);
- *p = save;
+ starttoken = p;
- sdomain.flags |= DOMAIN_HAVE_SOA;
+ p = endline;
+ save = *p;
+ *p = 0;
- break;
- case DNS_TYPE_PTR:
- p = endline;
- save = *p;
- *p = 0;
- {
- char *name;
+ {
+ char *name;
+ char *n;
- if ((name = dns_label(starttoken, (int *)&sdomain.ptrlen)) == NULL) {
- fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
- goto skip;
+ if ((name = dns_label(starttoken, (int *)&sdomain.mx[sdomain.mx_count].exchangelen)) == NULL) {
+ fprintf(stderr, "illegal mx server, skipping line %d\n", line);
+ goto skip;
+ }
+ n = (char *)sdomain.mx[sdomain.mx_count].exchange;
+
+ memcpy((char *)n, name, sdomain.mx[sdomain.mx_count].exchangelen);
+ free (name);
}
+
+ sdomain.mx_count++;
+ *p = save;
- memcpy((char *)&sdomain.ptr[0], name, sdomain.ptrlen);
- free (name);
- }
-
- *p = save;
+ sdomain.flags |= DOMAIN_HAVE_MX;
+ break;
+ case DNS_TYPE_SOA:
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(7) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
- sdomain.flags |= DOMAIN_HAVE_PTR;
- break;
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
- case DNS_TYPE_NS:
- p = endline;
- save = *p;
- *p = 0;
+ {
+ char *name;
- {
- char *name;
- char *n;
+ if ((name = dns_label(starttoken, (int *)&sdomain.soa.nsserver_len)) == NULL) {
+ fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
+ goto skip;
+ }
- if ((name = dns_label(starttoken, (int *)&sdomain.ns[sdomain.ns_count].nslen)) == NULL) {
- fprintf(stderr, "illegal mx server, skipping line %d\n", line);
- goto skip;
+ memcpy((char *)&sdomain.soa.nsserver[0], name, sdomain.soa.nsserver_len);
+ free (name);
}
- n = (char *)sdomain.ns[sdomain.ns_count].nsserver;
+
+ *p = save;
- memcpy((char *)n, name, sdomain.ns[sdomain.ns_count].nslen);
- free (name);
- }
-
- sdomain.ns_count++;
-
- *p = save;
+ if (++p >= endline) {
+ syslog(LOG_INFO, "(8) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
- sdomain.ns_ptr = 0;
- sdomain.flags |= DOMAIN_HAVE_NS;
- break;
+ starttoken = p;
- case DNS_TYPE_CNAME:
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(9) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
- p = endline;
- save = *p;
- *p = 0;
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
- {
- char *name;
+ {
+ char *name;
- if ((name = dns_label(starttoken, (int *)&sdomain.cnamelen)) == NULL) {
- fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
- goto skip;
+ if ((name = dns_label(starttoken, (int *)&sdomain.soa.rp_len)) == NULL) {
+ fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
+ goto skip;
+ }
+
+ memcpy((char *)&sdomain.soa.responsible_person[0], name, sdomain.soa.rp_len);
+ free (name);
}
+
+ *p = save;
- memcpy((char *)&sdomain.cname[0], name, sdomain.cnamelen);
- free (name);
- }
-
- *p = save;
+ if (++p >= endline) {
+ syslog(LOG_INFO, "(10) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
- sdomain.flags |= DOMAIN_HAVE_CNAME;
- break;
+ starttoken = p;
- default:
- break;
- }
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(11) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
- /* write new record into btree database */
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
- memset(&key, 0, sizeof(key));
- memset(&data, 0, sizeof(data));
+ sdomain.soa.serial = atoi(starttoken);
+
+ *p = save;
- key.data = (char *)converted_name;
- key.size = converted_namelen;
+ if (++p >= endline) {
+ syslog(LOG_INFO, "(12) malformed line %d\n", line);
+ fclose(f);
+ return -1;
+ }
- memcpy(sdomain.zone, converted_name, converted_namelen);
- sdomain.zonelen = converted_namelen;
+ starttoken = p;
- data.data = (void *)&sdomain;
- data.size = sizeof(struct domain);
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(13) malformed line %d\n", line);
+ fclose(f);
+ return -1;
+ }
-#if DB_VERSION_MAJOR > 3
- /* XXX */
- if ((ret = db->put(db, NULL, &key, &data, 0)) != 0) {
- fprintf(stderr, "db->put: %s, key=%s data=%s\n"
- , db_strerror(ret), key.data, data.data);
-#else
- if (db->put(db, &key, &data, 0) < 0) {
- syslog(LOG_INFO, "db->put: %m");
-#endif
- fclose(f);
- return -1;
- }
-
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
+
+ sdomain.soa.refresh = atoi(starttoken);
+
+ *p = save;
+
+ if (++p >= endline) {
+ syslog(LOG_INFO, "(14) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
+
+ starttoken = p;
+
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(15) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
+
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
+
+ sdomain.soa.retry = atoi(starttoken);
+
+ *p = save;
+
+ if (++p >= endline) {
+ syslog(LOG_INFO, "(16) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
+
+ starttoken = p;
+
+ for (p = starttoken; p < endline && *p != ','; p++);
+ if (p >= endline || *p != ',') {
+ syslog(LOG_INFO, "(17) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
+
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
+
+ sdomain.soa.expire = atoi(starttoken);
+
+ *p = save;
+
+ if (++p >= endline) {
+ syslog(LOG_INFO, "(18) malformed line %d", line);
+ fclose(f);
+ return -1;
+ }
+
+ starttoken = p;
+ p = endline;
+
+ tokenlen = (p - starttoken);
+ save = *p;
+ *p = 0;
+
+ sdomain.soa.minttl = atoi(starttoken);
+ *p = save;
+
+ sdomain.flags |= DOMAIN_HAVE_SOA;
+
+ break;
+ case DNS_TYPE_PTR:
+ p = endline;
+ save = *p;
+ *p = 0;
+
+ {
+ char *name;
+
+ if ((name = dns_label(starttoken, (int *)&sdomain.ptrlen)) == NULL) {
+ fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
+ goto skip;
+ }
+
+ memcpy((char *)&sdomain.ptr[0], name, sdomain.ptrlen);
+ free (name);
+ }
+
+ *p = save;
+
+ sdomain.flags |= DOMAIN_HAVE_PTR;
+ break;
+
+ case DNS_TYPE_NS:
+ p = endline;
+ save = *p;
+ *p = 0;
+
+ {
+ char *name;
+ char *n;
+
+ if ((name = dns_label(starttoken, (int *)&sdomain.ns[sdomain.ns_count].nslen)) == NULL) {
+ fprintf(stderr, "illegal mx server, skipping line %d\n", line);
+ goto skip;
+ }
+ n = (char *)sdomain.ns[sdomain.ns_count].nsserver;
+
+ memcpy((char *)n, name, sdomain.ns[sdomain.ns_count].nslen);
+ free (name);
+ }
+
+ sdomain.ns_count++;
+
+ *p = save;
+
+ sdomain.ns_ptr = 0;
+ sdomain.flags |= DOMAIN_HAVE_NS;
+ break;
+
+ case DNS_TYPE_CNAME:
+
+ p = endline;
+ save = *p;
+ *p = 0;
+
+ {
+ char *name;
+
+ if ((name = dns_label(starttoken, (int *)&sdomain.cnamelen)) == NULL) {
+ fprintf(stderr, "illegal nameserver, skipping line %d\n", line);
+ goto skip;
+ }
+
+ memcpy((char *)&sdomain.cname[0], name, sdomain.cnamelen);
+ free (name);
+ }
+
+ *p = save;
+
+ sdomain.flags |= DOMAIN_HAVE_CNAME;
+ break;
+
+ default:
+ break;
+ }
+
+ /* write new record into btree database */
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+
+ key.data = (char *)converted_name;
+ key.size = converted_namelen;
+
+ memcpy(sdomain.zone, converted_name, converted_namelen);
+ sdomain.zonelen = converted_namelen;
+
+ data.data = (void *)&sdomain;
+ data.size = sizeof(struct domain);
+
+ #if DB_VERSION_MAJOR > 3
+ /* XXX */
+ if ((ret = db->put(db, NULL, &key, &data, 0)) != 0) {
+ fprintf(stderr, "db->put: %s" , db_strerror(ret));
+ #else
+ if (db->put(db, &key, &data, 0) < 0) {
+ syslog(LOG_INFO, "db->put: %m");
+ #endif
+ fclose(f);
+ return -1;
+ }
skip:
#ifdef DEBUG
- save = *endline;
- *endline = 0;
-
- printf("line %d: \"%s\"\n", line, start);
+ save = *endline;
+ *endline = 0;
+
+ printf("line %d: \"%s\"\n", line, start);
- *endline = save;
+ *endline = save;
#endif
- if (converted_name)
+ if (converted_name)
free (converted_name);
- /* next line */
- endline++;
+ /* next line */
+ endline++;
- }
+ } /* if (CONFIG_ZONE) */
+ /*
+ * The config version starting at "2"
+ *
+ */
+ if (confstatus & CONFIG_VERSION) {
+ for (; *starttoken && *starttoken != '"'; starttoken++);
+ starttoken++;
+ for (p = starttoken; *p && *p != '"';p++);
+ if (*p == '\0') {
+ syslog(LOG_INFO, "(30) malformed line %d", line);
+ fclose(f);
+ return (-1);
+ }
+ *p++ = '\0';
+
+ version = atoi(starttoken);
+
+ if (version != WILDCARDVERSION) {
+ syslog(LOG_INFO, "version of configfile is wrong, must be"
+ " \"%d\"", WILDCARDVERSION);
+ fclose(f);
+ return (-1);
+ }
+
+ if (*p != ';') {
+ syslog(LOG_INFO, "missing trailing semi-colon on line %d", line);
+ fclose(f);
+ return (-1);
+ }
+
+ config |= CONFIG_VERSION;
+ confstatus &= ~(CONFIG_VERSION);
+ confstatus |= CONFIG_START;
+ }
+ if (confstatus & CONFIG_INCLUDE) {
+ confstatus &= ~(CONFIG_INCLUDE);
+ confstatus |= CONFIG_START;
+ }
+ if (confstatus & CONFIG_REGION) {
+ if (*starttoken == '}') {
+ confstatus &= ~(CONFIG_REGION);
+ confstatus |= CONFIG_START;
+ region++;
+ goto loop;
+ }
+
+ p = strchr(starttoken, '/');
+ if (p == NULL) {
+ if (*starttoken == '\n')
+ goto loop;
+
+ syslog(LOG_INFO, "(31) malformed line, line %d", line);
+ fclose(f);
+ return (-1);
+ }
+
+ *p++ = '\0';
+
+ address = starttoken;
+ starttoken = p;
+
+ p = strchr(starttoken, ';');
+ if (p == NULL) {
+ syslog(LOG_INFO, "(32) malformed line, line %d, must have closing semi-colon", line);
+ fclose(f);
+ return (-1);
+ }
+
+ *p = '\0';
+ insert_region(address, starttoken, region);
+ } /* CONFIG_REGION */
+
+loop:
+ continue;
+
+ } /* while fgets */
+
fclose(f);
return 0;
}
@@ -752,5 +993,3 @@ opendatabase(DB *ret)
return (ret);
}
-
-
blob - d77cacda159760a31269ec6fb83ad2e54a934c73
blob + 83ae012445f37e081607a81502822d3ab7c7ab4d
--- reply.c
+++ reply.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2009 Peter J. Philipp
+ * Copyright (c) 2005-2010 Peter J. Philipp
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@ extern int additional_ptr(char *, int, struct domain *
void update_db(DB *, struct domain *);
-static const char rcsid[] = "$Id: reply.c,v 1.11 2009/11/03 17:03:54 pbug Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.12 2010/03/09 15:38:22 pbug Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -64,6 +64,7 @@ reply_a(struct sreply *sreply, DB *db)
int outlen;
int a_count;
int mod, pos;
+ int ttlhack = 0;
struct answer {
char name[2];
@@ -84,6 +85,7 @@ reply_a(struct sreply *sreply, DB *db)
int salen = sreply->salen;
struct domain *sd = sreply->sd1;
+ u_int8_t region = sreply->region;
#if 0
memset(&reply, 0, sizeof(reply));
@@ -115,12 +117,25 @@ reply_a(struct sreply *sreply, DB *db)
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
q->hdr->namelen + 4);
+ /* if we aren't a balance record our region code is 0xff so check */
+ if (sd->region[sd->a_ptr] != 0xff) {
+ ttlhack = 1;
+ }
+
a_count = 0;
pos = sd->a_ptr;
mod = sd->a_count;
do {
/*
+ * skip records that are not in the needed region
+ */
+ if (ttlhack && sd->region[pos % mod] != region) {
+ pos++;
+ continue;
+ }
+
+ /*
* answer->name is a pointer to the request (0xc00c)
*/
@@ -146,9 +161,15 @@ reply_a(struct sreply *sreply, DB *db)
goto out;
}
+
/* set new offset for answer */
answer = (struct answer *)&reply[outlen];
} while (a_count < 10 && --sd->a_count);
+
+ if (ttlhack) {
+ odh->answer = ntohs(a_count);
+ }
+
out:
if (sendto(so, reply, outlen, 0, sa, salen) < 0) {
blob - /dev/null
blob + e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (mode 644)
repomaster@centroid.eu