msgencode.c File Reference

This file contains a routines to encode DNS messages. More...

#include "config.h"
#include "util/data/msgencode.h"
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"
#include "util/data/dname.h"
#include "util/log.h"
#include "util/regional.h"
#include "util/net_help.h"

Data Structures

struct  compress_tree_node
 Data structure to help domain name compression in outgoing messages. More...

Defines

#define RETVAL_OUTMEM   -2
 return code that means the function ran out of memory.
#define RETVAL_TRUNC   -4
 return code that means the data did not fit (completely) in the packet
#define RETVAL_OK   0
 return code that means all is peachy keen.

Functions

static int compress_tree_search (struct compress_tree_node **tree, uint8_t *dname, int labs, struct compress_tree_node **match, int *matchlabels, struct compress_tree_node ***insertpt)
 Find domain name in tree, returns exact and closest match.
static struct compress_tree_nodecompress_tree_lookup (struct compress_tree_node **tree, uint8_t *dname, int labs, struct compress_tree_node ***insertpt)
 Lookup a domain name in compression tree.
static struct compress_tree_nodecompress_tree_newnode (uint8_t *dname, int labs, size_t offset, struct regional *region)
 Create node for domain name compression tree.
static int compress_tree_store (uint8_t *dname, int labs, size_t offset, struct regional *region, struct compress_tree_node *closest, struct compress_tree_node **insertpt)
 Store domain name and ancestors into compression tree.
static int write_compressed_dname (ldns_buffer *pkt, uint8_t *dname, int labs, struct compress_tree_node *p)
 compress a domain name
static int compress_owner (struct ub_packed_rrset_key *key, ldns_buffer *pkt, struct regional *region, struct compress_tree_node **tree, size_t owner_pos, uint16_t *owner_ptr, int owner_labs)
 compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC
static int compress_any_dname (uint8_t *dname, ldns_buffer *pkt, int labs, struct regional *region, struct compress_tree_node **tree)
 compress any domain name to the packet, return RETVAL_*
static const ldns_rr_descriptor * type_rdata_compressable (struct ub_packed_rrset_key *key)
 return true if type needs domain name compression in rdata
static int compress_rdata (ldns_buffer *pkt, uint8_t *rdata, size_t todolen, struct regional *region, struct compress_tree_node **tree, const ldns_rr_descriptor *desc)
 compress domain names in rdata, return RETVAL_*
static int rrset_belongs_in_reply (ldns_pkt_section s, uint16_t rrtype, uint16_t qtype, int dnssec)
 Returns true if RR type should be included.
static int packed_rrset_encode (struct ub_packed_rrset_key *key, ldns_buffer *pkt, uint16_t *num_rrs, uint32_t timenow, struct regional *region, int do_data, int do_sig, struct compress_tree_node **tree, ldns_pkt_section s, uint16_t qtype, int dnssec)
 store rrset in buffer in wireformat, return RETVAL_*
static int insert_section (struct reply_info *rep, size_t num_rrsets, uint16_t *num_rrs, ldns_buffer *pkt, size_t rrsets_before, uint32_t timenow, struct regional *region, struct compress_tree_node **tree, ldns_pkt_section s, uint16_t qtype, int dnssec)
 store msg section in wireformat buffer, return RETVAL_*
static int insert_query (struct query_info *qinfo, struct compress_tree_node **tree, ldns_buffer *buffer, struct regional *region)
 store query section in wireformat buffer, return RETVAL
int reply_info_encode (struct query_info *qinfo, struct reply_info *rep, uint16_t id, uint16_t flags, ldns_buffer *buffer, uint32_t timenow, struct regional *region, uint16_t udpsize, int dnssec)
 Regenerate the wireformat from the stored msg reply.
uint16_t calc_edns_field_size (struct edns_data *edns)
 Estimate size of EDNS record in packet.
void attach_edns_record (ldns_buffer *pkt, struct edns_data *edns)
 Attach EDNS record to buffer.
int reply_info_answer_encode (struct query_info *qinf, struct reply_info *rep, uint16_t id, uint16_t qflags, ldns_buffer *pkt, uint32_t timenow, int cached, struct regional *region, uint16_t udpsize, struct edns_data *edns, int dnssec, int secure)
 Generate answer from reply_info.
void qinfo_query_encode (ldns_buffer *pkt, struct query_info *qinfo)
 Encode query packet.
void error_encode (ldns_buffer *buf, int r, struct query_info *qinfo, uint16_t qid, uint16_t qflags, struct edns_data *edns)
 Encode an error.


Detailed Description

This file contains a routines to encode DNS messages.


Define Documentation

#define RETVAL_OUTMEM   -2

return code that means the function ran out of memory.

negative so it does not conflict with DNS rcodes.

Referenced by compress_any_dname(), compress_owner(), and insert_query().

#define RETVAL_OK   0

return code that means all is peachy keen.

Equal to DNS rcode NOERROR

Referenced by compress_any_dname(), compress_owner(), compress_rdata(), insert_query(), insert_section(), packed_rrset_encode(), and reply_info_encode().


Function Documentation

static int compress_tree_search ( struct compress_tree_node **  tree,
uint8_t *  dname,
int  labs,
struct compress_tree_node **  match,
int *  matchlabels,
struct compress_tree_node ***  insertpt 
) [static]

Find domain name in tree, returns exact and closest match.

Parameters:
tree,: root of tree.
dname,: pointer to uncompressed dname.
labs,: number of labels in domain name.
match,: closest or exact match. guaranteed to be smaller or equal to the sought dname. can be null if the tree is empty.
matchlabels,: number of labels that match with closest match. can be zero is there is no match.
insertpt,: insert location for dname, if not found.
Returns:
: 0 if no exact match.

References compress_tree_node::dname, dname_lab_cmp(), compress_tree_node::labs, compress_tree_node::left, and compress_tree_node::right.

Referenced by compress_tree_lookup().

static struct compress_tree_node* compress_tree_lookup ( struct compress_tree_node **  tree,
uint8_t *  dname,
int  labs,
struct compress_tree_node ***  insertpt 
) [static, read]

Lookup a domain name in compression tree.

Parameters:
tree,: root of tree (not the node with '.').
dname,: pointer to uncompressed dname.
labs,: number of labels in domain name.
insertpt,: insert location for dname, if not found.
Returns:
: 0 if not found or compress treenode with best compression.

References compress_tree_search(), compress_tree_node::labs, and compress_tree_node::parent.

Referenced by compress_any_dname(), and compress_owner().

static struct compress_tree_node* compress_tree_newnode ( uint8_t *  dname,
int  labs,
size_t  offset,
struct regional region 
) [static, read]

Create node for domain name compression tree.

Parameters:
dname,: pointer to uncompressed dname (stored in tree).
labs,: number of labels in dname.
offset,: offset into packet for dname.
region,: how to allocate memory for new node.
Returns:
new node or 0 on malloc failure.

References compress_tree_node::dname, compress_tree_node::labs, compress_tree_node::left, compress_tree_node::offset, compress_tree_node::parent, regional_alloc(), and compress_tree_node::right.

Referenced by compress_tree_store().

static int compress_tree_store ( uint8_t *  dname,
int  labs,
size_t  offset,
struct regional region,
struct compress_tree_node closest,
struct compress_tree_node **  insertpt 
) [static]

Store domain name and ancestors into compression tree.

Parameters:
dname,: pointer to uncompressed dname (stored in tree).
labs,: number of labels in dname.
offset,: offset into packet for dname.
region,: how to allocate memory for new node.
closest,: match from previous lookup, used to compress dname. may be NULL if no previous match. if the tree has an ancestor of dname already, this must be it.
insertpt,: where to insert the dname in tree.
Returns:
: 0 on memory error.

References compress_tree_newnode(), compress_tree_node::labs, log_assert, compress_tree_node::parent, PTR_MAX_OFFSET, and compress_tree_node::right.

Referenced by compress_any_dname(), compress_owner(), and insert_query().

int reply_info_encode ( struct query_info qinfo,
struct reply_info rep,
uint16_t  id,
uint16_t  flags,
ldns_buffer *  buffer,
uint32_t  timenow,
struct regional region,
uint16_t  udpsize,
int  dnssec 
)

Regenerate the wireformat from the stored msg reply.

If the buffer is too small then the message is truncated at a whole rrset and the TC bit set, or whole rrsets are left out of the additional and the TC bit is not set.

Parameters:
qinfo,: query info to store.
rep,: reply to store.
id,: id value to store, network order.
flags,: flags value to store, host order.
buffer,: buffer to store the packet into.
timenow,: time now, to adjust ttl values.
region,: to store temporary data in.
udpsize,: size of the answer, 512, from EDNS, or 64k for TCP.
dnssec,: if 0 DNSSEC records are omitted from the answer.
Returns:
: nonzero is success, or 0 on error: malloc failure (no log_err has been done).

