DNS query is composed of a DNS request (question) and response (answer). This application only handles DNS query type "question", and provides a simple response. Implementation of DNS records database (zones) is not done as that is beyond the scope of purpose for this project.
Parsing EDNS opt RR is supported along with EDNS client subnet extension.
A single structure is used to hold query request and query response. Depending if query arrived over UDP or TCP, appropriate buffers are made available providing access to raw query data (as received or to be sent over the network).
|
| void | query_init (query_t *q, config_t *cfg, uint8_t protocol) |
| |
| void | query_reset (query_t *q) |
| |
| void | query_clean (query_t *q) |
| |
| int | query_tcp_response_buffer_increase (query_t *q) |
| |
| int | query_parse_edns_ext_cs (edns_client_subnet_t *cs) |
| |
| int | query_parse_edns_ext (query_t *q, unsigned char *buf, unsigned char *eobuf) |
| |
| int | query_parse_request_rr_additional_edns (query_t *q, unsigned char *ptr) |
| |
| int | query_parse_request_rr_question (query_t *q) |
| |
| void | query_parse (query_t *q) |
| |
| void | query_resolve (query_t *q) |
| |
| int | query_pack_edns (uint8_t *buf, uint16_t buf_len, edns_t *edns) |
| |
| int | query_pack_rr (const unsigned char *name, rr_record_t *rr, unsigned char *buf, uint16_t buf_len, const unsigned char **dnptrs, const unsigned char **lastdnptr) |
| |
| int | query_response_pack (query_t *q) |
| |
| int | query_log (char *buf, size_t buf_len, query_t *q) |
| |
| void | query_log_rotate (query_log_t *query_log) |
| |
| void * | query_log_loop (void *args) |
| |
| void | query_report_metrics (query_t *, metrics_t *metrics) |
| |
◆ edns_client_subnet_t
Structure for EDNS client subnet option.
◆ edns_t
Structure for EDNS optional resource record.
◆ query_log_loop_args_t
◆ query_log_t
Stucture describes a query log object.
Queries are logged into a buffer. There are two buffers, one is active, while the other one (inactive buffer) is having its data written to disk. This enables us to have no blocking operations (such as writing to disk) in the vectorloop.
Query logging thread uses channels to notify vectorloop thread when it should swap log buffers. Once VL thread swaps buffers, it sends a message back to query logging thread indicating so, which in turn signals the query logging thread that it should log data from VL inactive buffer to disk. Once data is written to disk the process repeats.
Each vectorloop thread has its own set of query log buffers.
Size of each buffer is set by configuration setting query_log_buffer_size.
◆ query_t
Structure describes a DNS query.
◆ rr_record_t
Structure describes a DNS Resource Record.
◆ query_clean()
Clean a query object. This releases all memory owned by query object.
- Parameters
-
◆ query_init()
Initialize a query object.
- Parameters
-
| q | Query object to initialize. |
| cfg | Configuration with settings to use. |
| protocol | Transport protocol used for query. Valid options are 0 = UDP, 1 = TCP. |
◆ query_log()
| int query_log |
( |
char * |
buf, |
|
|
size_t |
buf_len, |
|
|
query_t * |
q |
|
) |
| |
Log query to buffer.
Query log entry ends with new line "\n" (one query per line).
- Parameters
-
| buf | Buffer to log query to. |
| buf_len | Length of buffer (available space). |
| q | Query to log. |
- Returns
- Returns number of bytes added to buf on success, otherwise returns 0 and error occurred (ie not enough room in buffer, or not a logable query end code) and nothing was added to buf.
◆ query_log_loop()
| void * query_log_loop |
( |
void * |
args | ) |
|
Function polls vectorloop threads for query log data and writes it to file. This function is meant to run in its own dedicated thread.
- Parameters
-
| args | Structure with settings to use. |
- Returns
- Returns nULL just to abide by the pthread API.
◆ query_log_rotate()
Rotate query log.
Active log to write queries is switched to the other side.
- Parameters
-
| query_log | Query log to rotate. |
◆ query_pack_edns()
| int query_pack_edns |
( |
uint8_t * |
buf, |
|
|
uint16_t |
buf_len, |
|
|
edns_t * |
edns |
|
) |
| |
Pack EDNS and it extensions into buffer.
- Parameters
-
| buf | Buffer to pack EDNS and extensions into. |
| buf_len | Length in bytes of available space in buffer. |
| edns | EDNS object to pack. |
- Returns
- On success returns number of bytes packed into buffer. 0 is returned if edns object does not contain valid data. -1 is returned if there is not enough room in buffer to pack EDNS and all its extensions in which case buf is left untouched.
◆ query_pack_rr()
| int query_pack_rr |
( |
const unsigned char * |
name, |
|
|
rr_record_t * |
rr, |
|
|
unsigned char * |
buf, |
|
|
uint16_t |
buf_len, |
|
|
const unsigned char ** |
dnptrs, |
|
|
const unsigned char ** |
lastdnptr |
|
) |
| |
Pack resource record into buffer, non-EDNS. TO pack EDNS use query_pack_edns.
- Parameters
-
| name | Name to use to when packing RR. If NULL name in rr is used. |
| rr | Resource record to pack. |
| buf | Buffer into which to pack the record. |
| buf_len | Length (in bytes) of available space in buffer. |
| dnptrs | Pointer to first entry in domain name array used to track names already packed. |
| lastdnptr | Last entry in domain name array. |
- Returns
- On success returns number of bytes packed into buffer, Otherwise error occurred. Currently error can occur if there if not enough room in buffer to pack the record.
◆ query_parse()
◆ query_parse_edns_ext()
| int query_parse_edns_ext |
( |
query_t * |
q, |
|
|
unsigned char * |
buf, |
|
|
unsigned char * |
eobuf |
|
) |
| |
Parse EDNS extensions.
Format of EDNS option is: 2 bytes = Option code, 2 bytes = Option length (length that follows), Option length bytes = option specific
- Parameters
-
| q | Query to parse extensions into. |
| buf | Buffer to parse extensions from. |
| eobuf | End of buffer. |
- Returns
- Returns 0 on success, otherwise an error occurred i.e. format error.
◆ query_parse_edns_ext_cs()
Parse EDNS extension client subnet.
Format is:
2 bytes = family
1 byte = source netmask
1 byte = scope netmask
remaining bytes = client subnet
- Parameters
-
| cs | EDNS client subnet object to parse data into. |
- Returns
- Returns 0 on success, otherwise error occurred i.e. format error or unsupported address family.
◆ query_parse_request_rr_additional_edns()
| int query_parse_request_rr_additional_edns |
( |
query_t * |
q, |
|
|
unsigned char * |
ptr |
|
) |
| |
Parse query request additional section looking for EDNS RR and if found parse EDNS RR.
- Parameters
-
| q | Query to parse request additional section EDNS opt RR. |
| ptr | Pointer in request buffer where additional section starts. |
- Returns
- On success returns number of bytes consumed. On error returns -1 in which case query parameter end_code is set.
◆ query_parse_request_rr_question()
| int query_parse_request_rr_question |
( |
query_t * |
q | ) |
|
Parse query request question RR.
Format on the wire per RFC 1035 is:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ | | / QNAME / / / +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ | QTYPE | +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+ | QCLASS | +–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+
- Parameters
-
| q | Query for which to parse request question. |
- Returns
- On success returns number of bytes from request buffer that are the question RR. On error returns -1 in which case query parameter end_code is set.
◆ query_report_metrics()
Report query metrics.
- Parameters
-
| q | Query to report metrics for. |
| metrics | Metrics object where to report metrics. |
◆ query_reset()
Reset query object so it is suitable to be reused for new query processing.
- Parameters
-
◆ query_resolve()
Resolve a query and if appropriate pack the answer into response buffer.
- Parameters
-
◆ query_response_pack()
| int query_response_pack |
( |
query_t * |
q | ) |
|
Pack query response into query response buffer.
- Parameters
-
| q | Query to pack response for |
- Returns
- Returns 0 on success otherwise error occurred: -1 indicates that there was not enough room to pack full response and response is truncated.
◆ query_tcp_response_buffer_increase()
| int query_tcp_response_buffer_increase |
( |
query_t * |
q | ) |
|
Increase the query response buffer size. This is only valid if query is used with TCP transport.
Response buffer size is increased via call to realloc() in increments of RIP_NS_UDP_MAXMSG up to max size of RIP_NS_MAXMSG.
- Parameters
-
| q | Query whose response buffer to increase. |
- Returns
- Returns 0 on success, otherwise an error occurred and response buffer was untouched.