Blame
Date:
Thu Nov 19 09:25:28 2020 UTC
Message:
update README before 1.5.0 release
0001
2014-11-14
pjp
/*
0002
2020-04-23
pjp
* Copyright (c) 2005-2020 Peter J. Philipp
0003
2014-11-14
pjp
* All rights reserved.
0004
2014-11-14
pjp
*
0005
2014-11-14
pjp
* Redistribution and use in source and binary forms, with or without
0006
2014-11-14
pjp
* modification, are permitted provided that the following conditions
0007
2014-11-14
pjp
* are met:
0008
2014-11-14
pjp
* 1. Redistributions of source code must retain the above copyright
0009
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer.
0010
2014-11-14
pjp
* 2. Redistributions in binary form must reproduce the above copyright
0011
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer in the
0012
2014-11-14
pjp
* documentation and/or other materials provided with the distribution.
0013
2014-11-14
pjp
* 3. The name of the author may not be used to endorse or promote products
0014
2014-11-14
pjp
* derived from this software without specific prior written permission
0015
2014-11-14
pjp
*
0016
2014-11-14
pjp
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017
2014-11-14
pjp
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018
2014-11-14
pjp
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019
2014-11-14
pjp
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020
2014-11-14
pjp
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021
2014-11-14
pjp
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022
2014-11-14
pjp
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023
2014-11-14
pjp
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024
2014-11-14
pjp
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025
2014-11-14
pjp
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026
2014-11-14
pjp
*
0027
2014-11-14
pjp
*/
0028
2017-10-26
pjp
0029
2017-10-26
pjp
/*
0030
2020-09-30
pjp
* $Id: reply.c,v 1.114 2020/09/30 10:07:31 pjp Exp $
0031
2017-10-26
pjp
*/
0032
2017-10-26
pjp
0033
2019-06-06
pjp
#include <sys/types.h>
0034
2019-06-06
pjp
#include <sys/socket.h>
0035
2019-02-27
pjp
0036
2019-06-06
pjp
#include <netinet/in.h>
0037
2019-06-06
pjp
#include <arpa/inet.h>
0038
2019-06-06
pjp
#include <netdb.h>
0039
2019-06-06
pjp
0040
2019-06-06
pjp
#include <stdio.h>
0041
2019-06-06
pjp
#include <stdlib.h>
0042
2019-06-06
pjp
#include <string.h>
0043
2019-06-06
pjp
#include <errno.h>
0044
2019-06-06
pjp
#include <syslog.h>
0045
2020-07-06
pjp
#include <time.h>
0046
2019-06-06
pjp
0047
2019-06-06
pjp
#ifdef __linux__
0048
2019-06-06
pjp
#include <grp.h>
0049
2019-06-06
pjp
#define __USE_BSD 1
0050
2019-06-06
pjp
#include <endian.h>
0051
2019-06-06
pjp
#include <bsd/stdlib.h>
0052
2019-06-06
pjp
#include <bsd/string.h>
0053
2019-06-06
pjp
#include <bsd/sys/queue.h>
0054
2019-06-06
pjp
#define __unused
0055
2019-06-06
pjp
#include <bsd/sys/tree.h>
0056
2019-06-06
pjp
#include <bsd/sys/endian.h>
0057
2019-06-06
pjp
#else /* not linux */
0058
2019-06-06
pjp
#include <sys/queue.h>
0059
2019-06-06
pjp
#include <sys/tree.h>
0060
2019-06-06
pjp
#endif /* __linux__ */
0061
2019-06-06
pjp
0062
2019-06-06
pjp
#ifndef NTOHS
0063
2019-06-06
pjp
#include "endian.h"
0064
2019-06-06
pjp
#endif
0065
2019-06-06
pjp
0066
2019-02-27
pjp
#include <openssl/evp.h>
0067
2019-02-27
pjp
#include <openssl/hmac.h>
0068
2019-02-27
pjp
0069
2019-06-06
pjp
#include "ddd-dns.h"
0070
2019-06-06
pjp
#include "ddd-db.h"
0071
2016-07-06
pjp
0072
2015-07-01
pjp
/* prototypes */
0073
2014-11-14
pjp
0074
2019-12-03
pjp
extern void pack(char *, char *, int);
0075
2019-12-03
pjp
extern void pack32(char *, u_int32_t);
0076
2019-12-03
pjp
extern void pack16(char *, u_int16_t);
0077
2019-12-03
pjp
extern void pack8(char *, u_int8_t);
0078
2019-12-03
pjp
extern uint32_t unpack32(char *);
0079
2019-12-03
pjp
extern uint16_t unpack16(char *);
0080
2019-12-03
pjp
extern void unpack(char *, char *, int);
0081
2019-12-03
pjp
0082
2019-02-15
pjp
extern int checklabel(ddDB *, struct rbtree *, struct rbtree *, struct question *);
0083
2020-07-06
pjp
extern int additional_nsec3(char *, int, int, struct rbtree *, char *, int, int, int *, int);
0084
2019-02-15
pjp
extern int additional_a(char *, int, struct rbtree *, char *, int, int, int *);
0085
2019-02-15
pjp
extern int additional_aaaa(char *, int, struct rbtree *, char *, int, int, int *);
0086
2019-02-15
pjp
extern int additional_mx(char *, int, struct rbtree *, char *, int, int, int *);
0087
2019-11-09
pjp
extern int additional_ds(char *, int, struct rbtree *, char *, int, int, int *);
0088
2019-02-15
pjp
extern int additional_ptr(char *, int, struct rbtree *, char *, int, int, int *);
0089
2015-07-01
pjp
extern int additional_opt(struct question *, char *, int, int);
0090
2019-02-28
pjp
extern int additional_tsig(struct question *, char *, int, int, int, int, HMAC_CTX *);
0091
2020-07-06
pjp
extern int additional_rrsig(char *, int, int, struct rbtree *, char *, int, int, int *, int);
0092
2020-07-06
pjp
extern int additional_nsec(char *, int, int, struct rbtree *, char *, int, int, int);
0093
2019-02-26
pjp
extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
0094
2015-07-01
pjp
extern int compress_label(u_char *, int, int);
0095
2015-07-01
pjp
extern void dolog(int, char *, ...);
0096
2015-07-01
pjp
extern int free_question(struct question *);
0097
2017-06-26
pjp
extern int get_record_size(ddDB *, char *, int);
0098
2015-07-01
pjp
extern char * dns_label(char *, int *);
0099
2014-11-14
pjp
0100
2019-02-15
pjp
extern struct rbtree * find_rrset(ddDB *db, char *name, int len);
0101
2019-02-15
pjp
extern struct rrset * find_rr(struct rbtree *rbt, u_int16_t rrtype);
0102
2019-02-15
pjp
extern int display_rr(struct rrset *rrset);
0103
2019-02-15
pjp
extern int rotate_rr(struct rrset *rrset);
0104
2019-10-30
pjp
extern struct rbtree * find_nsec3_cover_next_closer(char *name, int namelen, struct rbtree *, ddDB *db);
0105
2019-10-30
pjp
extern struct rbtree * find_nsec3_match_closest(char *name, int namelen, struct rbtree *, ddDB *db);
0106
2019-10-30
pjp
extern struct rbtree * find_nsec3_wildcard_closest(char *name, int namelen, struct rbtree *, ddDB *db);
0107
2019-10-30
pjp
extern struct rbtree * find_nsec3_match_qname(char *name, int namelen, struct rbtree *, ddDB *db);
0108
2019-10-31
pjp
extern struct rbtree * get_soa(ddDB *, struct question *);
0109
2019-10-31
pjp
extern struct rbtree * get_ns(ddDB *, struct rbtree *, int *);
0110
2019-10-31
pjp
extern struct rbtree * Lookup_zone(ddDB *, char *, u_int16_t, u_int16_t, int);
0111
2019-11-12
pjp
extern int dn_contains(char *, int, char *, int);
0112
2019-02-15
pjp
0113
2019-02-15
pjp
0114
2015-07-01
pjp
u_int16_t create_anyreply(struct sreply *, char *, int, int, int);
0115
2020-07-23
pjp
int reply_caa(struct sreply *, int *, ddDB *);
0116
2020-07-23
pjp
int reply_hinfo(struct sreply *, int *, ddDB *);
0117
2020-07-23
pjp
int reply_rp(struct sreply *, int *, ddDB *);
0118
2020-07-21
pjp
int reply_generic(struct sreply *, int *, ddDB *);
0119
2020-07-21
pjp
int reply_a(struct sreply *, int *, ddDB *);
0120
2020-07-21
pjp
int reply_nsec3(struct sreply *, int *, ddDB *);
0121
2020-07-21
pjp
int reply_nsec3param(struct sreply *, int *, ddDB *);
0122
2020-07-21
pjp
int reply_nsec(struct sreply *, int *, ddDB *);
0123
2020-07-21
pjp
int reply_dnskey(struct sreply *, int *, ddDB *);
0124
2020-07-21
pjp
int reply_ds(struct sreply *, int *, ddDB *);
0125
2020-07-21
pjp
int reply_rrsig(struct sreply *, int *, ddDB *);
0126
2020-07-21
pjp
int reply_aaaa(struct sreply *, int *, ddDB *);
0127
2020-07-21
pjp
int reply_mx(struct sreply *, int *, ddDB *);
0128
2020-07-21
pjp
int reply_ns(struct sreply *, int *, ddDB *);
0129
2020-07-21
pjp
int reply_notimpl(struct sreply *, int *, ddDB *);
0130
2020-07-21
pjp
int reply_nxdomain(struct sreply *, int *, ddDB *);
0131
2020-07-21
pjp
int reply_noerror(struct sreply *, int *, ddDB *);
0132
2020-07-21
pjp
int reply_badvers(struct sreply *, int *, ddDB *);
0133
2020-07-21
pjp
int reply_nodata(struct sreply *, int *, ddDB *);
0134
2020-07-21
pjp
int reply_soa(struct sreply *, int *, ddDB *);
0135
2020-07-21
pjp
int reply_ptr(struct sreply *, int *, ddDB *);
0136
2020-07-21
pjp
int reply_txt(struct sreply *, int *, ddDB *);
0137
2020-07-21
pjp
int reply_version(struct sreply *, int *, ddDB *);
0138
2020-07-21
pjp
int reply_srv(struct sreply *, int *, ddDB *);
0139
2020-07-21
pjp
int reply_naptr(struct sreply *, int *, ddDB *);
0140
2020-07-21
pjp
int reply_sshfp(struct sreply *, int *, ddDB *);
0141
2020-07-21
pjp
int reply_tlsa(struct sreply *, int *, ddDB *);
0142
2020-07-21
pjp
int reply_cname(struct sreply *, int *, ddDB *);
0143
2020-07-21
pjp
int reply_any(struct sreply *, int *, ddDB *);
0144
2020-07-21
pjp
int reply_refused(struct sreply *, int *, ddDB *);
0145
2020-07-21
pjp
int reply_fmterror(struct sreply *, int *, ddDB *);
0146
2020-07-21
pjp
int reply_notauth(struct sreply *, int *, ddDB *);
0147
2020-07-21
pjp
int reply_notify(struct sreply *, int *, ddDB *);
0148
2019-02-15
pjp
struct rbtree * find_nsec(char *name, int namelen, struct rbtree *, ddDB *db);
0149
2015-07-01
pjp
int nsec_comp(const void *a, const void *b);
0150
2015-07-01
pjp
int count_dots(char *name);
0151
2015-09-12
pjp
char * base32hex_encode(u_char *input, int len);
0152
2020-07-20
pjp
void set_reply_flags(struct rbtree *, struct dns_header *, struct question *);
0153
2015-07-01
pjp
0154
2020-04-23
pjp
extern int debug, verbose, dnssec, tcpanyonly;
0155
2015-09-05
pjp
extern char *versionstring;
0156
2015-09-05
pjp
extern uint8_t vslen;
0157
2020-09-30
pjp
extern u_int max_udp_payload;
0158
2015-07-01
pjp
0159
2015-07-01
pjp
0160
2015-07-01
pjp
0161
2014-11-14
pjp
/*
0162
2014-11-14
pjp
* REPLY_A() - replies a DNS question (*q) on socket (so)
0163
2014-11-14
pjp
*
0164
2014-11-14
pjp
*/
0165
2014-11-14
pjp
0166
2014-11-14
pjp
int
0167
2020-07-21
pjp
reply_a(struct sreply *sreply, int *sretlen, ddDB *db)
0168
2014-11-14
pjp
{
0169
2014-11-14
pjp
char *reply = sreply->replybuf;
0170
2014-11-14
pjp
struct dns_header *odh;
0171
2015-06-20
pjp
u_int16_t outlen = 0;
0172
2014-11-14
pjp
int a_count;
0173
2014-11-14
pjp
0174
2014-11-14
pjp
struct answer {
0175
2014-11-14
pjp
char name[2];
0176
2014-11-14
pjp
u_int16_t type;
0177
2014-11-14
pjp
u_int16_t class;
0178
2014-11-14
pjp
u_int32_t ttl;
0179
2014-11-14
pjp
u_int16_t rdlength; /* 12 */
0180
2014-11-14
pjp
in_addr_t rdata; /* 16 */
0181
2014-11-14
pjp
} __attribute__((packed));
0182
2014-11-14
pjp
0183
2014-11-14
pjp
struct answer *answer;
0184
2014-11-14
pjp
0185
2014-11-14
pjp
int so = sreply->so;
0186
2014-11-14
pjp
char *buf = sreply->buf;
0187
2014-11-14
pjp
int len = sreply->len;
0188
2014-11-14
pjp
struct question *q = sreply->q;
0189
2014-11-14
pjp
struct sockaddr *sa = sreply->sa;
0190
2014-11-14
pjp
int salen = sreply->salen;
0191
2019-02-15
pjp
0192
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
0193
2019-02-15
pjp
struct rrset *rrset = NULL;
0194
2019-02-15
pjp
struct rr *rrp;
0195
2014-11-14
pjp
0196
2014-11-14
pjp
int istcp = sreply->istcp;
0197
2014-11-14
pjp
int replysize = 512;
0198
2014-11-14
pjp
int retlen = -1;
0199
2017-09-18
pjp
u_int16_t rollback;
0200
2020-07-06
pjp
time_t now;
0201
2014-11-14
pjp
0202
2020-07-06
pjp
now = time(NULL);
0203
2020-07-06
pjp
0204
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_A)) == 0)
0205
2015-06-16
pjp
return -1;
0206
2015-06-16
pjp
0207
2014-11-14
pjp
if (istcp) {
0208
2014-11-14
pjp
replysize = 65535;
0209
2014-11-14
pjp
}
0210
2014-11-14
pjp
0211
2015-06-20
pjp
if (!istcp && q->edns0len > 512)
0212
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
0213
2014-11-14
pjp
0214
2014-11-14
pjp
odh = (struct dns_header *)&reply[0];
0215
2014-11-14
pjp
0216
2014-11-14
pjp
outlen = sizeof(struct dns_header);
0217
2014-11-14
pjp
0218
2014-11-14
pjp
if (len > replysize) {
0219
2014-11-14
pjp
return (retlen);
0220
2014-11-14
pjp
}
0221
2014-11-14
pjp
0222
2014-11-14
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0223
2014-11-14
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0224
2014-11-14
pjp
0225
2014-11-14
pjp
outlen += (q->hdr->namelen + 4);
0226
2017-09-18
pjp
rollback = outlen;
0227
2014-11-14
pjp
0228
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
0229
2014-11-14
pjp
0230
2014-11-14
pjp
odh->question = htons(1);
0231
2019-02-15
pjp
odh->answer = htons(0);
0232
2014-11-14
pjp
odh->nsrr = 0;
0233
2014-11-14
pjp
odh->additional = 0;
0234
2014-11-14
pjp
0235
2014-11-14
pjp
/* skip dns header, question name, qtype and qclass */
0236
2014-11-14
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0237
2014-11-14
pjp
q->hdr->namelen + 4);
0238
2014-11-14
pjp
0239
2014-11-14
pjp
a_count = 0;
0240
2014-11-14
pjp
0241
2019-02-15
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
0242
2014-11-14
pjp
/*
0243
2014-11-14
pjp
* answer->name is a pointer to the request (0xc00c)
0244
2014-11-14
pjp
*/
0245
2014-11-14
pjp
0246
2014-11-14
pjp
answer->name[0] = 0xc0; /* 1 byte */
0247
2014-11-14
pjp
answer->name[1] = 0x0c; /* 2 bytes */
0248
2014-11-14
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
0249
2014-11-14
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
0250
2019-02-15
pjp
0251
2020-07-06
pjp
if (q->aa)
0252
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl); /* 10 b */
0253
2020-07-06
pjp
else
0254
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
0255
2020-07-06
pjp
0256
2014-11-14
pjp
answer->rdlength = htons(sizeof(in_addr_t)); /* 12 bytes */
0257
2014-11-14
pjp
0258
2019-02-15
pjp
memcpy((char *)&answer->rdata,
0259
2019-02-15
pjp
(char *)&((struct a *)rrp->rdata)->a,
0260
2014-11-14
pjp
sizeof(in_addr_t)); /* 16 bytes */
0261
2014-11-14
pjp
0262
2014-11-14
pjp
a_count++;
0263
2014-11-14
pjp
outlen += 16;
0264
2014-11-14
pjp
0265
2014-11-14
pjp
/* can we afford to write another header? if no truncate */
0266
2019-02-15
pjp
if (outlen + 16 > replysize) {
0267
2014-11-14
pjp
NTOHS(odh->query);
0268
2014-11-14
pjp
SET_DNS_TRUNCATION(odh);
0269
2014-11-14
pjp
HTONS(odh->query);
0270
2017-09-18
pjp
odh->answer = 0;
0271
2017-09-18
pjp
odh->nsrr = 0;
0272
2017-09-18
pjp
odh->additional = 0;
0273
2017-09-18
pjp
outlen = rollback;
0274
2014-11-14
pjp
goto out;
0275
2014-11-14
pjp
}
0276
2014-11-14
pjp
0277
2014-11-14
pjp
0278
2014-11-14
pjp
/* set new offset for answer */
0279
2014-11-14
pjp
answer = (struct answer *)&reply[outlen];
0280
2019-02-15
pjp
}
0281
2014-11-14
pjp
0282
2019-02-15
pjp
odh->answer = htons(a_count);
0283
2019-02-15
pjp
0284
2015-06-27
pjp
/* Add RRSIG reply_a */
0285
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
0286
2015-06-20
pjp
int tmplen = 0;
0287
2015-06-22
pjp
int origlen = outlen;
0288
2020-04-01
pjp
int retcount;
0289
2015-06-20
pjp
0290
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_A, rbt, reply, replysize, outlen, &retcount, q->aa);
0291
2015-06-20
pjp
0292
2015-06-20
pjp
if (tmplen == 0) {
0293
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
0294
2020-07-08
pjp
if (q->aa != 1)
0295
2020-07-08
pjp
return -1;
0296
2020-07-08
pjp
0297
2015-06-20
pjp
NTOHS(odh->query);
0298
2015-06-20
pjp
SET_DNS_TRUNCATION(odh);
0299
2015-06-20
pjp
HTONS(odh->query);
0300
2017-09-18
pjp
odh->answer = 0;
0301
2017-09-18
pjp
odh->nsrr = 0;
0302
2017-09-18
pjp
odh->additional = 0;
0303
2017-09-18
pjp
outlen = rollback;
0304
2015-06-20
pjp
goto out;
0305
2015-06-20
pjp
}
0306
2015-06-20
pjp
0307
2015-06-20
pjp
outlen = tmplen;
0308
2015-06-22
pjp
0309
2015-06-22
pjp
if (outlen > origlen)
0310
2020-04-01
pjp
odh->answer = htons(a_count + retcount);
0311
2015-06-22
pjp
0312
2014-11-14
pjp
}
0313
2014-11-14
pjp
0314
2015-11-14
pjp
out:
0315
2014-11-14
pjp
if (q->edns0len) {
0316
2014-11-14
pjp
/* tag on edns0 opt record */
0317
2014-11-14
pjp
odh->additional = htons(1);
0318
2014-11-14
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0319
2014-11-14
pjp
}
0320
2014-11-14
pjp
0321
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
0322
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
0323
2019-02-24
pjp
0324
2019-02-24
pjp
NTOHS(odh->additional);
0325
2019-02-24
pjp
odh->additional++;
0326
2019-02-24
pjp
HTONS(odh->additional);
0327
2019-02-24
pjp
}
0328
2019-02-24
pjp
0329
2015-12-19
pjp
if (istcp) {
0330
2015-12-19
pjp
char *tmpbuf;
0331
2015-12-19
pjp
0332
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
0333
2019-02-27
pjp
if (tmpbuf == 0) {
0334
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0335
2015-12-19
pjp
}
0336
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
0337
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
0338
2015-12-19
pjp
0339
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0340
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0341
2015-12-19
pjp
}
0342
2015-12-19
pjp
free(tmpbuf);
0343
2015-12-19
pjp
} else {
0344
2020-07-21
pjp
if (q->rawsocket) {
0345
2020-07-21
pjp
*sretlen = retlen = outlen;
0346
2020-07-21
pjp
} else {
0347
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0348
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0349
2020-07-21
pjp
}
0350
2015-06-20
pjp
}
0351
2015-12-19
pjp
}
0352
2015-06-20
pjp
0353
2015-06-20
pjp
/*
0354
2019-02-15
pjp
* update order XXX
0355
2015-06-20
pjp
*/
0356
2015-06-20
pjp
0357
2019-02-15
pjp
rotate_rr(rrset);
0358
2019-02-15
pjp
0359
2015-06-27
pjp
return (retlen);
0360
2015-06-27
pjp
}
0361
2015-06-20
pjp
0362
2015-06-27
pjp
/*
0363
2015-06-27
pjp
* REPLY_NSEC3PARAM() - replies a DNS question (*q) on socket (so)
0364
2015-06-27
pjp
*
0365
2015-06-27
pjp
*/
0366
2015-06-27
pjp
0367
2015-06-27
pjp
int
0368
2020-07-21
pjp
reply_nsec3param(struct sreply *sreply, int *sretlen, ddDB *db)
0369
2015-06-27
pjp
{
0370
2015-06-27
pjp
char *reply = sreply->replybuf;
0371
2015-06-27
pjp
struct dns_header *odh;
0372
2015-06-27
pjp
u_int16_t outlen = 0;
0373
2015-06-27
pjp
int a_count;
0374
2015-06-27
pjp
0375
2015-06-27
pjp
struct answer {
0376
2015-06-27
pjp
char name[2];
0377
2015-06-27
pjp
u_int16_t type;
0378
2015-06-27
pjp
u_int16_t class;
0379
2015-06-27
pjp
u_int32_t ttl;
0380
2015-06-27
pjp
u_int16_t rdlength; /* 12 */
0381
2015-06-27
pjp
u_int8_t algorithm;
0382
2015-06-27
pjp
u_int8_t flags;
0383
2015-06-27
pjp
u_int16_t iterations;
0384
2015-06-27
pjp
u_int8_t saltlen;
0385
2015-06-27
pjp
} __attribute__((packed));
0386
2015-06-27
pjp
0387
2015-06-27
pjp
struct answer *answer;
0388
2015-06-27
pjp
0389
2015-06-27
pjp
int so = sreply->so;
0390
2015-06-27
pjp
char *buf = sreply->buf;
0391
2015-06-27
pjp
int len = sreply->len;
0392
2015-06-27
pjp
struct question *q = sreply->q;
0393
2015-06-27
pjp
struct sockaddr *sa = sreply->sa;
0394
2015-06-27
pjp
int salen = sreply->salen;
0395
2019-02-15
pjp
0396
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
0397
2019-02-15
pjp
struct rrset *rrset = NULL;
0398
2019-02-15
pjp
struct rr *rrp = NULL;
0399
2015-06-27
pjp
0400
2015-06-27
pjp
int istcp = sreply->istcp;
0401
2015-06-27
pjp
int replysize = 512;
0402
2015-06-27
pjp
int retlen = -1;
0403
2017-09-18
pjp
u_int16_t rollback;
0404
2019-02-15
pjp
int saltlen;
0405
2020-07-06
pjp
0406
2020-07-06
pjp
time_t now;
0407
2015-06-27
pjp
0408
2020-07-06
pjp
now = time(NULL);
0409
2020-07-06
pjp
0410
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_NSEC3PARAM)) == 0)
0411
2015-06-27
pjp
return -1;
0412
2015-06-27
pjp
0413
2015-06-27
pjp
if (istcp) {
0414
2015-06-27
pjp
replysize = 65535;
0415
2015-06-27
pjp
}
0416
2015-06-27
pjp
0417
2015-06-27
pjp
if (!istcp && q->edns0len > 512)
0418
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
0419
2015-06-27
pjp
0420
2015-06-27
pjp
odh = (struct dns_header *)&reply[0];
0421
2015-06-27
pjp
0422
2015-06-27
pjp
outlen = sizeof(struct dns_header);
0423
2015-06-27
pjp
0424
2015-06-27
pjp
if (len > replysize) {
0425
2015-06-27
pjp
return (retlen);
0426
2015-06-27
pjp
}
0427
2015-06-27
pjp
0428
2015-06-27
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0429
2015-06-27
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0430
2015-06-27
pjp
0431
2015-06-27
pjp
outlen += (q->hdr->namelen + 4);
0432
2017-09-18
pjp
rollback = outlen;
0433
2015-06-27
pjp
0434
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
0435
2015-06-27
pjp
0436
2015-06-27
pjp
odh->question = htons(1);
0437
2015-06-27
pjp
odh->answer = htons(1);
0438
2015-06-27
pjp
odh->nsrr = 0;
0439
2015-06-27
pjp
odh->additional = 0;
0440
2015-06-27
pjp
0441
2019-02-15
pjp
0442
2015-06-27
pjp
/* skip dns header, question name, qtype and qclass */
0443
2015-06-27
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0444
2015-06-27
pjp
q->hdr->namelen + 4);
0445
2015-06-27
pjp
0446
2015-06-27
pjp
a_count = 0;
0447
2015-06-27
pjp
0448
2019-02-15
pjp
rrp = TAILQ_FIRST(&rrset->rr_head);
0449
2019-02-27
pjp
if (rrp == 0)
0450
2019-02-15
pjp
return -1;
0451
2019-02-15
pjp
0452
2019-02-15
pjp
saltlen = ((struct nsec3param *)rrp->rdata)->saltlen;
0453
2019-02-15
pjp
if ((outlen + sizeof(struct answer) + saltlen ) > replysize) {
0454
2015-06-27
pjp
NTOHS(odh->query);
0455
2015-06-27
pjp
SET_DNS_TRUNCATION(odh);
0456
2015-06-27
pjp
HTONS(odh->query);
0457
2017-09-18
pjp
odh->answer = 0;
0458
2017-09-18
pjp
odh->nsrr = 0;
0459
2017-09-18
pjp
odh->additional = 0;
0460
2017-09-18
pjp
outlen = rollback;
0461
2015-06-27
pjp
goto out;
0462
2015-06-27
pjp
}
0463
2015-06-27
pjp
0464
2019-02-15
pjp
0465
2019-02-15
pjp
0466
2015-06-27
pjp
/*
0467
2015-06-27
pjp
* answer->name is a pointer to the request (0xc00c)
0468
2015-06-27
pjp
*/
0469
2015-06-27
pjp
0470
2015-06-27
pjp
answer->name[0] = 0xc0; /* 1 byte */
0471
2015-06-27
pjp
answer->name[1] = 0x0c; /* 2 bytes */
0472
2015-06-27
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
0473
2015-06-27
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
0474
2019-02-15
pjp
0475
2020-07-06
pjp
if (q->aa)
0476
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl);
0477
2020-07-06
pjp
else
0478
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
0479
2020-07-06
pjp
0480
2019-02-15
pjp
answer->rdlength = htons(((struct nsec3param *)rrp->rdata)->saltlen + 5); /* 5 = rest */
0481
2015-06-27
pjp
0482
2019-02-15
pjp
answer->algorithm = ((struct nsec3param *)rrp->rdata)->algorithm;
0483
2019-02-15
pjp
answer->flags = ((struct nsec3param *)rrp->rdata)->flags;
0484
2019-02-15
pjp
answer->iterations = htons(((struct nsec3param *)rrp->rdata)->iterations);
0485
2019-02-15
pjp
answer->saltlen = saltlen;
0486
2015-06-27
pjp
outlen += sizeof(struct answer);
0487
2015-06-27
pjp
0488
2019-02-15
pjp
if (saltlen) {
0489
2019-02-15
pjp
memcpy(&reply[outlen],
0490
2019-02-15
pjp
&((struct nsec3param*)rrp->rdata)->salt,
0491
2019-02-15
pjp
saltlen);
0492
2019-02-15
pjp
0493
2019-02-15
pjp
outlen += saltlen;
0494
2015-06-27
pjp
}
0495
2015-06-27
pjp
0496
2015-06-27
pjp
a_count++;
0497
2015-06-27
pjp
0498
2015-06-27
pjp
/* set new offset for answer */
0499
2015-06-27
pjp
answer = (struct answer *)&reply[outlen];
0500
2015-06-27
pjp
0501
2015-06-27
pjp
0502
2015-06-27
pjp
/* Add RRSIG reply_nsec3 */
0503
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
0504
2015-06-27
pjp
int tmplen = 0;
0505
2015-06-27
pjp
int origlen = outlen;
0506
2020-04-01
pjp
int retcount;
0507
2015-06-27
pjp
0508
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_NSEC3PARAM, rbt, reply, replysize, outlen, &retcount, q->aa);
0509
2015-06-27
pjp
0510
2018-02-27
pjp
if (tmplen == 0) {
0511
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
0512
2020-07-08
pjp
if (q->aa != 1)
0513
2020-07-08
pjp
return -1;
0514
2020-07-08
pjp
0515
2018-02-27
pjp
NTOHS(odh->query);
0516
2018-02-27
pjp
SET_DNS_TRUNCATION(odh);
0517
2018-02-27
pjp
HTONS(odh->query);
0518
2018-02-27
pjp
outlen = rollback;
0519
2018-02-27
pjp
odh->answer = 0;
0520
2018-02-27
pjp
odh->nsrr = 0;
0521
2018-02-27
pjp
odh->additional = 0;
0522
2018-02-27
pjp
goto out;
0523
2015-06-27
pjp
}
0524
2015-06-27
pjp
0525
2018-02-27
pjp
outlen = tmplen;
0526
2018-02-27
pjp
0527
2018-02-27
pjp
if (outlen > origlen)
0528
2020-04-01
pjp
odh->answer = htons(a_count + retcount + 1);
0529
2015-11-14
pjp
}
0530
2015-11-14
pjp
0531
2015-11-14
pjp
out:
0532
2015-06-27
pjp
if (q->edns0len) {
0533
2015-06-27
pjp
/* tag on edns0 opt record */
0534
2015-06-27
pjp
odh->additional = htons(1);
0535
2015-06-27
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0536
2015-06-27
pjp
}
0537
2015-06-27
pjp
0538
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
0539
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
0540
2019-02-24
pjp
0541
2019-02-24
pjp
NTOHS(odh->additional);
0542
2019-02-24
pjp
odh->additional++;
0543
2019-02-24
pjp
HTONS(odh->additional);
0544
2019-02-24
pjp
}
0545
2019-02-24
pjp
0546
2019-02-24
pjp
0547
2015-12-19
pjp
if (istcp) {
0548
2015-12-19
pjp
char *tmpbuf;
0549
2015-12-19
pjp
0550
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
0551
2019-02-27
pjp
if (tmpbuf == 0) {
0552
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0553
2015-12-19
pjp
}
0554
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
0555
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
0556
2015-12-19
pjp
0557
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0558
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0559
2015-12-19
pjp
}
0560
2015-12-19
pjp
free(tmpbuf);
0561
2015-12-19
pjp
} else {
0562
2020-07-21
pjp
if (q->rawsocket) {
0563
2020-07-21
pjp
*sretlen = retlen = outlen;
0564
2020-07-21
pjp
} else {
0565
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0566
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0567
2020-07-21
pjp
}
0568
2015-06-27
pjp
}
0569
2015-12-19
pjp
}
0570
2015-06-27
pjp
0571
2015-06-25
pjp
return (retlen);
0572
2015-06-25
pjp
}
0573
2015-06-25
pjp
0574
2015-06-25
pjp
0575
2015-06-25
pjp
/*
0576
2015-06-27
pjp
* REPLY_NSEC3() - replies a DNS question (*q) on socket (so)
0577
2015-06-25
pjp
*
0578
2015-06-25
pjp
*/
0579
2015-06-25
pjp
0580
2015-06-25
pjp
int
0581
2020-07-21
pjp
reply_nsec3(struct sreply *sreply, int *sretlen, ddDB *db)
0582
2015-06-25
pjp
{
0583
2015-06-25
pjp
char *reply = sreply->replybuf;
0584
2015-06-25
pjp
struct dns_header *odh;
0585
2015-06-25
pjp
u_int16_t outlen = 0;
0586
2015-06-25
pjp
int a_count;
0587
2015-06-25
pjp
0588
2015-06-25
pjp
struct answer {
0589
2015-06-25
pjp
char name[2];
0590
2015-06-25
pjp
u_int16_t type;
0591
2015-06-25
pjp
u_int16_t class;
0592
2015-06-25
pjp
u_int32_t ttl;
0593
2015-06-25
pjp
u_int16_t rdlength; /* 12 */
0594
2015-06-27
pjp
u_int8_t algorithm;
0595
2015-06-27
pjp
u_int8_t flags;
0596
2015-06-27
pjp
u_int16_t iterations;
0597
2015-06-27
pjp
u_int8_t saltlen;
0598
2015-06-25
pjp
} __attribute__((packed));
0599
2015-06-25
pjp
0600
2015-06-25
pjp
struct answer *answer;
0601
2015-06-25
pjp
0602
2015-06-25
pjp
int so = sreply->so;
0603
2015-06-25
pjp
char *buf = sreply->buf;
0604
2015-06-25
pjp
int len = sreply->len;
0605
2015-06-25
pjp
struct question *q = sreply->q;
0606
2015-06-25
pjp
struct sockaddr *sa = sreply->sa;
0607
2015-06-25
pjp
int salen = sreply->salen;
0608
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
0609
2019-02-15
pjp
struct rrset *rrset = NULL;
0610
2019-02-15
pjp
struct rr *rrp = NULL;
0611
2015-06-25
pjp
0612
2015-06-25
pjp
int istcp = sreply->istcp;
0613
2015-06-25
pjp
int replysize = 512;
0614
2015-06-25
pjp
int retlen = -1;
0615
2017-09-18
pjp
u_int16_t rollback;
0616
2015-06-27
pjp
u_int8_t *somelen;
0617
2019-02-15
pjp
int bitmaplen, saltlen, nextlen;
0618
2015-06-25
pjp
0619
2020-07-06
pjp
time_t now;
0620
2020-07-06
pjp
0621
2020-07-06
pjp
now = time(NULL);
0622
2020-07-06
pjp
0623
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_A)) == 0)
0624
2015-06-25
pjp
return -1;
0625
2015-06-25
pjp
0626
2015-06-25
pjp
if (istcp) {
0627
2015-06-25
pjp
replysize = 65535;
0628
2015-06-25
pjp
}
0629
2015-06-25
pjp
0630
2015-06-25
pjp
if (!istcp && q->edns0len > 512)
0631
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
0632
2015-06-25
pjp
0633
2015-07-01
pjp
0634
2015-07-01
pjp
/* RFC 5155 section 7.2.8 */
0635
2019-02-15
pjp
/* perhaps we are accompanied by an rrsig */
0636
2019-02-15
pjp
if (find_rr(rbt, DNS_TYPE_NSEC3) && find_rr(rbt, DNS_TYPE_RRSIG)) {
0637
2020-07-21
pjp
return (reply_nxdomain(sreply, sretlen, db));
0638
2015-07-01
pjp
}
0639
2015-06-25
pjp
odh = (struct dns_header *)&reply[0];
0640
2015-06-25
pjp
0641
2015-06-25
pjp
outlen = sizeof(struct dns_header);
0642
2015-06-25
pjp
0643
2015-06-25
pjp
if (len > replysize) {
0644
2015-06-25
pjp
return (retlen);
0645
2015-06-25
pjp
}
0646
2015-06-25
pjp
0647
2015-06-25
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0648
2015-06-25
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0649
2015-06-25
pjp
0650
2015-06-25
pjp
outlen += (q->hdr->namelen + 4);
0651
2017-09-18
pjp
rollback = outlen;
0652
2015-06-25
pjp
0653
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
0654
2015-06-25
pjp
0655
2015-06-24
pjp
odh->question = htons(1);
0656
2015-06-25
pjp
odh->answer = htons(1);
0657
2015-06-24
pjp
odh->nsrr = 0;
0658
2015-06-24
pjp
odh->additional = 0;
0659
2015-06-24
pjp
0660
2015-06-24
pjp
/* skip dns header, question name, qtype and qclass */
0661
2015-06-24
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0662
2015-06-24
pjp
q->hdr->namelen + 4);
0663
2015-06-24
pjp
0664
2015-06-24
pjp
a_count = 0;
0665
2015-06-24
pjp
0666
2019-02-15
pjp
rrp = TAILQ_FIRST(&rrset->rr_head);
0667
2019-02-27
pjp
if (rrp == 0)
0668
2019-02-15
pjp
return -1;
0669
2019-02-15
pjp
0670
2019-02-15
pjp
saltlen = ((struct nsec3 *)rrp->rdata)->saltlen;
0671
2019-02-15
pjp
bitmaplen = ((struct nsec3 *)rrp->rdata)->bitmap_len;
0672
2019-02-15
pjp
nextlen = ((struct nsec3 *)rrp->rdata)->nextlen;
0673
2019-02-15
pjp
0674
2019-02-15
pjp
if ((outlen + sizeof(struct answer) +
0675
2019-02-15
pjp
nextlen + saltlen + 1 + bitmaplen) > replysize) {
0676
2015-06-25
pjp
NTOHS(odh->query);
0677
2015-06-25
pjp
SET_DNS_TRUNCATION(odh);
0678
2015-06-25
pjp
HTONS(odh->query);
0679
2017-09-18
pjp
odh->answer = 0;
0680
2017-09-18
pjp
odh->nsrr = 0;
0681
2017-09-18
pjp
odh->additional = 0;
0682
2017-09-18
pjp
outlen = rollback;
0683
2015-06-25
pjp
goto out;
0684
2015-06-25
pjp
}
0685
2015-06-25
pjp
0686
2015-06-25
pjp
/*
0687
2015-06-25
pjp
* answer->name is a pointer to the request (0xc00c)
0688
2015-06-25
pjp
*/
0689
2015-06-25
pjp
0690
2015-06-25
pjp
answer->name[0] = 0xc0; /* 1 byte */
0691
2015-06-25
pjp
answer->name[1] = 0x0c; /* 2 bytes */
0692
2015-06-25
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
0693
2015-06-25
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
0694
2020-07-06
pjp
0695
2020-07-06
pjp
if (q->aa)
0696
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl); /* 10 b */
0697
2020-07-06
pjp
else
0698
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
0699
2019-02-15
pjp
0700
2019-02-15
pjp
answer->rdlength = htons(nextlen + bitmaplen + saltlen + 6); /* 6 = rest */
0701
2015-06-25
pjp
0702
2019-02-15
pjp
answer->algorithm = ((struct nsec3 *)rrp->rdata)->algorithm;
0703
2019-02-15
pjp
answer->flags = ((struct nsec3 *)rrp->rdata)->flags;
0704
2019-02-15
pjp
answer->iterations = htons(((struct nsec3 *)rrp->rdata)->iterations);
0705
2019-02-15
pjp
answer->saltlen = saltlen;
0706
2015-06-25
pjp
outlen += sizeof(struct answer);
0707
2015-06-27
pjp
0708
2019-02-15
pjp
if (saltlen) {
0709
2019-02-15
pjp
memcpy(&reply[outlen],
0710
2019-02-15
pjp
(char *)&((struct nsec3 *)rrp->rdata)->salt,
0711
2019-02-15
pjp
saltlen);
0712
2019-02-15
pjp
0713
2019-02-15
pjp
outlen += saltlen;
0714
2015-06-27
pjp
}
0715
2015-06-25
pjp
0716
2015-06-27
pjp
somelen = (u_int8_t *)&reply[outlen];
0717
2019-02-15
pjp
*somelen = nextlen;
0718
2015-06-25
pjp
0719
2015-06-27
pjp
outlen += 1;
0720
2015-06-25
pjp
0721
2019-02-15
pjp
memcpy(&reply[outlen], ((struct nsec3 *)rrp->rdata)->next, nextlen);
0722
2015-06-27
pjp
0723
2019-02-15
pjp
outlen += nextlen;
0724
2015-06-27
pjp
0725
2019-02-15
pjp
memcpy(&reply[outlen], ((struct nsec3 *)rrp->rdata)->bitmap, bitmaplen);
0726
2019-02-15
pjp
outlen += bitmaplen;
0727
2015-06-27
pjp
0728
2015-06-25
pjp
a_count++;
0729
2015-06-25
pjp
0730
2015-06-25
pjp
/* set new offset for answer */
0731
2015-06-25
pjp
answer = (struct answer *)&reply[outlen];
0732
2015-06-25
pjp
0733
2015-06-25
pjp
0734
2015-06-27
pjp
/* Add RRSIG reply_nsec3 */
0735
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
0736
2015-06-25
pjp
int tmplen = 0;
0737
2015-06-25
pjp
int origlen = outlen;
0738
2020-04-01
pjp
int retcount;
0739
2015-06-25
pjp
0740
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_NSEC3, rbt, reply, replysize, outlen, &retcount, q->aa);
0741
2018-02-27
pjp
0742
2018-02-27
pjp
if (tmplen == 0) {
0743
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
0744
2020-07-08
pjp
if (q->aa != 1)
0745
2020-07-08
pjp
return -1;
0746
2020-07-08
pjp
0747
2018-02-27
pjp
NTOHS(odh->query);
0748
2018-02-27
pjp
SET_DNS_TRUNCATION(odh);
0749
2018-02-27
pjp
HTONS(odh->query);
0750
2018-02-27
pjp
odh->answer = 0;
0751
2018-02-27
pjp
odh->nsrr = 0;
0752
2018-02-27
pjp
odh->additional = 0;
0753
2018-02-27
pjp
outlen = rollback;
0754
2018-02-27
pjp
goto out;
0755
2018-02-27
pjp
}
0756
2018-02-27
pjp
0757
2018-02-27
pjp
outlen = tmplen;
0758
2018-02-27
pjp
0759
2018-02-27
pjp
if (outlen > origlen)
0760
2020-04-01
pjp
odh->answer = htons(a_count + retcount + 1);
0761
2018-02-27
pjp
}
0762
2018-02-27
pjp
0763
2018-02-27
pjp
out:
0764
2018-02-27
pjp
if (q->edns0len) {
0765
2018-02-27
pjp
/* tag on edns0 opt record */
0766
2018-02-27
pjp
odh->additional = htons(1);
0767
2018-02-27
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0768
2018-02-27
pjp
}
0769
2018-02-27
pjp
0770
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
0771
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
0772
2019-02-24
pjp
0773
2019-02-24
pjp
NTOHS(odh->additional);
0774
2019-02-24
pjp
odh->additional++;
0775
2019-02-24
pjp
HTONS(odh->additional);
0776
2019-02-24
pjp
}
0777
2019-02-24
pjp
0778
2018-02-27
pjp
if (istcp) {
0779
2018-02-27
pjp
char *tmpbuf;
0780
2018-02-27
pjp
0781
2018-02-27
pjp
tmpbuf = malloc(outlen + 2);
0782
2019-02-27
pjp
if (tmpbuf == 0) {
0783
2018-02-27
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0784
2018-02-27
pjp
}
0785
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
0786
2019-12-03
pjp
memcpy(&tmpbuf[2], reply, outlen);
0787
2019-12-03
pjp
0788
2019-12-03
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0789
2019-12-03
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0790
2019-12-03
pjp
}
0791
2019-12-03
pjp
free(tmpbuf);
0792
2019-12-03
pjp
} else {
0793
2020-07-21
pjp
if (q->rawsocket) {
0794
2020-07-21
pjp
*sretlen = retlen = outlen;
0795
2020-07-21
pjp
} else {
0796
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0797
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0798
2020-07-21
pjp
}
0799
2019-12-03
pjp
}
0800
2019-12-03
pjp
}
0801
2019-12-03
pjp
0802
2019-12-03
pjp
return (retlen);
0803
2019-12-03
pjp
}
0804
2019-12-03
pjp
0805
2020-07-23
pjp
/*
0806
2020-07-23
pjp
* REPLY_CAA
0807
2020-07-23
pjp
*/
0808
2020-07-23
pjp
0809
2020-07-23
pjp
int
0810
2020-07-23
pjp
reply_caa(struct sreply *sreply, int *sretlen, ddDB *db)
0811
2020-07-23
pjp
{
0812
2020-07-23
pjp
char *reply = sreply->replybuf;
0813
2020-07-23
pjp
struct dns_header *odh;
0814
2020-07-23
pjp
u_int16_t outlen = 0;
0815
2020-07-23
pjp
int caa_count;
0816
2020-07-23
pjp
0817
2020-07-23
pjp
struct answer {
0818
2020-07-23
pjp
char name[2];
0819
2020-07-23
pjp
u_int16_t type;
0820
2020-07-23
pjp
u_int16_t class;
0821
2020-07-23
pjp
u_int32_t ttl;
0822
2020-07-23
pjp
u_int16_t rdlength; /* 12 */
0823
2020-07-23
pjp
} __attribute__((packed));
0824
2020-07-23
pjp
0825
2020-07-23
pjp
struct answer *answer;
0826
2020-07-23
pjp
0827
2020-07-23
pjp
int so = sreply->so;
0828
2020-07-23
pjp
char *buf = sreply->buf;
0829
2020-07-23
pjp
int len = sreply->len;
0830
2020-07-23
pjp
struct question *q = sreply->q;
0831
2020-07-23
pjp
struct sockaddr *sa = sreply->sa;
0832
2020-07-23
pjp
int salen = sreply->salen;
0833
2020-07-23
pjp
struct rbtree *rbt = sreply->rbt1;
0834
2020-07-23
pjp
struct rrset *rrset = NULL;
0835
2020-07-23
pjp
struct rr *rrp = NULL;
0836
2020-07-23
pjp
0837
2020-07-23
pjp
int istcp = sreply->istcp;
0838
2020-07-23
pjp
int replysize = 512;
0839
2020-07-23
pjp
int retlen = -1;
0840
2020-07-23
pjp
u_int16_t rollback;
0841
2020-07-23
pjp
int valuelen, taglen;
0842
2020-07-23
pjp
time_t now;
0843
2020-07-23
pjp
0844
2020-07-23
pjp
0845
2020-07-23
pjp
now = time(NULL);
0846
2020-07-23
pjp
0847
2020-07-23
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_CAA)) == 0)
0848
2020-07-23
pjp
return -1;
0849
2020-07-23
pjp
0850
2020-07-23
pjp
if (istcp) {
0851
2020-07-23
pjp
replysize = 65535;
0852
2020-07-23
pjp
}
0853
2020-07-23
pjp
0854
2020-07-23
pjp
if (!istcp && q->edns0len > 512)
0855
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
0856
2020-07-23
pjp
0857
2020-07-23
pjp
odh = (struct dns_header *)&reply[0];
0858
2020-07-23
pjp
0859
2020-07-23
pjp
outlen = sizeof(struct dns_header);
0860
2020-07-23
pjp
0861
2020-07-23
pjp
if (len > replysize) {
0862
2020-07-23
pjp
return (retlen);
0863
2020-07-23
pjp
}
0864
2020-07-23
pjp
0865
2020-07-23
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0866
2020-07-23
pjp
0867
2020-07-23
pjp
outlen += (q->hdr->namelen + 4);
0868
2020-07-23
pjp
rollback = outlen;
0869
2020-07-23
pjp
0870
2020-07-23
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0871
2020-07-23
pjp
set_reply_flags(rbt, odh, q);
0872
2020-07-23
pjp
0873
2020-07-23
pjp
odh->question = htons(1);
0874
2020-07-23
pjp
odh->answer = htons(1);
0875
2020-07-23
pjp
odh->nsrr = 0;
0876
2020-07-23
pjp
odh->additional = 0;
0877
2020-07-23
pjp
0878
2020-07-23
pjp
/* skip dns header, question name, qtype and qclass */
0879
2020-07-23
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0880
2020-07-23
pjp
q->hdr->namelen + 4);
0881
2020-07-23
pjp
0882
2020-07-23
pjp
caa_count = 0;
0883
2020-07-23
pjp
0884
2020-07-23
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
0885
2020-07-23
pjp
if ((outlen + sizeof(struct answer) + 2 + \
0886
2020-07-23
pjp
((struct caa *)rrp->rdata)->taglen + \
0887
2020-07-23
pjp
((struct caa *)rrp->rdata)->valuelen) > replysize) {
0888
2020-07-23
pjp
0889
2020-07-23
pjp
NTOHS(odh->query);
0890
2020-07-23
pjp
SET_DNS_TRUNCATION(odh);
0891
2020-07-23
pjp
HTONS(odh->query);
0892
2020-07-23
pjp
odh->answer = 0;
0893
2020-07-23
pjp
odh->nsrr = 0;
0894
2020-07-23
pjp
odh->additional = 0;
0895
2020-07-23
pjp
outlen = rollback;
0896
2020-07-23
pjp
goto out;
0897
2020-07-23
pjp
}
0898
2020-07-23
pjp
0899
2020-07-23
pjp
answer->name[0] = 0xc0; /* 1 byte */
0900
2020-07-23
pjp
answer->name[1] = 0x0c; /* 2 bytes */
0901
2020-07-23
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
0902
2020-07-23
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
0903
2020-07-23
pjp
0904
2020-07-23
pjp
if (q->aa)
0905
2020-07-23
pjp
answer->ttl = htonl(rrset->ttl); /* 10 b */
0906
2020-07-23
pjp
else
0907
2020-07-23
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
0908
2020-07-23
pjp
0909
2020-07-23
pjp
0910
2020-07-23
pjp
caa_count++;
0911
2020-07-23
pjp
outlen += 12;
0912
2020-07-23
pjp
0913
2020-07-23
pjp
taglen = ((struct caa *)rrp->rdata)->taglen;
0914
2020-07-23
pjp
valuelen = ((struct caa *)rrp->rdata)->valuelen;
0915
2020-07-23
pjp
0916
2020-07-23
pjp
pack8(&reply[outlen++], ((struct caa *)rrp->rdata)->flags);
0917
2020-07-23
pjp
pack8(&reply[outlen++], taglen);
0918
2020-07-23
pjp
pack(&reply[outlen], ((struct caa *)rrp->rdata)->tag, taglen);
0919
2020-07-23
pjp
outlen += taglen;
0920
2020-07-23
pjp
pack(&reply[outlen],((struct caa *)rrp->rdata)->value,valuelen);
0921
2020-07-23
pjp
outlen += valuelen;
0922
2020-07-23
pjp
0923
2020-07-23
pjp
answer->rdlength = htons(2 + taglen + valuelen);
0924
2020-07-23
pjp
0925
2020-07-23
pjp
/* set new offset for answer */
0926
2020-07-23
pjp
answer = (struct answer *)&reply[outlen];
0927
2020-07-23
pjp
}
0928
2020-07-23
pjp
0929
2020-07-23
pjp
odh->answer = htons(caa_count);
0930
2020-07-23
pjp
0931
2020-07-23
pjp
0932
2020-07-23
pjp
/* Add RRSIG reply_nsec */
0933
2020-07-23
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
0934
2020-07-23
pjp
int tmplen = 0;
0935
2020-07-23
pjp
int origlen = outlen;
0936
2020-07-23
pjp
int retcount;
0937
2020-07-23
pjp
0938
2020-07-23
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_CAA, rbt, reply, replysize, outlen, &retcount, q->aa);
0939
2020-07-23
pjp
0940
2020-07-23
pjp
if (tmplen == 0) {
0941
2020-07-23
pjp
0942
2020-07-23
pjp
/* we're forwarding and had no RRSIG return with -1 */
0943
2020-07-23
pjp
if (q->aa != 1)
0944
2020-07-23
pjp
return -1;
0945
2020-07-23
pjp
0946
2020-07-23
pjp
NTOHS(odh->query);
0947
2020-07-23
pjp
SET_DNS_TRUNCATION(odh);
0948
2020-07-23
pjp
HTONS(odh->query);
0949
2020-07-23
pjp
odh->answer = 0;
0950
2020-07-23
pjp
odh->nsrr = 0;
0951
2020-07-23
pjp
odh->additional = 0;
0952
2020-07-23
pjp
outlen = rollback;
0953
2020-07-23
pjp
goto out;
0954
2020-07-23
pjp
}
0955
2020-07-23
pjp
0956
2020-07-23
pjp
outlen = tmplen;
0957
2020-07-23
pjp
0958
2020-07-23
pjp
if (outlen > origlen)
0959
2020-07-23
pjp
odh->answer = htons(caa_count + retcount);
0960
2020-07-23
pjp
0961
2020-07-23
pjp
}
0962
2020-07-23
pjp
0963
2020-07-23
pjp
out:
0964
2020-07-23
pjp
if (q->edns0len) {
0965
2020-07-23
pjp
/* tag on edns0 opt record */
0966
2020-07-23
pjp
odh->additional = htons(1);
0967
2020-07-23
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0968
2020-07-23
pjp
}
0969
2020-07-23
pjp
0970
2020-07-23
pjp
if (q->tsig.tsigverified == 1) {
0971
2020-07-23
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
0972
2020-07-23
pjp
0973
2020-07-23
pjp
NTOHS(odh->additional);
0974
2020-07-23
pjp
odh->additional++;
0975
2020-07-23
pjp
HTONS(odh->additional);
0976
2020-07-23
pjp
}
0977
2020-07-23
pjp
0978
2020-07-23
pjp
if (istcp) {
0979
2020-07-23
pjp
char *tmpbuf;
0980
2020-07-23
pjp
0981
2020-07-23
pjp
tmpbuf = malloc(outlen + 2);
0982
2020-07-23
pjp
if (tmpbuf == 0) {
0983
2020-07-23
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0984
2020-07-23
pjp
}
0985
2020-07-23
pjp
pack16(tmpbuf, htons(outlen));
0986
2020-07-23
pjp
memcpy(&tmpbuf[2], reply, outlen);
0987
2020-07-23
pjp
0988
2020-07-23
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0989
2020-07-23
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0990
2020-07-23
pjp
}
0991
2020-07-23
pjp
free(tmpbuf);
0992
2020-07-23
pjp
} else {
0993
2020-07-23
pjp
if (q->rawsocket) {
0994
2020-07-23
pjp
*sretlen = retlen = outlen;
0995
2020-07-23
pjp
} else {
0996
2020-07-23
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0997
2020-07-23
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0998
2020-07-23
pjp
}
0999
2020-07-23
pjp
}
1000
2020-07-23
pjp
}
1001
2020-07-23
pjp
1002
2020-07-23
pjp
1003
2020-07-23
pjp
return (retlen);
1004
2020-07-23
pjp
}
1005
2020-07-23
pjp
1006
2020-07-23
pjp
int
1007
2020-07-23
pjp
reply_hinfo(struct sreply *sreply, int *sretlen, ddDB *db)
1008
2020-07-23
pjp
{
1009
2020-07-23
pjp
char *reply = sreply->replybuf;
1010
2020-07-23
pjp
struct dns_header *odh;
1011
2020-07-23
pjp
u_int16_t outlen = 0;
1012
2020-07-23
pjp
int hinfo_count;
1013
2020-07-23
pjp
1014
2020-07-23
pjp
struct answer {
1015
2020-07-23
pjp
char name[2];
1016
2020-07-23
pjp
u_int16_t type;
1017
2020-07-23
pjp
u_int16_t class;
1018
2020-07-23
pjp
u_int32_t ttl;
1019
2020-07-23
pjp
u_int16_t rdlength; /* 12 */
1020
2020-07-23
pjp
} __attribute__((packed));
1021
2020-07-23
pjp
1022
2020-07-23
pjp
struct answer *answer;
1023
2020-07-23
pjp
1024
2020-07-23
pjp
int so = sreply->so;
1025
2020-07-23
pjp
char *buf = sreply->buf;
1026
2020-07-23
pjp
int len = sreply->len;
1027
2020-07-23
pjp
struct question *q = sreply->q;
1028
2020-07-23
pjp
struct sockaddr *sa = sreply->sa;
1029
2020-07-23
pjp
int salen = sreply->salen;
1030
2020-07-23
pjp
struct rbtree *rbt = sreply->rbt1;
1031
2020-07-23
pjp
struct rrset *rrset = NULL;
1032
2020-07-23
pjp
struct rr *rrp = NULL;
1033
2020-07-23
pjp
1034
2020-07-23
pjp
int istcp = sreply->istcp;
1035
2020-07-23
pjp
int replysize = 512;
1036
2020-07-23
pjp
int retlen = -1;
1037
2020-07-23
pjp
u_int16_t rollback;
1038
2020-07-23
pjp
time_t now;
1039
2020-07-23
pjp
1040
2020-07-23
pjp
1041
2020-07-23
pjp
now = time(NULL);
1042
2020-07-23
pjp
1043
2020-07-23
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_HINFO)) == 0)
1044
2020-07-23
pjp
return -1;
1045
2020-07-23
pjp
1046
2020-07-23
pjp
if (istcp) {
1047
2020-07-23
pjp
replysize = 65535;
1048
2020-07-23
pjp
}
1049
2020-07-23
pjp
1050
2020-07-23
pjp
if (!istcp && q->edns0len > 512)
1051
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
1052
2020-07-23
pjp
1053
2020-07-23
pjp
odh = (struct dns_header *)&reply[0];
1054
2020-07-23
pjp
1055
2020-07-23
pjp
outlen = sizeof(struct dns_header);
1056
2020-07-23
pjp
1057
2020-07-23
pjp
if (len > replysize) {
1058
2020-07-23
pjp
return (retlen);
1059
2020-07-23
pjp
}
1060
2020-07-23
pjp
1061
2020-07-23
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1062
2020-07-23
pjp
1063
2020-07-23
pjp
outlen += (q->hdr->namelen + 4);
1064
2020-07-23
pjp
rollback = outlen;
1065
2020-07-23
pjp
1066
2020-07-23
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1067
2020-07-23
pjp
set_reply_flags(rbt, odh, q);
1068
2020-07-23
pjp
1069
2020-07-23
pjp
odh->question = htons(1);
1070
2020-07-23
pjp
odh->answer = htons(1);
1071
2020-07-23
pjp
odh->nsrr = 0;
1072
2020-07-23
pjp
odh->additional = 0;
1073
2020-07-23
pjp
1074
2020-07-23
pjp
/* skip dns header, question name, qtype and qclass */
1075
2020-07-23
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1076
2020-07-23
pjp
q->hdr->namelen + 4);
1077
2020-07-23
pjp
1078
2020-07-23
pjp
hinfo_count = 0;
1079
2020-07-23
pjp
1080
2020-07-23
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
1081
2020-07-23
pjp
if ((outlen + sizeof(struct answer) + 2 + \
1082
2020-07-23
pjp
((struct hinfo *)rrp->rdata)->cpulen + \
1083
2020-07-23
pjp
((struct hinfo *)rrp->rdata)->oslen) > replysize) {
1084
2020-07-23
pjp
1085
2020-07-23
pjp
NTOHS(odh->query);
1086
2020-07-23
pjp
SET_DNS_TRUNCATION(odh);
1087
2020-07-23
pjp
HTONS(odh->query);
1088
2020-07-23
pjp
odh->answer = 0;
1089
2020-07-23
pjp
odh->nsrr = 0;
1090
2020-07-23
pjp
odh->additional = 0;
1091
2020-07-23
pjp
outlen = rollback;
1092
2020-07-23
pjp
goto out;
1093
2020-07-23
pjp
}
1094
2020-07-23
pjp
1095
2020-07-23
pjp
answer->name[0] = 0xc0; /* 1 byte */
1096
2020-07-23
pjp
answer->name[1] = 0x0c; /* 2 bytes */
1097
2020-07-23
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
1098
2020-07-23
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
1099
2020-07-23
pjp
1100
2020-07-23
pjp
if (q->aa)
1101
2020-07-23
pjp
answer->ttl = htonl(rrset->ttl); /* 10 b */
1102
2020-07-23
pjp
else
1103
2020-07-23
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
1104
2020-07-23
pjp
1105
2020-07-23
pjp
1106
2020-07-23
pjp
hinfo_count++;
1107
2020-07-23
pjp
outlen += 12;
1108
2020-07-23
pjp
1109
2020-07-23
pjp
pack8(&reply[outlen++], ((struct hinfo *)rrp->rdata)->cpulen);
1110
2020-07-23
pjp
pack(&reply[outlen], ((struct hinfo *)rrp->rdata)->cpu,
1111
2020-07-23
pjp
((struct hinfo *)rrp->rdata)->cpulen);
1112
2020-07-23
pjp
outlen += ((struct hinfo *)rrp->rdata)->cpulen;
1113
2020-07-23
pjp
pack8(&reply[outlen++], ((struct hinfo *)rrp->rdata)->oslen);
1114
2020-07-23
pjp
pack(&reply[outlen], ((struct hinfo *)rrp->rdata)->os,
1115
2020-07-23
pjp
((struct hinfo *)rrp->rdata)->oslen);
1116
2020-07-23
pjp
outlen += ((struct hinfo *)rrp->rdata)->oslen;
1117
2020-07-23
pjp
1118
2020-07-23
pjp
answer->rdlength = htons(2 + \
1119
2020-07-23
pjp
((struct hinfo *)rrp->rdata)->oslen + \
1120
2020-07-23
pjp
((struct hinfo *)rrp->rdata)->cpulen);
1121
2020-07-23
pjp
1122
2020-07-23
pjp
/* set new offset for answer */
1123
2020-07-23
pjp
answer = (struct answer *)&reply[outlen];
1124
2020-07-23
pjp
}
1125
2020-07-23
pjp
1126
2020-07-23
pjp
odh->answer = htons(hinfo_count);
1127
2020-07-23
pjp
1128
2020-07-23
pjp
1129
2020-07-23
pjp
/* Add RRSIG reply_nsec */
1130
2020-07-23
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
1131
2020-07-23
pjp
int tmplen = 0;
1132
2020-07-23
pjp
int origlen = outlen;
1133
2020-07-23
pjp
int retcount;
1134
2020-07-23
pjp
1135
2020-07-23
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_HINFO, rbt, reply, replysize, outlen, &retcount, q->aa);
1136
2020-07-23
pjp
1137
2020-07-23
pjp
if (tmplen == 0) {
1138
2020-07-23
pjp
1139
2020-07-23
pjp
/* we're forwarding and had no RRSIG return with -1 */
1140
2020-07-23
pjp
if (q->aa != 1)
1141
2020-07-23
pjp
return -1;
1142
2020-07-23
pjp
1143
2020-07-23
pjp
NTOHS(odh->query);
1144
2020-07-23
pjp
SET_DNS_TRUNCATION(odh);
1145
2020-07-23
pjp
HTONS(odh->query);
1146
2020-07-23
pjp
odh->answer = 0;
1147
2020-07-23
pjp
odh->nsrr = 0;
1148
2020-07-23
pjp
odh->additional = 0;
1149
2020-07-23
pjp
outlen = rollback;
1150
2020-07-23
pjp
goto out;
1151
2020-07-23
pjp
}
1152
2020-07-23
pjp
1153
2020-07-23
pjp
outlen = tmplen;
1154
2020-07-23
pjp
1155
2020-07-23
pjp
if (outlen > origlen)
1156
2020-07-23
pjp
odh->answer = htons(hinfo_count + retcount);
1157
2020-07-23
pjp
1158
2020-07-23
pjp
}
1159
2020-07-23
pjp
1160
2020-07-23
pjp
out:
1161
2020-07-23
pjp
if (q->edns0len) {
1162
2020-07-23
pjp
/* tag on edns0 opt record */
1163
2020-07-23
pjp
odh->additional = htons(1);
1164
2020-07-23
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1165
2020-07-23
pjp
}
1166
2020-07-23
pjp
1167
2020-07-23
pjp
if (q->tsig.tsigverified == 1) {
1168
2020-07-23
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
1169
2020-07-23
pjp
1170
2020-07-23
pjp
NTOHS(odh->additional);
1171
2020-07-23
pjp
odh->additional++;
1172
2020-07-23
pjp
HTONS(odh->additional);
1173
2020-07-23
pjp
}
1174
2020-07-23
pjp
1175
2020-07-23
pjp
if (istcp) {
1176
2020-07-23
pjp
char *tmpbuf;
1177
2020-07-23
pjp
1178
2020-07-23
pjp
tmpbuf = malloc(outlen + 2);
1179
2020-07-23
pjp
if (tmpbuf == 0) {
1180
2020-07-23
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1181
2020-07-23
pjp
}
1182
2020-07-23
pjp
pack16(tmpbuf, htons(outlen));
1183
2020-07-23
pjp
memcpy(&tmpbuf[2], reply, outlen);
1184
2020-07-23
pjp
1185
2020-07-23
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1186
2020-07-23
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1187
2020-07-23
pjp
}
1188
2020-07-23
pjp
free(tmpbuf);
1189
2020-07-23
pjp
} else {
1190
2020-07-23
pjp
if (q->rawsocket) {
1191
2020-07-23
pjp
*sretlen = retlen = outlen;
1192
2020-07-23
pjp
} else {
1193
2020-07-23
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1194
2020-07-23
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1195
2020-07-23
pjp
}
1196
2020-07-23
pjp
}
1197
2020-07-23
pjp
}
1198
2020-07-23
pjp
1199
2020-07-23
pjp
1200
2020-07-23
pjp
return (retlen);
1201
2020-07-23
pjp
}
1202
2020-07-23
pjp
1203
2020-07-23
pjp
int
1204
2020-07-23
pjp
reply_rp(struct sreply *sreply, int *sretlen, ddDB *db)
1205
2020-07-23
pjp
{
1206
2020-07-23
pjp
char *reply = sreply->replybuf;
1207
2020-07-23
pjp
struct dns_header *odh;
1208
2020-07-23
pjp
u_int16_t outlen = 0;
1209
2020-07-23
pjp
int rp_count;
1210
2020-07-23
pjp
1211
2020-07-23
pjp
struct answer {
1212
2020-07-23
pjp
char name[2];
1213
2020-07-23
pjp
u_int16_t type;
1214
2020-07-23
pjp
u_int16_t class;
1215
2020-07-23
pjp
u_int32_t ttl;
1216
2020-07-23
pjp
u_int16_t rdlength; /* 12 */
1217
2020-07-23
pjp
} __attribute__((packed));
1218
2020-07-23
pjp
1219
2020-07-23
pjp
struct answer *answer;
1220
2020-07-23
pjp
1221
2020-07-23
pjp
int so = sreply->so;
1222
2020-07-23
pjp
char *buf = sreply->buf;
1223
2020-07-23
pjp
int len = sreply->len;
1224
2020-07-23
pjp
struct question *q = sreply->q;
1225
2020-07-23
pjp
struct sockaddr *sa = sreply->sa;
1226
2020-07-23
pjp
int salen = sreply->salen;
1227
2020-07-23
pjp
struct rbtree *rbt = sreply->rbt1;
1228
2020-07-23
pjp
struct rrset *rrset = NULL;
1229
2020-07-23
pjp
struct rr *rrp = NULL;
1230
2020-07-23
pjp
1231
2020-07-23
pjp
int istcp = sreply->istcp;
1232
2020-07-23
pjp
int replysize = 512;
1233
2020-07-23
pjp
int retlen = -1;
1234
2020-07-23
pjp
u_int16_t rollback;
1235
2020-07-23
pjp
time_t now;
1236
2020-07-23
pjp
1237
2020-07-23
pjp
1238
2020-07-23
pjp
now = time(NULL);
1239
2020-07-23
pjp
1240
2020-07-23
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_RP)) == 0)
1241
2020-07-23
pjp
return -1;
1242
2020-07-23
pjp
1243
2020-07-23
pjp
if (istcp) {
1244
2020-07-23
pjp
replysize = 65535;
1245
2020-07-23
pjp
}
1246
2020-07-23
pjp
1247
2020-07-23
pjp
if (!istcp && q->edns0len > 512)
1248
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
1249
2020-07-23
pjp
1250
2020-07-23
pjp
odh = (struct dns_header *)&reply[0];
1251
2020-07-23
pjp
1252
2020-07-23
pjp
outlen = sizeof(struct dns_header);
1253
2020-07-23
pjp
1254
2020-07-23
pjp
if (len > replysize) {
1255
2020-07-23
pjp
return (retlen);
1256
2020-07-23
pjp
}
1257
2020-07-23
pjp
1258
2020-07-23
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1259
2020-07-23
pjp
1260
2020-07-23
pjp
outlen += (q->hdr->namelen + 4);
1261
2020-07-23
pjp
rollback = outlen;
1262
2020-07-23
pjp
1263
2020-07-23
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1264
2020-07-23
pjp
set_reply_flags(rbt, odh, q);
1265
2020-07-23
pjp
1266
2020-07-23
pjp
odh->question = htons(1);
1267
2020-07-23
pjp
odh->answer = htons(1);
1268
2020-07-23
pjp
odh->nsrr = 0;
1269
2020-07-23
pjp
odh->additional = 0;
1270
2020-07-23
pjp
1271
2020-07-23
pjp
/* skip dns header, question name, qtype and qclass */
1272
2020-07-23
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1273
2020-07-23
pjp
q->hdr->namelen + 4);
1274
2020-07-23
pjp
1275
2020-07-23
pjp
rp_count = 0;
1276
2020-07-23
pjp
1277
2020-07-23
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
1278
2020-07-23
pjp
if ((outlen + sizeof(struct answer) + \
1279
2020-07-23
pjp
((struct rp *)rrp->rdata)->mboxlen + \
1280
2020-07-23
pjp
((struct rp *)rrp->rdata)->txtlen) > replysize) {
1281
2020-07-23
pjp
1282
2020-07-23
pjp
NTOHS(odh->query);
1283
2020-07-23
pjp
SET_DNS_TRUNCATION(odh);
1284
2020-07-23
pjp
HTONS(odh->query);
1285
2020-07-23
pjp
odh->answer = 0;
1286
2020-07-23
pjp
odh->nsrr = 0;
1287
2020-07-23
pjp
odh->additional = 0;
1288
2020-07-23
pjp
outlen = rollback;
1289
2020-07-23
pjp
goto out;
1290
2020-07-23
pjp
}
1291
2020-07-23
pjp
1292
2020-07-23
pjp
answer->name[0] = 0xc0; /* 1 byte */
1293
2020-07-23
pjp
answer->name[1] = 0x0c; /* 2 bytes */
1294
2020-07-23
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
1295
2020-07-23
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
1296
2020-07-23
pjp
1297
2020-07-23
pjp
if (q->aa)
1298
2020-07-23
pjp
answer->ttl = htonl(rrset->ttl); /* 10 b */
1299
2020-07-23
pjp
else
1300
2020-07-23
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
1301
2020-07-23
pjp
1302
2020-07-23
pjp
1303
2020-07-23
pjp
rp_count++;
1304
2020-07-23
pjp
outlen += 12;
1305
2020-07-23
pjp
1306
2020-07-23
pjp
pack(&reply[outlen], ((struct rp *)rrp->rdata)->mbox,
1307
2020-07-23
pjp
((struct rp *)rrp->rdata)->mboxlen);
1308
2020-07-23
pjp
outlen += ((struct rp *)rrp->rdata)->mboxlen;
1309
2020-07-23
pjp
1310
2020-07-23
pjp
pack(&reply[outlen], ((struct rp *)rrp->rdata)->txt,
1311
2020-07-23
pjp
((struct rp *)rrp->rdata)->txtlen);
1312
2020-07-23
pjp
outlen += ((struct rp *)rrp->rdata)->txtlen;
1313
2020-07-23
pjp
1314
2020-07-23
pjp
answer->rdlength = htons(((struct rp *)rrp->rdata)->mboxlen + \
1315
2020-07-23
pjp
((struct rp *)rrp->rdata)->txtlen);
1316
2020-07-23
pjp
1317
2020-07-23
pjp
/* set new offset for answer */
1318
2020-07-23
pjp
answer = (struct answer *)&reply[outlen];
1319
2020-07-23
pjp
}
1320
2020-07-23
pjp
1321
2020-07-23
pjp
odh->answer = htons(rp_count);
1322
2020-07-23
pjp
1323
2020-07-23
pjp
1324
2020-07-23
pjp
/* Add RRSIG reply_nsec */
1325
2020-07-23
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
1326
2020-07-23
pjp
int tmplen = 0;
1327
2020-07-23
pjp
int origlen = outlen;
1328
2020-07-23
pjp
int retcount;
1329
2020-07-23
pjp
1330
2020-07-23
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_RP, rbt, reply, replysize, outlen, &retcount, q->aa);
1331
2020-07-23
pjp
1332
2020-07-23
pjp
if (tmplen == 0) {
1333
2020-07-23
pjp
1334
2020-07-23
pjp
/* we're forwarding and had no RRSIG return with -1 */
1335
2020-07-23
pjp
if (q->aa != 1)
1336
2020-07-23
pjp
return -1;
1337
2020-07-23
pjp
1338
2020-07-23
pjp
NTOHS(odh->query);
1339
2020-07-23
pjp
SET_DNS_TRUNCATION(odh);
1340
2020-07-23
pjp
HTONS(odh->query);
1341
2020-07-23
pjp
odh->answer = 0;
1342
2020-07-23
pjp
odh->nsrr = 0;
1343
2020-07-23
pjp
odh->additional = 0;
1344
2020-07-23
pjp
outlen = rollback;
1345
2020-07-23
pjp
goto out;
1346
2020-07-23
pjp
}
1347
2020-07-23
pjp
1348
2020-07-23
pjp
outlen = tmplen;
1349
2020-07-23
pjp
1350
2020-07-23
pjp
if (outlen > origlen)
1351
2020-07-23
pjp
odh->answer = htons(rp_count + retcount);
1352
2020-07-23
pjp
1353
2020-07-23
pjp
}
1354
2020-07-23
pjp
1355
2020-07-23
pjp
out:
1356
2020-07-23
pjp
if (q->edns0len) {
1357
2020-07-23
pjp
/* tag on edns0 opt record */
1358
2020-07-23
pjp
odh->additional = htons(1);
1359
2020-07-23
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1360
2020-07-23
pjp
}
1361
2020-07-23
pjp
1362
2020-07-23
pjp
if (q->tsig.tsigverified == 1) {
1363
2020-07-23
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
1364
2020-07-23
pjp
1365
2020-07-23
pjp
NTOHS(odh->additional);
1366
2020-07-23
pjp
odh->additional++;
1367
2020-07-23
pjp
HTONS(odh->additional);
1368
2020-07-23
pjp
}
1369
2020-07-23
pjp
1370
2020-07-23
pjp
if (istcp) {
1371
2020-07-23
pjp
char *tmpbuf;
1372
2020-07-23
pjp
1373
2020-07-23
pjp
tmpbuf = malloc(outlen + 2);
1374
2020-07-23
pjp
if (tmpbuf == 0) {
1375
2020-07-23
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1376
2020-07-23
pjp
}
1377
2020-07-23
pjp
pack16(tmpbuf, htons(outlen));
1378
2020-07-23
pjp
memcpy(&tmpbuf[2], reply, outlen);
1379
2020-07-23
pjp
1380
2020-07-23
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1381
2020-07-23
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1382
2020-07-23
pjp
}
1383
2020-07-23
pjp
free(tmpbuf);
1384
2020-07-23
pjp
} else {
1385
2020-07-23
pjp
if (q->rawsocket) {
1386
2020-07-23
pjp
*sretlen = retlen = outlen;
1387
2020-07-23
pjp
} else {
1388
2020-07-23
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1389
2020-07-23
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1390
2020-07-23
pjp
}
1391
2020-07-23
pjp
}
1392
2020-07-23
pjp
}
1393
2020-07-23
pjp
1394
2020-07-23
pjp
1395
2020-07-23
pjp
return (retlen);
1396
2020-07-23
pjp
}
1397
2020-07-23
pjp
1398
2015-06-27
pjp
/*
1399
2015-06-27
pjp
* REPLY_NSEC() - replies a DNS question (*q) on socket (so)
1400
2015-06-27
pjp
*
1401
2015-06-27
pjp
*/
1402
2015-06-27
pjp
1403
2015-06-27
pjp
int
1404
2020-07-21
pjp
reply_nsec(struct sreply *sreply, int *sretlen, ddDB *db)
1405
2015-06-27
pjp
{
1406
2015-06-27
pjp
char *reply = sreply->replybuf;
1407
2015-06-27
pjp
struct dns_header *odh;
1408
2015-06-27
pjp
u_int16_t outlen = 0;
1409
2015-06-27
pjp
int a_count;
1410
2015-06-27
pjp
1411
2015-06-27
pjp
struct answer {
1412
2015-06-27
pjp
char name[2];
1413
2015-06-27
pjp
u_int16_t type;
1414
2015-06-27
pjp
u_int16_t class;
1415
2015-06-27
pjp
u_int32_t ttl;
1416
2015-06-27
pjp
u_int16_t rdlength; /* 12 */
1417
2015-06-27
pjp
} __attribute__((packed));
1418
2015-06-27
pjp
1419
2015-06-27
pjp
struct answer *answer;
1420
2015-06-27
pjp
1421
2015-06-27
pjp
int so = sreply->so;
1422
2015-06-27
pjp
char *buf = sreply->buf;
1423
2015-06-27
pjp
int len = sreply->len;
1424
2015-06-27
pjp
struct question *q = sreply->q;
1425
2015-06-27
pjp
struct sockaddr *sa = sreply->sa;
1426
2015-06-27
pjp
int salen = sreply->salen;
1427
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
1428
2019-02-15
pjp
struct rrset *rrset = NULL;
1429
2019-02-15
pjp
struct rr *rrp = NULL;
1430
2015-06-27
pjp
1431
2015-06-27
pjp
int istcp = sreply->istcp;
1432
2015-06-27
pjp
int replysize = 512;
1433
2015-06-27
pjp
int retlen = -1;
1434
2017-09-18
pjp
u_int16_t rollback;
1435
2019-02-15
pjp
int ndnlen, bitmaplen;
1436
2020-07-06
pjp
time_t now;
1437
2015-06-27
pjp
1438
2020-07-06
pjp
now = time(NULL);
1439
2020-07-06
pjp
1440
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_A)) == 0)
1441
2015-06-27
pjp
return -1;
1442
2015-06-27
pjp
1443
2015-06-27
pjp
if (istcp) {
1444
2015-06-27
pjp
replysize = 65535;
1445
2015-06-27
pjp
}
1446
2015-06-27
pjp
1447
2015-06-27
pjp
if (!istcp && q->edns0len > 512)
1448
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
1449
2015-06-27
pjp
1450
2015-06-27
pjp
odh = (struct dns_header *)&reply[0];
1451
2015-06-27
pjp
1452
2015-06-27
pjp
outlen = sizeof(struct dns_header);
1453
2015-06-27
pjp
1454
2015-06-27
pjp
if (len > replysize) {
1455
2015-06-27
pjp
return (retlen);
1456
2015-06-27
pjp
}
1457
2015-06-27
pjp
1458
2015-06-27
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1459
2015-06-27
pjp
1460
2015-06-27
pjp
outlen += (q->hdr->namelen + 4);
1461
2017-09-18
pjp
rollback = outlen;
1462
2015-06-27
pjp
1463
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1464
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
1465
2015-06-27
pjp
1466
2015-06-27
pjp
odh->question = htons(1);
1467
2015-06-27
pjp
odh->answer = htons(1);
1468
2015-06-27
pjp
odh->nsrr = 0;
1469
2015-06-27
pjp
odh->additional = 0;
1470
2015-06-27
pjp
1471
2015-06-27
pjp
/* skip dns header, question name, qtype and qclass */
1472
2015-06-27
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1473
2015-06-27
pjp
q->hdr->namelen + 4);
1474
2015-06-27
pjp
1475
2015-06-27
pjp
a_count = 0;
1476
2015-06-27
pjp
1477
2019-02-15
pjp
rrp = TAILQ_FIRST(&rrset->rr_head);
1478
2019-02-27
pjp
if (rrp == 0)
1479
2019-02-15
pjp
return -1;
1480
2019-02-15
pjp
1481
2019-02-15
pjp
ndnlen = ((struct nsec *)rrp->rdata)->ndn_len;
1482
2019-02-15
pjp
bitmaplen = ((struct nsec *)rrp->rdata)->bitmap_len;
1483
2019-02-15
pjp
1484
2019-02-15
pjp
if ((outlen + sizeof(struct answer) + ndnlen + bitmaplen) > replysize) {
1485
2015-06-27
pjp
NTOHS(odh->query);
1486
2015-06-27
pjp
SET_DNS_TRUNCATION(odh);
1487
2015-06-27
pjp
HTONS(odh->query);
1488
2017-09-18
pjp
odh->answer = 0;
1489
2017-09-18
pjp
odh->nsrr = 0;
1490
2017-09-18
pjp
odh->additional = 0;
1491
2017-09-18
pjp
outlen = rollback;
1492
2015-06-27
pjp
goto out;
1493
2015-06-27
pjp
}
1494
2015-06-27
pjp
1495
2015-06-27
pjp
/*
1496
2015-06-27
pjp
* answer->name is a pointer to the request (0xc00c)
1497
2015-06-27
pjp
*/
1498
2015-06-27
pjp
1499
2015-06-27
pjp
answer->name[0] = 0xc0; /* 1 byte */
1500
2015-06-27
pjp
answer->name[1] = 0x0c; /* 2 bytes */
1501
2015-06-27
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
1502
2015-06-27
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
1503
2019-02-15
pjp
1504
2020-07-06
pjp
if (q->aa)
1505
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl); /* 10 b */
1506
2020-07-06
pjp
else
1507
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
1508
2020-07-06
pjp
1509
2019-02-15
pjp
answer->rdlength = htons(ndnlen + bitmaplen);
1510
2015-06-27
pjp
1511
2015-06-27
pjp
outlen += sizeof(struct answer);
1512
2015-06-27
pjp
1513
2019-02-15
pjp
memcpy(&reply[outlen], ((struct nsec *)rrp->rdata)->next_domain_name,
1514
2019-02-15
pjp
ndnlen);
1515
2015-06-27
pjp
1516
2019-02-15
pjp
outlen += ndnlen;
1517
2015-06-27
pjp
1518
2019-02-15
pjp
memcpy(&reply[outlen], ((struct nsec *)rrp->rdata)->bitmap, bitmaplen);
1519
2019-02-15
pjp
outlen += bitmaplen;
1520
2015-06-27
pjp
1521
2015-06-27
pjp
a_count++;
1522
2015-06-27
pjp
1523
2015-06-27
pjp
/* set new offset for answer */
1524
2015-06-27
pjp
answer = (struct answer *)&reply[outlen];
1525
2015-06-27
pjp
1526
2015-06-27
pjp
1527
2015-06-27
pjp
/* Add RRSIG reply_nsec */
1528
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
1529
2015-06-27
pjp
int tmplen = 0;
1530
2015-06-27
pjp
int origlen = outlen;
1531
2020-04-01
pjp
int retcount;
1532
2015-06-27
pjp
1533
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_NSEC, rbt, reply, replysize, outlen, &retcount, q->aa);
1534
2015-06-27
pjp
1535
2018-02-27
pjp
if (tmplen == 0) {
1536
2020-07-08
pjp
1537
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
1538
2020-07-08
pjp
if (q->aa != 1)
1539
2020-07-08
pjp
return -1;
1540
2020-07-08
pjp
1541
2018-02-27
pjp
NTOHS(odh->query);
1542
2018-02-27
pjp
SET_DNS_TRUNCATION(odh);
1543
2018-02-27
pjp
HTONS(odh->query);
1544
2018-02-27
pjp
odh->answer = 0;
1545
2018-02-27
pjp
odh->nsrr = 0;
1546
2018-02-27
pjp
odh->additional = 0;
1547
2018-02-27
pjp
outlen = rollback;
1548
2018-02-27
pjp
goto out;
1549
2015-06-27
pjp
}
1550
2015-06-27
pjp
1551
2018-02-27
pjp
outlen = tmplen;
1552
2018-02-27
pjp
1553
2018-02-27
pjp
if (outlen > origlen)
1554
2020-04-01
pjp
odh->answer = htons(a_count + retcount + 1);
1555
2018-02-27
pjp
1556
2015-11-14
pjp
}
1557
2015-11-14
pjp
1558
2015-11-14
pjp
out:
1559
2015-06-27
pjp
if (q->edns0len) {
1560
2015-06-27
pjp
/* tag on edns0 opt record */
1561
2015-06-27
pjp
odh->additional = htons(1);
1562
2015-06-27
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1563
2015-06-27
pjp
}
1564
2015-06-27
pjp
1565
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
1566
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
1567
2019-02-24
pjp
1568
2019-02-24
pjp
NTOHS(odh->additional);
1569
2019-02-24
pjp
odh->additional++;
1570
2019-02-24
pjp
HTONS(odh->additional);
1571
2019-02-24
pjp
}
1572
2019-02-24
pjp
1573
2015-12-19
pjp
if (istcp) {
1574
2015-12-19
pjp
char *tmpbuf;
1575
2015-12-19
pjp
1576
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
1577
2019-02-27
pjp
if (tmpbuf == 0) {
1578
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1579
2015-12-19
pjp
}
1580
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
1581
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
1582
2015-12-19
pjp
1583
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1584
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1585
2015-12-19
pjp
}
1586
2015-12-19
pjp
free(tmpbuf);
1587
2015-12-19
pjp
} else {
1588
2020-07-21
pjp
if (q->rawsocket) {
1589
2020-07-21
pjp
*sretlen = retlen = outlen;
1590
2020-07-21
pjp
} else {
1591
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1592
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1593
2020-07-21
pjp
}
1594
2015-06-25
pjp
}
1595
2015-12-19
pjp
}
1596
2015-06-25
pjp
1597
2015-06-25
pjp
1598
2015-06-25
pjp
return (retlen);
1599
2015-06-25
pjp
}
1600
2015-06-25
pjp
1601
2015-06-25
pjp
/*
1602
2015-06-25
pjp
* REPLY_DS() - replies a DNS question (*q) on socket (so)
1603
2015-06-25
pjp
*
1604
2015-06-25
pjp
*/
1605
2015-06-25
pjp
1606
2015-06-25
pjp
int
1607
2020-07-21
pjp
reply_ds(struct sreply *sreply, int *sretlen, ddDB *db)
1608
2015-06-25
pjp
{
1609
2015-06-25
pjp
char *reply = sreply->replybuf;
1610
2015-06-25
pjp
struct dns_header *odh;
1611
2015-06-25
pjp
u_int16_t outlen = 0;
1612
2015-06-25
pjp
int a_count;
1613
2015-06-25
pjp
1614
2015-06-25
pjp
struct answer {
1615
2015-06-25
pjp
char name[2];
1616
2015-06-25
pjp
u_int16_t type;
1617
2015-06-25
pjp
u_int16_t class;
1618
2015-06-25
pjp
u_int32_t ttl;
1619
2015-06-25
pjp
u_int16_t rdlength; /* 12 */
1620
2015-06-25
pjp
u_int16_t key_tag;
1621
2015-06-25
pjp
u_int8_t algorithm;
1622
2015-06-25
pjp
u_int8_t digest_type;
1623
2015-06-25
pjp
} __attribute__((packed));
1624
2015-06-25
pjp
1625
2015-06-25
pjp
struct answer *answer;
1626
2015-06-25
pjp
1627
2015-06-25
pjp
int so = sreply->so;
1628
2015-06-25
pjp
char *buf = sreply->buf;
1629
2015-06-25
pjp
int len = sreply->len;
1630
2015-06-25
pjp
struct question *q = sreply->q;
1631
2015-06-25
pjp
struct sockaddr *sa = sreply->sa;
1632
2015-06-25
pjp
int salen = sreply->salen;
1633
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
1634
2019-02-15
pjp
struct rrset *rrset = NULL;
1635
2019-02-15
pjp
struct rr *rrp = NULL;
1636
2015-06-25
pjp
1637
2015-06-25
pjp
int istcp = sreply->istcp;
1638
2015-06-25
pjp
int replysize = 512;
1639
2015-06-25
pjp
int retlen = -1;
1640
2017-09-18
pjp
u_int16_t rollback;
1641
2020-07-06
pjp
time_t now;
1642
2015-06-25
pjp
1643
2020-07-06
pjp
now = time(NULL);
1644
2020-07-06
pjp
1645
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_DS)) == 0)
1646
2015-06-25
pjp
return -1;
1647
2015-06-25
pjp
1648
2015-06-25
pjp
if (istcp) {
1649
2015-06-25
pjp
replysize = 65535;
1650
2015-06-24
pjp
}
1651
2015-06-25
pjp
1652
2015-06-25
pjp
if (!istcp && q->edns0len > 512)
1653
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
1654
2015-06-25
pjp
1655
2015-06-25
pjp
odh = (struct dns_header *)&reply[0];
1656
2015-06-25
pjp
1657
2015-06-25
pjp
outlen = sizeof(struct dns_header);
1658
2015-06-25
pjp
1659
2015-06-25
pjp
if (len > replysize) {
1660
2015-06-25
pjp
return (retlen);
1661
2015-06-24
pjp
}
1662
2015-06-25
pjp
1663
2015-06-25
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1664
2015-06-25
pjp
1665
2015-06-25
pjp
outlen += (q->hdr->namelen + 4);
1666
2017-09-18
pjp
rollback = outlen;
1667
2015-06-25
pjp
1668
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1669
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
1670
2015-06-25
pjp
1671
2015-06-25
pjp
odh->question = htons(1);
1672
2015-06-25
pjp
odh->nsrr = 0;
1673
2015-06-25
pjp
odh->additional = 0;
1674
2015-06-25
pjp
1675
2015-06-25
pjp
/* skip dns header, question name, qtype and qclass */
1676
2015-06-25
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1677
2015-06-25
pjp
q->hdr->namelen + 4);
1678
2015-06-25
pjp
1679
2015-06-25
pjp
a_count = 0;
1680
2015-06-25
pjp
1681
2019-02-15
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
1682
2015-06-25
pjp
if ((outlen + sizeof(struct answer) +
1683
2019-02-15
pjp
((struct ds *)rrp->rdata)->digestlen) > replysize) {
1684
2015-06-25
pjp
NTOHS(odh->query);
1685
2015-06-25
pjp
SET_DNS_TRUNCATION(odh);
1686
2015-06-25
pjp
HTONS(odh->query);
1687
2017-09-18
pjp
odh->answer = 0;
1688
2017-09-18
pjp
odh->nsrr = 0;
1689
2017-09-18
pjp
odh->additional = 0;
1690
2017-09-18
pjp
outlen = rollback;
1691
2015-06-25
pjp
goto out;
1692
2015-06-25
pjp
}
1693
2015-06-25
pjp
1694
2015-06-25
pjp
/*
1695
2015-06-25
pjp
* answer->name is a pointer to the request (0xc00c)
1696
2015-06-25
pjp
*/
1697
2015-06-25
pjp
1698
2015-06-25
pjp
answer->name[0] = 0xc0; /* 1 byte */
1699
2015-06-25
pjp
answer->name[1] = 0x0c; /* 2 bytes */
1700
2015-06-25
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
1701
2015-06-25
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
1702
2019-02-15
pjp
1703
2020-07-06
pjp
if (q->aa)
1704
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl); /* 10 */
1705
2020-07-06
pjp
else
1706
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
1707
2020-07-06
pjp
1708
2020-07-06
pjp
1709
2019-02-15
pjp
answer->rdlength = htons(((struct ds *)rrp->rdata)->digestlen + 4); /* 12 bytes */
1710
2015-06-25
pjp
1711
2019-02-15
pjp
answer->key_tag = htons(((struct ds *)rrp->rdata)->key_tag);
1712
2019-02-15
pjp
answer->algorithm = ((struct ds *)rrp->rdata)->algorithm;
1713
2019-02-15
pjp
answer->digest_type = ((struct ds *)rrp->rdata)->digest_type;
1714
2015-06-25
pjp
1715
2015-06-25
pjp
outlen += sizeof(struct answer);
1716
2015-06-25
pjp
1717
2019-02-15
pjp
memcpy(&reply[outlen], ((struct ds *)rrp->rdata)->digest,
1718
2019-02-15
pjp
((struct ds *)rrp->rdata)->digestlen);
1719
2015-06-25
pjp
1720
2019-02-15
pjp
outlen += ((struct ds *)rrp->rdata)->digestlen;
1721
2015-06-25
pjp
1722
2015-06-25
pjp
a_count++;
1723
2015-06-25
pjp
/* set new offset for answer */
1724
2015-06-25
pjp
answer = (struct answer *)&reply[outlen];
1725
2019-02-15
pjp
}
1726
2015-06-25
pjp
1727
2015-06-25
pjp
odh->answer = htons(a_count);
1728
2015-06-25
pjp
1729
2015-06-27
pjp
/* Add RRSIG reply_ds */
1730
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
1731
2015-06-25
pjp
int tmplen = 0;
1732
2015-06-25
pjp
int origlen = outlen;
1733
2020-04-01
pjp
int retcount;
1734
2015-06-25
pjp
1735
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_DS, rbt, reply, replysize, outlen, &retcount, q->aa);
1736
2015-06-25
pjp
1737
2018-03-03
pjp
if (tmplen == 0) {
1738
2020-07-08
pjp
1739
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
1740
2020-07-08
pjp
if (q->aa != 1)
1741
2020-07-08
pjp
return -1;
1742
2020-07-08
pjp
1743
2018-03-03
pjp
NTOHS(odh->query);
1744
2018-03-03
pjp
SET_DNS_TRUNCATION(odh);
1745
2018-03-03
pjp
HTONS(odh->query);
1746
2018-03-03
pjp
odh->answer = 0;
1747
2018-03-03
pjp
odh->nsrr = 0;
1748
2018-03-03
pjp
odh->additional = 0;
1749
2018-03-03
pjp
outlen = rollback;
1750
2018-03-03
pjp
goto out;
1751
2015-06-25
pjp
}
1752
2015-06-25
pjp
1753
2018-03-03
pjp
outlen = tmplen;
1754
2018-03-03
pjp
1755
2019-11-11
pjp
if (outlen > origlen) {
1756
2019-11-11
pjp
NTOHS(odh->answer);
1757
2020-04-01
pjp
odh->answer += retcount;
1758
2019-11-11
pjp
HTONS(odh->answer);
1759
2019-11-11
pjp
}
1760
2015-11-14
pjp
}
1761
2015-06-25
pjp
1762
2015-11-14
pjp
out:
1763
2015-06-25
pjp
if (q->edns0len) {
1764
2015-06-25
pjp
/* tag on edns0 opt record */
1765
2015-06-25
pjp
odh->additional = htons(1);
1766
2015-06-25
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1767
2015-06-24
pjp
}
1768
2015-06-25
pjp
1769
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
1770
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
1771
2019-02-24
pjp
1772
2019-02-24
pjp
NTOHS(odh->additional);
1773
2019-02-24
pjp
odh->additional++;
1774
2019-02-24
pjp
HTONS(odh->additional);
1775
2019-02-24
pjp
}
1776
2019-02-24
pjp
1777
2015-12-19
pjp
if (istcp) {
1778
2015-12-19
pjp
char *tmpbuf;
1779
2015-12-19
pjp
1780
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
1781
2019-02-27
pjp
if (tmpbuf == 0) {
1782
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1783
2015-12-19
pjp
}
1784
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
1785
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
1786
2015-12-19
pjp
1787
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1788
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1789
2015-12-19
pjp
}
1790
2015-12-19
pjp
free(tmpbuf);
1791
2015-12-19
pjp
} else {
1792
2020-07-21
pjp
if (q->rawsocket) {
1793
2020-07-21
pjp
*sretlen = retlen = outlen;
1794
2020-07-21
pjp
} else {
1795
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1796
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1797
2020-07-21
pjp
}
1798
2015-06-25
pjp
}
1799
2015-12-19
pjp
}
1800
2015-06-25
pjp
1801
2019-02-15
pjp
rotate_rr(rrset);
1802
2019-02-15
pjp
1803
2015-06-25
pjp
return (retlen);
1804
2015-06-25
pjp
}
1805
2015-06-25
pjp
1806
2015-06-25
pjp
/*
1807
2015-06-25
pjp
* REPLY_DNSKEY() - replies a DNS question (*q) on socket (so)
1808
2015-06-25
pjp
*
1809
2015-06-25
pjp
*/
1810
2015-06-25
pjp
1811
2015-06-25
pjp
int
1812
2020-07-21
pjp
reply_dnskey(struct sreply *sreply, int *sretlen, ddDB *db)
1813
2015-06-25
pjp
{
1814
2015-06-25
pjp
char *reply = sreply->replybuf;
1815
2015-06-25
pjp
struct dns_header *odh;
1816
2015-06-25
pjp
u_int16_t outlen = 0;
1817
2019-02-15
pjp
int dnskey_count;
1818
2015-06-25
pjp
1819
2015-06-25
pjp
struct answer {
1820
2015-06-25
pjp
char name[2];
1821
2015-06-25
pjp
u_int16_t type;
1822
2015-06-25
pjp
u_int16_t class;
1823
2015-06-25
pjp
u_int32_t ttl;
1824
2015-06-25
pjp
u_int16_t rdlength; /* 12 */
1825
2015-06-25
pjp
u_int16_t flags;
1826
2015-06-25
pjp
u_int8_t protocol;
1827
2015-06-25
pjp
u_int8_t algorithm;
1828
2015-06-25
pjp
} __attribute__((packed));
1829
2015-06-25
pjp
1830
2015-06-25
pjp
struct answer *answer;
1831
2015-06-25
pjp
1832
2015-06-25
pjp
int so = sreply->so;
1833
2015-06-25
pjp
char *buf = sreply->buf;
1834
2015-06-25
pjp
int len = sreply->len;
1835
2015-06-25
pjp
struct question *q = sreply->q;
1836
2015-06-25
pjp
struct sockaddr *sa = sreply->sa;
1837
2015-06-25
pjp
int salen = sreply->salen;
1838
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
1839
2019-02-15
pjp
struct rrset *rrset = NULL;
1840
2019-02-15
pjp
struct rr *rrp = NULL;
1841
2015-06-25
pjp
1842
2015-06-25
pjp
int istcp = sreply->istcp;
1843
2015-06-25
pjp
int replysize = 512;
1844
2015-06-25
pjp
int retlen = -1;
1845
2019-02-15
pjp
int rrsig_count = 0;
1846
2017-09-18
pjp
u_int16_t rollback;
1847
2020-07-06
pjp
time_t now;
1848
2015-06-25
pjp
1849
2020-07-06
pjp
now = time(NULL);
1850
2020-07-06
pjp
1851
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_DNSKEY)) == 0)
1852
2015-06-25
pjp
return -1;
1853
2015-06-25
pjp
1854
2015-06-25
pjp
if (istcp) {
1855
2015-06-25
pjp
replysize = 65535;
1856
2015-06-25
pjp
}
1857
2015-06-25
pjp
1858
2015-06-25
pjp
if (!istcp && q->edns0len > 512)
1859
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
1860
2015-06-25
pjp
1861
2015-06-25
pjp
odh = (struct dns_header *)&reply[0];
1862
2015-06-25
pjp
1863
2015-06-25
pjp
outlen = sizeof(struct dns_header);
1864
2015-06-25
pjp
1865
2015-06-25
pjp
if (len > replysize) {
1866
2015-06-25
pjp
return (retlen);
1867
2015-06-25
pjp
}
1868
2015-06-25
pjp
1869
2015-06-25
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1870
2015-06-25
pjp
1871
2015-06-25
pjp
outlen += (q->hdr->namelen + 4);
1872
2017-09-18
pjp
rollback = outlen;
1873
2015-06-25
pjp
1874
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1875
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
1876
2015-06-25
pjp
1877
2015-06-25
pjp
odh->question = htons(1);
1878
2019-02-15
pjp
odh->answer = htons(0);
1879
2015-06-25
pjp
odh->nsrr = 0;
1880
2015-06-25
pjp
odh->additional = 0;
1881
2015-06-25
pjp
1882
2015-06-25
pjp
/* skip dns header, question name, qtype and qclass */
1883
2015-06-25
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1884
2015-06-25
pjp
q->hdr->namelen + 4);
1885
2015-06-25
pjp
1886
2019-02-15
pjp
dnskey_count = 0;
1887
2015-06-25
pjp
1888
2019-02-15
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
1889
2015-06-25
pjp
if ((outlen + sizeof(struct answer) +
1890
2019-02-15
pjp
((struct dnskey *)rrp->rdata)->publickey_len) > replysize) {
1891
2015-06-25
pjp
NTOHS(odh->query);
1892
2015-06-25
pjp
SET_DNS_TRUNCATION(odh);
1893
2015-06-25
pjp
HTONS(odh->query);
1894
2017-09-18
pjp
odh->answer = 0;
1895
2017-09-18
pjp
odh->nsrr = 0;
1896
2017-09-18
pjp
odh->additional = 0;
1897
2017-09-18
pjp
outlen = rollback;
1898
2015-06-25
pjp
goto out;
1899
2015-06-25
pjp
}
1900
2015-06-25
pjp
1901
2015-06-25
pjp
/*
1902
2015-06-25
pjp
* answer->name is a pointer to the request (0xc00c)
1903
2015-06-25
pjp
*/
1904
2015-06-25
pjp
1905
2015-06-25
pjp
answer->name[0] = 0xc0; /* 1 byte */
1906
2015-06-25
pjp
answer->name[1] = 0x0c; /* 2 bytes */
1907
2015-06-25
pjp
answer->type = q->hdr->qtype; /* 4 bytes */
1908
2015-06-25
pjp
answer->class = q->hdr->qclass; /* 6 bytes */
1909
2019-02-15
pjp
1910
2020-07-06
pjp
if (q->aa)
1911
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl);
1912
2020-07-06
pjp
else
1913
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
1914
2020-07-06
pjp
1915
2019-02-15
pjp
answer->rdlength = htons(((struct dnskey *)rrp->rdata)->publickey_len + 4); /* 12 bytes */
1916
2015-06-25
pjp
1917
2019-02-15
pjp
answer->flags = htons(((struct dnskey *)rrp->rdata)->flags);
1918
2019-02-15
pjp
answer->protocol = ((struct dnskey *)rrp->rdata)->protocol;
1919
2019-02-15
pjp
answer->algorithm = ((struct dnskey *)rrp->rdata)->algorithm;
1920
2015-06-25
pjp
1921
2015-06-25
pjp
outlen += sizeof(struct answer);
1922
2015-06-25
pjp
1923
2019-02-15
pjp
memcpy(&reply[outlen], ((struct dnskey*)rrp->rdata)->public_key,
1924
2019-02-15
pjp
((struct dnskey *)rrp->rdata)->publickey_len);
1925
2015-06-25
pjp
1926
2019-02-15
pjp
outlen += ((struct dnskey *)rrp->rdata)->publickey_len;
1927
2015-06-25
pjp
1928
2019-02-15
pjp
dnskey_count++;
1929
2015-06-25
pjp
/* set new offset for answer */
1930
2015-06-25
pjp
answer = (struct answer *)&reply[outlen];
1931
2019-02-15
pjp
}
1932
2015-06-25
pjp
1933
2019-02-15
pjp
odh->answer = htons(dnskey_count);
1934
2019-02-15
pjp
1935
2015-06-27
pjp
/* Add RRSIG reply_dnskey */
1936
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
1937
2015-06-25
pjp
int tmplen = 0;
1938
2015-06-25
pjp
int origlen = outlen;
1939
2018-02-27
pjp
1940
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_DNSKEY, rbt, reply, replysize, outlen, &rrsig_count, q->aa);
1941
2015-06-25
pjp
1942
2020-04-01
pjp
if (tmplen == 0) {
1943
2020-07-08
pjp
1944
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
1945
2020-07-08
pjp
if (q->aa != 1)
1946
2020-07-08
pjp
return -1;
1947
2020-07-08
pjp
1948
2020-04-01
pjp
NTOHS(odh->query);
1949
2020-04-01
pjp
SET_DNS_TRUNCATION(odh);
1950
2020-04-01
pjp
HTONS(odh->query);
1951
2020-04-01
pjp
odh->answer = 0;
1952
2020-04-01
pjp
odh->nsrr = 0;
1953
2020-04-01
pjp
odh->additional = 0;
1954
2020-04-01
pjp
outlen = rollback;
1955
2020-04-01
pjp
goto out;
1956
2015-06-25
pjp
}
1957
2015-06-25
pjp
1958
2020-04-01
pjp
outlen = tmplen;
1959
2020-04-01
pjp
1960
2020-04-01
pjp
if (outlen > origlen)
1961
2020-04-01
pjp
odh->answer = htons(dnskey_count + rrsig_count);
1962
2015-11-10
pjp
}
1963
2015-11-10
pjp
1964
2015-11-14
pjp
out:
1965
2015-06-25
pjp
if (q->edns0len) {
1966
2015-06-25
pjp
/* tag on edns0 opt record */
1967
2015-06-25
pjp
odh->additional = htons(1);
1968
2015-06-25
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1969
2015-06-25
pjp
}
1970
2015-06-25
pjp
1971
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
1972
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
1973
2019-02-24
pjp
1974
2019-02-24
pjp
NTOHS(odh->additional);
1975
2019-02-24
pjp
odh->additional++;
1976
2019-02-24
pjp
HTONS(odh->additional);
1977
2019-02-24
pjp
}
1978
2019-02-24
pjp
1979
2015-12-19
pjp
if (istcp) {
1980
2015-12-19
pjp
char *tmpbuf;
1981
2015-12-19
pjp
1982
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
1983
2019-02-27
pjp
if (tmpbuf == 0) {
1984
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1985
2015-12-19
pjp
}
1986
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
1987
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
1988
2015-12-19
pjp
1989
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1990
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1991
2015-12-19
pjp
}
1992
2015-12-19
pjp
free(tmpbuf);
1993
2015-12-19
pjp
} else {
1994
2020-07-21
pjp
if (q->rawsocket) {
1995
2020-07-21
pjp
*sretlen = retlen = outlen;
1996
2020-07-21
pjp
} else {
1997
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1998
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1999
2020-07-21
pjp
}
2000
2015-06-25
pjp
}
2001
2015-12-19
pjp
}
2002
2015-06-25
pjp
2003
2015-06-25
pjp
return (retlen);
2004
2015-06-25
pjp
}
2005
2015-06-25
pjp
2006
2015-06-25
pjp
/*
2007
2015-06-25
pjp
* REPLY_RRSIG() - replies a DNS question (*q) on socket (so)
2008
2015-06-25
pjp
*
2009
2015-06-25
pjp
*/
2010
2015-06-25
pjp
2011
2015-06-25
pjp
2012
2015-06-25
pjp
int
2013
2020-07-21
pjp
reply_rrsig(struct sreply *sreply, int *sretlen, ddDB *db)
2014
2015-06-25
pjp
{
2015
2015-06-25
pjp
char *reply = sreply->replybuf;
2016
2015-06-25
pjp
struct dns_header *odh;
2017
2015-06-25
pjp
u_int16_t outlen = 0;
2018
2015-06-25
pjp
int a_count;
2019
2015-06-25
pjp
2020
2015-06-25
pjp
struct answer {
2021
2015-06-25
pjp
char name[2];
2022
2015-06-25
pjp
u_int16_t type;
2023
2015-06-25
pjp
u_int16_t class;
2024
2015-06-25
pjp
u_int32_t ttl;
2025
2015-06-25
pjp
u_int16_t rdlength; /* 12 */
2026
2015-06-25
pjp
in_addr_t rdata; /* 16 */
2027
2015-06-25
pjp
} __attribute__((packed));
2028
2015-06-25
pjp
2029
2015-06-25
pjp
int so = sreply->so;
2030
2015-06-25
pjp
char *buf = sreply->buf;
2031
2015-06-25
pjp
int len = sreply->len;
2032
2015-06-25
pjp
struct question *q = sreply->q;
2033
2015-06-25
pjp
struct sockaddr *sa = sreply->sa;
2034
2015-06-25
pjp
int salen = sreply->salen;
2035
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
2036
2015-06-25
pjp
2037
2015-06-25
pjp
int istcp = sreply->istcp;
2038
2015-06-25
pjp
int replysize = 512;
2039
2015-06-25
pjp
int retlen = -1;
2040
2015-06-25
pjp
int tmplen = 0;
2041
2017-09-18
pjp
u_int16_t rollback;
2042
2015-06-25
pjp
2043
2019-02-27
pjp
if ((find_rr(rbt, DNS_TYPE_RRSIG)) == 0)
2044
2015-06-25
pjp
return -1;
2045
2015-06-25
pjp
2046
2015-06-25
pjp
if (istcp) {
2047
2015-06-25
pjp
replysize = 65535;
2048
2015-06-25
pjp
}
2049
2015-06-25
pjp
2050
2015-06-25
pjp
if (! istcp && q->edns0len > 512)
2051
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
2052
2015-06-25
pjp
2053
2015-06-25
pjp
odh = (struct dns_header *)&reply[0];
2054
2015-06-25
pjp
2055
2015-06-25
pjp
outlen = sizeof(struct dns_header);
2056
2015-06-25
pjp
2057
2015-06-25
pjp
if (len > replysize) {
2058
2015-06-25
pjp
return (retlen);
2059
2015-06-25
pjp
}
2060
2015-06-25
pjp
2061
2015-06-25
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2062
2015-06-25
pjp
2063
2015-06-25
pjp
outlen += (q->hdr->namelen + 4);
2064
2017-09-18
pjp
rollback = outlen;
2065
2015-06-25
pjp
2066
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2067
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
2068
2015-06-25
pjp
2069
2015-06-25
pjp
odh->question = htons(1);
2070
2015-06-25
pjp
odh->nsrr = 0;
2071
2015-06-25
pjp
odh->additional = 0;
2072
2015-06-25
pjp
2073
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, -1, rbt, reply, replysize, outlen, &a_count, q->aa);
2074
2020-04-01
pjp
if (tmplen == 0) {
2075
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2076
2020-07-08
pjp
if (q->aa != 1)
2077
2020-07-08
pjp
return -1;
2078
2020-07-08
pjp
2079
2020-04-01
pjp
NTOHS(odh->query);
2080
2020-04-01
pjp
SET_DNS_TRUNCATION(odh);
2081
2020-04-01
pjp
HTONS(odh->query);
2082
2020-04-01
pjp
odh->answer = 0;
2083
2020-04-01
pjp
odh->nsrr = 0;
2084
2020-04-01
pjp
odh->additional = 0;
2085
2020-04-01
pjp
outlen = rollback;
2086
2020-04-01
pjp
goto out;
2087
2015-06-25
pjp
}
2088
2020-04-01
pjp
outlen = tmplen;
2089
2015-06-25
pjp
2090
2015-06-24
pjp
odh->answer = htons(a_count);
2091
2015-06-24
pjp
2092
2015-11-14
pjp
out:
2093
2015-06-24
pjp
if (q->edns0len) {
2094
2015-06-24
pjp
/* tag on edns0 opt record */
2095
2015-06-24
pjp
odh->additional = htons(1);
2096
2015-06-24
pjp
outlen = additional_opt(q, reply, replysize, outlen);
2097
2015-06-24
pjp
}
2098
2015-06-24
pjp
2099
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
2100
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
2101
2019-02-24
pjp
2102
2019-02-24
pjp
NTOHS(odh->additional);
2103
2019-02-24
pjp
odh->additional++;
2104
2019-02-24
pjp
HTONS(odh->additional);
2105
2019-02-24
pjp
}
2106
2019-02-24
pjp
2107
2015-12-19
pjp
if (istcp) {
2108
2015-12-19
pjp
char *tmpbuf;
2109
2015-12-19
pjp
2110
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
2111
2019-02-27
pjp
if (tmpbuf == 0) {
2112
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2113
2015-12-19
pjp
}
2114
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
2115
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
2116
2015-12-19
pjp
2117
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2118
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2119
2015-12-19
pjp
}
2120
2015-12-19
pjp
free(tmpbuf);
2121
2015-12-19
pjp
} else {
2122
2020-07-21
pjp
if (q->rawsocket) {
2123
2020-07-21
pjp
*sretlen = retlen = outlen;
2124
2020-07-21
pjp
} else {
2125
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2126
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2127
2020-07-21
pjp
}
2128
2015-06-24
pjp
}
2129
2015-12-19
pjp
}
2130
2015-06-24
pjp
2131
2015-06-20
pjp
return (retlen);
2132
2015-06-20
pjp
2133
2015-06-20
pjp
2134
2015-06-20
pjp
}
2135
2015-06-20
pjp
2136
2015-06-20
pjp
/*
2137
2014-11-14
pjp
* REPLY_AAAA() - replies a DNS question (*q) on socket (so)
2138
2014-11-14
pjp
*
2139
2014-11-14
pjp
*/
2140
2014-11-14
pjp
2141
2014-11-14
pjp
int
2142
2020-07-21
pjp
reply_aaaa(struct sreply *sreply, int *sretlen, ddDB *db)
2143
2014-11-14
pjp
{
2144
2014-11-14
pjp
char *reply = sreply->replybuf;
2145
2014-11-14
pjp
struct dns_header *odh;
2146
2015-06-20
pjp
u_int16_t outlen = 0;
2147
2014-11-14
pjp
int aaaa_count;
2148
2014-11-14
pjp
2149
2014-11-14
pjp
struct answer {
2150
2014-11-14
pjp
char name[2];
2151
2014-11-14
pjp
u_int16_t type;
2152
2014-11-14
pjp
u_int16_t class;
2153
2014-11-14
pjp
u_int32_t ttl;
2154
2014-11-14
pjp
u_int16_t rdlength; /* 12 */
2155
2014-11-14
pjp
char rdata; /* 12 + 16 */
2156
2014-11-14
pjp
} __attribute__((packed));
2157
2014-11-14
pjp
2158
2014-11-14
pjp
struct answer *answer;
2159
2014-11-14
pjp
2160
2014-11-14
pjp
int so = sreply->so;
2161
2014-11-14
pjp
char *buf = sreply->buf;
2162
2014-11-14
pjp
int len = sreply->len;
2163
2014-11-14
pjp
struct question *q = sreply->q;
2164
2014-11-14
pjp
struct sockaddr *sa = sreply->sa;
2165
2014-11-14
pjp
int salen = sreply->salen;
2166
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
2167
2019-02-15
pjp
struct rr *rrp = NULL;
2168
2019-02-15
pjp
struct rrset *rrset = NULL;
2169
2014-11-14
pjp
int istcp = sreply->istcp;
2170
2014-11-14
pjp
int replysize = 512;
2171
2014-11-14
pjp
int retlen = -1;
2172
2017-09-18
pjp
u_int16_t rollback;
2173
2020-07-06
pjp
time_t now;
2174
2014-11-14
pjp
2175
2020-07-06
pjp
now = time(NULL);
2176
2020-07-06
pjp
2177
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_AAAA)) == 0)
2178
2015-06-16
pjp
return -1;
2179
2015-06-16
pjp
2180
2014-11-14
pjp
if (istcp) {
2181
2014-11-14
pjp
replysize = 65535;
2182
2014-11-14
pjp
}
2183
2014-11-14
pjp
2184
2015-06-20
pjp
if (! istcp && q->edns0len > 512)
2185
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
2186
2014-11-14
pjp
2187
2014-11-14
pjp
2188
2014-11-14
pjp
odh = (struct dns_header *)&reply[0];
2189
2014-11-14
pjp
2190
2014-11-14
pjp
outlen = sizeof(struct dns_header);
2191
2014-11-14
pjp
2192
2014-11-14
pjp
if (len > replysize) {
2193
2014-11-14
pjp
return (retlen);
2194
2014-11-14
pjp
}
2195
2014-11-14
pjp
2196
2014-11-14
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2197
2014-11-14
pjp
2198
2014-11-14
pjp
outlen += (q->hdr->namelen + 4);
2199
2017-09-18
pjp
rollback = outlen;
2200
2014-11-14
pjp
2201
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2202
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
2203
2014-11-14
pjp
2204
2014-11-14
pjp
odh->question = htons(1);
2205
2019-02-15
pjp
odh->answer = htons(0);
2206
2014-11-14
pjp
odh->nsrr = 0;
2207
2014-11-14
pjp
odh->additional = 0;
2208
2014-11-14
pjp
2209
2014-11-14
pjp
/* skip dns header, question name, qtype and qclass */
2210
2014-11-14
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2211
2014-11-14
pjp
q->hdr->namelen + 4);
2212
2014-11-14
pjp
2213
2014-11-14
pjp
2214
2014-11-14
pjp
aaaa_count = 0;
2215
2014-11-14
pjp
2216
2019-02-15
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
2217
2014-11-14
pjp
answer->name[0] = 0xc0;
2218
2014-11-14
pjp
answer->name[1] = 0x0c;
2219
2014-11-14
pjp
answer->type = q->hdr->qtype;
2220
2014-11-14
pjp
answer->class = q->hdr->qclass;
2221
2020-07-06
pjp
2222
2020-07-06
pjp
if (q->aa)
2223
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl);
2224
2020-07-06
pjp
else
2225
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
2226
2014-11-14
pjp
2227
2014-11-14
pjp
answer->rdlength = htons(sizeof(struct in6_addr));
2228
2014-11-14
pjp
2229
2019-02-15
pjp
memcpy((char *)&answer->rdata, (char *)&((struct aaaa *)rrp->rdata)->aaaa, sizeof(struct in6_addr));
2230
2014-11-14
pjp
outlen += 28;
2231
2014-11-14
pjp
2232
2015-06-27
pjp
aaaa_count++;
2233
2015-06-27
pjp
2234
2015-06-27
pjp
/* set new offset for answer */
2235
2015-06-27
pjp
answer = (struct answer *)&reply[outlen];
2236
2019-02-15
pjp
};
2237
2015-06-27
pjp
2238
2019-02-15
pjp
odh->answer = htons(aaaa_count);
2239
2019-02-15
pjp
2240
2015-06-27
pjp
/* RRSIG reply_aaaa */
2241
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
2242
2015-06-27
pjp
int tmplen = 0;
2243
2015-06-27
pjp
int origlen = outlen;
2244
2020-04-01
pjp
int retcount;
2245
2015-06-27
pjp
2246
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_AAAA, rbt, reply, replysize, outlen, &retcount, q->aa);
2247
2015-06-27
pjp
2248
2015-06-27
pjp
if (tmplen == 0) {
2249
2020-07-08
pjp
2250
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2251
2020-07-08
pjp
if (q->aa != 1)
2252
2020-07-08
pjp
return -1;
2253
2020-07-08
pjp
2254
2014-11-14
pjp
NTOHS(odh->query);
2255
2014-11-14
pjp
SET_DNS_TRUNCATION(odh);
2256
2014-11-14
pjp
HTONS(odh->query);
2257
2017-09-18
pjp
odh->answer = 0;
2258
2017-09-18
pjp
odh->nsrr = 0;
2259
2017-09-18
pjp
odh->additional = 0;
2260
2017-09-18
pjp
outlen = rollback;
2261
2014-11-14
pjp
goto out;
2262
2014-11-14
pjp
}
2263
2014-11-14
pjp
2264
2015-06-27
pjp
outlen = tmplen;
2265
2014-11-14
pjp
2266
2015-06-27
pjp
if (outlen > origlen)
2267
2020-04-01
pjp
odh->answer = htons(aaaa_count + retcount);
2268
2014-11-14
pjp
2269
2015-06-27
pjp
}
2270
2015-06-27
pjp
2271
2015-11-14
pjp
out:
2272
2014-11-14
pjp
if (q->edns0len) {
2273
2014-11-14
pjp
/* tag on edns0 opt record */
2274
2014-11-14
pjp
odh->additional = htons(1);
2275
2014-11-14
pjp
outlen = additional_opt(q, reply, replysize, outlen);
2276
2014-11-14
pjp
}
2277
2014-11-14
pjp
2278
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
2279
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
2280
2019-02-24
pjp
2281
2019-02-24
pjp
NTOHS(odh->additional);
2282
2019-02-24
pjp
odh->additional++;
2283
2019-02-24
pjp
HTONS(odh->additional);
2284
2019-02-24
pjp
}
2285
2019-02-24
pjp
2286
2019-02-24
pjp
2287
2015-12-19
pjp
if (istcp) {
2288
2015-12-19
pjp
char *tmpbuf;
2289
2015-12-19
pjp
2290
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
2291
2019-02-27
pjp
if (tmpbuf == 0) {
2292
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2293
2015-12-19
pjp
}
2294
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
2295
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
2296
2015-12-19
pjp
2297
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2298
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2299
2015-12-19
pjp
}
2300
2015-12-19
pjp
free(tmpbuf);
2301
2015-12-19
pjp
} else {
2302
2020-07-21
pjp
if (q->rawsocket) {
2303
2020-07-21
pjp
*sretlen = retlen = outlen;
2304
2020-07-21
pjp
} else {
2305
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2306
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2307
2020-07-21
pjp
}
2308
2014-11-14
pjp
}
2309
2014-11-14
pjp
}
2310
2014-11-14
pjp
2311
2019-02-15
pjp
rotate_rr(rrset);
2312
2014-11-14
pjp
2313
2014-11-14
pjp
return (retlen);
2314
2014-11-14
pjp
}
2315
2014-11-14
pjp
2316
2014-11-14
pjp
/*
2317
2014-11-14
pjp
* REPLY_MX() - replies a DNS question (*q) on socket (so)
2318
2014-11-14
pjp
*
2319
2014-11-14
pjp
*/
2320
2014-11-14
pjp
2321
2014-11-14
pjp
int
2322
2020-07-21
pjp
reply_mx(struct sreply *sreply, int *sretlen, ddDB *db)
2323
2014-11-14
pjp
{
2324
2014-11-14
pjp
char *reply = sreply->replybuf;
2325
2014-11-14
pjp
struct dns_header *odh;
2326
2014-11-14
pjp
int mx_count;
2327
2014-11-14
pjp
char *name;
2328
2015-06-20
pjp
u_int16_t outlen = 0;
2329
2014-11-14
pjp
u_int16_t namelen;
2330
2015-06-20
pjp
int tmplen = 0;
2331
2014-11-14
pjp
2332
2014-11-14
pjp
struct answer {
2333
2014-11-14
pjp
char name[2];
2334
2014-11-14
pjp
u_int16_t type;
2335
2014-11-14
pjp
u_int16_t class;
2336
2014-11-14
pjp
u_int32_t ttl;
2337
2014-11-14
pjp
u_int16_t rdlength; /* 12 */
2338
2014-11-14
pjp
u_int16_t mx_priority;
2339
2014-11-14
pjp
char exchange;
2340
2014-11-14
pjp
} __attribute__((packed));
2341
2014-11-14
pjp
2342
2014-11-14
pjp
struct answer *answer;
2343
2014-11-14
pjp
2344
2014-11-14
pjp
int so = sreply->so;
2345
2014-11-14
pjp
char *buf = sreply->buf;
2346
2014-11-14
pjp
int len = sreply->len;
2347
2014-11-14
pjp
struct question *q = sreply->q;
2348
2014-11-14
pjp
struct sockaddr *sa = sreply->sa;
2349
2014-11-14
pjp
int salen = sreply->salen;
2350
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
2351
2019-11-11
pjp
struct rbtree *rbt0 = NULL;
2352
2019-02-15
pjp
struct rrset *rrset = NULL;
2353
2019-02-15
pjp
struct rr *rrp = NULL;
2354
2014-11-14
pjp
int istcp = sreply->istcp;
2355
2014-11-14
pjp
int replysize = 512;
2356
2014-11-14
pjp
int retlen = -1;
2357
2017-09-18
pjp
u_int16_t rollback;
2358
2020-07-06
pjp
time_t now;
2359
2019-11-11
pjp
2360
2019-11-11
pjp
int addiscount;
2361
2019-11-11
pjp
2362
2019-11-11
pjp
SLIST_HEAD(, addis) addishead;
2363
2019-11-11
pjp
struct addis {
2364
2019-11-11
pjp
char name[DNS_MAXNAME];
2365
2019-11-11
pjp
int namelen;
2366
2019-11-12
pjp
int contained;
2367
2019-11-11
pjp
SLIST_ENTRY(addis) addis_entries;
2368
2019-11-11
pjp
} *ad0, *ad1;
2369
2019-11-11
pjp
2370
2019-11-11
pjp
SLIST_INIT(&addishead);
2371
2019-11-11
pjp
/* check for apex, delegations */
2372
2020-07-06
pjp
2373
2020-07-06
pjp
now = time(NULL);
2374
2016-01-29
pjp
2375
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_MX)) == 0)
2376
2015-06-16
pjp
return -1;
2377
2015-06-16
pjp
2378
2015-06-17
pjp
2379
2014-11-14
pjp
if (istcp) {
2380
2014-11-14
pjp
replysize = 65535;
2381
2014-11-14
pjp
}
2382
2014-11-14
pjp
2383
2015-06-20
pjp
if (! istcp && q->edns0len > 512)
2384
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
2385
2014-11-14
pjp
2386
2014-11-14
pjp
odh = (struct dns_header *)&reply[0];
2387
2014-11-14
pjp
2388
2014-11-14
pjp
outlen = sizeof(struct dns_header);
2389
2014-11-14
pjp
2390
2014-11-14
pjp
if (len > replysize) {
2391
2014-11-14
pjp
return (retlen);
2392
2014-11-14
pjp
}
2393
2014-11-14
pjp
2394
2014-11-14
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2395
2014-11-14
pjp
2396
2014-11-14
pjp
outlen += (q->hdr->namelen + 4);
2397
2017-09-18
pjp
rollback = outlen;
2398
2014-11-14
pjp
2399
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2400
2020-07-20
pjp
set_reply_flags(rbt, odh, q);
2401
2014-11-14
pjp
2402
2014-11-14
pjp
odh->question = htons(1);
2403
2019-02-15
pjp
odh->answer = htons(0);
2404
2014-11-14
pjp
odh->nsrr = 0;
2405
2014-11-14
pjp
odh->additional = 0;
2406
2014-11-14
pjp
2407
2014-11-14
pjp
/* skip dns header, question name, qtype and qclass */
2408
2014-11-14
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2409
2014-11-14
pjp
q->hdr->namelen + 4);
2410
2014-11-14
pjp
2411
2014-11-14
pjp
mx_count = 0;
2412
2019-02-15
pjp
2413
2019-02-15
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
2414
2014-11-14
pjp
answer->name[0] = 0xc0;
2415
2014-11-14
pjp
answer->name[1] = 0x0c;
2416
2014-11-14
pjp
answer->type = q->hdr->qtype;
2417
2014-11-14
pjp
answer->class = q->hdr->qclass;
2418
2020-07-06
pjp
2419
2020-07-06
pjp
if (q->aa)
2420
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl);
2421
2020-07-06
pjp
else
2422
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
2423
2014-11-14
pjp
2424
2019-02-15
pjp
answer->rdlength = htons(sizeof(u_int16_t) + ((struct smx *)rrp->rdata)->exchangelen);
2425
2014-11-14
pjp
2426
2019-02-15
pjp
answer->mx_priority = htons(((struct smx *)rrp->rdata)->preference);
2427
2019-02-15
pjp
memcpy((char *)&answer->exchange, (char *)((struct smx *)rrp->rdata)->exchange, ((struct smx *)rrp->rdata)->exchangelen);
2428
2014-11-14
pjp
2429
2019-02-15
pjp
name = ((struct smx *)rrp->rdata)->exchange;
2430
2019-02-15
pjp
namelen = ((struct smx *)rrp->rdata)->exchangelen;
2431
2014-11-14
pjp
2432
2019-02-15
pjp
outlen += (12 + 2 + ((struct smx *)rrp->rdata)->exchangelen);
2433
2014-11-14
pjp
2434
2015-06-20
pjp
/* can we afford to write another header? if no truncate */
2435
2019-02-15
pjp
if ((outlen + 12 + 2 + ((struct smx *)rrp->rdata)->exchangelen) > replysize) {
2436
2015-06-20
pjp
NTOHS(odh->query);
2437
2015-06-20
pjp
SET_DNS_TRUNCATION(odh);
2438
2015-06-20
pjp
HTONS(odh->query);
2439
2017-09-18
pjp
odh->answer = 0;
2440
2017-09-18
pjp
odh->nsrr = 0;
2441
2017-09-18
pjp
odh->additional = 0;
2442
2017-09-18
pjp
outlen = rollback;
2443
2015-06-20
pjp
goto out;
2444
2014-11-14
pjp
}
2445
2014-11-14
pjp
2446
2019-11-11
pjp
ad0 = malloc(sizeof(struct addis));
2447
2019-11-11
pjp
if (ad0 == NULL) {
2448
2019-11-11
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2449
2019-11-11
pjp
return -1;
2450
2019-11-11
pjp
}
2451
2019-11-11
pjp
2452
2019-11-11
pjp
memcpy(ad0->name, name, namelen);
2453
2019-11-11
pjp
ad0->namelen = namelen;
2454
2019-11-11
pjp
2455
2019-11-12
pjp
if (dn_contains(name, namelen, rbt->zone, rbt->zonelen) == 1)
2456
2019-11-12
pjp
ad0->contained = 1;
2457
2019-11-12
pjp
else
2458
2019-11-12
pjp
ad0->contained = 0;
2459
2019-11-12
pjp
2460
2019-11-11
pjp
SLIST_INSERT_HEAD(&addishead, ad0, addis_entries);
2461
2019-11-11
pjp
2462
2015-06-20
pjp
/* set new offset for answer */
2463
2015-06-20
pjp
answer = (struct answer *)&reply[outlen];
2464
2019-02-15
pjp
mx_count++;
2465
2019-02-15
pjp
}
2466
2015-06-20
pjp
2467
2019-02-24
pjp
odh->answer = htons(mx_count);
2468
2019-02-15
pjp
2469
2015-06-27
pjp
/* RRSIG reply_mx*/
2470
2015-06-27
pjp
2471
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
2472
2015-06-22
pjp
int origlen = outlen;
2473
2020-04-01
pjp
int retcount;
2474
2015-06-20
pjp
2475
2020-07-06
pjp
tmplen = additional_rrsig(q->hdr->name, q->hdr->namelen, DNS_TYPE_MX, rbt, reply, replysize, outlen, &retcount, q->aa);
2476
2015-06-22
pjp
2477
2015-06-20
pjp
if (tmplen == 0) {
2478
2020-07-08
pjp
2479
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2480
2020-07-08
pjp
if (q->aa != 1)
2481
2020-07-08
pjp
return -1;
2482
2020-07-08
pjp
2483
2014-11-14
pjp
NTOHS(odh->query);
2484
2014-11-14
pjp
SET_DNS_TRUNCATION(odh);
2485
2014-11-14
pjp
HTONS(odh->query);
2486
2017-09-18
pjp
odh->answer = 0;
2487
2017-09-18
pjp
odh->nsrr = 0;
2488
2017-09-18
pjp
odh->additional = 0;
2489
2017-09-18
pjp
outlen = rollback;
2490
2014-11-14
pjp
goto out;
2491
2014-11-14
pjp
}
2492
2014-11-14
pjp
2493
2015-06-20
pjp
outlen = tmplen;
2494
2014-11-14
pjp
2495
2015-06-22
pjp
if (outlen > origlen)
2496
2020-04-01
pjp
odh->answer = htons(mx_count + retcount);
2497
2014-11-14
pjp
2498
2015-06-20
pjp
}
2499
2014-11-14
pjp
2500
2019-11-11
pjp
/* tack on additional A or AAAA records */
2501
2019-11-11
pjp
2502
2019-11-11
pjp
SLIST_FOREACH(ad0, &addishead, addis_entries) {
2503
2019-11-12
pjp
if (ad0->contained == 0)
2504
2019-11-12
pjp
continue;
2505
2019-11-12
pjp
2506
2019-11-11
pjp
addiscount = 0;
2507
2019-11-11
pjp
rbt0 = find_rrset(db, ad0->name, ad0->namelen);
2508
2019-11-11
pjp
if (rbt0 != NULL && find_rr(rbt0, DNS_TYPE_AAAA) != NULL) {
2509
2019-11-11
pjp
tmplen = additional_aaaa(ad0->name, ad0->namelen, rbt0, reply, replysize, outlen, &addiscount);
2510
2019-11-11
pjp
if (tmplen == 0) {
2511
2019-11-11
pjp
NTOHS(odh->query);
2512
2019-11-11
pjp
SET_DNS_TRUNCATION(odh);
2513
2019-11-11
pjp
HTONS(odh->query);
2514
2019-11-11
pjp
odh->answer = 0;
2515
2019-11-11
pjp
odh->nsrr = 0;
2516
2019-11-11
pjp
odh->additional = 0;
2517
2019-11-11
pjp
outlen = rollback;
2518
2019-11-11
pjp
goto out;
2519
2019-11-11
pjp
}
2520
2019-11-11
pjp
2521
2019-11-11
pjp
outlen = tmplen;
2522
2019-11-11
pjp
NTOHS(odh->additional);
2523
2019-11-11
pjp
odh->additional += addiscount;
2524
2019-11-11
pjp
HTONS(odh->additional);
2525
2019-11-11
pjp
2526
2019-11-11
pjp
/* additional RRSIG for the additional AAAA */
2527
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt0->flags & RBT_DNSSEC)) {
2528
2020-04-01
pjp
int retcount;
2529
2019-11-11
pjp
2530
2020-07-06
pjp
tmplen = additional_rrsig(ad0->name, ad0->namelen, DNS_TYPE_AAAA, rbt0, reply, replysize, outlen, &retcount, q->aa);
2531
2020-04-01
pjp
2532
2019-11-11
pjp
if (tmplen == 0) {
2533
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2534
2020-07-08
pjp
if (q->aa != 1)
2535
2020-07-08
pjp
return -1;
2536
2020-07-08
pjp
2537
2019-11-11
pjp
NTOHS(odh->query);
2538
2019-11-11
pjp
SET_DNS_TRUNCATION(odh);
2539
2019-11-11
pjp
HTONS(odh->query);
2540
2019-11-11
pjp
odh->answer = 0;
2541
2019-11-11
pjp
odh->nsrr = 0;
2542
2019-11-11
pjp
odh->additional = 0;
2543
2019-11-11
pjp
outlen = rollback;
2544
2019-11-11
pjp
goto out;
2545
2019-11-11
pjp
}
2546
2019-11-11
pjp
2547
2019-11-11
pjp
NTOHS(odh->additional);
2548
2020-04-01
pjp
odh->additional += retcount;
2549
2019-11-11
pjp
HTONS(odh->additional);
2550
2019-11-11
pjp
2551
2019-11-11
pjp
outlen = tmplen;
2552
2019-11-11
pjp
}
2553
2019-11-11
pjp
2554
2019-11-11
pjp
rbt0 = NULL;
2555
2019-11-11
pjp
}
2556
2019-11-11
pjp
2557
2019-11-11
pjp
addiscount = 0;
2558
2019-11-11
pjp
rbt0 = find_rrset(db, ad0->name, ad0->namelen);
2559
2019-11-11
pjp
if (rbt0 != NULL && find_rr(rbt0, DNS_TYPE_A) != NULL) {
2560
2019-11-11
pjp
tmplen = additional_a(ad0->name, ad0->namelen, rbt0, reply, replysize, outlen, &addiscount);
2561
2019-11-11
pjp
if (tmplen == 0) {
2562
2019-11-11
pjp
NTOHS(odh->query);
2563
2019-11-11
pjp
SET_DNS_TRUNCATION(odh);
2564
2019-11-11
pjp
HTONS(odh->query);
2565
2019-11-11
pjp
odh->answer = 0;
2566
2019-11-11
pjp
odh->nsrr = 0;
2567
2019-11-11
pjp
odh->additional = 0;
2568
2019-11-11
pjp
outlen = rollback;
2569
2019-11-11
pjp
goto out;
2570
2019-11-11
pjp
}
2571
2019-11-11
pjp
2572
2019-11-11
pjp
outlen = tmplen;
2573
2019-11-11
pjp
NTOHS(odh->additional);
2574
2019-11-11
pjp
odh->additional += addiscount;
2575
2019-11-11
pjp
HTONS(odh->additional);
2576
2019-11-11
pjp
2577
2019-11-11
pjp
/* additional RRSIG for the additional A RR */
2578
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt0->flags & RBT_DNSSEC)) {
2579
2020-04-01
pjp
int retcount;
2580
2019-11-11
pjp
2581
2020-07-06
pjp
tmplen = additional_rrsig(ad0->name, ad0->namelen, DNS_TYPE_A, rbt0, reply, replysize, outlen, &retcount, q->aa);
2582
2020-04-01
pjp
2583
2019-11-11
pjp
if (tmplen == 0) {
2584
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2585
2020-07-08
pjp
if (q->aa != 1)
2586
2020-07-08
pjp
return -1;
2587
2020-07-08
pjp
2588
2019-11-11
pjp
NTOHS(odh->query);
2589
2019-11-11
pjp
SET_DNS_TRUNCATION(odh);
2590
2019-11-11
pjp
HTONS(odh->query);
2591
2019-11-11
pjp
odh->answer = 0;
2592
2019-11-11
pjp
odh->nsrr = 0;
2593
2019-11-11
pjp
odh->additional = 0;
2594
2019-11-11
pjp
outlen = rollback;
2595
2019-11-11
pjp
goto out;
2596
2019-11-11
pjp
}
2597
2019-11-11
pjp
2598
2019-11-11
pjp
NTOHS(odh->additional);
2599
2020-04-01
pjp
odh->additional += retcount;
2600
2019-11-11
pjp
HTONS(odh->additional);
2601
2019-11-11
pjp
2602
2019-11-11
pjp
outlen = tmplen;
2603
2019-11-11
pjp
}
2604
2019-11-11
pjp
2605
2019-11-11
pjp
rbt0 = NULL;
2606
2019-11-11
pjp
}
2607
2019-11-11
pjp
2608
2019-11-11
pjp
}
2609
2019-11-11
pjp
2610
2015-11-14
pjp
out:
2611
2019-11-11
pjp
while (!SLIST_EMPTY(&addishead)) { /* clean up */
2612
2019-11-11
pjp
ad1 = SLIST_FIRST(&addishead);
2613
2019-11-11
pjp
SLIST_REMOVE_HEAD(&addishead, addis_entries);
2614
2019-11-11
pjp
free(ad1);
2615
2019-11-11
pjp
}
2616
2019-11-11
pjp
2617
2014-11-14
pjp
if (q->edns0len) {
2618
2014-11-14
pjp
/* tag on edns0 opt record */
2619
2014-11-14
pjp
NTOHS(odh->additional);
2620
2014-11-14
pjp
odh->additional++;
2621
2014-11-14
pjp
HTONS(odh->additional);
2622
2014-11-14
pjp
2623
2014-11-14
pjp
outlen = additional_opt(q, reply, replysize, outlen);
2624
2014-11-14
pjp
}
2625
2014-11-14
pjp
2626
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
2627
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
2628
2019-02-24
pjp
2629
2019-02-24
pjp
NTOHS(odh->additional);
2630
2019-02-24
pjp
odh->additional++;
2631
2019-02-24
pjp
HTONS(odh->additional);
2632
2019-02-24
pjp
}
2633
2019-02-24
pjp
2634
2015-12-19
pjp
if (istcp) {
2635
2015-12-19
pjp
char *tmpbuf;
2636
2015-06-20
pjp
2637
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
2638
2019-02-27
pjp
if (tmpbuf == 0) {
2639
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2640
2015-12-19
pjp
}
2641
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
2642
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
2643
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2644
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2645
2015-12-19
pjp
}
2646
2015-12-19
pjp
free(tmpbuf);
2647
2015-12-19
pjp
} else {
2648
2020-07-21
pjp
if (q->rawsocket) {
2649
2020-07-21
pjp
*sretlen = retlen = outlen;
2650
2020-07-21
pjp
} else {
2651
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2652
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2653
2020-07-21
pjp
}
2654
2014-11-14
pjp
}
2655
2014-11-14
pjp
}
2656
2014-11-14
pjp
2657
2014-11-14
pjp
return (retlen);
2658
2014-11-14
pjp
}
2659
2014-11-14
pjp
2660
2014-11-14
pjp
/*
2661
2014-11-14
pjp
* REPLY_NS() - replies a DNS question (*q) on socket (so)
2662
2014-11-14
pjp
*
2663
2014-11-14
pjp
*/
2664
2014-11-14
pjp
2665
2014-11-14
pjp
int
2666
2020-07-21
pjp
reply_ns(struct sreply *sreply, int *sretlen, ddDB *db)
2667
2014-11-14
pjp
{
2668
2014-11-14
pjp
char *reply = sreply->replybuf;
2669
2014-11-14
pjp
struct dns_header *odh;
2670
2015-06-20
pjp
int tmplen = 0;
2671
2014-11-14
pjp
int ns_count;
2672
2014-11-14
pjp
char *name;
2673
2015-06-20
pjp
u_int16_t outlen = 0;
2674
2014-11-14
pjp
u_int16_t namelen;
2675
2014-11-14
pjp
2676
2014-11-14
pjp
struct answer {
2677
2014-11-14
pjp
u_int16_t type;
2678
2014-11-14
pjp
u_int16_t class;
2679
2014-11-14
pjp
u_int32_t ttl;
2680
2014-11-14
pjp
u_int16_t rdlength; /* 12 */
2681
2014-11-14
pjp
char ns;
2682
2014-11-14
pjp
} __attribute__((packed));
2683
2014-11-14
pjp
2684
2014-11-14
pjp
struct answer *answer;
2685
2014-11-14
pjp
2686
2014-11-14
pjp
int so = sreply->so;
2687
2014-11-14
pjp
char *buf = sreply->buf;
2688
2014-11-14
pjp
int len = sreply->len;
2689
2014-11-14
pjp
struct question *q = sreply->q;
2690
2014-11-14
pjp
struct sockaddr *sa = sreply->sa;
2691
2014-11-14
pjp
int salen = sreply->salen;
2692
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
2693
2019-10-30
pjp
struct rbtree *rbt0 = NULL, *rbt1 = NULL;
2694
2019-10-30
pjp
struct rbtree *nrbt = NULL;
2695
2019-02-15
pjp
struct rrset *rrset = NULL;
2696
2019-02-15
pjp
struct rr *rrp = NULL;
2697
2014-11-14
pjp
int istcp = sreply->istcp;
2698
2014-11-14
pjp
int replysize = 512;
2699
2014-11-14
pjp
int retlen = -1;
2700
2017-09-18
pjp
u_int16_t rollback;
2701
2019-10-30
pjp
int delegation, addiscount;
2702
2019-11-09
pjp
int addcount = 0;
2703
2020-04-01
pjp
int retcount;
2704
2020-07-06
pjp
time_t now;
2705
2014-11-14
pjp
2706
2019-10-30
pjp
SLIST_HEAD(, addis) addishead;
2707
2019-10-30
pjp
struct addis {
2708
2019-10-30
pjp
char name[DNS_MAXNAME];
2709
2019-10-30
pjp
int namelen;
2710
2019-10-30
pjp
SLIST_ENTRY(addis) addis_entries;
2711
2019-10-30
pjp
} *ad0, *ad1;
2712
2019-10-30
pjp
2713
2019-10-30
pjp
SLIST_INIT(&addishead);
2714
2019-10-30
pjp
/* check for apex, delegations */
2715
2020-07-06
pjp
2716
2020-07-06
pjp
now = time(NULL);
2717
2020-07-06
pjp
2718
2019-10-30
pjp
rbt1 = get_ns(db, rbt, &delegation);
2719
2019-10-30
pjp
2720
2019-10-30
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_NS)) == NULL) {
2721
2015-06-16
pjp
return -1;
2722
2019-10-30
pjp
}
2723
2015-06-16
pjp
2724
2014-11-14
pjp
if (istcp) {
2725
2014-11-14
pjp
replysize = 65535;
2726
2014-11-14
pjp
}
2727
2014-11-14
pjp
2728
2015-06-20
pjp
if (! istcp && q->edns0len > 512)
2729
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
2730
2014-11-14
pjp
2731
2014-11-14
pjp
odh = (struct dns_header *)&reply[0];
2732
2014-11-14
pjp
2733
2014-11-14
pjp
outlen = sizeof(struct dns_header);
2734
2014-11-14
pjp
2735
2014-11-14
pjp
if (len > replysize) {
2736
2014-11-14
pjp
return (retlen);
2737
2014-11-14
pjp
}
2738
2014-11-14
pjp
2739
2014-11-14
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2740
2014-11-14
pjp
2741
2014-11-14
pjp
2742
2014-11-14
pjp
outlen += (q->hdr->namelen + 4);
2743
2017-09-18
pjp
rollback = outlen;
2744
2017-09-18
pjp
2745
2020-07-18
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2746
2020-07-18
pjp
/* no set_reply_flags here, it differs */
2747
2020-07-18
pjp
2748
2014-11-14
pjp
SET_DNS_REPLY(odh);
2749
2019-10-30
pjp
2750
2020-07-06
pjp
if (! delegation && q->aa)
2751
2019-10-30
pjp
SET_DNS_AUTHORITATIVE(odh);
2752
2014-11-14
pjp
2753
2017-09-05
pjp
if (q->rd) {
2754
2017-09-05
pjp
SET_DNS_RECURSION(odh);
2755
2020-07-06
pjp
2756
2020-07-06
pjp
if (! q->aa)
2757
2020-07-06
pjp
SET_DNS_RECURSION_AVAIL(odh);
2758
2017-09-05
pjp
}
2759
2014-11-14
pjp
2760
2014-11-14
pjp
HTONS(odh->query);
2761
2014-11-14
pjp
2762
2014-11-14
pjp
odh->question = htons(1);
2763
2019-02-15
pjp
odh->answer = 0;
2764
2019-02-15
pjp
odh->nsrr = 0;
2765
2014-11-14
pjp
odh->additional = 0;
2766
2014-11-14
pjp
2767
2014-11-14
pjp
2768
2014-11-14
pjp
ns_count = 0;
2769
2014-11-14
pjp
2770
2019-02-15
pjp
TAILQ_FOREACH(rrp, &rrset->rr_head, entries) {
2771
2019-10-30
pjp
memcpy(&reply[outlen], rbt1->zone, rbt1->zonelen);
2772
2019-10-30
pjp
answer = (struct answer *)(&reply[outlen] + rbt1->zonelen);
2773
2014-11-14
pjp
answer->type = htons(DNS_TYPE_NS);
2774
2014-11-14
pjp
answer->class = q->hdr->qclass;
2775
2019-02-15
pjp
2776
2020-07-06
pjp
if (q->aa)
2777
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl);
2778
2020-07-06
pjp
else
2779
2020-07-06
pjp
answer->ttl = htonl(rrset->ttl - (MIN(rrset->ttl, difftime(now, rrset->created))));
2780
2020-07-06
pjp
2781
2019-02-15
pjp
name = ((struct ns *)rrp->rdata)->nsserver;
2782
2019-02-15
pjp
namelen = ((struct ns *)rrp->rdata)->nslen;
2783
2020-08-08
pjp
#if 0
2784
2019-02-15
pjp
ns_type = ((struct ns *)rrp->rdata)->ns_type;
2785
2020-08-08
pjp
#endif
2786
2014-11-14
pjp
2787
2014-11-14
pjp
answer->rdlength = htons(namelen);
2788
2014-11-14
pjp
2789
2014-11-14
pjp
memcpy((char *)&answer->ns, (char *)name, namelen);
2790
2014-11-14
pjp
2791
2019-10-30
pjp
outlen += (10 + namelen + rbt1->zonelen);
2792
2014-11-14
pjp
2793
2019-10-30
pjp
ad0 = malloc(sizeof(struct addis));
2794
2019-10-30
pjp
if (ad0 == NULL) {
2795
2019-10-30
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2796
2019-10-30
pjp
return -1;
2797
2019-10-30
pjp
}
2798
2019-10-30
pjp
2799
2019-10-30
pjp
memcpy(ad0->name, name, namelen);
2800
2019-10-30
pjp
ad0->namelen = namelen;
2801
2019-10-30
pjp
2802
2019-10-30
pjp
SLIST_INSERT_HEAD(&addishead, ad0, addis_entries);
2803
2019-10-30
pjp
2804
2014-11-14
pjp
/* compress the label if possible */
2805
2014-11-14
pjp
if ((tmplen = compress_label((u_char*)reply, outlen, namelen)) > 0) {
2806
2014-11-14
pjp
/* XXX */
2807
2014-11-14
pjp
outlen = tmplen;
2808
2014-11-14
pjp
}
2809
2014-11-14
pjp
2810
2014-11-14
pjp
answer->rdlength = htons(&reply[outlen] - &answer->ns);
2811
2019-02-15
pjp
ns_count++;
2812
2019-02-15
pjp
}
2813
2014-11-14
pjp
2814
2019-10-30
pjp
if (delegation) {
2815
2019-02-15
pjp
odh->answer = 0;
2816
2019-02-15
pjp
odh->nsrr = htons(ns_count);
2817
2019-10-30
pjp
} else {
2818
2019-02-15
pjp
odh->answer = htons(ns_count);
2819
2019-02-15
pjp
odh->nsrr = 0;
2820
2019-02-15
pjp
}
2821
2014-11-14
pjp
2822
2015-06-27
pjp
/* add RRSIG reply_ns */
2823
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt->flags & RBT_DNSSEC)) {
2824
2015-06-22
pjp
int origlen = outlen;
2825
2020-04-01
pjp
int retcount;
2826
2015-06-22
pjp
2827
2020-07-06
pjp
tmplen = additional_rrsig(rbt1->zone, rbt1->zonelen, DNS_TYPE_NS, rbt1, reply, replysize, outlen, &retcount, q->aa);
2828
2015-06-22
pjp
2829
2015-06-22
pjp
if (tmplen == 0) {
2830
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2831
2020-07-08
pjp
if (q->aa != 1)
2832
2020-07-08
pjp
return -1;
2833
2020-07-08
pjp
2834
2014-11-14
pjp
NTOHS(odh->query);
2835
2014-11-14
pjp
SET_DNS_TRUNCATION(odh);
2836
2014-11-14
pjp
HTONS(odh->query);
2837
2017-09-18
pjp
odh->answer = 0;
2838
2017-09-18
pjp
odh->nsrr = 0;
2839
2017-09-18
pjp
odh->additional = 0;
2840
2017-09-18
pjp
outlen = rollback;
2841
2014-11-14
pjp
goto out;
2842
2014-11-14
pjp
}
2843
2014-11-14
pjp
2844
2015-06-22
pjp
outlen = tmplen;
2845
2015-06-22
pjp
if (outlen > origlen) {
2846
2015-06-22
pjp
if (odh->answer)
2847
2020-04-01
pjp
odh->answer = htons(ns_count + retcount);
2848
2015-06-22
pjp
else if (odh->nsrr)
2849
2020-04-01
pjp
odh->nsrr = htons(ns_count + retcount);
2850
2015-06-22
pjp
}
2851
2019-10-30
pjp
2852
2019-10-30
pjp
if (delegation) {
2853
2019-11-09
pjp
tmplen = additional_ds(rbt1->zone, rbt1->zonelen, rbt1, reply, replysize, outlen, &addcount);
2854
2019-11-09
pjp
if (tmplen != 0) {
2855
2019-11-09
pjp
outlen = tmplen;
2856
2019-10-30
pjp
2857
2019-11-09
pjp
NTOHS(odh->nsrr);
2858
2019-11-09
pjp
odh->nsrr += addcount;
2859
2019-11-09
pjp
HTONS(odh->nsrr);
2860
2019-10-30
pjp
2861
2020-07-06
pjp
tmplen = additional_rrsig(rbt1->zone, rbt1->zonelen, DNS_TYPE_DS, rbt1, reply, replysize, outlen, &retcount, q->aa);
2862
2019-11-09
pjp
2863
2019-10-30
pjp
if (tmplen == 0) {
2864
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2865
2020-07-08
pjp
if (q->aa != 1)
2866
2020-07-08
pjp
return -1;
2867
2020-07-08
pjp
2868
2019-10-30
pjp
NTOHS(odh->query);
2869
2019-10-30
pjp
SET_DNS_TRUNCATION(odh);
2870
2019-10-30
pjp
HTONS(odh->query);
2871
2019-10-30
pjp
odh->answer = 0;
2872
2019-10-30
pjp
odh->nsrr = 0;
2873
2019-10-30
pjp
odh->additional = 0;
2874
2019-10-30
pjp
outlen = rollback;
2875
2019-10-30
pjp
goto out;
2876
2019-10-30
pjp
}
2877
2019-10-30
pjp
2878
2019-10-30
pjp
outlen = tmplen;
2879
2019-10-30
pjp
2880
2019-11-09
pjp
NTOHS(odh->nsrr);
2881
2020-04-01
pjp
odh->nsrr += retcount;
2882
2019-11-09
pjp
HTONS(odh->nsrr);
2883
2019-11-09
pjp
2884
2019-11-09
pjp
} else {
2885
2019-11-09
pjp
rbt0 = get_soa(db, q);
2886
2019-11-09
pjp
if (rbt0 == NULL) {
2887
2019-11-09
pjp
return -1;
2888
2019-10-30
pjp
}
2889
2019-10-30
pjp
2890
2019-11-09
pjp
nrbt = find_nsec3_match_qname(rbt1->zone, rbt1->zonelen, rbt0, db);
2891
2019-11-09
pjp
if (nrbt != NULL) {
2892
2020-07-06
pjp
tmplen = additional_nsec3(nrbt->zone, nrbt->zonelen, DNS_TYPE_NSEC3, nrbt, reply, replysize, outlen, &retcount, q->aa);
2893
2019-10-30
pjp
2894
2019-11-09
pjp
if (tmplen == 0) {
2895
2019-11-09
pjp
NTOHS(odh->query);
2896
2019-11-09
pjp
SET_DNS_TRUNCATION(odh);
2897
2019-11-09
pjp
HTONS(odh->query);
2898
2019-11-09
pjp
odh->answer = 0;
2899
2019-11-09
pjp
odh->nsrr = 0;
2900
2019-11-09
pjp
odh->additional = 0;
2901
2019-11-09
pjp
outlen = rollback;
2902
2019-11-09
pjp
goto out;
2903
2019-11-09
pjp
}
2904
2019-10-30
pjp
2905
2019-11-09
pjp
outlen = tmplen;
2906
2019-10-30
pjp
2907
2019-11-09
pjp
/* additional_nsec3 adds an RRSIG automatically */
2908
2019-11-09
pjp
NTOHS(odh->nsrr);
2909
2020-04-01
pjp
odh->nsrr += retcount;
2910
2019-11-09
pjp
HTONS(odh->nsrr);
2911
2019-11-09
pjp
2912
2019-11-09
pjp
}
2913
2019-11-09
pjp
2914
2019-11-09
pjp
} /* nrbt != NULL */
2915
2019-11-09
pjp
} /* else tmplen != 0 */
2916
2019-11-09
pjp
} /* if delegation */
2917
2019-11-09
pjp
2918
2019-10-30
pjp
/* tack on additional A or AAAA records */
2919
2019-10-30
pjp
2920
2019-10-30
pjp
SLIST_FOREACH(ad0, &addishead, addis_entries) {
2921
2019-10-30
pjp
addiscount = 0;
2922
2019-11-11
pjp
rbt0 = find_rrset(db, ad0->name, ad0->namelen);
2923
2019-10-30
pjp
if (rbt0 != NULL && find_rr(rbt0, DNS_TYPE_AAAA) != NULL) {
2924
2019-10-30
pjp
tmplen = additional_aaaa(ad0->name, ad0->namelen, rbt0, reply, replysize, outlen, &addiscount);
2925
2019-10-30
pjp
if (tmplen == 0) {
2926
2019-10-30
pjp
NTOHS(odh->query);
2927
2019-10-30
pjp
SET_DNS_TRUNCATION(odh);
2928
2019-10-30
pjp
HTONS(odh->query);
2929
2019-10-30
pjp
odh->answer = 0;
2930
2019-10-30
pjp
odh->nsrr = 0;
2931
2019-10-30
pjp
odh->additional = 0;
2932
2019-10-30
pjp
outlen = rollback;
2933
2019-10-30
pjp
goto out;
2934
2019-10-30
pjp
}
2935
2019-10-30
pjp
2936
2019-10-30
pjp
outlen = tmplen;
2937
2019-10-30
pjp
NTOHS(odh->additional);
2938
2019-10-30
pjp
odh->additional += addiscount;
2939
2019-10-30
pjp
HTONS(odh->additional);
2940
2019-10-30
pjp
2941
2019-10-30
pjp
/* additional RRSIG for the additional AAAA */
2942
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt0->flags & RBT_DNSSEC)) {
2943
2020-07-06
pjp
tmplen = additional_rrsig(ad0->name, ad0->namelen, DNS_TYPE_AAAA, rbt0, reply, replysize, outlen, &retcount, q->aa);
2944
2019-10-30
pjp
2945
2019-10-30
pjp
if (tmplen == 0) {
2946
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2947
2020-07-08
pjp
if (q->aa != 1)
2948
2020-07-08
pjp
return -1;
2949
2020-07-08
pjp
2950
2019-10-30
pjp
NTOHS(odh->query);
2951
2019-10-30
pjp
SET_DNS_TRUNCATION(odh);
2952
2019-10-30
pjp
HTONS(odh->query);
2953
2019-10-30
pjp
odh->answer = 0;
2954
2019-10-30
pjp
odh->nsrr = 0;
2955
2019-10-30
pjp
odh->additional = 0;
2956
2019-10-30
pjp
outlen = rollback;
2957
2019-10-30
pjp
goto out;
2958
2019-10-30
pjp
}
2959
2019-10-30
pjp
2960
2019-10-30
pjp
NTOHS(odh->additional);
2961
2020-04-01
pjp
odh->additional += retcount;
2962
2019-10-30
pjp
HTONS(odh->additional);
2963
2019-10-30
pjp
2964
2019-10-30
pjp
outlen = tmplen;
2965
2019-10-30
pjp
}
2966
2019-10-30
pjp
2967
2019-10-30
pjp
rbt0 = NULL;
2968
2019-10-30
pjp
}
2969
2019-10-30
pjp
2970
2019-10-30
pjp
2971
2019-10-30
pjp
addiscount = 0;
2972
2019-11-11
pjp
rbt0 = find_rrset(db, ad0->name, ad0->namelen);
2973
2019-10-30
pjp
if (rbt0 != NULL && find_rr(rbt0, DNS_TYPE_A) != NULL) {
2974
2019-10-30
pjp
tmplen = additional_a(ad0->name, ad0->namelen, rbt0, reply, replysize, outlen, &addiscount);
2975
2019-10-30
pjp
if (tmplen == 0) {
2976
2019-10-30
pjp
NTOHS(odh->query);
2977
2019-10-30
pjp
SET_DNS_TRUNCATION(odh);
2978
2019-10-30
pjp
HTONS(odh->query);
2979
2019-10-30
pjp
odh->answer = 0;
2980
2019-10-30
pjp
odh->nsrr = 0;
2981
2019-10-30
pjp
odh->additional = 0;
2982
2019-10-30
pjp
outlen = rollback;
2983
2019-10-30
pjp
goto out;
2984
2019-10-30
pjp
}
2985
2019-10-30
pjp
2986
2019-10-30
pjp
outlen = tmplen;
2987
2019-10-30
pjp
NTOHS(odh->additional);
2988
2019-10-30
pjp
odh->additional += addiscount;
2989
2019-10-30
pjp
HTONS(odh->additional);
2990
2019-10-30
pjp
2991
2019-10-30
pjp
/* additional RRSIG for the additional A RR */
2992
2019-11-11
pjp
if (dnssec && q->dnssecok && (rbt0->flags & RBT_DNSSEC)) {
2993
2020-04-01
pjp
int retcount;
2994
2019-10-30
pjp
2995
2020-07-06
pjp
tmplen = additional_rrsig(ad0->name, ad0->namelen, DNS_TYPE_A, rbt0, reply, replysize, outlen, &retcount, q->aa);
2996
2020-04-01
pjp
2997
2019-10-30
pjp
if (tmplen == 0) {
2998
2020-07-08
pjp
/* we're forwarding and had no RRSIG return with -1 */
2999
2020-07-08
pjp
if (q->aa != 1)
3000
2020-07-08
pjp
return -1;
3001
2020-07-08
pjp
3002
2019-10-30
pjp
NTOHS(odh->query);
3003
2019-10-30
pjp
SET_DNS_TRUNCATION(odh);
3004
2019-10-30
pjp
HTONS(odh->query);
3005
2019-10-30
pjp
odh->answer = 0;
3006
2019-10-30
pjp
odh->nsrr = 0;
3007
2019-10-30
pjp
odh->additional = 0;
3008
2019-10-30
pjp
outlen = rollback;
3009
2019-10-30
pjp
goto out;
3010
2019-10-30
pjp
}
3011
2019-10-30
pjp
3012
2019-10-30
pjp
NTOHS(odh->additional);
3013
2020-04-01
pjp
odh->additional += retcount;
3014
2019-10-30
pjp
HTONS(odh->additional);
3015
2019-10-30
pjp
3016
2019-10-30
pjp
outlen = tmplen;
3017
2019-10-30
pjp
}
3018
2019-10-30
pjp
3019
2019-10-30
pjp
rbt0 = NULL;
3020
2019-10-30
pjp
}
3021
2019-10-30
pjp
3022
2014-11-14
pjp
}
3023
2014-11-14
pjp
3024
2019-11-11
pjp
out:
3025
2019-10-30
pjp
while (!SLIST_EMPTY(&addishead)) { /* clean up */
3026
2019-10-30
pjp
ad1 = SLIST_FIRST(&addishead);
3027
2019-10-30
pjp
SLIST_REMOVE_HEAD(&addishead, addis_entries);
3028
2019-10-30
pjp
free(ad1);
3029
2019-10-30
pjp
}
3030
2019-10-30
pjp
3031
2019-10-30
pjp
3032
2014-11-14
pjp
if (q->edns0len) {
3033
2014-11-14
pjp
/* tag on edns0 opt record */
3034
2014-11-14
pjp
NTOHS(odh->additional);
3035
2014-11-14
pjp
odh->additional++;
3036
2014-11-14
pjp
HTONS(odh->additional);
3037
2014-11-14
pjp
3038
2014-11-14
pjp
outlen = additional_opt(q, reply, replysize, outlen);
3039
2014-11-14
pjp
}
3040
2014-11-14
pjp
3041
2019-02-24
pjp
if (q->tsig.tsigverified == 1) {
3042
2019-02-28
pjp
outlen = additional_tsig(q, reply, replysize, outlen, 0, 0, NULL);
3043
2019-02-24
pjp
3044
2019-02-24
pjp
NTOHS(odh->additional);
3045
2019-02-24
pjp
odh->additional++;
3046
2019-02-24
pjp
HTONS(odh->additional);
3047
2019-02-24
pjp
}
3048
2019-02-24
pjp
3049
2015-12-19
pjp
if (istcp) {
3050
2015-12-19
pjp
char *tmpbuf;
3051
2015-06-20
pjp
3052
2015-12-19
pjp
tmpbuf = malloc(outlen + 2);
3053
2019-02-27
pjp
if (tmpbuf == 0) {
3054
2015-12-19
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
3055
2015-12-19
pjp
}
3056
2019-12-03
pjp
pack16(tmpbuf, htons(outlen));
3057
2015-12-19
pjp
memcpy(&tmpbuf[2], reply, outlen);
3058
2015-12-19
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
3059
2015-12-19
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
3060
2015-12-19
pjp
}
3061
2015-12-19
pjp
free(tmpbuf);
3062
2015-12-19
pjp
} else {
3063
2020-07-21
pjp
if (q->rawsocket) {
3064
2020-07-21
pjp
*sretlen = retlen = outlen;
3065
2020-07-21
pjp
} else {
3066
2020-07-21
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
3067
2020-07-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
3068
2020-07-21
pjp
}
3069
2014-11-14
pjp
}
3070
2014-11-14
pjp
}
3071
2014-11-14
pjp
3072
2019-02-15
pjp
rotate_rr(rrset);
3073
2014-11-14
pjp
3074
2014-11-14
pjp
return (retlen);
3075
2014-11-14
pjp
}
3076
2014-11-14
pjp
3077
2014-11-14
pjp
3078
2014-11-14
pjp
/*
3079
2014-11-14
pjp
* REPLY_CNAME() - replies a DNS question (*q) on socket (so)
3080
2014-11-14
pjp
*
3081
2014-11-14
pjp
*/
3082
2014-11-14
pjp
3083
2014-11-14
pjp
3084
2014-11-14
pjp
int
3085
2020-07-21
pjp
reply_cname(struct sreply *sreply, int *sretlen, ddDB *db)
3086
2014-11-14
pjp
{
3087
2014-11-14
pjp
char *reply = sreply->replybuf;
3088
2014-11-14
pjp
struct dns_header *odh;
3089
2014-11-14
pjp
u_int16_t outlen;
3090
2014-11-14
pjp
int i, tmplen;
3091
2014-11-14
pjp
int labellen;
3092
2014-11-14
pjp
char *label, *plabel;
3093
2014-11-14
pjp
int addcount;
3094
2014-11-14
pjp
3095
2014-11-14
pjp
struct answer {
3096
2014-11-14
pjp
char name[2];
3097
2014-11-14
pjp
u_int16_t type;
3098
2014-11-14
pjp
u_int16_t class;
3099
2014-11-14
pjp
u_int32_t ttl;
3100
2014-11-14
pjp
u_int16_t rdlength; /* 12 */
3101
2014-11-14
pjp
char rdata;
3102
2014-11-14
pjp
} __attribute__((packed));
3103
2014-11-14
pjp
3104
2014-11-14
pjp
struct answer *answer;
3105
2014-11-14
pjp
3106
2014-11-14
pjp
int so = sreply->so;
3107
2014-11-14
pjp
char *buf = sreply->buf;
3108
2014-11-14
pjp
int len = sreply->len;
3109
2014-11-14
pjp
struct question *q = sreply->q;
3110
2014-11-14
pjp
struct sockaddr *sa = sreply->sa;
3111
2014-11-14
pjp
int salen = sreply->salen;
3112
2019-02-15
pjp
struct rbtree *rbt = sreply->rbt1;
3113
2019-02-15
pjp
struct rrset *rrset = NULL;
3114
2019-02-15
pjp
struct rbtree *rbt1 = sreply->rbt2;
3115
2019-02-15
pjp
struct rr *rrp = NULL;
3116
2014-11-14
pjp
int istcp = sreply->istcp;
3117
2014-11-14
pjp
int replysize = 512;
3118
2014-11-14
pjp
int retlen = -1;
3119
2017-09-18
pjp
u_int16_t rollback;
3120
2020-07-06
pjp
time_t now;
3121
2014-11-14
pjp
3122
2020-07-06
pjp
now = time(NULL);
3123
2020-07-06
pjp
3124
2019-02-27
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_CNAME)) == 0)
3125
2015-06-16
pjp
return -1;
3126
2015-06-16
pjp
3127
2014-11-14
pjp
if (istcp) {
3128
2014-11-14
pjp
replysize = 65535;
3129
2014-11-14
pjp
}
3130
2014-11-14
pjp
3131
2015-06-20
pjp
if (! istcp && q->edns0len > 512)
3132
2020-09-30
pjp
replysize = MIN(q->edns0len, max_udp_payload);
3133
2014-11-14
pjp
3134
2014-11-14
pjp
odh = (struct dns_header *)&reply[0];
3135
2014-11-14
pjp
outlen = sizeof(struct dns_header);
3136
2014-11-14
pjp
3137
2014-11-14
pjp
if (len > replysize) {
3138
2014-11-14
pjp
return (retlen);
3139
2014-11-14
pjp
}
3140
2014-11-14
pjp
3141
2014-11-14
pjp
/* copy question to reply */
3142
2014-11-14
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
3143
2014-11-14
pjp
3144
2014-11-14
pjp
3145
2014-11-14
pjp
outlen += (q->hdr->namelen + 4);
3146
2017-09-18
pjp
rollback = outlen;
3147
2014-11-14
pjp
3148
2020-07-18
pjp
/* blank query */
3149