References reply_info::an_numrrsets, reply_info::ar_numrrsets, insert_query(), insert_section(), reply_info::ns_numrrsets, reply_info::qdcount, query_info::qtype, RETVAL_OK, and RETVAL_TRUNC.

Referenced by log_dns_msg(), perf_encode(), reply_info_answer_encode(), and testpkt().

uint16_t calc_edns_field_size ( struct edns_data edns  ) 

Estimate size of EDNS record in packet.

EDNS record will be no larger.

Parameters:
edns,: edns data or NULL.
Returns:
octets to reserve for EDNS.

References edns_data::edns_present.

Referenced by error_encode(), reply_info_answer_encode(), and testpkt().

void attach_edns_record ( ldns_buffer *  pkt,
struct edns_data edns 
)

Attach EDNS record to buffer.

Buffer has complete packet. There must be enough room left for the EDNS record.

Parameters:
pkt,: packet added to.
edns,: if NULL or present=0, nothing is added to the packet.

References edns_data::bits, edns_data::edns_present, edns_data::edns_version, edns_data::ext_rcode, and edns_data::udp_size.

Referenced by chaos_replystr(), error_encode(), outnet_serviced_query(), perf_encode(), qlist_parse_line(), reply_info_answer_encode(), serviced_encode(), testpkt(), and worker_handle_request().

int reply_info_answer_encode ( struct query_info qinf,
struct reply_info rep,
uint16_t  id,
uint16_t  qflags,
ldns_buffer *  dest,
uint32_t  timenow,
int  cached,
struct regional region,
uint16_t  udpsize,
struct edns_data edns,
int  dnssec,
int  secure 
)

Generate answer from reply_info.

Parameters:
qinf,: query information that provides query section in packet.
rep,: reply to fill in.
id,: id word from the query.
qflags,: flags word from the query.
dest,: buffer to put message into; will truncate if it does not fit.
timenow,: time to subtract.
cached,: set true if a cached reply (so no AA bit). set false for the first reply.
region,: where to allocate temp variables (for compression).
udpsize,: size of the answer, 512, from EDNS, or 64k for TCP.
edns,: EDNS data included in the answer, NULL for none. or if edns_present = 0, it is not included.
dnssec,: if 0 DNSSEC records are omitted from the answer.
secure,: if 1, the AD bit is set in the reply.
Returns:
: 0 on error (server failure).

References attach_edns_record(), reply_info::authoritative, BIT_AA, BIT_AD, BIT_CD, BIT_QR, BIT_RD, calc_edns_field_size(), reply_info::flags, log_assert, log_err(), and reply_info_encode().

Referenced by answer_from_cache(), answer_norec_from_cache(), local_encode(), mesh_do_callback(), and mesh_send_reply().

void qinfo_query_encode ( ldns_buffer *  pkt,
struct query_info qinfo 
)

Encode query packet.

Assumes the buffer is large enough.

Parameters:
pkt,: where to store the packet.
qinfo,: query info.

References log_assert, query_info::qclass, query_info::qname, query_info::qname_len, and query_info::qtype.

Referenced by qlist_parse_line(), and write_q().

void error_encode ( ldns_buffer *  pkt,
int  r,
struct query_info qinfo,
uint16_t  qid,
uint16_t  qflags,
struct edns_data edns 
)

Encode an error.

With QR and RA set.

Parameters:
pkt,: where to store the packet.
r,: RCODE value to encode.
qinfo,: if not NULL, the query is included.
qid,: query ID to set in packet. network order.
qflags,: original query flags (to copy RD and CD bits). host order.
edns,: if not NULL, this is the query edns info, and an edns reply is attached. Only attached if EDNS record fits reply.

References attach_edns_record(), BIT_CD, BIT_QR, BIT_RA, BIT_RD, edns_data::bits, calc_edns_field_size(), EDNS_ADVERTISED_SIZE, EDNS_ADVERTISED_VERSION, EDNS_DO, edns_data::edns_version, edns_data::ext_rcode, query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, and edns_data::udp_size.

Referenced by answer_from_cache(), answer_norec_from_cache(), libworker_bg_done_cb(), local_encode(), lz_zone_answer(), mesh_new_client(), mesh_send_reply(), and worker_handle_request().


Generated on Tue Oct 13 06:45:51 2009 for unbound by  doxygen 1.5.9