edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
+ edns->subnet_option_add = 0;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns);
regional_free_all(worker->scratchpad);
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
+ edns->subnet_option_add = 0;
msg->rep->flags |= BIT_QR|BIT_RA;
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
repinfo->c->buffer, 0, 1, worker->scratchpad,
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
+ edns->subnet_option_add = 0;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
rrset_array_unlock_touch(worker->env.rrset_cache,
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
+ edns->subnet_option_add = 0;
if(!reply_info_answer_encode(qinfo, rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->bits &= EDNS_DO;
+ edns->subnet_option_add = 0;
attach_edns_record(pkt, edns);
}
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
+ edns.subnet_option_add = 0;
verbose(VERB_ALGO, "query with bad edns version.");
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
edns->bits &= EDNS_DO;
+ edns->subnet_option_add = 0;
if(!reply_info_answer_encode(qinfo, &rep,
*(uint16_t*)ldns_buffer_begin(buf),
ldns_buffer_read_u16_at(buf, 2),
r->edns.udp_size = EDNS_ADVERTISED_SIZE;
r->edns.ext_rcode = 0;
r->edns.bits &= EDNS_DO;
+ r->edns.subnet_option_add = 0;
if(!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->buf, 0, 1,
m->s.env->scratch, udp_size, &r->edns,
r->edns.udp_size = EDNS_ADVERTISED_SIZE;
r->edns.ext_rcode = 0;
r->edns.bits &= EDNS_DO;
+ r->edns.subnet_option_add = 0;
m->s.qinfo.qname = r->qname;
if(!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->query_reply.c->buffer, 0, 1,
edns.edns_present = 1;
edns.ext_rcode = 0;
edns.edns_version = EDNS_ADVERTISED_VERSION;
+ edns.subnet_option_add = 0;
if(sq->status == serviced_query_UDP_EDNS_FRAG) {
if(addr_is_ip6(&sq->addr, sq->addrlen)) {
if(EDNS_FRAG_SIZE_IP6 < EDNS_ADVERTISED_SIZE)
MAX_TTL = (uint32_t)config->max_ttl;
MIN_TTL = (uint32_t)config->min_ttl;
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
+ EDNS_SUBNET_OPC = (uint16_t)config->client_subnet_opc;
MINIMAL_RESPONSES = config->minimal_responses;
RRSET_ROUNDROBIN = config->rrset_roundrobin;
log_set_time_asc(config->log_time_ascii);
void
attach_edns_record(ldns_buffer* pkt, struct edns_data* edns)
{
- size_t len;
+ size_t len, sn_octs, sn_octs_remainder;
+ int i;
if(!edns || !edns->edns_present)
return;
/* inc additional count */
ldns_buffer_write_u8(pkt, edns->ext_rcode); /* ttl */
ldns_buffer_write_u8(pkt, edns->edns_version);
ldns_buffer_write_u16(pkt, edns->bits);
- ldns_buffer_write_u16(pkt, 0); /* rdatalen */
+ /* YBS: do vandergaast hier! */
+ if(edns->subnet_option_add) {
+ assert(edns.addr_fam == 0x01 || edns.addr_fam == 0x02);
+ assert(edns.addr_fam != 0x01 || edns->subnet_source_mask <= 32);
+ assert(edns.addr_fam != 0x02 || edns->subnet_source_mask <= 128); //ipv6 addr fam?
+
+ sn_octs = edns->subnet_source_mask / 8;
+ sn_octs_remainder = !!(edns->subnet_source_mask % 8);
+
+ ldns_buffer_write_u16(pkt, sn_octs + sn_octs_remainder + 4 + 4); /* rdatalen */
+ ldns_buffer_write_u16(pkt, EDNS_SUBNET_OPC); /* opc */
+ ldns_buffer_write_u16(pkt, sn_octs + sn_octs_remainder + 4); /* datalen */
+ ldns_buffer_write_u16(pkt, edns->subnet_addr_fam); /* addr fam */
+ ldns_buffer_write_u8(pkt, edns->subnet_source_mask); /* source mask */
+ ldns_buffer_write_u8(pkt, edns->subnet_scope_mask); /* scope mask */
+
+ for(i = 0; i<sn_octs; i++)
+ ldns_buffer_write_u8(pkt, edns->subnet_addr[i]);
+ if(sn_octs_remainder)
+ ldns_buffer_write_u8(pkt, edns->subnet_addr[sn_octs] &
+ ~(1<<(8-(edns->subnet_source_mask % 8))-1));
+ } else ldns_buffer_write_u16(pkt, 0); /* rdatalen */
+ /* //YBS: do vandergaast hier! */
ldns_buffer_flip(pkt);
}
uint16_t bits;
/** UDP reassembly size. */
uint16_t udp_size;
+ // YBS add vandergaast here
+ int subnet_option_add;
+ uint16_t subnet_addr_fam;
+ uint8_t subnet_source_mask;
+ uint8_t subnet_scope_mask;
+ uint8_t subnet_addr[16];
+ // YBS add vandergaast here
};
/**
#define MAX_ADDR_STRLEN 128 /* characters */
/** default value for EDNS ADVERTISED size */
uint16_t EDNS_ADVERTISED_SIZE = 4096;
+/** YBS: opcode for edns subnet option, is TBD. */
+uint16_t EDNS_SUBNET_OPC = 0x50fa;
/** minimal responses when positive answer: default is no */
int MINIMAL_RESPONSES = 0;
#define EDNS_ADVERTISED_VERSION 0
/** Advertised size of EDNS capabilities */
extern uint16_t EDNS_ADVERTISED_SIZE;
+/** YBS: opcode for edns subnet option, is TBD. */
+extern uint16_t EDNS_SUBNET_OPC;
/** bits for EDNS bitfield */
#define EDNS_DO 0x8000 /* Dnssec Ok */
/** byte size of ip4 address */