Blame
Date:
Sat Nov 8 20:28:31 2014 UTC
Message:
0.9.0 is the last version of Wildcarddnsd, the succeeding project is called Delphinusdnsd and will have its first release around November 15th, 2015. The new project page is at http://delphinusdns.centroid.eu.
0001
2011-09-19
pbug
/*
0002
2014-04-13
pjp
* Copyright (c) 2011-2014 Peter J. Philipp
0003
2011-09-19
pbug
* All rights reserved.
0004
2011-09-19
pbug
*
0005
2011-09-19
pbug
* Redistribution and use in source and binary forms, with or without
0006
2011-09-19
pbug
* modification, are permitted provided that the following conditions
0007
2011-09-19
pbug
* are met:
0008
2011-09-19
pbug
* 1. Redistributions of source code must retain the above copyright
0009
2011-09-19
pbug
* notice, this list of conditions and the following disclaimer.
0010
2011-09-19
pbug
* 2. Redistributions in binary form must reproduce the above copyright
0011
2011-09-19
pbug
* notice, this list of conditions and the following disclaimer in the
0012
2011-09-19
pbug
* documentation and/or other materials provided with the distribution.
0013
2011-09-19
pbug
* 3. The name of the author may not be used to endorse or promote products
0014
2011-09-19
pbug
* derived from this software without specific prior written permission
0015
2011-09-19
pbug
*
0016
2011-09-19
pbug
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017
2011-09-19
pbug
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018
2011-09-19
pbug
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019
2011-09-19
pbug
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020
2011-09-19
pbug
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021
2011-09-19
pbug
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022
2011-09-19
pbug
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023
2011-09-19
pbug
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024
2011-09-19
pbug
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025
2011-09-19
pbug
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026
2011-09-19
pbug
*
0027
2011-09-19
pbug
*/
0028
2011-09-19
pbug
#include "include.h"
0029
2011-09-19
pbug
#include "dns.h"
0030
2011-09-19
pbug
#include "db.h"
0031
2011-09-19
pbug
0032
2011-09-19
pbug
0033
2014-05-18
pjp
void axfrloop(int *, int, char **, DB *);
0034
2014-05-18
pjp
void axfr_connection(int, char *, int, DB *);
0035
2014-05-18
pjp
int build_header(DB *, char *, char *, struct question *, int);
0036
2014-05-18
pjp
int build_soa(DB *, char *, int, struct domain *, struct question *);
0037
2014-05-18
pjp
int checklabel(DB *, struct domain *, struct domain *, struct question *);
0038
2014-05-18
pjp
void gather_notifydomains(DB *);
0039
2014-05-18
pjp
void init_axfr(void);
0040
2014-05-18
pjp
void init_notifyslave(void);
0041
2014-05-18
pjp
int insert_axfr(char *, char *);
0042
2014-05-18
pjp
int insert_notifyslave(char *, char *);
0043
2014-05-18
pjp
void notifypacket(int, void *, void *, int);
0044
2014-05-18
pjp
void notifyslaves(int *);
0045
2014-05-18
pjp
void reap(int);
0046
2011-09-19
pbug
0047
2014-05-18
pjp
extern in_addr_t getmask(int);
0048
2014-05-18
pjp
extern int getmask6(int, struct sockaddr_in6 *);
0049
2014-05-18
pjp
extern void reply_fmterror(struct sreply *);
0050
2014-05-18
pjp
extern void reply_nxdomain(struct sreply *);
0051
2014-05-18
pjp
extern int get_soa(DB *, struct question *, struct domain *, int);
0052
2014-05-18
pjp
extern int compress_label(u_char *, int, int);
0053
2014-05-18
pjp
extern u_int16_t create_anyreply(struct sreply *, char *, int, int, int);
0054
2014-05-18
pjp
extern struct question *build_fake_question(char *, int, u_int16_t);
0055
2014-05-18
pjp
extern struct question *build_question(char *, int, int);
0056
2014-05-18
pjp
extern int free_question(struct question *);
0057
2014-05-18
pjp
extern void dolog(int, char *, ...);
0058
2014-05-18
pjp
extern void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct domain *, struct domain *, u_int8_t, int, int, struct recurses *);
0059
2014-05-17
pjp
0060
2014-05-18
pjp
0061
2014-05-18
pjp
int notify = 0; /* do not notify when set to 0 */
0062
2014-05-18
pjp
0063
2013-02-16
pjp
extern int debug, verbose;
0064
2014-05-17
pjp
extern time_t time_changed;
0065
2013-02-16
pjp
0066
2011-09-19
pbug
SLIST_HEAD(listhead, axfrentry) axfrhead;
0067
2011-09-19
pbug
0068
2014-05-01
pjp
static struct axfrentry {
0069
2011-09-19
pbug
char name[INET6_ADDRSTRLEN];
0070
2011-09-19
pbug
int family;
0071
2011-09-19
pbug
struct sockaddr_storage hostmask;
0072
2011-09-19
pbug
struct sockaddr_storage netmask;
0073
2011-09-19
pbug
u_int8_t prefixlen;
0074
2014-05-01
pjp
SLIST_ENTRY(axfrentry) axfr_entry;
0075
2014-05-01
pjp
} *an2, *anp;
0076
2011-09-19
pbug
0077
2014-05-17
pjp
SLIST_HEAD(notifyslavelisthead, notifyslaveentry) notifyslavehead;
0078
2011-09-19
pbug
0079
2014-05-17
pjp
static struct notifyslaveentry {
0080
2014-05-17
pjp
char name[INET6_ADDRSTRLEN];
0081
2014-05-17
pjp
int family;
0082
2014-05-17
pjp
struct sockaddr_storage hostmask;
0083
2014-05-17
pjp
struct sockaddr_storage netmask;
0084
2014-05-17
pjp
u_int8_t prefixlen;
0085
2014-05-17
pjp
SLIST_ENTRY(notifyslaveentry) notifyslave_entry;
0086
2014-05-17
pjp
} *nfslnp2, *nfslnp;
0087
2011-09-19
pbug
0088
2014-05-17
pjp
0089
2014-05-17
pjp
0090
2014-05-17
pjp
SLIST_HEAD(notifylisthead, notifyentry) notifyhead;
0091
2014-05-17
pjp
0092
2014-05-17
pjp
static struct notifyentry {
0093
2014-05-17
pjp
char domain[DNS_MAXNAME];
0094
2014-05-17
pjp
int domainlen;
0095
2014-05-17
pjp
u_int16_t *ids;
0096
2014-05-17
pjp
u_int16_t *attempts;
0097
2014-05-17
pjp
SLIST_ENTRY(notifyentry) notify_entry;
0098
2014-05-17
pjp
} *notn2, *notnp;
0099
2014-05-17
pjp
0100
2014-05-17
pjp
0101
2014-05-18
pjp
static const char rcsid[] = "$Id: axfr.c,v 1.10 2014/05/18 17:14:05 pjp Exp $";
0102
2014-05-17
pjp
0103
2011-09-19
pbug
/*
0104
2011-09-19
pbug
* INIT_AXFR - initialize the axfr singly linked list
0105
2011-09-19
pbug
*/
0106
2011-09-19
pbug
0107
2011-09-19
pbug
void
0108
2011-09-19
pbug
init_axfr(void)
0109
2011-09-19
pbug
{
0110
2011-09-19
pbug
SLIST_INIT(&axfrhead);
0111
2011-09-19
pbug
return;
0112
2011-09-19
pbug
}
0113
2011-09-19
pbug
0114
2011-09-19
pbug
/*
0115
2011-09-19
pbug
* INSERT_AXFR - insert an address and prefixlen into the axfr slist
0116
2011-09-19
pbug
*/
0117
2011-09-19
pbug
0118
2011-09-19
pbug
int
0119
2011-09-19
pbug
insert_axfr(char *address, char *prefixlen)
0120
2011-09-19
pbug
{
0121
2011-09-19
pbug
struct sockaddr_in *sin;
0122
2011-09-19
pbug
struct sockaddr_in6 *sin6;
0123
2011-09-19
pbug
int pnum;
0124
2011-09-19
pbug
int ret;
0125
2011-09-19
pbug
0126
2011-09-19
pbug
pnum = atoi(prefixlen);
0127
2011-09-19
pbug
an2 = malloc(sizeof(struct axfrentry)); /* Insert after. */
0128
2011-09-19
pbug
0129
2011-09-19
pbug
if (strchr(address, ':') != NULL) {
0130
2011-09-19
pbug
an2->family = AF_INET6;
0131
2011-09-19
pbug
sin6 = (struct sockaddr_in6 *)&an2->hostmask;
0132
2011-09-19
pbug
if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
0133
2011-09-19
pbug
return (-1);
0134
2011-09-19
pbug
sin6->sin6_family = AF_INET6;
0135
2011-09-19
pbug
sin6 = (struct sockaddr_in6 *)&an2->netmask;
0136
2011-09-19
pbug
sin6->sin6_family = AF_INET6;
0137
2011-09-19
pbug
if (getmask6(pnum, sin6) < 0)
0138
2011-09-19
pbug
return(-1);
0139
2011-09-19
pbug
an2->prefixlen = pnum;
0140
2011-09-19
pbug
} else {
0141
2011-09-19
pbug
0142
2011-09-19
pbug
an2->family = AF_INET;
0143
2011-09-19
pbug
sin = (struct sockaddr_in *)&an2->hostmask;
0144
2011-09-19
pbug
sin->sin_family = AF_INET;
0145
2011-09-19
pbug
sin->sin_addr.s_addr = inet_addr(address);
0146
2011-09-19
pbug
sin = (struct sockaddr_in *)&an2->netmask;
0147
2011-09-19
pbug
sin->sin_family = AF_INET;
0148
2011-09-19
pbug
sin->sin_addr.s_addr = getmask(pnum);
0149
2011-09-19
pbug
an2->prefixlen = pnum;
0150
2011-09-19
pbug
0151
2011-09-19
pbug
}
0152
2011-09-19
pbug
0153
2014-05-01
pjp
SLIST_INSERT_HEAD(&axfrhead, an2, axfr_entry);
0154
2011-09-19
pbug
0155
2011-09-19
pbug
return (0);
0156
2011-09-19
pbug
}
0157
2011-09-19
pbug
0158
2011-09-19
pbug
/*
0159
2011-09-19
pbug
* FIND_AXFR - walk the axfr list and find the correponding network
0160
2011-09-19
pbug
* if a network matches return 1, if no match is found return
0161
2011-09-19
pbug
* 0.
0162
2011-09-19
pbug
*/
0163
2011-09-19
pbug
0164
2011-09-19
pbug
int
0165
2011-09-19
pbug
find_axfr(struct sockaddr_storage *sst, int family)
0166
2011-09-19
pbug
{
0167
2011-09-19
pbug
struct sockaddr_in *sin, *sin0;
0168
2011-09-19
pbug
struct sockaddr_in6 *sin6, *sin60, *sin61;
0169
2011-09-19
pbug
u_int32_t hostmask, netmask;
0170
2011-09-19
pbug
u_int32_t a;
0171
2011-09-19
pbug
#ifdef __amd64
0172
2011-09-19
pbug
u_int64_t *hm[2], *nm[2], *a6[2];
0173
2011-09-19
pbug
#else
0174
2011-09-19
pbug
u_int32_t *hm[4], *nm[4], *a6[4];
0175
2011-09-19
pbug
#endif
0176
2011-09-19
pbug
0177
2014-05-01
pjp
SLIST_FOREACH(anp, &axfrhead, axfr_entry) {
0178
2011-09-19
pbug
if (anp->family == AF_INET) {
0179
2011-09-19
pbug
if (family != AF_INET)
0180
2011-09-19
pbug
continue;
0181
2011-09-19
pbug
sin = (struct sockaddr_in *)sst;
0182
2011-09-19
pbug
a = sin->sin_addr.s_addr;
0183
2011-09-19
pbug
sin = (struct sockaddr_in *)&anp->hostmask;
0184
2011-09-19
pbug
sin0 = (struct sockaddr_in *)&anp->netmask;
0185
2011-09-19
pbug
hostmask = sin->sin_addr.s_addr;
0186
2011-09-19
pbug
netmask = sin0->sin_addr.s_addr;
0187
2011-09-19
pbug
if ((hostmask & netmask) == (a & netmask)) {
0188
2011-09-19
pbug
return (1);
0189
2011-09-19
pbug
} /* if hostmask */
0190
2011-09-19
pbug
} else if (anp->family == AF_INET6) {
0191
2011-09-19
pbug
if (family != AF_INET6)
0192
2011-09-19
pbug
continue;
0193
2011-09-19
pbug
sin6 = (struct sockaddr_in6 *)sst;
0194
2011-09-19
pbug
sin60 = (struct sockaddr_in6 *)&anp->hostmask;
0195
2011-09-19
pbug
sin61 = (struct sockaddr_in6 *)&anp->netmask;
0196
2011-09-19
pbug
#ifdef __amd64
0197
2011-09-19
pbug
/*
0198
2011-09-19
pbug
* If this is on a 64 bit machine, we'll benefit
0199
2011-09-19
pbug
* by using 64 bit registers, this should make it
0200
2011-09-19
pbug
* a tad faster...
0201
2011-09-19
pbug
*/
0202
2011-09-19
pbug
hm[0] = (u_int64_t *)&sin60->sin6_addr.s6_addr;
0203
2011-09-19
pbug
hm[1] = (hm[0] + 1);
0204
2011-09-19
pbug
nm[0] = (u_int64_t *)&sin61->sin6_addr.s6_addr;
0205
2011-09-19
pbug
nm[1] = (nm[0] + 1);
0206
2011-09-19
pbug
a6[0] = (u_int64_t *)&sin6->sin6_addr.s6_addr;
0207
2011-09-19
pbug
a6[1] = (a6[0] + 1);
0208
2011-09-19
pbug
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
0209
2011-09-19
pbug
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))) {
0210
2011-09-19
pbug
#else
0211
2011-09-19
pbug
hm[0] = (u_int32_t *)&sin60->sin6_addr.s6_addr;
0212
2011-09-19
pbug
hm[1] = (hm[0] + 1); hm[2] = (hm[1] + 1);
0213
2011-09-19
pbug
hm[3] = (hm[2] + 1);
0214
2011-09-19
pbug
nm[0] = (u_int32_t *)&sin61->sin6_addr.s6_addr;
0215
2011-09-19
pbug
nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
0216
2011-09-19
pbug
nm[3] = (nm[2] + 1);
0217
2011-09-19
pbug
a6[0] = (u_int32_t *)&sin6->sin6_addr.s6_addr;
0218
2011-09-19
pbug
a6[1] = (a6[0] + 1); a6[2] = (a6[1] + 1);
0219
2011-09-19
pbug
a6[3] = (a6[2] + 1);
0220
2011-09-19
pbug
0221
2011-09-19
pbug
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
0222
2011-09-19
pbug
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))&&
0223
2011-09-19
pbug
((*hm[2] & *nm[2]) == (*a6[2] & *nm[2]))&&
0224
2011-09-19
pbug
((*hm[3] & *nm[3]) == (*a6[3] & *nm[3]))) {
0225
2011-09-19
pbug
#endif
0226
2011-09-19
pbug
0227
2011-09-19
pbug
return (1);
0228
2011-09-19
pbug
} /* if ip6 address */
0229
2011-09-19
pbug
0230
2011-09-19
pbug
} /* if AF_INET6 */
0231
2011-09-19
pbug
} /* SLIST */
0232
2011-09-19
pbug
0233
2011-09-19
pbug
return (0);
0234
2011-09-19
pbug
}
0235
2011-09-19
pbug
0236
2014-05-17
pjp
/*
0237
2014-05-17
pjp
* INIT_NOTIFYSLAVE - initialize the axfr singly linked list
0238
2014-05-17
pjp
*/
0239
2014-05-17
pjp
0240
2014-05-17
pjp
void
0241
2014-05-17
pjp
init_notifyslave(void)
0242
2014-05-17
pjp
{
0243
2014-05-17
pjp
SLIST_INIT(&notifyslavehead);
0244
2014-05-17
pjp
return;
0245
2014-05-17
pjp
}
0246
2014-05-17
pjp
0247
2014-05-17
pjp
/*
0248
2014-05-17
pjp
* INSERT_NOTIFYSLAVE - insert an address and prefixlen into the notifyslave slist
0249
2014-05-17
pjp
*/
0250
2014-05-17
pjp
0251
2014-05-17
pjp
int
0252
2014-05-17
pjp
insert_notifyslave(char *address, char *prefixlen)
0253
2014-05-17
pjp
{
0254
2014-05-17
pjp
struct sockaddr_in *sin;
0255
2014-05-17
pjp
struct sockaddr_in6 *sin6;
0256
2014-05-17
pjp
int pnum;
0257
2014-05-17
pjp
int ret;
0258
2014-05-17
pjp
0259
2014-05-17
pjp
pnum = atoi(prefixlen);
0260
2014-05-17
pjp
nfslnp2 = calloc(1, sizeof(struct notifyslaveentry)); /* Insert after. */
0261
2014-05-17
pjp
if (nfslnp2 == NULL)
0262
2014-05-17
pjp
return (-1);
0263
2014-05-17
pjp
0264
2014-05-17
pjp
0265
2014-05-17
pjp
if (strchr(address, ':') != NULL) {
0266
2014-05-17
pjp
nfslnp2->family = AF_INET6;
0267
2014-05-17
pjp
sin6 = (struct sockaddr_in6 *)&nfslnp2->hostmask;
0268
2014-05-17
pjp
if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
0269
2014-05-17
pjp
return (-1);
0270
2014-05-17
pjp
sin6->sin6_family = AF_INET6;
0271
2014-05-17
pjp
sin6->sin6_port = htons(53);
0272
2014-05-17
pjp
sin6 = (struct sockaddr_in6 *)&nfslnp2->netmask;
0273
2014-05-17
pjp
sin6->sin6_family = AF_INET6;
0274
2014-05-17
pjp
if (getmask6(pnum, sin6) < 0)
0275
2014-05-17
pjp
return(-1);
0276
2014-05-17
pjp
nfslnp2->prefixlen = pnum;
0277
2014-05-17
pjp
} else {
0278
2014-05-17
pjp
0279
2014-05-17
pjp
nfslnp2->family = AF_INET;
0280
2014-05-17
pjp
sin = (struct sockaddr_in *)&nfslnp2->hostmask;
0281
2014-05-17
pjp
sin->sin_family = AF_INET;
0282
2014-05-17
pjp
sin->sin_addr.s_addr = inet_addr(address);
0283
2014-05-17
pjp
sin->sin_port = htons(53);
0284
2014-05-17
pjp
sin = (struct sockaddr_in *)&nfslnp2->netmask;
0285
2014-05-17
pjp
sin->sin_family = AF_INET;
0286
2014-05-17
pjp
sin->sin_addr.s_addr = getmask(pnum);
0287
2014-05-17
pjp
nfslnp2->prefixlen = pnum;
0288
2014-05-17
pjp
0289
2014-05-17
pjp
}
0290
2014-05-17
pjp
0291
2014-05-17
pjp
SLIST_INSERT_HEAD(&notifyslavehead, nfslnp2, notifyslave_entry);
0292
2014-05-17
pjp
0293
2014-05-17
pjp
return (0);
0294
2014-05-17
pjp
}
0295
2014-05-17
pjp
0296
2011-09-19
pbug
void
0297
2011-09-19
pbug
axfrloop(int *afd, int sockcount, char **ident, DB *db)
0298
2011-09-19
pbug
{
0299
2011-09-19
pbug
fd_set rset;
0300
2011-09-19
pbug
0301
2011-09-19
pbug
struct timeval tv;
0302
2011-09-19
pbug
struct sockaddr_storage from;
0303
2014-05-17
pjp
struct sockaddr_in6 *sin6, *sin62;
0304
2014-05-17
pjp
struct sockaddr_in *sin, *sin2;
0305
2014-05-17
pjp
struct dns_header *dh;
0306
2014-05-17
pjp
struct question *question;
0307
2011-09-19
pbug
0308
2014-05-17
pjp
int i, so, len;
0309
2011-09-19
pbug
int sel, maxso = 0;
0310
2011-09-19
pbug
int is_ipv6, axfr_acl;
0311
2014-05-17
pjp
int notifyfd[2];
0312
2014-05-17
pjp
0313
2011-09-19
pbug
socklen_t fromlen;
0314
2014-05-17
pjp
char buf[512];
0315
2014-05-17
pjp
0316
2014-05-17
pjp
time_t now;
0317
2011-09-19
pbug
pid_t pid;
0318
2011-09-19
pbug
0319
2011-09-19
pbug
char address[INET6_ADDRSTRLEN];
0320
2011-09-19
pbug
0321
2011-09-19
pbug
signal(SIGCHLD, reap);
0322
2011-09-19
pbug
0323
2011-09-19
pbug
for (i = 0; i < sockcount; i++) {
0324
2011-09-19
pbug
listen(afd[i], 5);
0325
2011-09-19
pbug
}
0326
2011-09-19
pbug
0327
2014-05-17
pjp
if (notify) {
0328
2014-05-17
pjp
/*
0329
2014-05-17
pjp
* If a zonefile has changed in the last half hour then
0330
2014-05-17
pjp
* gather all notifydomains and start the notify process
0331
2014-05-17
pjp
*/
0332
2014-05-17
pjp
0333
2014-05-17
pjp
notifyfd[0] = -1;
0334
2014-05-17
pjp
notifyfd[1] = -1;
0335
2014-05-17
pjp
0336
2014-05-17
pjp
now = time(NULL);
0337
2014-05-17
pjp
if (difftime(now, time_changed) <= 1800) {
0338
2014-05-17
pjp
gather_notifydomains(db);
0339
2014-05-17
pjp
notifyfd[0] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
0340
2014-05-17
pjp
notifyfd[1] = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
0341
2014-05-17
pjp
0342
2014-05-17
pjp
memset((char *)&from, 0, sizeof(from));
0343
2014-05-17
pjp
sin = (struct sockaddr_in *)&from;
0344
2014-05-17
pjp
sin->sin_family = AF_INET;
0345
2014-05-17
pjp
sin->sin_port = htons(0);
0346
2014-05-17
pjp
0347
2014-05-17
pjp
if (bind(notifyfd[0], (struct sockaddr *)sin, sizeof(*sin)) < 0) {
0348
2014-05-17
pjp
dolog(LOG_INFO, "bind notify: %s\n", strerror(errno));
0349
2014-05-17
pjp
}
0350
2014-05-17
pjp
0351
2014-05-17
pjp
memset((char *)&from, 0, sizeof(from));
0352
2014-05-17
pjp
sin6 = (struct sockaddr_in6 *)&from;
0353
2014-05-17
pjp
sin->sin_family = AF_INET6;
0354
2014-05-17
pjp
sin->sin_port = htons(0);
0355
2014-05-17
pjp
0356
2014-05-17
pjp
if (bind(notifyfd[1], (struct sockaddr *)sin, sizeof(*sin6)) < 0) {
0357
2014-05-17
pjp
dolog(LOG_INFO, "bind notify6: %s\n", strerror(errno));
0358
2014-05-17
pjp
}
0359
2014-05-17
pjp
0360
2014-05-17
pjp
memset((char *)&from, 0, sizeof(from));
0361
2014-05-17
pjp
0362
2014-05-17
pjp
notifyslaves((int *)&notifyfd);
0363
2014-05-17
pjp
}
0364
2014-05-17
pjp
}
0365
2014-05-17
pjp
0366
2011-09-19
pbug
for (;;) {
0367
2011-09-19
pbug
0368
2011-09-19
pbug
FD_ZERO(&rset);
0369
2014-05-17
pjp
maxso = 0;
0370
2011-09-19
pbug
0371
2011-09-19
pbug
for (i = 0; i < sockcount; i++) {
0372
2011-09-19
pbug
FD_SET(afd[i], &rset);
0373
2014-05-17
pjp
if (maxso < afd[i])
0374
2014-05-17
pjp
maxso = afd[i];
0375
2011-09-19
pbug
}
0376
2014-05-17
pjp
0377
2014-05-17
pjp
if (notify) {
0378
2014-05-17
pjp
if (notifyfd[0] > -1) {
0379
2014-05-17
pjp
FD_SET(notifyfd[0], &rset);
0380
2014-05-17
pjp
if (maxso < notifyfd[0])
0381
2014-05-17
pjp
maxso = notifyfd[0];
0382
2014-05-17
pjp
}
0383
2014-05-17
pjp
0384
2014-05-17
pjp
if (notifyfd[1] > -1) {
0385
2014-05-17
pjp
FD_SET(notifyfd[1], &rset);
0386
2014-05-17
pjp
if (maxso < notifyfd[1])
0387
2014-05-17
pjp
maxso = notifyfd[1];
0388
2014-05-17
pjp
}
0389
2014-05-17
pjp
}
0390
2011-09-19
pbug
0391
2011-09-19
pbug
tv.tv_sec = 10;
0392
2011-09-19
pbug
tv.tv_usec = 0;
0393
2011-09-19
pbug
0394
2014-05-17
pjp
sel = select(maxso + 1, &rset, NULL, NULL, &tv);
0395
2011-09-19
pbug
0396
2014-05-17
pjp
if (sel == 0) {
0397
2014-05-17
pjp
if (notify) {
0398
2014-05-17
pjp
if (notifyfd[0] > -1 || notifyfd[1] > -1)
0399
2014-05-17
pjp
notifyslaves((int *)&notifyfd);
0400
2014-05-17
pjp
}
0401
2014-05-17
pjp
0402
2014-05-17
pjp
continue;
0403
2014-05-17
pjp
}
0404
2011-09-19
pbug
if (sel < 0) {
0405
2013-02-16
pjp
dolog(LOG_INFO, "select: %s\n", strerror(errno));
0406
2011-09-19
pbug
continue;
0407
2011-09-19
pbug
}
0408
2011-09-19
pbug
0409
2011-09-19
pbug
for (i = 0; i < sockcount; i++) {
0410
2011-09-19
pbug
if (FD_ISSET(afd[i], &rset)) {
0411
2011-09-19
pbug
fromlen = sizeof(struct sockaddr_storage);
0412
2011-09-19
pbug
0413
2011-09-19
pbug
so = accept(afd[i], (struct sockaddr*)&from, &fromlen);
0414
2011-09-19
pbug
if (so < 0) {
0415
2013-02-16
pjp
dolog(LOG_INFO, "afd accept: %s\n", strerror(errno));
0416
2011-09-19
pbug
continue;
0417
2011-09-19
pbug
}
0418
2011-09-19
pbug
0419
2011-09-19
pbug
if (from.ss_family == AF_INET6) {
0420
2011-09-19
pbug
is_ipv6 = 1;
0421
2011-09-19
pbug
0422
2011-09-19
pbug
fromlen = sizeof(struct sockaddr_in6);
0423
2011-09-19
pbug
sin6 = (struct sockaddr_in6 *)&from;
0424
2011-09-19
pbug
inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
0425
2011-09-19
pbug
axfr_acl = find_axfr((struct sockaddr_storage *)sin6, AF_INET6);
0426
2011-09-19
pbug
0427
2011-09-19
pbug
} else if (from.ss_family == AF_INET) {
0428
2011-09-19
pbug
is_ipv6 = 0;
0429
2011-09-19
pbug
0430
2011-09-19
pbug
fromlen = sizeof(struct sockaddr_in);
0431
2011-09-19
pbug
sin = (struct sockaddr_in *)&from;
0432
2011-09-19
pbug
inet_ntop(AF_INET, (void*)&sin->sin_addr, (char*)&address, sizeof(address));
0433
2011-09-19
pbug
0434
2011-09-19
pbug
axfr_acl = find_axfr((struct sockaddr_storage *)sin, AF_INET);
0435
2011-09-19
pbug
0436
2011-09-19
pbug
} else {
0437
2013-02-16
pjp
dolog(LOG_INFO, "afd accept unknown family %d, close\n", from.ss_family);
0438
2011-09-19
pbug
close(so);
0439
2011-09-19
pbug
continue;
0440
2011-09-19
pbug
}
0441
2011-09-19
pbug
0442
2011-09-19
pbug
if (! axfr_acl) {
0443
2013-02-16
pjp
dolog(LOG_INFO, "connection from %s was not in our axfr acl, drop\n", address);
0444
2011-09-19
pbug
close(so);
0445
2011-09-19
pbug
continue;
0446
2011-09-19
pbug
}
0447
2011-09-19
pbug
0448
2013-02-16
pjp
dolog(LOG_INFO, "AXFR connection from %s on interface \"%s\"\n", address, ident[i]);
0449
2011-09-19
pbug
0450
2011-09-19
pbug
switch (pid = fork()) {
0451
2011-09-19
pbug
case 0:
0452
2011-09-19
pbug
axfr_connection(so, address, is_ipv6, db);
0453
2011-09-19
pbug
exit(0);
0454
2011-09-19
pbug
/*NOTREACHED*/
0455
2011-09-19
pbug
default:
0456
2011-09-19
pbug
close(so);
0457
2011-09-19
pbug
break;
0458
2011-09-19
pbug
}
0459
2011-09-19
pbug
0460
2011-09-19
pbug
} /* if(FD_ISSET..) */
0461
2011-09-19
pbug
0462
2011-09-19
pbug
} /* for (i.. */
0463
2011-09-19
pbug
0464
2014-05-17
pjp
if (notify) {
0465
2014-05-17
pjp
if (notifyfd[0] > -1 && FD_ISSET(notifyfd[0], &rset)) {
0466
2014-05-17
pjp
fromlen = sizeof(struct sockaddr_storage);
0467
2014-05-17
pjp
len = recvfrom(notifyfd[0], buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
0468
2014-05-17
pjp
if (len < 0) {
0469
2014-05-17
pjp
dolog(LOG_INFO, "recvfrom: %s\n", strerror(errno));
0470
2014-05-17
pjp
}
0471
2014-05-17
pjp
0472
2014-05-17
pjp
if (len < sizeof(struct dns_header)) {
0473
2014-05-17
pjp
dolog(LOG_INFO, "received bogus reply on notify port, drop\n");
0474
2014-05-17
pjp
continue;
0475
2014-05-17
pjp
}
0476
2014-05-17
pjp
0477
2014-05-17
pjp
dh = (struct dns_header *)&buf[0];
0478
2014-05-17
pjp
if (ntohs(dh->question) != 1) {
0479
2014-05-17
pjp
dolog(LOG_INFO, "question header on notify reply not 1, drop\n");
0480
2014-05-17
pjp
continue;
0481
2014-05-17
pjp
}
0482
2014-05-17
pjp
0483
2014-05-17
pjp
if (! (ntohs(dh->query) & DNS_REPLY)) {
0484
2014-05-17
pjp
dolog(LOG_INFO, "question header is not a reply, drop\n");
0485
2014-05-17
pjp
continue;
0486
2014-05-17
pjp
}
0487
2014-05-17
pjp
0488
2014-05-17
pjp
question = build_question(buf, len, ntohs(dh->additional));
0489
2014-05-17
pjp
if (question == NULL) {
0490
2014-05-17
pjp
dolog(LOG_INFO, "build_question failed on notify reply, drop\n");
0491
2014-05-17
pjp
continue;
0492
2014-05-17
pjp
}
0493
2014-05-17
pjp
0494
2014-05-17
pjp
sin = (struct sockaddr_in *)&from;
0495
2014-05-17
pjp
inet_ntop(AF_INET, (void*)&sin->sin_addr, (char*)&address, sizeof(address));
0496
2014-05-17
pjp
0497
2014-05-18
pjp
#ifdef __linux__
0498
2014-05-18
pjp
SLIST_FOREACH(notnp, &notifyhead, notify_entry) {
0499
2014-05-18
pjp
#else
0500
2014-05-17
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
0501
2014-05-18
pjp
#endif
0502
2014-05-17
pjp
0503
2014-05-17
pjp
for (i = 0; i < notify; i++) {
0504
2014-05-17
pjp
if (ntohs(dh->id) == notnp->ids[i] &&
0505
2014-05-17
pjp
(ntohs(dh->query) & DNS_NOTIFY) &&
0506
2014-05-17
pjp
(ntohs(dh->query) & DNS_AUTH) &&
0507
2014-05-17
pjp
ntohs(question->hdr->qtype) == DNS_TYPE_SOA &&
0508
2014-05-17
pjp
ntohs(question->hdr->qclass) == DNS_CLASS_IN &&
0509
2014-05-17
pjp
question->hdr->namelen == notnp->domainlen &&
0510
2014-05-17
pjp
memcmp(question->hdr->name, notnp->domain, notnp->domainlen) == 0) {
0511
2014-05-18
pjp
#ifdef __linux__
0512
2014-05-18
pjp
SLIST_FOREACH(nfslnp, &notifyslavehead, notifyslave_entry) {
0513
2014-05-18
pjp
#else
0514
2014-05-17
pjp
SLIST_FOREACH_SAFE(nfslnp, &notifyslavehead, notifyslave_entry, nfslnp2) {
0515
2014-05-18
pjp
#endif
0516
2014-05-17
pjp
if (nfslnp->family != AF_INET)
0517
2014-05-17
pjp
continue;
0518
2014-05-17
pjp
0519
2014-05-17
pjp
sin2 = (struct sockaddr_in *)&nfslnp->hostmask;
0520
2014-05-17
pjp
if (sin->sin_addr.s_addr == sin2->sin_addr.s_addr) {
0521
2014-05-17
pjp
dolog(LOG_INFO, "notify success! removing address \"%s\" from notify contact list\n", address);
0522
2014-05-17
pjp
SLIST_REMOVE(&notifyslavehead, nfslnp, notifyslaveentry, notifyslave_entry);
0523
2014-05-17
pjp
}
0524
2014-05-17
pjp
}
0525
2014-05-17
pjp
} else {
0526
2014-05-17
pjp
dolog(LOG_INFO, "got a reply from a notify host (%s) DNS->ID %u that says: %04x\n", address, ntohs(dh->id), ntohs(dh->query));
0527
2014-05-17
pjp
}
0528
2014-05-17
pjp
}
0529
2014-05-17
pjp
}
0530
2014-05-17
pjp
0531
2014-05-17
pjp
free_question(question);
0532
2014-05-17
pjp
0533
2014-05-17
pjp
if (SLIST_EMPTY(&notifyslavehead)) {
0534
2014-05-17
pjp
dolog(LOG_INFO, "notifys have been completed, closing notify descriptors!\n");
0535
2014-05-17
pjp
if (notifyfd[0] > -1)
0536
2014-05-17
pjp
close(notifyfd[0]);
0537
2014-05-17
pjp
0538
2014-05-17
pjp
if (notifyfd[1] > -1)
0539
2014-05-17
pjp
close(notifyfd[1]);
0540
2014-05-17
pjp
0541
2014-05-17
pjp
notifyfd[0] = -1;
0542
2014-05-17
pjp
notifyfd[1] = -1;
0543
2014-05-17
pjp
}
0544
2014-05-17
pjp
}
0545
2014-05-17
pjp
0546
2014-05-17
pjp
if (notifyfd[1] > -1 && FD_ISSET(notifyfd[1], &rset)) {
0547
2014-05-17
pjp
fromlen = sizeof(struct sockaddr_storage);
0548
2014-05-17
pjp
len = recvfrom(notifyfd[1], buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
0549
2014-05-17
pjp
if (len < 0) {
0550
2014-05-17
pjp
dolog(LOG_INFO, "recvfrom: %s\n", strerror(errno));
0551
2014-05-17
pjp
}
0552
2014-05-17
pjp
0553
2014-05-17
pjp
if (len < sizeof(struct dns_header)) {
0554
2014-05-17
pjp
dolog(LOG_INFO, "received bogus reply on notify port, drop\n");
0555
2014-05-17
pjp
continue;
0556
2014-05-17
pjp
}
0557
2014-05-17
pjp
0558
2014-05-17
pjp
dh = (struct dns_header *)&buf[0];
0559
2014-05-17
pjp
if (ntohs(dh->question) != 1) {
0560
2014-05-17
pjp
dolog(LOG_INFO, "question header on notify reply not 1, drop\n");
0561
2014-05-17
pjp
continue;
0562
2014-05-17
pjp
}
0563
2014-05-17
pjp
0564
2014-05-17
pjp
if (! (ntohs(dh->query) & DNS_REPLY)) {
0565
2014-05-17
pjp
dolog(LOG_INFO, "question header is not a reply, drop\n");
0566
2014-05-17
pjp
continue;
0567
2014-05-17
pjp
}
0568
2014-05-17
pjp
0569
2014-05-17
pjp
question = build_question(buf, len, ntohs(dh->additional));
0570
2014-05-17
pjp
if (question == NULL) {
0571
2014-05-17
pjp
dolog(LOG_INFO, "build_question failed on notify reply, drop\n");
0572
2014-05-17
pjp
continue;
0573
2014-05-17
pjp
}
0574
2014-05-17
pjp
0575
2014-05-17
pjp
sin6 = (struct sockaddr_in6 *)&from;
0576
2014-05-17
pjp
inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
0577
2014-05-17
pjp
0578
2014-05-18
pjp
#ifdef __linux
0579
2014-05-18
pjp
SLIST_FOREACH(notnp, &notifyhead, notify_entry) {
0580
2014-05-18
pjp
#else
0581
2014-05-17
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
0582
2014-05-18
pjp
#endif
0583
2014-05-17
pjp
for (i = 0; i < notify; i++) {
0584
2014-05-17
pjp
if (ntohs(dh->id) == notnp->ids[i] &&
0585
2014-05-17
pjp
(ntohs(dh->query) & DNS_NOTIFY) &&
0586
2014-05-17
pjp
(ntohs(dh->query) & DNS_AUTH) &&
0587
2014-05-17
pjp
ntohs(question->hdr->qtype) == DNS_TYPE_SOA &&
0588
2014-05-17
pjp
ntohs(question->hdr->qclass) == DNS_CLASS_IN &&
0589
2014-05-17
pjp
question->hdr->namelen == notnp->domainlen &&
0590
2014-05-17
pjp
memcmp(question->hdr->name, notnp->domain, notnp->domainlen) == 0) {
0591
2014-05-18
pjp
#ifdef __linux__
0592
2014-05-18
pjp
SLIST_FOREACH(nfslnp, &notifyslavehead, notifyslave_entry) {
0593
2014-05-18
pjp
#else
0594
2014-05-17
pjp
SLIST_FOREACH_SAFE(nfslnp, &notifyslavehead, notifyslave_entry, nfslnp2) {
0595
2014-05-18
pjp
#endif
0596
2014-05-17
pjp
if (nfslnp->family != AF_INET6)
0597
2014-05-17
pjp
continue;
0598
2014-05-17
pjp
0599
2014-05-17
pjp
sin62 = (struct sockaddr_in6 *)&nfslnp->hostmask;
0600
2014-05-17
pjp
if (memcmp(&sin6->sin6_addr, &sin62->sin6_addr, 16) == 0) {
0601
2014-05-17
pjp
dolog(LOG_INFO, "notify success! removing address \"%s\" from notify contact list\n", address);
0602
2014-05-17
pjp
SLIST_REMOVE(&notifyslavehead, nfslnp, notifyslaveentry, notifyslave_entry);
0603
2014-05-17
pjp
}
0604
2014-05-17
pjp
}
0605
2014-05-17
pjp
} else {
0606
2014-05-17
pjp
dolog(LOG_INFO, "got a reply from a notify host (%s) DNS->ID %u that says: %04x\n", address, ntohs(dh->id), ntohs(dh->query));
0607
2014-05-17
pjp
}
0608
2014-05-17
pjp
}
0609
2014-05-17
pjp
}
0610
2014-05-17
pjp
0611
2014-05-17
pjp
free_question(question);
0612
2014-05-17
pjp
0613
2014-05-17
pjp
if (SLIST_EMPTY(&notifyslavehead)) {
0614
2014-05-17
pjp
dolog(LOG_INFO, "notifys have been completed, closing notify descriptors!\n");
0615
2014-05-17
pjp
if (notifyfd[0] > -1)
0616
2014-05-17
pjp
close(notifyfd[0]);
0617
2014-05-17
pjp
0618
2014-05-17
pjp
if (notifyfd[1] > -1)
0619
2014-05-17
pjp
close(notifyfd[1]);
0620
2014-05-17
pjp
0621
2014-05-17
pjp
notifyfd[0] = -1;
0622
2014-05-17
pjp
notifyfd[1] = -1;
0623
2014-05-17
pjp
}
0624
2014-05-17
pjp
}
0625
2014-05-17
pjp
0626
2014-05-17
pjp
}
0627
2014-05-17
pjp
0628
2011-09-19
pbug
} /* for (;;) */
0629
2011-09-19
pbug
0630
2011-09-19
pbug
}
0631
2011-09-19
pbug
0632
2011-09-19
pbug
/*
0633
2011-09-19
pbug
* AXFR_CONNECTION - this is the main core of AXFR engine, forked
0634
2011-09-19
pbug
*
0635
2011-09-19
pbug
*/
0636
2011-09-19
pbug
0637
2011-09-19
pbug
void
0638
2011-09-19
pbug
axfr_connection(int so, char *address, int is_ipv6, DB *db)
0639
2011-09-19
pbug
{
0640
2011-09-19
pbug
0641
2011-09-19
pbug
char buf[4000];
0642
2011-09-19
pbug
char *p = &buf[0];
0643
2011-09-19
pbug
char *q;
0644
2011-09-19
pbug
char *reply;
0645
2011-09-19
pbug
0646
2011-09-19
pbug
int len, dnslen;
0647
2011-09-19
pbug
int offset = 0;
0648
2011-09-19
pbug
int ret;
0649
2011-09-19
pbug
int qlen;
0650
2011-09-19
pbug
int outlen, i;
0651
2011-09-19
pbug
int rrcount;
0652
2011-09-19
pbug
0653
2011-09-19
pbug
u_int16_t *tmp;
0654
2011-09-19
pbug
0655
2011-09-19
pbug
struct dns_header *dh, *odh;
0656
2011-09-19
pbug
struct sreply sreply;
0657
2011-09-19
pbug
struct question *question, *fq;
0658
2011-09-19
pbug
struct domain soa, sdomain, nsdomain, savesd;
0659
2011-09-19
pbug
0660
2011-09-19
pbug
DBT key, data;
0661
2011-09-19
pbug
DBC *cursor;
0662
2011-09-19
pbug
0663
2011-09-19
pbug
for (;;) {
0664
2011-09-19
pbug
len = recv(so, p + offset, sizeof(buf) - offset, 0);
0665
2011-09-19
pbug
if (len <= 0) {
0666
2011-09-19
pbug
close(so);
0667
2011-09-19
pbug
exit(1);
0668
2011-09-19
pbug
}
0669
2011-09-19
pbug
0670
2011-09-19
pbug
/*
0671
2011-09-19
pbug
* do a little dance here because we don't know if the
0672
2011-09-19
pbug
* input is fragmented or not...
0673
2011-09-19
pbug
*/
0674
2011-09-19
pbug
if (offset + len >= 2) {
0675
2011-09-19
pbug
tmp = (u_int16_t *)p;
0676
2011-09-19
pbug
dnslen = ntohs(*tmp);
0677
2011-09-19
pbug
} else {
0678
2011-09-19
pbug
offset += len;
0679
2011-09-19
pbug
continue;
0680
2011-09-19
pbug
}
0681
2011-09-19
pbug
if (dnslen + 2 != offset + len) {
0682
2011-09-19
pbug
offset += len;
0683
2011-09-19
pbug
continue;
0684
2011-09-19
pbug
}
0685
2011-09-19
pbug
0686
2011-09-19
pbug
0687
2011-09-19
pbug
/* by now the packet should be normalized */
0688
2011-09-19
pbug
0689
2011-09-19
pbug
dh = (struct dns_header *)(p + 2);
0690
2011-09-19
pbug
0691
2011-09-19
pbug
if ((ntohs(dh->query) & DNS_REPLY)) {
0692
2013-02-16
pjp
dolog(LOG_INFO, "AXFR dns packet is not a question, drop\n");
0693
2011-09-19
pbug
goto drop;
0694
2011-09-19
pbug
}
0695
2011-09-19
pbug
0696
2011-09-19
pbug
if (ntohs(dh->question) != 1) {
0697
2013-02-16
pjp
dolog(LOG_INFO, "AXFR dns packet does not have a question count of 1 (RFC 5936, page 9), reply fmterror\n");
0698
2011-09-19
pbug
0699
2011-09-19
pbug
build_reply(&sreply, so, (p + 2), dnslen, NULL, NULL, 0, NULL, NULL, 0xff, 1, 0, NULL);
0700
2011-09-19
pbug
0701
2011-09-19
pbug
reply_fmterror(&sreply);
0702
2011-09-19
pbug
goto drop;
0703
2011-09-19
pbug
}
0704
2011-09-19
pbug
0705
2014-05-17
pjp
if ((question = build_question((p + 2), dnslen, 0)) == NULL) {
0706
2013-02-16
pjp
dolog(LOG_INFO, "AXFR malformed question, drop\n");
0707
2011-09-19
pbug
goto drop;
0708
2011-09-19
pbug
}
0709
2011-09-19
pbug
0710
2011-09-19
pbug
if (ntohs(question->hdr->qclass) != DNS_CLASS_IN) {
0711
2013-02-16
pjp
dolog(LOG_INFO, "AXFR question wasn't for class DNS_CLASS_IN, drop\n");
0712
2011-09-19
pbug
goto drop;
0713
2011-09-19
pbug
}
0714
2011-09-19
pbug
0715
2011-09-22
pbug
switch (ntohs(question->hdr->qtype)) {
0716
2011-09-22
pbug
case DNS_TYPE_AXFR:
0717
2011-09-22
pbug
case DNS_TYPE_IXFR:
0718
2011-09-22
pbug
case DNS_TYPE_SOA:
0719
2011-09-22
pbug
break;
0720
2011-09-22
pbug
default:
0721
2013-02-16
pjp
dolog(LOG_INFO, "AXFR question wasn't for valid types (ixfr, axfr, soa) with requested type %d, drop\n", ntohs(question->hdr->qtype));
0722
2011-09-19
pbug
goto drop;
0723
2011-09-22
pbug
0724
2011-09-19
pbug
}
0725
2011-09-19
pbug
0726
2011-09-19
pbug
/* now we can be reasonably sure that it's an AXFR for us */
0727
2011-09-19
pbug
0728
2011-09-19
pbug
reply = calloc(1, 65538);
0729
2011-09-19
pbug
if (reply == NULL) {
0730
2013-02-16
pjp
dolog(LOG_INFO, "internal error: %s\n", strerror(errno));
0731
2011-09-19
pbug
goto drop;
0732
2011-09-19
pbug
}
0733
2011-09-19
pbug
0734
2011-09-19
pbug
odh = (struct dns_header *)(reply + 2);
0735
2011-09-19
pbug
0736
2011-09-19
pbug
q = question->hdr->name;
0737
2011-09-19
pbug
qlen = question->hdr->namelen;
0738
2011-09-19
pbug
0739
2011-09-19
pbug
memset(&key, 0, sizeof(key));
0740
2011-09-19
pbug
memset(&data, 0, sizeof(data));
0741
2011-09-19
pbug
0742
2011-09-19
pbug
key.data = (char *)q;
0743
2011-09-19
pbug
key.size = qlen;
0744
2011-09-19
pbug
0745
2011-09-19
pbug
data.data = NULL;
0746
2011-09-19
pbug
data.size = 0;
0747
2011-09-19
pbug
0748
2011-09-19
pbug
ret = db->get(db, NULL, &key, &data, 0);
0749
2011-09-19
pbug
0750
2011-09-19
pbug
if (ret != 0) {
0751
2011-09-19
pbug
memset(&sdomain, 0, sizeof(sdomain));
0752
2011-09-19
pbug
(void)get_soa(db, question, &sdomain, 0);
0753
2011-09-19
pbug
build_reply(&sreply, so, (p + 2), dnslen, question, NULL, 0, &sdomain, NULL, 0xff, 1, 0, NULL);
0754
2011-09-19
pbug
reply_nxdomain(&sreply);
0755
2013-02-16
pjp
dolog(LOG_INFO, "AXFR request for zone %s, no db entry, nxdomain -> drop\n", question->converted_name);
0756
2011-09-19
pbug
goto drop;
0757
2011-09-19
pbug
}
0758
2011-09-19
pbug
0759
2011-09-19
pbug
if (data.size != sizeof(struct domain)) {
0760
2013-02-16
pjp
dolog(LOG_INFO, "AXFR btree db is damaged, drop\n");
0761
2011-09-19
pbug
goto drop;
0762
2011-09-19
pbug
}
0763
2011-09-19
pbug
0764
2011-09-19
pbug
memcpy((char *)&soa, (char *)data.data, data.size);
0765
2011-09-19
pbug
0766
2011-09-19
pbug
/*
0767
2011-09-19
pbug
* check if we have an SOA record
0768
2011-09-19
pbug
*/
0769
2011-09-19
pbug
0770
2011-09-19
pbug
if (! (soa.flags & DOMAIN_HAVE_SOA)) {
0771
2011-09-19
pbug
memset(&sdomain, 0, sizeof(sdomain));
0772
2011-09-19
pbug
(void)get_soa(db, question, &sdomain, 0);
0773
2011-09-19
pbug
build_reply(&sreply, so, (p + 2), dnslen, question, NULL, 0, &sdomain, NULL, 0xff, 1, 0, NULL);
0774
2011-09-19
pbug
reply_nxdomain(&sreply);
0775
2011-09-19
pbug
0776
2013-02-16
pjp
dolog(LOG_INFO, "AXFR request for zone %s, which has no SOA for the zone, nxdomain -> drop\n", question->converted_name);
0777
2011-09-19
pbug
goto drop;
0778
2011-09-19
pbug
}
0779
2011-09-19
pbug
0780
2011-09-19
pbug
if (ntohs(question->hdr->qtype) == DNS_TYPE_SOA) {
0781
2013-02-16
pjp
dolog(LOG_INFO, "TCP SOA request for zone \"%s\", replying...\n", question->converted_name);
0782
2011-09-19
pbug
outlen = 0;
0783
2011-09-19
pbug
outlen = build_header(db, (reply + 2), (p + 2), question, 1);
0784
2011-09-19
pbug
outlen = build_soa(db, (reply + 2), outlen, &soa, question);
0785
2011-09-19
pbug
0786
2011-09-19
pbug
tmp = (u_int16_t *)reply;
0787
2011-09-19
pbug
*tmp = htons(outlen);
0788
2011-09-19
pbug
0789
2011-09-19
pbug
len = send(so, reply, outlen + 2, 0);
0790
2011-09-19
pbug
if (len <= 0) {
0791
2011-09-19
pbug
goto drop;
0792
2011-09-19
pbug
}
0793
2011-09-19
pbug
0794
2011-09-19
pbug
outlen = 0;
0795
2011-09-19
pbug
offset = 0;
0796
2011-09-19
pbug
p = &buf[0];
0797
2011-09-19
pbug
0798
2011-09-19
pbug
free (reply);
0799
2011-09-19
pbug
0800
2011-09-19
pbug
continue;
0801
2011-09-19
pbug
}
0802
2011-09-19
pbug
0803
2013-02-16
pjp
dolog(LOG_INFO, "%s request for zone \"%s\", replying...\n",
0804
2011-09-22
pbug
(ntohs(question->hdr->qtype) == DNS_TYPE_AXFR ? "AXFR"
0805
2011-09-22
pbug
: "IXFR"), question->converted_name);
0806
2011-09-19
pbug
0807
2011-09-19
pbug
outlen = build_header(db, (reply + 2), (p + 2), question, 0);
0808
2011-09-19
pbug
outlen = build_soa(db, (reply + 2), outlen, &soa, question);
0809
2011-09-19
pbug
rrcount = 1;
0810
2011-09-19
pbug
0811
2011-09-19
pbug
if (db->cursor(db, NULL, &cursor, 0) != 0) {
0812
2013-02-16
pjp
dolog(LOG_INFO, "db->cursor: %s\n", strerror(errno));
0813
2011-09-19
pbug
goto drop;
0814
2011-09-19
pbug
}
0815
2011-09-19
pbug
0816
2011-09-19
pbug
memset(&key, 0, sizeof(key));
0817
2011-09-19
pbug
memset(&data, 0, sizeof(data));
0818
2011-09-19
pbug
0819
2011-09-19
pbug
0820
2011-09-19
pbug
if (cursor->c_get(cursor, &key, &data, DB_FIRST) != 0) {
0821
2013-02-16
pjp
dolog(LOG_INFO, "cursor->c_get: %s\n", strerror(errno));
0822
2011-09-19
pbug
goto drop;
0823
2011-09-19
pbug
}
0824
2011-09-19
pbug
0825
2011-09-19
pbug
do {
0826
2011-09-19
pbug
if (data.size != sizeof(struct domain)) {
0827
2013-02-16
pjp
dolog(LOG_INFO, "AXFR btree db is damaged (%d), drop\n", __LINE__);
0828
2011-09-19
pbug
goto drop;
0829
2011-09-19
pbug
}
0830
2011-09-19
pbug
0831
2011-09-19
pbug
memcpy((char *)&sdomain, (char *)data.data, data.size);
0832
2011-09-19
pbug
memcpy((char *)&savesd, (char *)data.data, data.size);
0833
2011-09-19
pbug
0834
2011-09-19
pbug
if (checklabel(db, &sdomain, &soa, question)) {
0835
2011-09-19
pbug
fq = build_fake_question(sdomain.zone, sdomain.zonelen, 0);
0836
2011-09-19
pbug
build_reply(&sreply, so, (p + 2), dnslen, fq, NULL, 0, &sdomain, NULL, 0xff, 1, 0, NULL);
0837
2011-09-19
pbug
outlen = create_anyreply(&sreply, (reply + 2), 65535, outlen, 0);
0838
2011-09-19
pbug
free_question(fq);
0839
2011-09-19
pbug
0840
2011-09-19
pbug
if ((savesd.flags & DOMAIN_HAVE_NS) &&
0841
2011-09-19
pbug
(savesd.ns_type & NS_TYPE_DELEGATE)) {
0842
2011-09-19
pbug
for (i = 0; i < savesd.ns_count; i++) {
0843
2011-09-19
pbug
fq = build_fake_question(savesd.ns[i].nsserver,
0844
2011-09-19
pbug
savesd.ns[i].nslen, 0);
0845
2011-09-19
pbug
memset(&key, 0, sizeof(key));
0846
2011-09-19
pbug
memset(&data, 0, sizeof(data));
0847
2011-09-19
pbug
0848
2011-09-19
pbug
key.data = fq->hdr->name;
0849
2011-09-19
pbug
key.size = fq->hdr->namelen;
0850
2011-09-19
pbug
0851
2011-09-19
pbug
data.data = NULL;
0852
2011-09-19
pbug
data.size = 0;
0853
2011-09-19
pbug
0854
2011-09-19
pbug
ret = db->get(db, NULL, &key, &data, 0);
0855
2011-09-19
pbug
if (ret != 0) {
0856
2011-09-19
pbug
free_question(fq);
0857
2011-09-19
pbug
continue;
0858
2011-09-19
pbug
}
0859
2011-09-19
pbug
0860
2011-09-19
pbug
if (data.size != sizeof(struct domain)) {
0861
2013-02-16
pjp
dolog(LOG_INFO, "AXFR btree db is damaged (%d), drop\n", __LINE__);
0862
2011-09-19
pbug
goto drop;
0863
2011-09-19
pbug
}
0864
2011-09-19
pbug
0865
2011-09-19
pbug
memcpy((char *)&nsdomain, (char*)data.data, data.size);
0866
2011-09-19
pbug
0867
2011-09-19
pbug
build_reply(&sreply, so, (p + 2), dnslen, fq, NULL, 0, &nsdomain, NULL, 0xff, 1, 0, NULL);
0868
2011-09-19
pbug
outlen = create_anyreply(&sreply, (reply + 2), 65535, outlen, 0);
0869
2011-09-19
pbug
free_question(fq);
0870
2011-09-19
pbug
0871
2011-09-19
pbug
} /* for (i.. */
0872
2011-09-19
pbug
} /* if (sdomain.flags */
0873
2011-09-19
pbug
0874
2011-09-19
pbug
} /* if (checklabel */
0875
2011-09-19
pbug
0876
2011-09-19
pbug
/*
0877
2011-09-19
pbug
* if we accumulate 60000 bytes out of the maximum
0878
2011-09-19
pbug
* 65535 bytes then we fragment.
0879
2011-09-19
pbug
*/
0880
2011-09-19
pbug
/* XXX */
0881
2011-09-19
pbug
if (outlen > 60000) {
0882
2011-09-19
pbug
tmp = (u_int16_t *)reply;
0883
2011-09-19
pbug
*tmp = htons(outlen);
0884
2011-09-19
pbug
0885
2011-09-19
pbug
/* set the rrcount in there */
0886
2011-09-19
pbug
0887
2011-09-19
pbug
NTOHS(odh->answer);
0888
2011-09-19
pbug
odh->answer += rrcount;
0889
2011-09-19
pbug
HTONS(odh->answer);
0890
2011-09-19
pbug
0891
2011-09-19
pbug
len = send(so, reply, outlen + 2, 0);
0892
2011-09-19
pbug
if (len <= 0) {
0893
2011-09-19
pbug
goto drop;
0894
2011-09-19
pbug
}
0895
2011-09-19
pbug
0896
2011-09-19
pbug
rrcount = 0;
0897
2011-09-19
pbug
outlen = build_header(db, (reply + 2), (p + 2), question, 0);
0898
2011-09-19
pbug
}
0899
2011-09-19
pbug
0900
2011-09-19
pbug
memset(&key, 0, sizeof(key));
0901
2011-09-19
pbug
memset(&data, 0, sizeof(data));
0902
2011-09-19
pbug
} while (cursor->c_get(cursor, &key, &data, DB_NEXT) == 0);
0903
2011-09-19
pbug
0904
2011-09-19
pbug
cursor->c_close(cursor);
0905
2011-09-19
pbug
0906
2011-09-19
pbug
outlen = build_soa(db, (reply + 2), outlen, &soa, question);
0907
2011-09-19
pbug
rrcount++;
0908
2011-09-19
pbug
0909
2011-09-19
pbug
tmp = (u_int16_t *)reply;
0910
2011-09-19
pbug
*tmp = htons(outlen);
0911
2011-09-19
pbug
0912
2011-09-19
pbug
/* set the rrcount in there */
0913
2011-09-19
pbug
0914
2011-09-19
pbug
NTOHS(odh->answer);
0915
2011-09-19
pbug
odh->answer += rrcount;
0916
2011-09-19
pbug
HTONS(odh->answer);
0917
2011-09-19
pbug
0918
2011-09-19
pbug
len = send(so, reply, outlen + 2, 0);
0919
2011-09-19
pbug
if (len <= 0)
0920
2011-09-19
pbug
goto drop;
0921
2011-09-19
pbug
0922
2011-09-19
pbug
goto drop;
0923
2011-09-19
pbug
0924
2011-09-19
pbug
} /* for(;;) */
0925
2011-09-19
pbug
0926
2011-09-19
pbug
0927
2011-09-19
pbug
0928
2011-09-19
pbug
drop:
0929
2011-09-19
pbug
close(so);
0930
2011-09-19
pbug
exit(0);
0931
2011-09-19
pbug
}
0932
2011-09-19
pbug
0933
2011-09-19
pbug
/*
0934
2011-09-19
pbug
* REAP - reap the child that is zombied by now, this is a sighandler for
0935
2011-09-19
pbug
* SIGCHLD
0936
2011-09-19
pbug
*/
0937
2011-09-19
pbug
0938
2011-09-19
pbug
void
0939
2011-09-19
pbug
reap(int sig)
0940
2011-09-19
pbug
{
0941
2011-09-19
pbug
int status;
0942
2011-09-19
pbug
pid_t pid;
0943
2011-09-19
pbug
0944
2011-09-19
pbug
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
0945
2011-09-19
pbug
}
0946
2011-09-19
pbug
}
0947
2011-09-19
pbug
0948
2011-09-19
pbug
0949
2011-09-19
pbug
/*
0950
2011-09-19
pbug
* build_header - build a header reply
0951
2011-09-19
pbug
*
0952
2011-09-19
pbug
*/
0953
2011-09-19
pbug
0954
2011-09-19
pbug
int
0955
2011-09-19
pbug
build_header(DB *db, char *reply, char *buf, struct question *q, int answercount)
0956
2011-09-19
pbug
{
0957
2011-09-19
pbug
struct dns_header *odh;
0958
2011-09-19
pbug
u_int16_t outlen;
0959
2011-09-19
pbug
0960
2011-09-19
pbug
odh = (struct dns_header *)reply;
0961
2011-09-19
pbug
outlen = sizeof(struct dns_header);
0962
2011-09-19
pbug
0963
2011-09-19
pbug
/* copy question to reply */
0964
2011-09-19
pbug
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0965
2011-09-19
pbug
/* blank query */
0966
2011-09-19
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0967
2011-09-19
pbug
0968
2011-09-19
pbug
outlen += (q->hdr->namelen + 4);
0969
2011-09-19
pbug
0970
2011-09-19
pbug
SET_DNS_REPLY(odh);
0971
2011-09-19
pbug
SET_DNS_AUTHORITATIVE(odh);
0972
2011-09-19
pbug
0973
2011-09-19
pbug
NTOHS(odh->query);
0974
2011-09-19
pbug
0975
2011-09-19
pbug
odh->question = htons(1);
0976
2011-09-19
pbug
odh->answer = htons(answercount);
0977
2011-09-19
pbug
odh->nsrr = 0;
0978
2011-09-19
pbug
odh->additional = 0;
0979
2011-09-19
pbug
0980
2011-09-19
pbug
return (outlen);
0981
2011-09-19
pbug
}
0982
2011-09-19
pbug
0983
2011-09-19
pbug
0984
2011-09-19
pbug
0985
2011-09-19
pbug
/*
0986
2011-09-19
pbug
* BUILD_SOA - build an SOA answer
0987
2011-09-19
pbug
*/
0988
2011-09-19
pbug
0989
2011-09-19
pbug
int
0990
2011-09-19
pbug
build_soa(DB *db, char *reply, int offset, struct domain *sd, struct question *q)
0991
2011-09-19
pbug
{
0992
2011-09-19
pbug
char *p;
0993
2011-09-19
pbug
char *label;
0994
2011-09-19
pbug
char *plabel;
0995
2011-09-19
pbug
0996
2011-09-19
pbug
int labellen;
0997
2011-09-19
pbug
int tmplen;
0998
2011-09-19
pbug
u_int32_t *soa_val;
0999
2011-09-19
pbug
1000
2011-09-19
pbug
struct answer {
1001
2011-09-19
pbug
char name[2];
1002
2011-09-19
pbug
u_int16_t type;
1003
2011-09-19
pbug
u_int16_t class;
1004
2011-09-19
pbug
u_int32_t ttl;
1005
2011-09-19
pbug
u_int16_t rdlength; /* 12 */
1006
2011-09-19
pbug
char rdata;
1007
2011-09-19
pbug
} __attribute__((packed));
1008
2011-09-19
pbug
1009
2011-09-19
pbug
struct answer *answer;
1010
2011-09-19
pbug
answer = (struct answer *)(&reply[offset]);
1011
2011-09-19
pbug
1012
2011-09-19
pbug
answer->name[0] = 0xc0;
1013
2011-09-19
pbug
answer->name[1] = 0x0c;
1014
2011-09-19
pbug
answer->type = htons(DNS_TYPE_SOA);
1015
2011-09-19
pbug
answer->class = htons(DNS_CLASS_IN);
1016
2011-09-19
pbug
answer->ttl = htonl(sd->ttl);
1017
2011-09-19
pbug
1018
2011-09-19
pbug
offset += 12; /* up to rdata length */
1019
2011-09-19
pbug
1020
2011-09-19
pbug
p = (char *)&answer->rdata;
1021
2011-09-19
pbug
1022
2011-09-19
pbug
1023
2011-09-19
pbug
label = sd->soa.nsserver;
1024
2011-09-19
pbug
labellen = sd->soa.nsserver_len;
1025
2011-09-19
pbug
1026
2011-09-19
pbug
plabel = label;
1027
2011-09-19
pbug
1028
2011-09-19
pbug
if (offset + labellen <= 65535)
1029
2011-09-19
pbug
memcpy(&reply[offset], (char *)plabel, labellen);
1030
2011-09-19
pbug
else
1031
2011-09-19
pbug
return (offset); /* XXX */
1032
2011-09-19
pbug
1033
2011-09-19
pbug
offset += labellen;
1034
2011-09-19
pbug
1035
2011-09-19
pbug
/* compress the label if possible */
1036
2011-09-19
pbug
if ((tmplen = compress_label((u_char*)reply, offset, labellen)) > 0) {
1037
2011-09-19
pbug
offset = tmplen;
1038
2011-09-19
pbug
}
1039
2011-09-19
pbug
1040
2011-09-19
pbug
label = sd->soa.responsible_person;
1041
2011-09-19
pbug
labellen = sd->soa.rp_len;
1042
2011-09-19
pbug
plabel = label;
1043
2011-09-19
pbug
1044
2011-09-19
pbug
if (offset + labellen <= 65535)
1045
2011-09-19
pbug
memcpy(&reply[offset], (char *)plabel, labellen);
1046
2011-09-19
pbug
else
1047
2011-09-19
pbug
return (offset); /* XXX */
1048
2011-09-19
pbug
1049
2011-09-19
pbug
offset += labellen;
1050
2011-09-19
pbug
1051
2011-09-19
pbug
/* 2 compress the label if possible */
1052
2011-09-19
pbug
1053
2011-09-19
pbug
if ((tmplen = compress_label((u_char*)reply, offset, labellen)) > 0) {
1054
2011-09-19
pbug
offset = tmplen;
1055
2011-09-19
pbug
}
1056
2011-09-19
pbug
1057
2011-09-19
pbug
1058
2011-09-19
pbug
/* XXX */
1059
2011-09-19
pbug
if ((offset + sizeof(sd->soa.serial)) >= 65535 ) {
1060
2011-09-19
pbug
/* XXX server error reply? */
1061
2011-09-19
pbug
return (offset);
1062
2011-09-19
pbug
}
1063
2011-09-19
pbug
soa_val = (u_int32_t *)&reply[offset];
1064
2011-09-19
pbug
*soa_val = htonl(sd->soa.serial);
1065
2011-09-19
pbug
offset += sizeof(sd->soa.serial); /* XXX */
1066
2011-09-19
pbug
1067
2011-09-19
pbug
/* XXX */
1068
2011-09-19
pbug
if ((offset + sizeof(sd->soa.refresh)) >= 65535 ) {
1069
2011-09-19
pbug
return (offset);
1070
2011-09-19
pbug
}
1071
2011-09-19
pbug
soa_val = (u_int32_t *)&reply[offset];
1072
2011-09-19
pbug
*soa_val = htonl(sd->soa.refresh);
1073
2011-09-19
pbug
offset += sizeof(sd->soa.refresh); /* XXX */
1074
2011-09-19
pbug
1075
2011-09-19
pbug
if ((offset + sizeof(sd->soa.retry)) >= 65535 ) {
1076
2011-09-19
pbug
return (offset);
1077
2011-09-19
pbug
}
1078
2011-09-19
pbug
soa_val = (u_int32_t *)&reply[offset];
1079
2011-09-19
pbug
*soa_val = htonl(sd->soa.retry);
1080
2011-09-19
pbug
offset += sizeof(sd->soa.retry); /* XXX */
1081
2011-09-19
pbug
1082
2011-09-19
pbug
if ((offset + sizeof(sd->soa.expire)) >= 65535 ) {
1083
2011-09-19
pbug
return (offset);
1084
2011-09-19
pbug
}
1085
2011-09-19
pbug
soa_val = (u_int32_t *)&reply[offset];
1086
2011-09-19
pbug
*soa_val = htonl(sd->soa.expire);
1087
2011-09-19
pbug
offset += sizeof(sd->soa.expire);
1088
2011-09-19
pbug
1089
2011-09-19
pbug
if ((offset + sizeof(sd->soa.minttl)) > 65535 ) {
1090
2011-09-19
pbug
return (offset);
1091
2011-09-19
pbug
}
1092
2011-09-19
pbug
soa_val = (u_int32_t *)&reply[offset];
1093
2011-09-19
pbug
*soa_val = htonl(sd->soa.minttl);
1094
2011-09-19
pbug
offset += sizeof(sd->soa.minttl);
1095
2011-09-19
pbug
1096
2011-09-19
pbug
answer->rdlength = htons(&reply[offset] - &answer->rdata);
1097
2011-09-19
pbug
1098
2011-09-19
pbug
return (offset);
1099
2011-09-19
pbug
}
1100
2011-09-19
pbug
1101
2011-09-19
pbug
int
1102
2011-09-19
pbug
checklabel(DB *db, struct domain *sd, struct domain *soa, struct question *q)
1103
2011-09-19
pbug
{
1104
2011-09-19
pbug
struct domain tmpsd;
1105
2011-09-19
pbug
char *p;
1106
2011-09-19
pbug
int plen, ret;
1107
2011-09-19
pbug
1108
2011-09-19
pbug
DBT key, data;
1109
2011-09-19
pbug
1110
2011-09-19
pbug
if (memcmp(sd, soa, sizeof(struct domain)) == 0)
1111
2011-09-19
pbug
return 1;
1112
2011-09-19
pbug
1113
2011-09-19
pbug
p = sd->zone;
1114
2011-09-19
pbug
plen = sd->zonelen;
1115
2011-09-19
pbug
1116
2011-09-19
pbug
do {
1117
2011-09-19
pbug
if (*p == '\0')
1118
2011-09-19
pbug
return (0);
1119
2011-09-19
pbug
1120
2011-09-19
pbug
memset(&key, 0, sizeof(key));
1121
2011-09-19
pbug
memset(&data, 0, sizeof(data));
1122
2011-09-19
pbug
1123
2011-09-19
pbug
key.data = (char *)p;
1124
2011-09-19
pbug
key.size = plen;
1125
2011-09-19
pbug
1126
2011-09-19
pbug
data.data = NULL;
1127
2011-09-19
pbug
data.size = 0;
1128
2011-09-19
pbug
1129
2011-09-19
pbug
ret = db->get(db, NULL, &key, &data, 0);
1130
2011-09-19
pbug
if (ret == DB_NOTFOUND) {
1131
2011-09-19
pbug
plen -= (*p + 1);
1132
2011-09-19
pbug
p = (p + (*p + 1));
1133
2011-09-19
pbug
1134
2011-09-19
pbug
continue;
1135
2011-09-19
pbug
}
1136
2011-09-19
pbug
1137
2011-09-19
pbug
if (data.size != sizeof(struct domain)) {
1138
2013-02-16
pjp
dolog(LOG_INFO, "AXFR btree db is damaged (%d), drop\n", __LINE__);
1139
2011-09-19
pbug
return (0);
1140
2011-09-19
pbug
}
1141
2011-09-19
pbug
1142
2011-09-19
pbug
memcpy(&tmpsd, data.data, sizeof(tmpsd));
1143
2011-09-19
pbug
1144
2011-09-19
pbug
/*
1145
2011-09-19
pbug
* the encountered label has an SOA before we got to the
1146
2011-09-19
pbug
* root, so we skip this record entirely...
1147
2011-09-19
pbug
*/
1148
2011-09-19
pbug
1149
2011-09-19
pbug
if (tmpsd.flags & DOMAIN_HAVE_SOA)
1150
2011-09-19
pbug
return (0);
1151
2011-09-19
pbug
1152
2011-09-19
pbug
1153
2011-09-19
pbug
/*
1154
2011-09-19
pbug
* and check the next label...
1155
2011-09-19
pbug
*/
1156
2011-09-19
pbug
1157
2011-09-19
pbug
plen -= (*p + 1);
1158
2011-09-19
pbug
p = (p + (*p + 1));
1159
2011-09-19
pbug
1160
2011-09-19
pbug
1161
2011-09-19
pbug
} while (memcmp(p, q->hdr->name, q->hdr->namelen) != 0);
1162
2011-09-19
pbug
1163
2011-09-19
pbug
1164
2011-09-19
pbug
return (1);
1165
2014-05-17
pjp
}
1166
2014-05-17
pjp
1167
2014-05-17
pjp
void
1168
2014-05-17
pjp
gather_notifydomains(DB *db)
1169
2014-05-17
pjp
{
1170
2014-05-17
pjp
DBT key, data;
1171
2014-05-17
pjp
DBC *cursor;
1172
2014-05-17
pjp
1173
2014-05-17
pjp
time_t now, soatime;
1174
2014-05-17
pjp
struct tm *tm;
1175
2014-05-17
pjp
1176
2014-05-17
pjp
char timestring[128];
1177
2014-05-17
pjp
char buf[128];
1178
2014-05-17
pjp
1179
2014-05-17
pjp
struct domain *sd;
1180
2014-05-17
pjp
1181
2014-05-17
pjp
1182
2014-05-17
pjp
SLIST_INIT(&notifyhead);
1183
2014-05-17
pjp
1184
2014-05-17
pjp
now = time(NULL);
1185
2014-05-17
pjp
tm = localtime(&now);
1186
2014-05-17
pjp
if (tm != NULL)
1187
2014-05-17
pjp
strftime(timestring, sizeof(timestring), "%Y%m%d", tm);
1188
2014-05-17
pjp
else
1189
2014-05-17
pjp
snprintf(timestring, sizeof(timestring), "19700101");
1190
2014-05-17
pjp
1191
2014-05-17
pjp
now = time(NULL);
1192
2014-05-17
pjp
1193
2014-05-17
pjp
if (db->cursor(db, NULL, &cursor, 0) != 0) {
1194
2014-05-17
pjp
dolog(LOG_INFO, "db->cursor: %s\n", strerror(errno));
1195
2014-05-17
pjp
return;
1196
2014-05-17
pjp
}
1197
2014-05-17
pjp
1198
2014-05-17
pjp
memset(&key, 0, sizeof(key));
1199
2014-05-17
pjp
memset(&data, 0, sizeof(data));
1200
2014-05-17
pjp
1201
2014-05-17
pjp
1202
2014-05-17
pjp
if (cursor->c_get(cursor, &key, &data, DB_FIRST) != 0) {
1203
2014-05-17
pjp
dolog(LOG_INFO, "cursor->c_get: %s\n", strerror(errno));
1204
2014-05-17
pjp
cursor->c_close(cursor);
1205
2014-05-17
pjp
return;
1206
2014-05-17
pjp
}
1207
2014-05-17
pjp
1208
2014-05-17
pjp
do {
1209
2014-05-17
pjp
if (data.size != sizeof(struct domain)) {
1210
2014-05-17
pjp
dolog(LOG_INFO, "btree db is damaged\n");
1211
2014-05-17
pjp
cursor->c_close(cursor);
1212
2014-05-17
pjp
return;
1213
2014-05-17
pjp
}
1214
2014-05-17
pjp
1215
2014-05-17
pjp
sd = (struct domain *)data.data;
1216
2014-05-17
pjp
1217
2014-05-17
pjp
if ((sd->flags & DOMAIN_HAVE_SOA) == DOMAIN_HAVE_SOA) {
1218
2014-05-17
pjp
notn2 = malloc(sizeof(struct notifyentry));
1219
2014-05-17
pjp
if (notn2 == NULL) {
1220
2014-05-17
pjp
continue;
1221
2014-05-17
pjp
}
1222
2014-05-17
pjp
1223
2014-05-17
pjp
notn2->ids = calloc(notify, sizeof(u_int16_t));
1224
2014-05-17
pjp
if (notn2->ids == NULL) {
1225
2014-05-17
pjp
free(notn2);
1226
2014-05-17
pjp
continue;
1227
2014-05-17
pjp
}
1228
2014-05-17
pjp
1229
2014-05-17
pjp
notn2->attempts = calloc(notify, sizeof(u_int16_t));
1230
2014-05-17
pjp
if (notn2->attempts == NULL) {
1231
2014-05-17
pjp
free(notn2);
1232
2014-05-17
pjp
continue;
1233
2014-05-17
pjp
}
1234
2014-05-17
pjp
1235
2014-05-17
pjp
memcpy(notn2->domain, sd->zone, sd->zonelen);
1236
2014-05-17
pjp
notn2->domainlen = sd->zonelen;
1237
2014-05-17
pjp
1238
2014-05-17
pjp
soatime = (time_t)sd->soa.serial;
1239
2014-05-17
pjp
snprintf(buf, sizeof(buf), "%u", sd->soa.serial);
1240
2014-05-17
pjp
1241
2014-05-17
pjp
if (strncmp(buf, timestring, strlen(timestring)) == 0) {
1242
2014-05-17
pjp
dolog(LOG_INFO, "inserting zone \"%s\" for notification...\n", sd->zonename);
1243
2014-05-17
pjp
SLIST_INSERT_HEAD(&notifyhead, notn2, notify_entry);
1244
2014-05-17
pjp
} else if (difftime(now, soatime) < 1800 && difftime(now, soatime) > 0) {
1245
2014-05-17
pjp
dolog(LOG_INFO, "2 inserting zone \"%s\" for notification...\n", sd->zonename);
1246
2014-05-17
pjp
SLIST_INSERT_HEAD(&notifyhead, notn2, notify_entry);
1247
2014-05-17
pjp
} else {
1248
2014-05-17
pjp
#if 0
1249
2014-05-17
pjp
dolog(LOG_INFO, "SOA serial for zone \"%s\" did not make sense (%s), not notifying\n", sd->zonename, buf);
1250
2014-05-17
pjp
#endif
1251
2014-05-17
pjp
free(notn2);
1252
2014-05-17
pjp
}
1253
2014-05-17
pjp
}
1254
2014-05-17
pjp
1255
2014-05-17
pjp
memset(&key, 0, sizeof(key));
1256
2014-05-17
pjp
memset(&data, 0, sizeof(data));
1257
2014-05-17
pjp
} while (cursor->c_get(cursor, &key, &data, DB_NEXT) == 0);
1258
2014-05-17
pjp
1259
2014-05-17
pjp
cursor->c_close(cursor);
1260
2014-05-17
pjp
1261
2014-05-17
pjp
return;
1262
2014-05-17
pjp
}
1263
2014-05-17
pjp
1264
2014-05-17
pjp
void
1265
2014-05-17
pjp
notifyslaves(int *notifyfd)
1266
2014-05-17
pjp
{
1267
2014-05-17
pjp
int so;
1268
2014-05-17
pjp
int i;
1269
2014-05-17
pjp
1270
2014-05-17
pjp
i = 0;
1271
2014-05-17
pjp
SLIST_FOREACH(nfslnp, &notifyslavehead, notifyslave_entry) {
1272
2014-05-17
pjp
if (nfslnp->family == AF_INET6) {
1273
2014-05-17
pjp
so = notifyfd[1];
1274
2014-05-17
pjp
} else {
1275
2014-05-17
pjp
so = notifyfd[0];
1276
2014-05-17
pjp
}
1277
2014-05-17
pjp
#if 0
1278
2014-05-17
pjp
dolog(LOG_INFO, "notifying %s...\n", nfslnp->name);
1279
2014-05-17
pjp
#endif
1280
2014-05-17
pjp
1281
2014-05-18
pjp
#ifdef __linux__
1282
2014-05-18
pjp
SLIST_FOREACH(notnp, &notifyhead, notify_entry) {
1283
2014-05-18
pjp
#else
1284
2014-05-17
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
1285
2014-05-18
pjp
#endif
1286
2014-05-17
pjp
notnp->ids[i] = arc4random() & 0xffff;
1287
2014-05-17
pjp
notnp->attempts[i]++;
1288
2014-05-17
pjp
if (notnp->attempts[i] > 10) {
1289
2014-05-17
pjp
dolog(LOG_INFO, "notify entry removed due to timeout\n");
1290
2014-05-17
pjp
SLIST_REMOVE(&notifyhead, notnp, notifyentry, notify_entry);
1291
2014-05-17
pjp
}
1292
2014-05-17
pjp
1293
2014-05-17
pjp
notifypacket(so, nfslnp, notnp, i);
1294
2014-05-17
pjp
}
1295
2014-05-17
pjp
1296
2014-05-17
pjp
i++;
1297
2014-05-17
pjp
}
1298
2014-05-17
pjp
1299
2014-05-17
pjp
return;
1300
2014-05-17
pjp
}
1301
2014-05-17
pjp
1302
2014-05-17
pjp
void
1303
2014-05-17
pjp
notifypacket(int so, void *vnse, void *vnotnp, int packetcount)
1304
2014-05-17
pjp
{
1305
2014-05-17
pjp
struct notifyslaveentry *nse = (struct notifyslaveentry *)vnse;
1306
2014-05-17
pjp
struct notifyentry *notnp = (struct notifyentry *)vnotnp;
1307
2014-05-17
pjp
struct sockaddr_in bsin, *sin;
1308
2014-05-17
pjp
struct sockaddr_in6 bsin6, *sin6;
1309
2014-05-17
pjp
char packet[512];
1310
2014-05-17
pjp
char *questionname;
1311
2014-05-17
pjp
u_int16_t *classtype;
1312
2014-05-17
pjp
struct dns_header *dnh;
1313
2014-05-17
pjp
int outlen = 0, slen, ret;
1314
2014-05-17
pjp
1315
2014-05-17
pjp
memset(&packet, 0, sizeof(packet));
1316
2014-05-17
pjp
dnh = (struct dns_header *)&packet[0];
1317
2014-05-17
pjp
1318
2014-05-17
pjp
dnh->id = htons(notnp->ids[packetcount]);
1319
2014-05-17
pjp
SET_DNS_NOTIFY(dnh);
1320
2014-05-17
pjp
SET_DNS_AUTHORITATIVE(dnh);
1321
2014-05-17
pjp
SET_DNS_QUERY(dnh);
1322
2014-05-17
pjp
HTONS(dnh->query);
1323
2014-05-17
pjp
1324
2014-05-17
pjp
dnh->question = htons(1);
1325
2014-05-17
pjp
1326
2014-05-17
pjp
outlen += sizeof(struct dns_header);
1327
2014-05-17
pjp
questionname = (char *)&packet[outlen];
1328
2014-05-17
pjp
1329
2014-05-17
pjp
memcpy(questionname, notnp->domain, notnp->domainlen);
1330
2014-05-17
pjp
outlen += notnp->domainlen;
1331
2014-05-17
pjp
1332
2014-05-17
pjp
classtype = (u_int16_t *)&packet[outlen];
1333
2014-05-17
pjp
classtype[0] = htons(DNS_TYPE_SOA);
1334
2014-05-17
pjp
classtype[1] = htons(DNS_CLASS_IN);
1335
2014-05-17
pjp
1336
2014-05-17
pjp
outlen += (2 * sizeof(u_int16_t));
1337
2014-05-17
pjp
1338
2014-05-17
pjp
if (nse->family == AF_INET) {
1339
2014-05-17
pjp
slen = sizeof(struct sockaddr_in);
1340
2014-05-17
pjp
sin = (struct sockaddr_in *)&nse->hostmask;
1341
2014-05-17
pjp
memset(&bsin, 0, sizeof(bsin));
1342
2014-05-17
pjp
bsin.sin_family = AF_INET;
1343
2014-05-17
pjp
bsin.sin_port = htons(53);
1344
2014-05-17
pjp
bsin.sin_addr.s_addr = sin->sin_addr.s_addr;
1345
2014-05-17
pjp
1346
2014-05-17
pjp
ret = sendto(so, packet, outlen, 0, (struct sockaddr *)&bsin, slen);
1347
2014-05-17
pjp
} else {
1348
2014-05-17
pjp
slen = sizeof(struct sockaddr_in6);
1349
2014-05-17
pjp
sin6 = (struct sockaddr_in6 *)&nse->hostmask;
1350
2014-05-17
pjp
memset(&bsin6, 0, sizeof(bsin6));
1351
2014-05-17
pjp
bsin6.sin6_family = AF_INET6;
1352
2014-05-17
pjp
bsin6.sin6_port = htons(53);
1353
2014-05-17
pjp
memcpy(&bsin6.sin6_addr, &sin6->sin6_addr, 16);
1354
2014-05-17
pjp
1355
2014-05-17
pjp
ret = sendto(so, packet, outlen, 0, (struct sockaddr *)sin6, slen);
1356
2014-05-17
pjp
}
1357
2014-05-17
pjp
1358
2014-05-17
pjp
if (ret < 0) {
1359
2014-05-17
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1360
2014-05-17
pjp
}
1361
2014-05-17
pjp
1362
2014-05-17
pjp
return;
1363
2011-09-19
pbug
}
repomaster@centroid.eu