Ripples 1.0
High Performant Software Architecture For Transaction Processing
Loading...
Searching...
No Matches
DNS Query

Detailed Description

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).

Data Structures

struct  edns_client_subnet_s
 
struct  edns_s
 
struct  query_s
 
struct  query_log_s
 
struct  query_log_loop_args_s
 
struct  rr_record_s
 

Typedefs

typedef struct edns_client_subnet_s edns_client_subnet_t
 
typedef struct edns_s edns_t
 
typedef struct query_s query_t
 
typedef struct query_log_s query_log_t
 
typedef struct query_log_loop_args_s query_log_loop_args_t
 
typedef struct rr_record_s rr_record_t
 

Functions

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)
 

Typedef Documentation

◆ edns_client_subnet_t

Structure for EDNS client subnet option.

◆ edns_t

typedef struct edns_s edns_t

Structure for EDNS optional resource record.

◆ query_log_loop_args_t

Structure holds arguments passed to query_log_loop function.

◆ query_log_t

typedef struct query_log_s 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

typedef struct query_s query_t

Structure describes a DNS query.

◆ rr_record_t

typedef struct rr_record_s rr_record_t

Structure describes a DNS Resource Record.

Function Documentation

◆ query_clean()

void query_clean ( query_t q)

Clean a query object. This releases all memory owned by query object.

Parameters
qQuery to clean.
Here is the caller graph for this function:

◆ query_init()

void query_init ( query_t q,
config_t cfg,
uint8_t  protocol 
)

Initialize a query object.

Parameters
qQuery object to initialize.
cfgConfiguration with settings to use.
protocolTransport protocol used for query. Valid options are 0 = UDP, 1 = TCP.
Here is the caller graph for this function:

◆ 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
bufBuffer to log query to.
buf_lenLength of buffer (available space).
qQuery 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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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
argsStructure with settings to use.
Returns
Returns nULL just to abide by the pthread API.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_log_rotate()

void query_log_rotate ( query_log_t query_log)

Rotate query log.

Active log to write queries is switched to the other side.

Parameters
query_logQuery log to rotate.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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
bufBuffer to pack EDNS and extensions into.
buf_lenLength in bytes of available space in buffer.
ednsEDNS 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.
Here is the caller graph for this function:

◆ 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
nameName to use to when packing RR. If NULL name in rr is used.
rrResource record to pack.
bufBuffer into which to pack the record.
buf_lenLength (in bytes) of available space in buffer.
dnptrsPointer to first entry in domain name array used to track names already packed.
lastdnptrLast 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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_parse()

void query_parse ( query_t q)

Parse query request from request buffer into query_t structure fields.

DNS request & response format is as per RFC 1035 https://datatracker.ietf.org/doc/html/rfc1035.

Parameters
qQuery to parse DNS request for.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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
qQuery to parse extensions into.
bufBuffer to parse extensions from.
eobufEnd of buffer.
Returns
Returns 0 on success, otherwise an error occurred i.e. format error.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_parse_edns_ext_cs()

int query_parse_edns_ext_cs ( edns_client_subnet_t cs)

Parse EDNS extension client subnet.

Format is:
2 bytes = family
1 byte = source netmask
1 byte = scope netmask
remaining bytes = client subnet

Parameters
csEDNS client subnet object to parse data into.
Returns
Returns 0 on success, otherwise error occurred i.e. format error or unsupported address family.
Here is the caller graph for this function:

◆ 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
qQuery to parse request additional section EDNS opt RR.
ptrPointer 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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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
qQuery 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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_report_metrics()

void query_report_metrics ( query_t q,
metrics_t metrics 
)

Report query metrics.

Parameters
qQuery to report metrics for.
metricsMetrics object where to report metrics.
Here is the caller graph for this function:

◆ query_reset()

void query_reset ( query_t q)

Reset query object so it is suitable to be reused for new query processing.

Parameters
qQuery to reset.
Here is the caller graph for this function:

◆ query_resolve()

void query_resolve ( query_t q)

Resolve a query and if appropriate pack the answer into response buffer.

Parameters
qQuery to resolve.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_response_pack()

int query_response_pack ( query_t q)

Pack query response into query response buffer.

Parameters
qQuery 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.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ 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
qQuery whose response buffer to increase.
Returns
Returns 0 on success, otherwise an error occurred and response buffer was untouched.
Here is the caller graph for this function: