int reply_info_parse(sldns_buffer* pkt, struct alloc_cache* alloc, struct query_info* qinf, struct reply_info** rep, struct regional* region, struct edns_data* edns) { /* use scratch pad region-allocator during parsing. */ struct msg_parse* msg; int ret; qinf->qname = NULL; *rep = NULL; if(!(msg = regional_alloc(region, sizeof(*msg)))) { return LDNS_RCODE_SERVFAIL; } memset(msg, 0, sizeof(*msg)); sldns_buffer_set_position(pkt, 0); if((ret = parse_packet(pkt, msg, region)) != 0) { return ret; } if((ret = parse_extract_edns(msg, edns)) != 0) return ret; /* parse OK, allocate return structures */ /* this also performs dname decompression */ if(!parse_create_msg(pkt, msg, alloc, qinf, rep, NULL)) { query_info_clear(qinf); reply_info_parsedelete(*rep, alloc); *rep = NULL; return LDNS_RCODE_SERVFAIL; } return 0; }
/* Create response according to the ldns packet content */ int createResponse(struct module_qstate* qstate, sldns_buffer* pkt) { struct msg_parse* prs; struct edns_data edns; /* parse message */ prs = (struct msg_parse*) regional_alloc(qstate->env->scratch, sizeof(struct msg_parse)); if (!prs) { log_err("storeResponse: out of memory on incoming message"); return 0; } memset(prs, 0, sizeof(*prs)); memset(&edns, 0, sizeof(edns)); sldns_buffer_set_position(pkt, 0); if (parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) { verbose(VERB_ALGO, "storeResponse: parse error on reply packet"); return 0; } /* edns is not examined, but removed from message to help cache */ if(parse_extract_edns(prs, &edns) != LDNS_RCODE_NOERROR) return 0; /* remove CD-bit, we asked for in case we handle validation ourself */ prs->flags &= ~BIT_CD; /* allocate response dns_msg in region */ qstate->return_msg = (struct dns_msg*)regional_alloc(qstate->region, sizeof(struct dns_msg)); if (!qstate->return_msg) return 0; memset(qstate->return_msg, 0, sizeof(*qstate->return_msg)); if(!parse_create_msg(pkt, prs, NULL, &(qstate->return_msg)->qinfo, &(qstate->return_msg)->rep, qstate->region)) { log_err("storeResponse: malloc failure: allocating incoming dns_msg"); return 0; } /* Make sure that the RA flag is set (since the presence of * this module means that recursion is available) */ /* qstate->return_msg->rep->flags |= BIT_RA; */ /* Clear the AA flag */ /* FIXME: does this action go here or in some other module? */ /*qstate->return_msg->rep->flags &= ~BIT_AA; */ /* make sure QR flag is on */ /*qstate->return_msg->rep->flags |= BIT_QR; */ if(verbosity >= VERB_ALGO) log_dns_msg("storeResponse: packet:", &qstate->return_msg->qinfo, qstate->return_msg->rep); return 1; }
struct dns_msg* dns_alloc_msg(sldns_buffer* pkt, struct msg_parse* msg, struct regional* region) { struct dns_msg* m = (struct dns_msg*)regional_alloc(region, sizeof(struct dns_msg)); if(!m) return NULL; memset(m, 0, sizeof(*m)); if(!parse_create_msg(pkt, msg, NULL, &m->qinfo, &m->rep, region)) { log_err("malloc failure: allocating incoming dns_msg"); return NULL; } return m; }
/** get msg reply struct (in temp region) */ static struct reply_info* parse_reply(ldns_buffer* pkt, struct regional* region, struct query_info* qi) { struct reply_info* rep; struct msg_parse* msg; if(!(msg = regional_alloc(region, sizeof(*msg)))) { return NULL; } memset(msg, 0, sizeof(*msg)); ldns_buffer_set_position(pkt, 0); if(parse_packet(pkt, msg, region) != 0) return 0; if(!parse_create_msg(pkt, msg, NULL, qi, &rep, region)) { return 0; } return rep; }