mirror of https://github.com/getdnsapi/getdns.git
First pass at sending packets
This commit is contained in:
parent
102d55d4a5
commit
25cc88e1a2
|
@ -753,17 +753,26 @@ getdns_wire2msg_dict_scan(
|
||||||
if (!getdns_dict_get_int(reply, "/header/" #X, &n) && n) \
|
if (!getdns_dict_get_int(reply, "/header/" #X, &n) && n) \
|
||||||
GLDNS_ ## Y ## _SET(header);
|
GLDNS_ ## Y ## _SET(header);
|
||||||
|
|
||||||
static getdns_return_t
|
getdns_return_t
|
||||||
_getdns_reply_dict2wire(const getdns_dict *reply, gldns_buffer *buf)
|
_getdns_reply_dict2wire(
|
||||||
|
const getdns_dict *reply, gldns_buffer *buf,int reuse_header)
|
||||||
{
|
{
|
||||||
uint8_t header[GLDNS_HEADER_SIZE];
|
uint8_t header_spc[GLDNS_HEADER_SIZE], *header;
|
||||||
uint32_t n, qtype, qclass = GETDNS_RRCLASS_IN;
|
uint32_t n, qtype, qclass = GETDNS_RRCLASS_IN;
|
||||||
size_t pkt_start, i;
|
size_t pkt_start, i;
|
||||||
getdns_list *section;
|
getdns_list *section;
|
||||||
getdns_dict *rr_dict;
|
getdns_dict *rr_dict;
|
||||||
getdns_bindata *qname;
|
getdns_bindata *qname;
|
||||||
|
|
||||||
(void) memset(header, 0, sizeof(GLDNS_HEADER_SIZE));
|
pkt_start = gldns_buffer_position(buf);
|
||||||
|
if (reuse_header) {
|
||||||
|
if (gldns_buffer_remaining(buf) < GLDNS_HEADER_SIZE)
|
||||||
|
return GETDNS_RETURN_NEED_MORE_SPACE;
|
||||||
|
header = gldns_buffer_current(buf);
|
||||||
|
gldns_buffer_skip(buf, GLDNS_HEADER_SIZE);
|
||||||
|
} else
|
||||||
|
(void) memset((header = header_spc), 0, GLDNS_HEADER_SIZE);
|
||||||
|
|
||||||
SET_HEADER_INT(id, ID);
|
SET_HEADER_INT(id, ID);
|
||||||
SET_HEADER_BIT(qr, QR);
|
SET_HEADER_BIT(qr, QR);
|
||||||
SET_HEADER_BIT(aa, AA);
|
SET_HEADER_BIT(aa, AA);
|
||||||
|
@ -776,7 +785,7 @@ _getdns_reply_dict2wire(const getdns_dict *reply, gldns_buffer *buf)
|
||||||
SET_HEADER_INT(rcode, RCODE);
|
SET_HEADER_INT(rcode, RCODE);
|
||||||
SET_HEADER_BIT(z, Z);
|
SET_HEADER_BIT(z, Z);
|
||||||
|
|
||||||
pkt_start = gldns_buffer_position(buf);
|
if (!reuse_header)
|
||||||
gldns_buffer_write(buf, header, sizeof(header));
|
gldns_buffer_write(buf, header, sizeof(header));
|
||||||
|
|
||||||
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
|
if (!getdns_dict_get_bindata(reply, "/question/qname", &qname) &&
|
||||||
|
@ -786,6 +795,14 @@ _getdns_reply_dict2wire(const getdns_dict *reply, gldns_buffer *buf)
|
||||||
gldns_buffer_write_u16(buf, (uint16_t)qtype);
|
gldns_buffer_write_u16(buf, (uint16_t)qtype);
|
||||||
gldns_buffer_write_u16(buf, (uint16_t)qclass);
|
gldns_buffer_write_u16(buf, (uint16_t)qclass);
|
||||||
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
|
gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
|
||||||
|
if (reuse_header) {
|
||||||
|
gldns_buffer_write_u16_at(
|
||||||
|
buf, pkt_start+GLDNS_ANCOUNT_OFF, 0);
|
||||||
|
gldns_buffer_write_u16_at(
|
||||||
|
buf, pkt_start+GLDNS_NSCOUNT_OFF, 0);
|
||||||
|
gldns_buffer_write_u16_at(
|
||||||
|
buf, pkt_start+GLDNS_ARCOUNT_OFF, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!getdns_dict_get_list(reply, "answer", §ion)) {
|
if (!getdns_dict_get_list(reply, "answer", §ion)) {
|
||||||
for ( n = 0, i = 0
|
for ( n = 0, i = 0
|
||||||
|
@ -817,7 +834,7 @@ _getdns_reply_dict2wire(const getdns_dict *reply, gldns_buffer *buf)
|
||||||
return GETDNS_RETURN_GOOD;
|
return GETDNS_RETURN_GOOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static getdns_return_t
|
getdns_return_t
|
||||||
_getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
|
_getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
|
||||||
{
|
{
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
|
@ -828,11 +845,11 @@ _getdns_msg_dict2wire_buf(const getdns_dict *msg_dict, gldns_buffer *gbuf)
|
||||||
if ((r = getdns_dict_get_list(msg_dict, "replies_tree", &replies))) {
|
if ((r = getdns_dict_get_list(msg_dict, "replies_tree", &replies))) {
|
||||||
if (r != GETDNS_RETURN_NO_SUCH_DICT_NAME)
|
if (r != GETDNS_RETURN_NO_SUCH_DICT_NAME)
|
||||||
return r;
|
return r;
|
||||||
return _getdns_reply_dict2wire(msg_dict, gbuf);
|
return _getdns_reply_dict2wire(msg_dict, gbuf, 0);
|
||||||
}
|
}
|
||||||
for (i = 0; r == GETDNS_RETURN_GOOD; i++) {
|
for (i = 0; r == GETDNS_RETURN_GOOD; i++) {
|
||||||
if (!(r = getdns_list_get_dict(replies, i, &reply)))
|
if (!(r = getdns_list_get_dict(replies, i, &reply)))
|
||||||
r = _getdns_reply_dict2wire(reply, gbuf);
|
r = _getdns_reply_dict2wire(reply, gbuf, 0);
|
||||||
}
|
}
|
||||||
return r == GETDNS_RETURN_NO_SUCH_LIST_ITEM ? GETDNS_RETURN_GOOD : r;
|
return r == GETDNS_RETURN_NO_SUCH_LIST_ITEM ? GETDNS_RETURN_GOOD : r;
|
||||||
}
|
}
|
||||||
|
@ -889,10 +906,9 @@ getdns_msg_dict2wire_scan(
|
||||||
getdns_return_t r;
|
getdns_return_t r;
|
||||||
gldns_buffer gbuf;
|
gldns_buffer gbuf;
|
||||||
|
|
||||||
if (!msg_dict || !wire || !*wire || !wire_sz)
|
if (!msg_dict || !wire || !wire_sz || (!*wire && *wire_sz))
|
||||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
|
||||||
gldns_buffer_init_frm_data(&gbuf, *wire, *wire_sz);
|
gldns_buffer_init_frm_data(&gbuf, *wire, *wire_sz);
|
||||||
if ((r = _getdns_msg_dict2wire_buf(msg_dict, &gbuf)))
|
if ((r = _getdns_msg_dict2wire_buf(msg_dict, &gbuf)))
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -53,5 +53,8 @@ getdns_return_t _getdns_str2rr_dict(struct mem_funcs *mf, const char *str,
|
||||||
getdns_return_t _getdns_fp2rr_list(struct mem_funcs *mf, FILE *in,
|
getdns_return_t _getdns_fp2rr_list(struct mem_funcs *mf, FILE *in,
|
||||||
getdns_list **rr_list, const char *origin, uint32_t default_ttl);
|
getdns_list **rr_list, const char *origin, uint32_t default_ttl);
|
||||||
|
|
||||||
|
getdns_return_t _getdns_reply_dict2wire(
|
||||||
|
const getdns_dict *reply, gldns_buffer *buf, int reuse_header);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* convert.h */
|
/* convert.h */
|
||||||
|
|
|
@ -164,7 +164,7 @@ gldns_buffer_invariant(gldns_buffer *buffer)
|
||||||
assert(buffer != NULL);
|
assert(buffer != NULL);
|
||||||
assert(buffer->_position <= buffer->_limit || buffer->_fixed);
|
assert(buffer->_position <= buffer->_limit || buffer->_fixed);
|
||||||
assert(buffer->_limit <= buffer->_capacity);
|
assert(buffer->_limit <= buffer->_capacity);
|
||||||
assert(buffer->_data != NULL);
|
assert(buffer->_data != NULL || (buffer->_capacity == 0 && buffer->_fixed));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "gldns/pkthdr.h"
|
#include "gldns/pkthdr.h"
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "convert.h"
|
||||||
|
|
||||||
/* MAXIMUM_TSIG_SPACE = TSIG name (dname) : 256
|
/* MAXIMUM_TSIG_SPACE = TSIG name (dname) : 256
|
||||||
* TSIG type (uint16_t) : 2
|
* TSIG type (uint16_t) : 2
|
||||||
|
@ -143,7 +144,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
||||||
int edns_maximum_udp_payload_size,
|
int edns_maximum_udp_payload_size,
|
||||||
uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit,
|
uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit,
|
||||||
uint16_t opt_options_size, size_t noptions, getdns_list *options,
|
uint16_t opt_options_size, size_t noptions, getdns_list *options,
|
||||||
size_t wire_data_sz, size_t max_query_sz)
|
size_t wire_data_sz, size_t max_query_sz, getdns_dict *extensions)
|
||||||
{
|
{
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
getdns_dict *option;
|
getdns_dict *option;
|
||||||
|
@ -151,6 +152,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
||||||
getdns_bindata *option_data;
|
getdns_bindata *option_data;
|
||||||
size_t i;
|
size_t i;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
gldns_buffer gbuf;
|
||||||
|
|
||||||
/* variables that stay the same on reinit, don't touch
|
/* variables that stay the same on reinit, don't touch
|
||||||
*/
|
*/
|
||||||
|
@ -204,6 +206,10 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
|
||||||
gldns_write_uint16(buf + GLDNS_ARCOUNT_OFF, with_opt ? 1 : 0);
|
gldns_write_uint16(buf + GLDNS_ARCOUNT_OFF, with_opt ? 1 : 0);
|
||||||
|
|
||||||
buf = netreq_reset(net_req);
|
buf = netreq_reset(net_req);
|
||||||
|
gldns_buffer_init_frm_data(
|
||||||
|
&gbuf, net_req->query, net_req->wire_data_sz - 2);
|
||||||
|
_getdns_reply_dict2wire(extensions, &gbuf, 1);
|
||||||
|
|
||||||
if (with_opt) {
|
if (with_opt) {
|
||||||
net_req->opt = buf;
|
net_req->opt = buf;
|
||||||
buf[0] = 0; /* dname for . */
|
buf[0] = 0; /* dname for . */
|
||||||
|
@ -907,7 +913,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
edns_maximum_udp_payload_size,
|
edns_maximum_udp_payload_size,
|
||||||
edns_extended_rcode, edns_version, edns_do_bit,
|
edns_extended_rcode, edns_version, edns_do_bit,
|
||||||
opt_options_size, noptions, options,
|
opt_options_size, noptions, options,
|
||||||
netreq_sz - sizeof(getdns_network_req), max_query_sz);
|
netreq_sz - sizeof(getdns_network_req), max_query_sz,
|
||||||
|
extensions);
|
||||||
|
|
||||||
if (a_aaaa_query)
|
if (a_aaaa_query)
|
||||||
network_req_init(result->netreqs[1], result,
|
network_req_init(result->netreqs[1], result,
|
||||||
|
@ -917,7 +924,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
||||||
edns_maximum_udp_payload_size,
|
edns_maximum_udp_payload_size,
|
||||||
edns_extended_rcode, edns_version, edns_do_bit,
|
edns_extended_rcode, edns_version, edns_do_bit,
|
||||||
opt_options_size, noptions, options,
|
opt_options_size, noptions, options,
|
||||||
netreq_sz - sizeof(getdns_network_req), max_query_sz);
|
netreq_sz - sizeof(getdns_network_req), max_query_sz,
|
||||||
|
extensions);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1147,12 +1147,14 @@ getdns_return_t
|
||||||
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
|
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
|
||||||
{
|
{
|
||||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||||
|
getdns_bindata root = { 1, (void *)"" };
|
||||||
getdns_bindata *name;
|
getdns_bindata *name;
|
||||||
getdns_bindata *rdata_raw;
|
getdns_bindata *rdata_raw;
|
||||||
getdns_dict *rdata;
|
getdns_dict *rdata;
|
||||||
uint32_t rr_type;
|
uint32_t rr_type;
|
||||||
uint32_t rr_class = GETDNS_RRCLASS_IN;
|
uint32_t rr_class = GETDNS_RRCLASS_IN;
|
||||||
uint32_t rr_ttl = 0;
|
uint32_t rr_ttl = 0;
|
||||||
|
uint32_t value;
|
||||||
const _getdns_rr_def *rr_def;
|
const _getdns_rr_def *rr_def;
|
||||||
const _getdns_rdata_def *rd_def, *rep_rd_def;
|
const _getdns_rdata_def *rd_def, *rep_rd_def;
|
||||||
int n_rdata_fields, rep_n_rdata_fields;
|
int n_rdata_fields, rep_n_rdata_fields;
|
||||||
|
@ -1164,18 +1166,35 @@ _getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
|
||||||
assert(rr_dict);
|
assert(rr_dict);
|
||||||
assert(buf);
|
assert(buf);
|
||||||
|
|
||||||
if ((r = getdns_dict_get_bindata(rr_dict, "name", &name)))
|
|
||||||
return r;
|
|
||||||
gldns_buffer_write(buf, name->data, name->size);
|
|
||||||
|
|
||||||
if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type)))
|
if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type)))
|
||||||
return r;
|
return r;
|
||||||
|
if ((r = getdns_dict_get_bindata(rr_dict, "name", &name))) {
|
||||||
|
if (r == GETDNS_RETURN_NO_SUCH_DICT_NAME &&
|
||||||
|
rr_type == GETDNS_RRTYPE_OPT) {
|
||||||
|
name = &root;
|
||||||
|
} else
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
gldns_buffer_write(buf, name->data, name->size);
|
||||||
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
|
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
|
||||||
|
|
||||||
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
|
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
|
||||||
|
if (rr_type == GETDNS_RRTYPE_OPT)
|
||||||
|
(void) getdns_dict_get_int(
|
||||||
|
rr_dict, "udp_payload_size", &rr_class);
|
||||||
gldns_buffer_write_u16(buf, (uint16_t)rr_class);
|
gldns_buffer_write_u16(buf, (uint16_t)rr_class);
|
||||||
|
|
||||||
(void) getdns_dict_get_int(rr_dict, "ttl", &rr_ttl);
|
(void) getdns_dict_get_int(rr_dict, "ttl", &rr_ttl);
|
||||||
|
if (rr_type == GETDNS_RRTYPE_OPT) {
|
||||||
|
if (!getdns_dict_get_int(rr_dict, "extended_rcode", &value))
|
||||||
|
rr_ttl = (rr_ttl & 0x00FFFFFF)|((value & 0xFF) << 24);
|
||||||
|
if (!getdns_dict_get_int(rr_dict, "version", &value))
|
||||||
|
rr_ttl = (rr_ttl & 0xFF00FFFF)|((value & 0xFF) << 16);
|
||||||
|
if (!getdns_dict_get_int(rr_dict, "z", &value))
|
||||||
|
rr_ttl = (rr_ttl & 0xFFFF0000)| (value & 0xFFFF);
|
||||||
|
if (!getdns_dict_get_int(rr_dict, "do", &value))
|
||||||
|
rr_ttl = (rr_ttl & 0xFFFF7FFF)| (value ? 0x8000 : 0);
|
||||||
|
}
|
||||||
gldns_buffer_write_u32(buf, rr_ttl);
|
gldns_buffer_write_u32(buf, rr_ttl);
|
||||||
|
|
||||||
/* Does rdata contain compressed names?
|
/* Does rdata contain compressed names?
|
||||||
|
|
Loading…
Reference in New Issue