1 /*------------------------------------------------------------------------------
2  *
3  * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4  * The YADIFA TM software product is provided under the BSD 3-clause license:
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *        * Redistributions in binary form must reproduce the above copyright
13  *          notice, this list of conditions and the following disclaimer in the
14  *          documentation and/or other materials provided with the distribution.
15  *        * Neither the name of EURid nor the names of its contributors may be
16  *          used to endorse or promote products derived from this software
17  *          without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  *------------------------------------------------------------------------------
32  *
33  */
34 
35 /** @defgroup dnspacket DNS Messages
36  *  @ingroup dnscore
37  *  @brief
38  *
39  * @{
40  */
41 /*----------------------------------------------------------------------------*/
42 
43 #pragma once
44 
45 #ifdef __cplusplus
46 extern "C"
47 {
48 #endif
49 
50     /*    ------------------------------------------------------------    */
51 
52 #include <sys/socket.h>
53 #include <arpa/inet.h>
54 #include <ctype.h>
55 #include <netinet/in.h>
56 #include <dnscore/thread.h>
57 
58 #include <dnscore/rfc.h>
59 #include <dnscore/sys_types.h>
60 #include <dnscore/fingerprint.h>
61 #include <dnscore/host_address.h>
62 #include <dnscore/input_stream.h>
63 #include <dnscore/output_stream.h>
64 #include <dnscore/tsig.h>
65 #include <dnscore/network.h>
66 #include <dnscore/fdtools.h>
67 #include <dnscore/ptr_vector.h>
68 #include <dnscore/format.h>
69 
70 #include <dnscore/logger.h>
71 
72 // Processing flags
73 
74 #define PROCESS_FL_ADDITIONAL_AUTH      0x01
75 #define PROCESS_FL_AUTHORITY_AUTH       0x02
76 #define PROCESS_FL_ADDITIONAL_CACHE     0x04
77 #define PROCESS_FL_AUTHORITY_CACHE      0x08
78 #define PROCESS_FL_RECURSION            0x20
79 #define PROCESS_FL_TCP                  0x80
80 
81 #define NETWORK_BUFFER_SIZE 65536
82 
83 #define MESSAGE_PAYLOAD_IS_POINTER      1
84 
85     /**
86      * @note buffer MUST be aligned on 16 bits
87      */
88 
89 #define MESSAGE_HIFLAGS(buffer_) ((buffer_)[ 2])
90 #define MESSAGE_LOFLAGS(buffer_) ((buffer_)[ 3])
91 
92 #define MESSAGE_FLAGS(buffer_) GET_U16_AT((buffer_)[ 2])
93 
94 /* Only use constants with this */
95 #if AVOID_ANTIALIASING
96 
MESSAGE_FLAGS_OR_P(void * address,u16 f)97 static inline void MESSAGE_FLAGS_OR_P(void* address, u16 f)
98 {
99     u16 *p = (u16*)address;
100     *p |= f;
101 }
102 
MESSAGE_FLAGS_AND_P(void * address,u16 f)103 static inline void MESSAGE_FLAGS_AND_P(void* address, u16 f)
104 {
105     u16 *p = (u16*)address;
106     *p &= f;
107 }
108 
109 struct packet_writer;
110 struct dns_resource_record;
111 
112 #ifdef WORDS_BIGENDIAN
113 #define MESSAGE_FLAGS_OR(buffer_, hi_, lo_)   MESSAGE_FLAGS_OR_P(&(buffer_)[2], (u16)((u16)((lo_) & 0xff) | ((u16)(hi_) << 8)))
114 #define MESSAGE_FLAGS_AND(buffer_, hi_, lo_)  MESSAGE_FLAGS_AND_P(&(buffer_)[2], (u16)((u16)((lo_) & 0xff) | ((u16)(hi_) << 8)))
115 #define MESSAGE_FLAGS_SET(buffer_, hi_, lo_)  SET_U16_AT_P(&(buffer_)[2], (u16)((u16)((lo_) & 0xff) | ((u16)hi_ << 8)))
116 #else
117 #define MESSAGE_FLAGS_OR(buffer_, hi_, lo_)   MESSAGE_FLAGS_OR_P(&(buffer_)[2], (u16)(((u16)((hi_) & 0xff)) | (((u16)(lo_)) << 8)))
118 #define MESSAGE_FLAGS_AND(buffer_, hi_, lo_)  MESSAGE_FLAGS_AND_P(&(buffer_)[2], (u16)(((u16)((hi_) & 0xff)) | (((u16)(lo_)) << 8)))
119 #define MESSAGE_FLAGS_SET(buffer_, hi_, lo_)  SET_U16_AT_P(&(buffer_)[2], (u16)(((u16)((hi_) & 0xff)) | (((u16)(lo_)) << 8)))
120 #endif
121 
122 #define MESSAGE_ID(buffer_)                   GET_U16_AT_P(&(buffer_)[0])
123 #define MESSAGE_SET_ID(buffer_,id_)           SET_U16_AT_P(&(buffer_)[0],(id_))
124 
125 #else
126 
127 #ifdef WORDS_BIGENDIAN
128 #define MESSAGE_FLAGS_OR(buffer_, hi_, lo_)  *((u16*)&(buffer_[2])) |= (lo_ | ((u16)hi_ << 8))
129 #define MESSAGE_FLAGS_AND(buffer_, hi_, lo_) *((u16*)&(buffer_[2])) &= (lo_ | ((u16)hi_ << 8))
130 #define MESSAGE_FLAGS_SET(buffer_, hi_, lo_) *((u16*)&(buffer_[2]))  = (lo_ | ((u16)hi_ << 8))
131 #else
132 #define MESSAGE_FLAGS_OR(buffer_, hi_, lo_)  *((u16*)&(buffer_[2])) |= (hi_ | ((u16)lo_ << 8))
133 #define MESSAGE_FLAGS_AND(buffer_, hi_, lo_) *((u16*)&(buffer_[2])) &= (hi_ | ((u16)lo_ << 8))
134 #define MESSAGE_FLAGS_SET(buffer_, hi_, lo_) *((u16*)&(buffer_[2]))  = (hi_ | ((u16)lo_ << 8))
135 #endif
136 
137 #define MESSAGE_ID(buffer)	(*((u16*)&(buffer)[ 0]))
138 #define MESSAGE_SET_ID(buffer_,id_)	(*((u16*)&(buffer)[ 0])) = (id_)
139 
140 #endif
141 
142 #define MESSAGE_QR(buffer_)     (MESSAGE_HIFLAGS(buffer_) & QR_BITS)
143 #define MESSAGE_OP(buffer_)     (MESSAGE_HIFLAGS(buffer_) & OPCODE_BITS)
144 #define MESSAGE_AA(buffer_)     (MESSAGE_HIFLAGS(buffer_) & AA_BITS)
145 #define MESSAGE_TC(buffer_)  	(MESSAGE_HIFLAGS(buffer_) & TC_BITS)
146 #define MESSAGE_RD(buffer_)     (MESSAGE_HIFLAGS(buffer_) & RD_BITS)
147 
148 #define MESSAGE_RA(buffer_)  	(MESSAGE_LOFLAGS(buffer_) & RA_BITS)
149 #define MESSAGE_ZF(buffer_)  	(MESSAGE_LOFLAGS(buffer_) & Z_BITS)
150 #define MESSAGE_AD(buffer_)     (MESSAGE_LOFLAGS(buffer_) & AD_BITS)
151 #define MESSAGE_CD(buffer_)     (MESSAGE_LOFLAGS(buffer_) & CD_BITS)
152 #define MESSAGE_RCODE(buffer_)  (MESSAGE_LOFLAGS(buffer_) & RCODE_BITS)
153 
154 // the size of the section by index [0;3]
155 
156 #define MESSAGE_SECTION_COUNT(buffer_,index_)   GET_U16_AT(((buffer_)[4 + ((index_)<< 1)]))
157 
158 #define MESSAGE_QD(buffer_)   GET_U16_AT((buffer_)[4])
159 #define MESSAGE_AN(buffer_)   GET_U16_AT((buffer_)[6])
160 #define MESSAGE_NS(buffer_)   GET_U16_AT((buffer_)[8])
161 #define MESSAGE_AR(buffer_)   GET_U16_AT((buffer_)[10])
162 #define MESSAGE_NSAR(buffer_) GET_U32_AT((buffer_)[8])
163 
164 #define MESSAGE_SET_OP(buffer_, val_)   (MESSAGE_HIFLAGS(buffer_) = (MESSAGE_HIFLAGS(buffer_) & ~OPCODE_BITS) | (val_))
165 
166 #define MESSAGE_SET_QD(buffer_,val_)   SET_U16_AT((buffer_)[4],(val_))
167 #define MESSAGE_SET_AN(buffer_,val_)   SET_U16_AT((buffer_)[6],(val_))
168 #define MESSAGE_SET_NS(buffer_,val_)   SET_U16_AT((buffer_)[8],(val_))
169 #define MESSAGE_SET_AR(buffer_,val_)   SET_U16_AT((buffer_)[10],(val_))
170 #define MESSAGE_SET_NSAR(buffer_,val_) SET_U32_AT((buffer_)[8],(val_))
171 
172     /* DYNUPDATE rfc 2136 */
173 #define MESSAGE_ZO(buffer_)   GET_U16_AT((buffer_)[4])
174 #define MESSAGE_PR(buffer_)   GET_U16_AT((buffer_)[6])
175 #define MESSAGE_UP(buffer_)   GET_U16_AT((buffer_)[8])
176 
177 #define MESSAGE_SET_ZO(buffer_, val_)   SET_U16_AT((buffer_)[4],(val_))
178 #define MESSAGE_SET_PR(buffer_, val_)   SET_U16_AT((buffer_)[6],(val_))
179 #define MESSAGE_SET_UP(buffer_, val_)   SET_U16_AT((buffer_)[8],(val_))
180 
181 //#define MESSAGE_AD(buffer)	(*((u16*)&(buffer)[10]))
182 
183 #define MESGDATA_TAG 0x415441444753454d
184 
185 #if DNSCORE_HAS_TSIG_SUPPORT
186 
187 typedef struct message_tsig message_tsig;
188 
189 struct message_tsig
190 {
191     const tsig_item *tsig;
192 
193     u16 reserved_0; /* ALIGN32 */
194     u16 timehi;     /* NETWORK */
195 
196     u32 timelo;     /* NETWORK */
197 
198     u16 fudge;      /* NETWORK */
199     u16 mac_size;   /* NATIVE  */
200 
201     u16 original_id;/* NETWORK */
202     u16 error;      /* NETWORK */
203 
204     u16 other_len;  /* NETWORK */
205     u16 tsig_offset;// keeps the tsig_offset in the message for internal processing, do not use directly
206 
207     u32 reserved_2; /* ALIGN64 */
208 
209     u8 mac[64];
210     u8 *other;
211 
212     tsig_hmac_t hmac;       /* only used for tcp */
213     s8 tcp_tsig_countdown;  /* maximum value is supposed to be 100 */
214     u8 mac_algorithm;
215 };
216 
217 #endif
218 
219 /* A memory pool for the lookup's benefit */
220 
221 #define MESSAGE_POOL_SIZE 0x20000
222 
223 // flags for MESSAGE_MAKE_QUERY_EX
224 #define MESSAGE_EDNS0_SIZE      0x4000 // any bit that is not set in EDNS0
225 #define MESSAGE_EDNS0_DNSSEC    0x8000
226 
227 #define MESSAGE_BUFFER_SIZE     0x10500
228 
229 #define MESSAGE_DATA_CONTROL_BUFFER_SIZE 64
230 
231 struct message_data
232 {
233     struct msghdr _msghdr;
234     struct iovec  _iovec;
235     socketaddress _sender;  // who the sender is
236     u8 *_ar_start;          // for the TSIG
237 
238     // THIS CROUP IS COPIED USING A MEMCPY IN message_dup() ->
239 
240     u32 _rcode_ext;         // network endian
241     finger_print _status;   // contains an RCODE, why is it separated from the buffer ?
242 #if MESSAGE_PAYLOAD_IS_POINTER
243     u32 _message_data_size; // the size of the allocated message structure
244 #endif
245     u16 _query_type;
246     u16 _query_class;
247     bool _edns;
248     bool _nsid;
249     u8 _referral;
250     u8 _control_buffer_size;
251     u8 _tcp_serial;
252 
253     /* bool is_delegation; for quick referral : later */
254 
255     u32 _buffer_size;                   // 32 bits aligned      // the maximum number of bytes we are ready to fill (can be changed)
256     u32 _buffer_size_limit;             //                      // the maximum number of bytes we can ever fill (as the buffer size is limited and )
257 
258     void    *_pool;                     // a pool to be used as a quick memory for the message
259     int     _pool_size;                 // a zdb query will store some temporary records in it. Consider size to be from 64K to 128K.
260 
261 #if DNSCORE_HAS_TSIG_SUPPORT
262     message_tsig _tsig;
263 #endif
264 
265     volatile u64 recv_us;
266     volatile u64 pushed_us;
267     volatile u64 popped_us;
268 
269     // <- THIS GROUP IS COPIED USING A MEMCPY IN message_dup()
270 
271     u8 _msghdr_control_buffer[(MESSAGE_DATA_CONTROL_BUFFER_SIZE + 7) & ~7]; // receives the destination address, IF MOVED, YOU NEED TO LOOK AT message_new_instance() ZEROMEMORY call
272     u8 _canonised_fqdn[(MAX_DOMAIN_LENGTH + 7) & ~7];
273 
274     /* Ensure (buffer - buffer_tcp_len) is equal to 2 ! */
275 #if MESSAGE_PAYLOAD_IS_POINTER
276     u8 *_buffer;
277 #else
278     u64 __reserved_force_align__1;      // 64 bits aligned
279     u16 __reserved_force_align__2;      // 32 bits aligned
280     u8  _buffer_tcp_len[2];             // DON'T SEPARATE THESE TWO (FIRST)
281     u8  _buffer[NETWORK_BUFFER_SIZE];   // DON'T SEPARATE THESE TWO (SECOND)
282 #endif
283 };
284 
285 typedef struct message_data message_data;
286 
287 struct message_data_with_buffer
288 {
289     message_data message;
290 #if MESSAGE_PAYLOAD_IS_POINTER
291     u64 __reserved_force_align__1;      // 64 bits aligned
292     u8 _buffer[NETWORK_BUFFER_SIZE];    // DON'T SEPARATE THESE TWO (SECOND)
293     u8 _buffer_limit[1];
294 #endif
295 };
296 
297 typedef struct message_data_with_buffer message_data_with_buffer;
298 
299 struct message_dnsupdate_data
300 {
301     struct message_dnsupdate_data                                 *next;
302     u32                                                            zttl;
303     u16                                                           ztype;
304     u16                                                          zclass;
305     u8                                         zname[MAX_DOMAIN_LENGTH];
306     output_stream                           zrdata[RDATA_MAX_LENGTH +1];
307     u8                                                         *zrdata2;
308     u16                                                      zrdata_len;
309 };
310 
311 typedef struct message_dnsupdate_data message_dnsupdate_data;
312 
313 /**
314  * A message_map is a message_data wrapper that got the records indexed
315  * Each vector entry points to the FQDN of a record in the message.
316  */
317 
318 struct message_map
319 {
320     const message_data *mesg;
321     ptr_vector records;
322     u16 section_base[4];
323 };
324 
325 typedef struct message_map message_map;
326 
327 
328 /*    ------------------------------------------------------------    */
329 
330 /**
331  * This sets a default, global, rate for functions supporting it.
332  * Rate is used in TCP streaming so that if the other end reads or writes
333  * too slowly then the connection is severed, harshly.
334  *
335  * @param rate
336  */
337 
338 void message_set_minimum_troughput_default(double rate);
339 
340 /*    ------------------------------------------------------------    */
341 
message_set_protocol(message_data * mesg,u8 protocol)342 static inline void message_set_protocol(message_data *mesg, u8 protocol)
343 {
344     // THIS SEEMS POINTLESS AS IT'S ONLY USED FOR LOGGING
345     (void)mesg;
346     (void)protocol;
347 }
348 
message_get_protocol(const message_data * mesg)349 static inline u8 message_get_protocol(const message_data *mesg)
350 {
351     // THIS SEEMS POINTLESS AS IT'S ONLY USED FOR LOGGING
352     (void)mesg;
353     return 0;
354 }
355 
356 /**
357  *
358  * The hope here is that the compiler will be smart enough to translates this as
359  * one move. (mov)
360  *
361  * @param mesg
362  * @param qd
363  * @param an
364  * @param ns
365  * @param ar
366  */
367 
message_set_query_answer_authority_additional_counts_ne(message_data * mesg,u16 qd,u16 an,u16 ns,u16 ar)368 static inline void message_set_query_answer_authority_additional_counts_ne(message_data *mesg, u16 qd, u16 an, u16 ns, u16 ar)
369 {
370 #ifdef WORDS_BIGENDIAN
371     u64 value = (((u64)qd) << 48) | (((u64)an) << 32) | (((u64)ns) << 16) | (((u64)ar)      );
372 #else
373     u64 value = (((u64)qd)      ) | (((u64)an) << 16) | (((u64)ns) << 32) | (((u64)ar) << 48);
374 #endif
375     SET_U64_AT(mesg->_buffer[4], value);
376 }
377 
message_set_query_answer_authority_additional_counts(message_data * mesg,u16 qd,u16 an,u16 ns,u16 ar)378 static inline void message_set_query_answer_authority_additional_counts(message_data *mesg, u16 qd, u16 an, u16 ns, u16 ar)
379 {
380 #ifdef WORDS_BIGENDIAN
381     u64 value = (((u64)ntohs(qd)) << 48) | (((u64)ntohs(an)) << 32) | (((u64)ntohs(ns)) << 16) | (((u64)ntohs(ar))      );
382 #else
383     u64 value = (((u64)ntohs(qd))      ) | (((u64)ntohs(an)) << 16) | (((u64)ntohs(ns)) << 32) | (((u64)ntohs(ar)) << 48);
384 #endif
385     SET_U64_AT(mesg->_buffer[4], value);
386 }
387 
message_set_authority_additional_counts(message_data * mesg,u16 ns,u16 ar)388 static inline void message_set_authority_additional_counts(message_data *mesg, u16 ns, u16 ar)
389 {
390 #ifdef WORDS_BIGENDIAN
391     u32 value = (((u32)ns) << 16) | (((u32)ar)      );
392 #else
393     u32 value = (((u32)ns)      ) | (((u32)ar) << 16);
394 #endif
395     MESSAGE_SET_NSAR(mesg->_buffer, value);
396 }
397 
message_set_pool_buffer(message_data * mesg,void * p,int size)398 static inline void message_set_pool_buffer(message_data *mesg, void *p, int size)
399 {
400     mesg->_pool = p;
401     mesg->_pool_size = size;
402 }
403 
message_get_pool_buffer(const message_data * mesg)404 static inline void* message_get_pool_buffer(const message_data *mesg)
405 {
406     return mesg->_pool;
407 }
408 
message_get_pool_size(const message_data * mesg)409 static inline int message_get_pool_size(const message_data *mesg)
410 {
411     return mesg->_pool_size;
412 }
413 
message_get_opcode(const message_data * mesg)414 static inline u8 message_get_opcode(const message_data *mesg)
415 {
416     return MESSAGE_OP(mesg->_buffer);
417 }
418 
message_set_opcode(message_data * mesg,u8 opcode)419 static inline void message_set_opcode(message_data *mesg, u8 opcode)
420 {
421     MESSAGE_SET_OP(mesg->_buffer, opcode);
422 }
423 
message_set_referral(message_data * mesg,u8 referral)424 static inline void message_set_referral(message_data *mesg, u8 referral)
425 {
426     mesg->_referral = referral;
427 }
428 
message_get_referral(const message_data * mesg)429 static inline u8 message_get_referral(const message_data *mesg)
430 {
431     return mesg->_referral;
432 }
433 
434 // Network Endian operations
435 
message_get_query_count_ne(const message_data * mesg)436 static inline u16 message_get_query_count_ne(const message_data *mesg)
437 {
438     return MESSAGE_QD(mesg->_buffer);
439 }
440 
message_set_answer_count_ne(message_data * mesg,u16 network_endian_value)441 static inline void message_set_answer_count_ne(message_data *mesg, u16 network_endian_value)
442 {
443     MESSAGE_SET_AN(mesg->_buffer, network_endian_value);
444 }
445 
message_get_answer_count_ne(const message_data * mesg)446 static inline u16 message_get_answer_count_ne(const message_data *mesg)
447 {
448     return MESSAGE_AN(mesg->_buffer);
449 }
450 
message_set_authority_count_ne(message_data * mesg,u16 network_endian_value)451 static inline void message_set_authority_count_ne(message_data *mesg, u16 network_endian_value)
452 {
453     MESSAGE_SET_NS(mesg->_buffer, network_endian_value);
454 }
455 
message_get_authority_count_ne(const message_data * mesg)456 static inline u16 message_get_authority_count_ne(const message_data *mesg)
457 {
458     return MESSAGE_NS(mesg->_buffer);
459 }
460 
message_set_additional_count_ne(message_data * mesg,u16 network_endian_value)461 static inline void message_set_additional_count_ne(message_data *mesg, u16 network_endian_value)
462 {
463     MESSAGE_SET_AR(mesg->_buffer, network_endian_value);
464 }
465 
message_get_additional_count_ne(const message_data * mesg)466 static inline u16 message_get_additional_count_ne(const message_data *mesg)
467 {
468     return MESSAGE_AR(mesg->_buffer);
469 }
470 
message_set_update_count_ne(message_data * mesg,u16 network_endian_value)471 static inline void message_set_update_count_ne(message_data *mesg, u16 network_endian_value)
472 {
473     MESSAGE_SET_UP(mesg->_buffer, network_endian_value);
474 }
475 
message_get_update_count_ne(const message_data * mesg)476 static inline u16 message_get_update_count_ne(const message_data *mesg)
477 {
478     return MESSAGE_UP(mesg->_buffer);
479 }
480 
message_get_prerequisite_count_ne(const message_data * mesg)481 static inline u16 message_get_prerequisite_count_ne(const message_data *mesg)
482 {
483     return MESSAGE_PR(mesg->_buffer);
484 }
485 
message_get_section_count_ne(const message_data * mesg,int section)486 static inline u16 message_get_section_count_ne(const message_data *mesg, int section)
487 {
488     return MESSAGE_SECTION_COUNT(mesg->_buffer, section);
489 }
490 
491 // Host endian
492 
message_get_query_count(const message_data * mesg)493 static inline u16 message_get_query_count(const message_data *mesg)
494 {
495     return ntohs(message_get_query_count_ne(mesg));
496 }
497 
message_set_answer_count(message_data * mesg,u16 host_endian_value)498 static inline void message_set_answer_count(message_data *mesg, u16 host_endian_value)
499 {
500     message_set_answer_count_ne(mesg, htons(host_endian_value));
501 }
502 
message_get_answer_count(const message_data * mesg)503 static inline u16 message_get_answer_count(const message_data *mesg)
504 {
505     return ntohs(message_get_answer_count_ne(mesg));
506 }
507 
message_set_authority_count(message_data * mesg,u16 host_endian_value)508 static inline void message_set_authority_count(message_data *mesg, u16 host_endian_value)
509 {
510     message_set_authority_count_ne(mesg, htons(host_endian_value));
511 }
512 
message_get_authority_count(const message_data * mesg)513 static inline u16 message_get_authority_count(const message_data *mesg)
514 {
515     return ntohs(message_get_authority_count_ne(mesg));
516 }
517 
message_set_additional_count(message_data * mesg,u16 host_endian_value)518 static inline void message_set_additional_count(message_data *mesg, u16 host_endian_value)
519 {
520     message_set_additional_count_ne(mesg, htons(host_endian_value));
521 }
522 
message_get_additional_count(const message_data * mesg)523 static inline u16 message_get_additional_count(const message_data *mesg)
524 {
525     return ntohs(message_get_additional_count_ne(mesg));
526 }
527 
message_add_additional_count(message_data * mesg,u16 value)528 static inline void message_add_additional_count(message_data *mesg, u16 value)
529 {
530     message_set_additional_count(mesg, message_get_additional_count(mesg) + value);
531 }
532 
message_sub_additional_count(message_data * mesg,u16 value)533 static inline void message_sub_additional_count(message_data *mesg, u16 value)
534 {
535     message_set_additional_count(mesg, message_get_additional_count(mesg) - value);
536 }
537 
message_set_update_count(message_data * mesg,u16 host_endian_value)538 static inline void message_set_update_count(message_data *mesg, u16 host_endian_value)
539 {
540     message_set_update_count_ne(mesg, htons(host_endian_value));
541 }
542 
message_get_update_count(const message_data * mesg)543 static inline u16 message_get_update_count(const message_data *mesg)
544 {
545     return ntohs(message_get_update_count_ne(mesg));
546 }
547 
message_add_update_count(message_data * mesg,u16 host_endian_value)548 static inline void message_add_update_count(message_data *mesg, u16 host_endian_value)
549 {
550     message_set_update_count(mesg, message_get_update_count(mesg) + host_endian_value);
551 }
552 
message_get_prerequisite_count(const message_data * mesg)553 static inline u16 message_get_prerequisite_count(const message_data *mesg)
554 {
555     return ntohs(message_get_prerequisite_count_ne(mesg));
556 }
557 
message_get_section_count(const message_data * mesg,int section)558 static inline u16 message_get_section_count(const message_data *mesg, int section)
559 {
560     return ntohs(message_get_section_count_ne(mesg, section));
561 }
562 
563 //
564 
message_isquery(const message_data * mesg)565 static inline bool message_isquery(const message_data *mesg)
566 {
567     return MESSAGE_QR(mesg->_buffer) == 0;
568 }
569 
message_isanswer(const message_data * mesg)570 static inline bool message_isanswer(const message_data *mesg)
571 {
572     return MESSAGE_QR(mesg->_buffer) != 0;
573 }
574 
message_istruncated(const message_data * mesg)575 static inline bool message_istruncated(const message_data *mesg)
576 {
577     return MESSAGE_TC(mesg->_buffer) != 0;
578 }
579 
message_set_truncated(message_data * mesg,bool truncated)580 static inline void message_set_truncated(message_data *mesg, bool truncated)
581 {
582     if(truncated)
583     {
584         MESSAGE_HIFLAGS(mesg->_buffer) |= TC_BITS;
585     }
586     else
587     {
588         MESSAGE_HIFLAGS(mesg->_buffer) &= ~TC_BITS;
589     }
590 }
591 
message_set_answer(message_data * mesg)592 static inline void message_set_answer(message_data *mesg)
593 {
594     MESSAGE_HIFLAGS(mesg->_buffer) |= QR_BITS;
595 }
596 
message_clear_answer(message_data * mesg)597 static inline void message_clear_answer(message_data *mesg)
598 {
599     MESSAGE_HIFLAGS(mesg->_buffer) &= ~QR_BITS;
600 }
601 
message_has_recursion_desired(const message_data * mesg)602 static inline bool message_has_recursion_desired(const message_data *mesg)
603 {
604     return MESSAGE_RD(mesg->_buffer) != 0;
605 }
606 
message_has_recursion_available(const message_data * mesg)607 static inline bool message_has_recursion_available(const message_data *mesg)
608 {
609     return MESSAGE_RA(mesg->_buffer) != 0;
610 }
611 
message_has_authenticated_data(const message_data * mesg)612 static inline bool message_has_authenticated_data(const message_data *mesg)
613 {
614     return MESSAGE_AD(mesg->_buffer) != 0;
615 }
616 
message_has_checking_disabled(const message_data * mesg)617 static inline bool message_has_checking_disabled(const message_data *mesg)
618 {
619     return MESSAGE_CD(mesg->_buffer) != 0;
620 }
621 
message_get_rcode(const message_data * mesg)622 static inline u8 message_get_rcode(const message_data *mesg)
623 {
624     return MESSAGE_RCODE(mesg->_buffer);
625 }
626 
message_or_rcode(message_data * mesg,u8 rcode)627 static inline void message_or_rcode(message_data *mesg, u8 rcode)
628 {
629     MESSAGE_LOFLAGS(mesg->_buffer) |= rcode;
630 }
631 
message_set_rcode(message_data * mesg,u8 rcode)632 static inline void message_set_rcode(message_data *mesg, u8 rcode)
633 {
634     MESSAGE_LOFLAGS(mesg->_buffer) = (MESSAGE_LOFLAGS(mesg->_buffer) & ~RCODE_BITS) | rcode;
635 }
636 
message_get_rcode_ext(const message_data * mesg)637 static inline u32 message_get_rcode_ext(const message_data *mesg)
638 {
639     return mesg->_rcode_ext;
640 }
641 
message_has_rcode_ext_dnssec(const message_data * mesg)642 static inline bool message_has_rcode_ext_dnssec(const message_data *mesg)
643 {
644     return (mesg->_rcode_ext & RCODE_EXT_DNSSEC) != 0;
645 }
646 
message_set_authoritative_answer(message_data * mesg)647 static inline void message_set_authoritative_answer(message_data *mesg)
648 {
649     MESSAGE_HIFLAGS(mesg->_buffer) |= AA_BITS|QR_BITS;
650 }
651 
message_set_truncated_answer(message_data * mesg)652 static inline void message_set_truncated_answer(message_data *mesg)
653 {
654     MESSAGE_HIFLAGS(mesg->_buffer) |= TC_BITS|QR_BITS;
655 }
656 
message_is_truncated(message_data * mesg)657 static inline bool message_is_truncated(message_data *mesg)
658 {
659     return (MESSAGE_HIFLAGS(mesg->_buffer) & TC_BITS) != 0;
660 }
661 
message_set_authoritative(message_data * mesg)662 static inline void message_set_authoritative(message_data *mesg)
663 {
664     MESSAGE_HIFLAGS(mesg->_buffer) |= AA_BITS;
665 }
666 
message_disable_authoritative(message_data * mesg)667 static inline void message_disable_authoritative(message_data *mesg)
668 {
669     MESSAGE_HIFLAGS(mesg->_buffer) &= ~AA_BITS;
670 }
671 
message_set_recursion_desired(message_data * mesg)672 static inline void message_set_recursion_desired(message_data *mesg)
673 {
674     MESSAGE_HIFLAGS(mesg->_buffer) |= RD_BITS;
675 }
676 
message_set_authenticated_data(message_data * mesg)677 static inline void message_set_authenticated_data(message_data *mesg)
678 {
679     MESSAGE_LOFLAGS(mesg->_buffer) |= AD_BITS;
680 }
681 
message_isauthoritative(const message_data * mesg)682 static inline bool  message_isauthoritative(const message_data *mesg)
683 {
684     return (MESSAGE_HIFLAGS(mesg->_buffer) & AA_BITS) != 0;
685 }
686 
message_apply_mask(message_data * mesg,int hi,int lo)687 static inline void message_apply_mask(message_data *mesg, int hi, int lo)
688 {
689     MESSAGE_FLAGS_AND(mesg->_buffer, (u8)hi, (u8)lo);
690 }
691 
message_apply_lo_mask(message_data * mesg,u8 lo)692 static inline void message_apply_lo_mask(message_data *mesg, u8 lo)
693 {
694     MESSAGE_LOFLAGS(mesg->_buffer) &= lo;
695 }
696 
message_get_query_type(const message_data * mesg)697 static inline u16 message_get_query_type(const message_data *mesg)
698 {
699     return mesg->_query_type;
700 }
701 
message_get_query_type_ptr(const message_data * mesg)702 static inline const u16* message_get_query_type_ptr(const message_data *mesg)
703 {
704     return &mesg->_query_type;
705 }
706 
message_set_query_type(message_data * mesg,u16 qtype)707 static inline void message_set_query_type(message_data *mesg, u16 qtype)
708 {
709     mesg->_query_type = qtype;
710 }
711 
message_get_query_class(const message_data * mesg)712 static inline u16 message_get_query_class(const message_data *mesg)
713 {
714     return mesg->_query_class;
715 }
716 
717 // mostly for printing with format
718 
message_get_query_class_ptr(const message_data * mesg)719 static inline const u16* message_get_query_class_ptr(const message_data *mesg)
720 {
721     return &mesg->_query_class;
722 }
723 
message_set_query_class(message_data * mesg,u16 qclass)724 static inline void message_set_query_class(message_data *mesg, u16 qclass)
725 {
726     mesg->_query_class = qclass;
727 }
728 
message_get_size_u16(const message_data * mesg)729 static inline u16 message_get_size_u16(const message_data *mesg)
730 {
731     return (u16)mesg->_msghdr.msg_iov[0].iov_len;
732 }
733 
message_get_size(const message_data * mesg)734 static inline size_t message_get_size(const message_data *mesg)
735 {
736     return mesg->_msghdr.msg_iov[0].iov_len;
737 }
738 
message_set_size(message_data * mesg,size_t size)739 static inline void message_set_size(message_data *mesg, size_t size)
740 {
741     mesg->_msghdr.msg_iov[0].iov_len = size;
742 }
743 
message_increase_size(message_data * mesg,size_t size)744 static inline void message_increase_size(message_data *mesg, size_t size)
745 {
746     mesg->_msghdr.msg_iov[0].iov_len += size;
747 }
748 
message_get_buffer_const(const message_data * mesg)749 static inline const u8 *message_get_buffer_const(const message_data *mesg)
750 {
751     return mesg->_buffer;
752 }
753 
message_get_buffer(message_data * mesg)754 static inline u8 *message_get_buffer(message_data *mesg)
755 {
756     return mesg->_buffer;
757 }
758 
message_get_flags(const message_data * mesg)759 static inline u16 message_get_flags(const message_data *mesg)
760 {
761     return MESSAGE_FLAGS(mesg->_buffer);
762 }
763 
message_get_flags_hi(const message_data * mesg)764 static inline u8 message_get_flags_hi(const message_data *mesg)
765 {
766     return MESSAGE_HIFLAGS(mesg->_buffer);
767 }
768 
message_get_flags_lo(const message_data * mesg)769 static inline u8 message_get_flags_lo(const message_data *mesg)
770 {
771     return MESSAGE_LOFLAGS(mesg->_buffer);
772 }
773 
message_set_flags_hi(message_data * mesg,u8 hi)774 static inline void message_set_flags_hi(message_data *mesg, u8 hi)
775 {
776     MESSAGE_HIFLAGS(mesg->_buffer) = hi;
777 }
778 
message_set_flags_lo(message_data * mesg,u8 lo)779 static inline void message_set_flags_lo(message_data *mesg, u8 lo)
780 {
781     MESSAGE_LOFLAGS(mesg->_buffer) = lo;
782 }
783 
message_get_op(message_data * mesg)784 static inline u8 message_get_op(message_data *mesg)
785 {
786     return MESSAGE_OP(mesg->_buffer);
787 }
788 
789 /**
790  * Returns a pointer to the first byte not set in the buffer (&buffer[size])
791  * WILL BE RENAMED INTO message_get_buffer_end(mesg)
792  * @param mesg
793  * @return
794  */
795 
message_get_buffer_limit(message_data * mesg)796 static inline u8 *message_get_buffer_limit(message_data *mesg)
797 {
798     return &mesg->_buffer[message_get_size(mesg)];
799 }
800 
message_get_buffer_limit_const(const message_data * mesg)801 static inline const u8 *message_get_buffer_limit_const(const message_data *mesg)
802 {
803     return &mesg->_buffer[message_get_size(mesg)];
804 }
805 
806 /**
807  * The maximum size of the buffer is, of course, a constant.
808  * This value is the one used to artificially limit the writing in the buffer.
809  * This is mostly used to reserve room for additional records (EDNS, TSIG)
810  *
811  * @param
812  * @return
813  */
814 
message_set_buffer_size(message_data * mesg,u32 size)815 static inline void message_set_buffer_size(message_data *mesg, u32 size)
816 {
817     assert(size <= mesg->_buffer_size_limit);
818     mesg->_buffer_size = size;
819 }
820 
message_reserve_buffer_size(message_data * mesg,u32 size)821 static inline void message_reserve_buffer_size(message_data *mesg, u32 size)
822 {
823     assert(size <= mesg->_buffer_size);
824     mesg->_buffer_size -= size;
825 }
826 
message_increase_buffer_size(message_data * mesg,u32 size)827 static inline void message_increase_buffer_size(message_data *mesg, u32 size)
828 {
829     assert(size + mesg->_buffer_size <= mesg->_buffer_size_limit);
830     mesg->_buffer_size += size;
831 }
832 
message_get_buffer_size(const message_data * mesg)833 static inline u32 message_get_buffer_size(const message_data *mesg)
834 {
835     return mesg->_buffer_size;
836 }
837 
message_reset_buffer_size(message_data * mesg)838 static inline void message_reset_buffer_size(message_data *mesg)
839 {
840     mesg->_buffer_size = mesg->_buffer_size_limit;
841 }
842 
message_get_buffer_size_max(const message_data * mesg)843 static inline u32 message_get_buffer_size_max(const message_data *mesg)
844 {
845     return mesg->_buffer_size_limit;
846 }
847 
848 /**
849  * Copies the data content into the buffer
850  */
851 
message_copy_buffer(const message_data * mesg,void * out_data,size_t data_size)852 static inline void message_copy_buffer(const message_data *mesg, void *out_data, size_t data_size)
853 {
854     yassert(data_size >= message_get_size(mesg));
855     (void)data_size;
856     memcpy(out_data, message_get_buffer_const(mesg), message_get_size(mesg));
857 }
858 
message_copy_into_buffer(message_data * mesg,const void * in_data,size_t data_size)859 static inline void message_copy_into_buffer(message_data *mesg, const void *in_data, size_t data_size)
860 {
861     if(data_size > message_get_buffer_size(mesg))
862     {
863         formatln("message_copy_into_buffer: %p data_size=%llu <= buffer_size=%u", mesg, data_size, message_get_buffer_size(mesg));
864     }
865     yassert(data_size <= message_get_buffer_size(mesg));
866     memcpy(message_get_buffer(mesg), in_data, data_size);
867     message_set_size(mesg, data_size);
868 }
869 
870 /**
871  * Copies the control content into the buffer
872  */
873 
message_copy_control(const message_data * mesg,void * out_data,size_t data_size)874 static inline u8 message_copy_control(const message_data *mesg, void *out_data, size_t data_size)
875 {
876 #ifndef WIN32
877     yassert(data_size >= mesg->_msghdr.msg_controllen);
878     (void)data_size;
879     memcpy(out_data, mesg->_msghdr.msg_control, mesg->_msghdr.msg_controllen);
880     return mesg->_msghdr.msg_controllen;
881 #else
882     return 0;
883 #endif
884 }
885 
message_control_size(const message_data * mesg)886 static inline u8 message_control_size(const message_data *mesg)
887 {
888     return mesg->_msghdr.msg_controllen;
889 }
890 
message_set_control(message_data * mesg,const void * data,size_t data_size)891 static inline void message_set_control(message_data *mesg, const void *data, size_t data_size)
892 {
893 #ifndef WIN32
894     yassert(data_size <= sizeof(mesg->_msghdr_control_buffer));
895     memcpy(mesg->_msghdr_control_buffer, data, data_size);
896     mesg->_msghdr.msg_controllen = data_size;
897 #if __FreeBSD__
898     if(data_size != 0)
899     {
900         mesg->_msghdr.msg_control = mesg->_msghdr_control_buffer;
901     }
902     else
903     {
904         mesg->_msghdr.msg_control = NULL;
905     }
906 #endif
907 #else
908 #endif
909 }
910 
message_reset_control_size(message_data * mesg)911 static inline void message_reset_control_size(message_data *mesg)
912 {
913 #ifndef WIN32
914 #if __FreeBSD__
915     mesg->_msghdr.msg_control = mesg->_msghdr_control_buffer;
916 #endif
917     mesg->_msghdr.msg_controllen = sizeof(mesg->_msghdr_control_buffer);
918 #else
919 #endif
920 }
921 
message_reset_control(message_data * mesg)922 static inline void message_reset_control(message_data *mesg)
923 {
924 #ifndef WIN32
925     mesg->_msghdr.msg_control = mesg->_msghdr_control_buffer;
926     mesg->_msghdr.msg_controllen = sizeof(mesg->_msghdr_control_buffer);
927 #else
928 #endif
929 }
930 
message_clear_control(message_data * mesg)931 static inline void message_clear_control(message_data *mesg)
932 {
933 #ifndef WIN32
934     mesg->_msghdr.msg_control = NULL;
935     mesg->_msghdr.msg_controllen = 0;
936 #else
937 #endif
938 }
939 
message_set_edns0(message_data * mesg,bool enabled)940 static inline void message_set_edns0(message_data *mesg, bool enabled)
941 {
942     mesg->_edns = enabled;
943 }
944 
message_is_edns0(const message_data * mesg)945 static inline bool message_is_edns0(const message_data *mesg)
946 {
947     return mesg->_edns;
948 }
949 
message_has_nsid(const message_data * mesg)950 static inline bool message_has_nsid(const message_data *mesg)
951 {
952     return mesg->_nsid;
953 }
954 
message_has_tsig(const message_data * mesg)955 static inline bool message_has_tsig(const message_data *mesg)
956 {
957     return mesg->_tsig.tsig != NULL;
958 }
959 
message_clear_hmac(message_data * mesg)960 static inline void message_clear_hmac(message_data *mesg)
961 {
962     if(mesg->_tsig.hmac != NULL)
963     {
964         hmac_free(mesg->_tsig.hmac);
965         mesg->_tsig.hmac = NULL;
966     }
967 }
968 
message_tsig_get_name(const message_data * mesg)969 static inline const u8 *message_tsig_get_name(const message_data *mesg)
970 {
971     return mesg->_tsig.tsig->name;
972 }
973 
message_tsig_get_epoch(const message_data * mesg)974 static inline s64 message_tsig_get_epoch(const message_data *mesg)
975 {
976     u64 then = (u64)ntohs(mesg->_tsig.timehi);
977     then <<= 32;
978     then |= (u64)ntohl(mesg->_tsig.timelo);
979     return (s64)then;
980 }
981 
message_tsig_get_fudge(const message_data * mesg)982 static inline s64 message_tsig_get_fudge(const message_data *mesg)
983 {
984     u64 then = (u64)ntohs(mesg->_tsig.fudge);
985     return (s64)then;
986 }
987 
message_tsig_mac_get_size(const message_data * mesg)988 static inline int message_tsig_mac_get_size(const message_data *mesg)
989 {
990     return mesg->_tsig.mac_size;
991 }
992 
message_tsig_set_error(message_data * mesg,u16 err)993 static inline void message_tsig_set_error(message_data *mesg, u16 err)
994 {
995     mesg->_tsig.error = err;
996 }
997 
message_tsig_get_error(message_data * mesg)998 static inline u16 message_tsig_get_error(message_data *mesg)
999 {
1000     return mesg->_tsig.error;
1001 }
1002 
1003 
message_tsig_mac_copy(const message_data * mesg,u8 * to)1004 static inline void message_tsig_mac_copy(const message_data *mesg, u8 *to)
1005 {
1006     memcpy(to, mesg->_tsig.mac, message_tsig_mac_get_size(mesg));
1007 }
1008 
message_tsig_mac_get_const(const message_data * mesg)1009 static inline const u8* message_tsig_mac_get_const(const message_data *mesg)
1010 {
1011     return mesg->_tsig.mac;
1012 }
1013 
message_tsig_copy_from(message_data * mesg,const message_data * source)1014 static inline void message_tsig_copy_from(message_data *mesg, const message_data *source)
1015 {
1016     message_tsig *d  = &mesg->_tsig;
1017     const message_tsig *s = &source->_tsig;
1018     memcpy(d, s, offsetof(message_tsig, mac));
1019     memcpy(d->mac, s->mac, s->mac_size);
1020     if((s->other != NULL) && (s->other_len > 0))
1021     {
1022         MALLOC_OR_DIE(u8*, d->other, s->other_len, TSIGOTHR_TAG);
1023         memcpy(d->other, s->other, s->other_len);
1024     }
1025     else
1026     {
1027         d->other = NULL;
1028     }
1029     d->hmac = s->hmac;
1030     d->tcp_tsig_countdown = s->tcp_tsig_countdown;
1031     d->mac_algorithm = s->mac_algorithm;
1032 }
1033 
message_tsig_set_key(message_data * mesg,const tsig_item * key)1034 static inline void message_tsig_set_key(message_data *mesg, const tsig_item *key)
1035 {
1036     mesg->_tsig.tsig = key;
1037     mesg->_tsig.mac_algorithm = key->mac_algorithm;
1038 }
1039 
message_tsig_get_key(const message_data * mesg)1040 static inline const tsig_item *message_tsig_get_key(const message_data *mesg)
1041 {
1042     return mesg->_tsig.tsig;
1043 }
1044 
message_tsig_clear_key(message_data * mesg)1045 static inline void message_tsig_clear_key(message_data *mesg)
1046 {
1047     mesg->_tsig.tsig = NULL ;
1048 }
1049 
message_tsig_get_key_bytes(const message_data * mesg)1050 static inline const u8 *message_tsig_get_key_bytes(const message_data *mesg)
1051 {
1052     return mesg->_tsig.tsig->mac;
1053 }
1054 
message_tsig_get_key_size(const message_data * mesg)1055 static inline u16 message_tsig_get_key_size(const message_data *mesg)
1056 {
1057     return mesg->_tsig.tsig->mac_size;
1058 }
1059 
message_get_header(message_data * mesg)1060 static inline message_header *message_get_header(message_data *mesg)
1061 {
1062     return (message_header*)message_get_buffer(mesg);
1063 }
1064 
1065 #if DEBUG
message_debug_trash_buffer(message_data * mesg)1066 static inline void message_debug_trash_buffer(message_data *mesg)
1067 {
1068     memset(message_get_buffer(mesg), 0xee, message_get_buffer_size_max(mesg));
1069 }
1070 #else
message_debug_trash_buffer(message_data * mesg)1071 static inline void message_debug_trash_buffer(message_data *mesg)
1072 {
1073     (void)mesg;
1074 }
1075 #endif
1076 
message_copy_msghdr(const message_data * mesg,struct msghdr * copyto)1077 static inline void message_copy_msghdr(const message_data *mesg, struct msghdr *copyto)
1078 {
1079     memcpy(copyto, &mesg->_msghdr, sizeof(mesg->_msghdr));
1080 }
1081 
1082 ya_result message_process_query(message_data *mesg);
1083 
1084 int message_process(message_data *);
1085 int message_process_lenient(message_data *mesg);
1086 
1087 void message_transform_to_error(message_data *mesg);
1088 void message_transform_to_signed_error(message_data *mesg);
1089 
1090 /* global */
1091 
1092 void message_edns0_setmaxsize(u16 maxsize);
1093 
message_edns0_clear_undefined_flags(message_data * mesg)1094 static inline void message_edns0_clear_undefined_flags(message_data *mesg) // all but DO
1095 {
1096     mesg->_rcode_ext &= RCODE_EXT_DNSSEC;
1097 }
1098 
1099 /**
1100     *
1101     * @param mesg
1102     * @param qname
1103     * @param qtype
1104     * @param qclass
1105     * @param id
1106     */
1107 
1108 void message_make_query(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass);
1109 
1110 void message_make_query_ex(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass, u16 flags);
1111 
1112 void message_make_query_ex_with_edns0(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass, u32 edns0_ttl);
1113 
1114 struct packet_writer;
1115 
1116 void message_make_message(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass, struct packet_writer* uninitialised_packet_writer);
1117 
1118 void message_make_dnsupdate_init(message_data *mesg, u16 id, const u8 *zzone, u16 zclass, u32 max_size, struct packet_writer *uninitialised_pw);
1119 ya_result message_make_dnsupdate_delete_all_rrsets(message_data *mesg, struct packet_writer *pw, const u8 *fqdn);
1120 ya_result message_make_dnsupdate_delete_rrset(message_data *mesg, struct packet_writer *pw, const u8 *fqdn, u16 rtype);
1121 ya_result message_make_dnsupdate_delete_record(message_data *mesg, struct packet_writer *pw, const u8 *fqdn, u16 rtype, u16 rdata_size, const u8 *rdata);
1122 ya_result message_make_dnsupdate_delete_dns_resource_record(message_data *mesg, struct packet_writer *pw, const struct dns_resource_record *rr);
1123 ya_result message_make_dnsupdate_delete_dnskey(message_data *mesg, struct packet_writer *pw, dnssec_key *key);
1124 ya_result message_make_dnsupdate_add_record(message_data *mesg, struct packet_writer *pw, const u8 *fqdn, u16 rtype, u16 rclass, s32 rttl, u16 rdata_size, const u8 *rdata);
1125 ya_result message_make_dnsupdate_add_dns_resource_record(message_data *mesg, struct packet_writer *pw, const struct dns_resource_record *rr);
1126 ya_result message_make_dnsupdate_add_dnskey(message_data *mesg, struct packet_writer *pw, dnssec_key *key, s32 ttl);
1127 ya_result message_make_dnsupdate_finalize(message_data *mesg, struct packet_writer *pw);
1128 
1129 /**
1130     *
1131     * @param mesg
1132     * @param qname
1133     * @param qtype
1134     * @param qclass
1135     * @param id
1136     */
1137 
1138 void message_make_notify(message_data *mesg, u16 id, const u8 *qname, u16 qtype /* TYPE_SOA */, u16 qclass /* CLASS_IN */);
1139 
1140 void message_make_ixfr_query(message_data *mesg, u16 id, const u8 *qname, u32 soa_ttl, u16 soa_rdata_size, const u8 *soa_rdata);
1141 
1142 #if DNSCORE_HAS_TSIG_SUPPORT
1143 
1144 ya_result message_sign_query_by_name(message_data *mesg, const u8 *tsig_name);
1145 
1146 ya_result message_sign_query_by_name_with_epoch_and_fudge(message_data *mesg, const u8 *tsig_name, s64 epoch, u16 fudge);
1147 
1148 ya_result message_sign_answer_by_name(message_data *mesg, const u8 *tsig_name);
1149 
1150 ya_result message_sign_query(message_data *mesg, const tsig_item *key);
1151 
1152 ya_result message_sign_query_with_epoch_and_fudge(message_data *mesg, const tsig_item *key, s64 epoch, u16 fudge);
1153 
1154 ya_result message_sign_answer(message_data *mesg, const tsig_item *key);
1155 
1156 #endif
1157 
1158 /**
1159  * Creates an empty answer with an error code
1160  *
1161  * @param mesg
1162  * @param error_code
1163  */
1164 
1165 void message_make_error(message_data *mesg, u16 error_code);
1166 
1167 /**
1168  * Creates an empty answer with an error code and TSIG signs it if needed
1169  *
1170  * @param mesg
1171  * @param error_code
1172  */
1173 
1174 void message_make_signed_error(message_data *mesg, u16 error_code);
1175 
1176 ya_result message_make_error_and_reply_tcp(message_data *mesg, u16 error_code, int tcpfd);
1177 
1178 ssize_t message_make_error_and_reply_tcp_with_default_minimum_throughput(message_data *mesg, u16 error_code, int tcpfd);
1179 /**
1180  * Creates an answer with an OPT error code
1181  */
1182 
1183 void message_make_error_ext(message_data *mesg, u32 error_code);
1184 
message_set_sender_from_host_address(message_data * mesg,const host_address * ha)1185 static inline ya_result message_set_sender_from_host_address(message_data *mesg, const host_address *ha)
1186 {
1187     ya_result ret = host_address2sockaddr(ha, &mesg->_sender);
1188     if(ISOK(ret))
1189     {
1190         mesg->_msghdr.msg_namelen = ret;
1191     }
1192     return ret;
1193 }
1194 
message_get_sender_size(const message_data * mesg)1195 static inline int message_get_sender_size(const message_data *mesg)
1196 {
1197     return mesg->_msghdr.msg_namelen;
1198 }
1199 
message_get_sender(const message_data * mesg)1200 static inline const socketaddress *message_get_sender(const message_data *mesg)
1201 {
1202     return &mesg->_sender;
1203 }
1204 
message_set_sender_port(message_data * mesg,u16 port)1205 static inline ya_result message_set_sender_port(message_data *mesg, u16 port)
1206 {
1207     switch(mesg->_sender.sa.sa_family)
1208     {
1209         case AF_INET:
1210         {
1211             mesg->_sender.sa4.sin_port = port;
1212             return port;
1213         }
1214         case AF_INET6:
1215         {
1216             mesg->_sender.sa6.sin6_port = port;
1217             return port;
1218         }
1219         default:
1220         {
1221             return INVALID_STATE_ERROR;
1222         }
1223     }
1224 }
1225 
message_get_sender_sa(const message_data * mesg)1226 static inline const struct sockaddr *message_get_sender_sa(const message_data *mesg)
1227 {
1228     return &mesg->_sender.sa;
1229 }
1230 
message_get_sender_sa_family(const message_data * mesg)1231 static inline sa_family_t message_get_sender_sa_family(const message_data *mesg)
1232 {
1233     return mesg->_sender.sa.sa_family;
1234 }
1235 
message_get_sender_sa_family_size(const message_data * mesg)1236 static inline size_t message_get_sender_sa_family_size(const message_data *mesg)
1237 {
1238     switch(mesg->_sender.sa.sa_family)
1239     {
1240         case AF_INET:
1241         {
1242             return sizeof(struct sockaddr_in);
1243         }
1244         case AF_INET6:
1245         {
1246             return sizeof(struct sockaddr_in6);
1247         }
1248         default:
1249         {
1250             return 0;
1251         }
1252     }
1253 }
1254 
message_get_sender_sa4(const message_data * mesg)1255 static inline const struct sockaddr_in *message_get_sender_sa4(const message_data *mesg)
1256 {
1257     return &mesg->_sender.sa4;
1258 }
1259 
message_get_sender_sa6(const message_data * mesg)1260 static inline const struct sockaddr_in6 *message_get_sender_sa6(const message_data *mesg)
1261 {
1262     return &mesg->_sender.sa6;
1263 }
1264 
message_copy_sender_from(message_data * mesg,const message_data * original)1265 static inline void message_copy_sender_from(message_data *mesg, const message_data *original)
1266 {
1267     memcpy(&mesg->_sender, &original->_sender, message_get_sender_size(original));
1268     mesg->_msghdr.msg_name = &mesg->_sender;
1269     mesg->_msghdr.msg_namelen = original->_msghdr.msg_namelen;
1270 }
1271 
message_copy_sender_from_sa(message_data * mesg,const struct sockaddr * sa,socklen_t sa_len)1272 static inline void message_copy_sender_from_sa(message_data *mesg, const struct sockaddr *sa, socklen_t sa_len)
1273 {
1274     memcpy(&mesg->_sender, sa, sa_len);
1275     mesg->_msghdr.msg_namelen = sa_len;
1276 }
1277 
message_copy_sender_from_socket(message_data * mesg,int client_sockfd)1278 static inline ya_result message_copy_sender_from_socket(message_data *mesg, int client_sockfd)
1279 {
1280     mesg->_msghdr.msg_namelen = sizeof(mesg->_sender);
1281     if(getpeername(client_sockfd, (struct sockaddr*)&mesg->_sender, &mesg->_msghdr.msg_namelen) >= 0)
1282     {
1283         mesg->_msghdr.msg_name = &mesg->_sender;
1284         return SUCCESS;
1285     }
1286     else
1287     {
1288         return ERRNO_ERROR;
1289     }
1290 }
1291 
message_copy_sender_to_sa(const message_data * mesg,struct sockaddr * bigenoughforipv6)1292 static inline void message_copy_sender_to_sa(const message_data *mesg, struct sockaddr *bigenoughforipv6)
1293 {
1294     memcpy(bigenoughforipv6, message_get_sender_sa(mesg), message_get_sender_size(mesg));
1295 }
1296 
message_get_u16_at(const message_data * mesg,int offset)1297 static inline u16 message_get_u16_at(const message_data *mesg, int offset)
1298 {
1299     return GET_U16_AT(mesg->_buffer[offset]);
1300 }
1301 
message_send_udp_reset(message_data * mesg)1302 static inline void message_send_udp_reset(message_data *mesg)
1303 {
1304     mesg->_msghdr.msg_namelen = sizeof(mesg->_sender);
1305     mesg->_iovec.iov_len = mesg->_buffer_size;
1306 }
1307 
1308 #if !DEBUG
message_send_udp(const message_data * mesg,int sockfd)1309 static inline s32 message_send_udp(const message_data *mesg, int sockfd)
1310 {
1311     s32 n;
1312 
1313     while((n = sendmsg(sockfd, &mesg->_msghdr, 0)) < 0)
1314     {
1315         int err = errno;
1316 
1317         if(err != EINTR)
1318         {
1319             return MAKE_ERRNO_ERROR(err);
1320         }
1321     }
1322 
1323     return n;
1324 }
1325 #else
1326 s32 message_send_udp_debug(const message_data *mesg, int sockfd);
1327 
message_send_udp(const message_data * mesg,int sockfd)1328 static inline s32 message_send_udp(const message_data *mesg, int sockfd)
1329 {
1330     s32 ret = message_send_udp_debug(mesg, sockfd);
1331     return ret;
1332 }
1333 #endif
1334 
message_recv_udp_reset(message_data * mesg)1335 static inline void message_recv_udp_reset(message_data *mesg)
1336 {
1337     mesg->_msghdr.msg_namelen = sizeof(mesg->_sender);
1338     mesg->_iovec.iov_len = mesg->_buffer_size;
1339 }
1340 
message_recv_udp(message_data * mesg,int sockfd)1341 static inline ssize_t message_recv_udp(message_data *mesg, int sockfd)
1342 {
1343     ssize_t ret = recvmsg(sockfd, &mesg->_msghdr, 0);
1344     if(ret >= 0)
1345     {
1346         message_set_size(mesg, ret);
1347 #if __FreeBSD__
1348         if(mesg->_msghdr.msg_controllen == 0)
1349         {
1350             mesg->_msghdr.msg_control = NULL;
1351         }
1352 #endif
1353     }
1354     return ret;
1355 }
1356 /*
1357 static inline ssize_t message_send_udp(message_data *mesg, int sockfd)
1358 {
1359     mesg->_iovec.iov_len = message_get_size(mesg);
1360     ssize_t ret = sendmsg(sockfd, &mesg->_msghdr, 0);
1361     return ret;
1362 }
1363 */
1364 
message_parse_query_fqdn(const message_data * mesg)1365 static inline const u8 *message_parse_query_fqdn(const message_data *mesg)
1366 {
1367     if(message_get_query_count_ne(mesg) != 0)
1368     {
1369         return &mesg->_buffer[DNS_HEADER_LENGTH];
1370     }
1371     else
1372     {
1373         return NULL;
1374     }
1375 }
1376 
message_parse_query_type(const message_data * mesg)1377 static inline u16 message_parse_query_type(const message_data *mesg)
1378 {
1379     if(message_get_query_count_ne(mesg) != 0)
1380     {
1381         const u8 *fqdn = &mesg->_buffer[DNS_HEADER_LENGTH];
1382         fqdn += dnsname_len(fqdn);
1383         return GET_U16_AT_P(fqdn);
1384     }
1385     else
1386     {
1387         return TYPE_NONE;
1388     }
1389 }
1390 
message_parse_query_class(const message_data * mesg)1391 static inline u16 message_parse_query_class(const message_data *mesg)
1392 {
1393     if(message_get_query_count_ne(mesg) != 0)
1394     {
1395         const u8 *fqdn = &mesg->_buffer[DNS_HEADER_LENGTH];
1396         fqdn += dnsname_len(fqdn) + 2;
1397         return GET_U16_AT_P(fqdn);
1398     }
1399     else
1400     {
1401         return TYPE_NONE;
1402     }
1403 }
1404 
message_get_canonised_fqdn(const message_data * mesg)1405 static inline const u8 *message_get_canonised_fqdn(const message_data *mesg)
1406 {
1407     return mesg->_canonised_fqdn;
1408 }
1409 
message_set_canonised_fqdn(message_data * mesg,const u8 * canonised_fqdn)1410 static inline void message_set_canonised_fqdn(message_data *mesg, const u8 *canonised_fqdn)
1411 {
1412     dnsname_copy(mesg->_canonised_fqdn, canonised_fqdn);
1413 }
1414 
message_get_maximum_size(const message_data * mesg)1415 static inline int message_get_maximum_size(const message_data *mesg)
1416 {
1417     return mesg->_buffer_size;
1418 }
1419 
message_get_query_section_ptr(message_data * mesg)1420 static inline u8* message_get_query_section_ptr(message_data *mesg)
1421 {
1422     return &mesg->_buffer[DNS_HEADER_LENGTH];
1423 }
1424 
message_get_additional_section_ptr(message_data * mesg)1425 static inline u8* message_get_additional_section_ptr(message_data *mesg)
1426 {
1427     return mesg->_ar_start;
1428 }
1429 
message_get_additional_section_ptr_const(const message_data * mesg)1430 static inline const u8* message_get_additional_section_ptr_const(const message_data *mesg)
1431 {
1432     return mesg->_ar_start;
1433 }
1434 
message_is_additional_section_ptr_set(const message_data * mesg)1435 static inline bool message_is_additional_section_ptr_set(const message_data *mesg)
1436 {
1437     return mesg->_ar_start != NULL;
1438 }
1439 
message_set_additional_section_ptr(message_data * mesg,void * ptr)1440 static inline void message_set_additional_section_ptr(message_data *mesg, void *ptr)
1441 {
1442     mesg->_ar_start = (u8*)ptr;
1443 }
1444 
message_get_status(const message_data * mesg)1445 static inline finger_print message_get_status(const message_data *mesg)
1446 {
1447     return mesg->_status;
1448 }
1449 
message_set_status(message_data * mesg,finger_print fp)1450 static inline void message_set_status(message_data *mesg, finger_print fp)
1451 {
1452     mesg->_status = fp;
1453 }
1454 
message_set_error_status_from_result(message_data * mesg,ya_result error_code)1455 static inline void message_set_error_status_from_result(message_data *mesg, ya_result error_code)
1456 {
1457     finger_print fp;
1458 
1459     if(YA_ERROR_BASE(error_code) == RCODE_ERROR_BASE)
1460     {
1461         fp = RCODE_ERROR_GETCODE(error_code);
1462     }
1463     else
1464     {
1465         fp = FP_RCODE_SERVFAIL;
1466     }
1467 
1468     message_set_status(mesg, fp);
1469 }
1470 
message_set_status_from_result(message_data * mesg,ya_result error_code)1471 static inline void message_set_status_from_result(message_data *mesg, ya_result error_code)
1472 {
1473     finger_print fp;
1474 
1475     if(ISOK(error_code))
1476     {
1477         fp = RCODE_NOERROR;
1478     }
1479     else if(YA_ERROR_BASE(error_code) == RCODE_ERROR_BASE)
1480     {
1481         fp = RCODE_ERROR_GETCODE(error_code);
1482     }
1483     else
1484     {
1485         fp = FP_RCODE_SERVFAIL;
1486     }
1487 
1488     message_set_status(mesg, fp);
1489 }
1490 
message_clear_status(message_data * mesg)1491 static inline void message_clear_status(message_data *mesg)
1492 {
1493     MESSAGE_FLAGS_AND(mesg->_buffer, 0xff, 0xf0);
1494 }
1495 
message_update_answer_status(message_data * mesg)1496 static inline void message_update_answer_status(message_data *mesg)
1497 {
1498     MESSAGE_FLAGS_OR(mesg->_buffer, QR_BITS, mesg->_status);
1499 }
1500 
message_update_truncated_answer_status(message_data * mesg)1501 static inline void message_update_truncated_answer_status(message_data *mesg)
1502 {
1503     MESSAGE_FLAGS_OR(mesg->_buffer, QR_BITS|TC_BITS, mesg->_status);
1504 }
1505 
message_get_id(const message_data * mesg)1506 static inline u16 message_get_id(const message_data *mesg)
1507 {
1508     return MESSAGE_ID(mesg->_buffer);
1509 }
1510 
1511 #if MESSAGE_PAYLOAD_IS_POINTER
1512 
message_recv_tcp(message_data * mesg,int sockfd)1513 static inline ssize_t message_recv_tcp(message_data *mesg, int sockfd)
1514 {
1515     u16 tcp_len;
1516 
1517     ssize_t ret = readfully(sockfd, &tcp_len, 2);
1518 
1519     if(ret < 0)
1520     {
1521         return ret;
1522     }
1523 
1524     tcp_len = ntohs(tcp_len);
1525 
1526     if(tcp_len < message_get_maximum_size(mesg))
1527     {
1528         ret = readfully(sockfd, mesg->_buffer, tcp_len);
1529 
1530         if(ISOK(ret))
1531         {
1532             message_set_size(mesg, ret);
1533         }
1534 
1535         return ret;
1536     }
1537     else
1538     {
1539         return BUFFER_WOULD_OVERFLOW;
1540     }
1541 }
1542 
message_write_tcp(const message_data * mesg,output_stream * os)1543 static inline ssize_t message_write_tcp(const message_data *mesg, output_stream *os)
1544 {
1545     ssize_t ret;
1546     u16 tcp_len = htons(message_get_size_u16(mesg));
1547     if(ISOK(ret = output_stream_write_fully(os, &tcp_len, 2)))
1548     {
1549         ret = output_stream_write_fully(os, message_get_buffer_const(mesg), message_get_size(mesg));
1550     }
1551     return ret;
1552 }
1553 
message_read_tcp(message_data * mesg,input_stream * is)1554 static inline ssize_t message_read_tcp(message_data *mesg, input_stream *is)
1555 {
1556     u16 tcp_len;
1557 
1558     ssize_t ret = input_stream_read_fully(is, &tcp_len, 2);
1559 
1560     if(ret < 0)
1561     {
1562         return ret;
1563     }
1564 
1565     tcp_len = ntohs(tcp_len);
1566 
1567     if(tcp_len < message_get_maximum_size(mesg))
1568     {
1569         ret = input_stream_read_fully(is, mesg->_buffer, tcp_len);
1570 
1571         if(ISOK(ret))
1572         {
1573             message_set_size(mesg, ret);
1574         }
1575 
1576         return ret;
1577     }
1578     else
1579     {
1580         return BUFFER_WOULD_OVERFLOW;
1581     }
1582 }
1583 
1584 #if 0
1585 static inline ssize_t message_send_tcp(const message_data *mesg, int sockfd)
1586 {
1587     ssize_t ret;
1588 
1589     u16 tcp_len = htons(message_get_size_u16(mesg));
1590     if(ISOK(ret = writefully(sockfd, &tcp_len, 2)))
1591     {
1592         if(ISOK(ret = writefully(sockfd, message_get_buffer_const(mesg), message_get_size(mesg))))
1593         {
1594             ret += 2;
1595         }
1596     }
1597 
1598     return ret;
1599 }
1600 #else
1601 ssize_t message_send_tcp(const message_data *mesg, int sockfd);
1602 #endif
1603 
message_send_tcp_with_minimum_throughput(const message_data * mesg,int sockfd,double minimum_rate)1604 static inline ssize_t message_send_tcp_with_minimum_throughput(const message_data *mesg, int sockfd, double minimum_rate)
1605 {
1606     ssize_t ret;
1607     u16 tcp_len = htons(message_get_size_u16(mesg));
1608     if(ISOK(ret = writefully_limited(sockfd, &tcp_len, 2, minimum_rate)))
1609     {
1610         assert(ret == 2);
1611 
1612         if(ISOK(ret = writefully_limited(sockfd, message_get_buffer_const(mesg), message_get_size(mesg), minimum_rate)))
1613         {
1614             assert(ret == (ssize_t)message_get_size(mesg));
1615 
1616             return ret + 2;
1617         }
1618     }
1619     return ret;
1620 }
1621 
message_update_length_send_tcp_with_minimum_throughput(message_data * mesg,int sockfd,double minimum_rate)1622 static inline ssize_t message_update_length_send_tcp_with_minimum_throughput(message_data *mesg, int sockfd, double minimum_rate)
1623 {
1624     ssize_t ret = message_send_tcp_with_minimum_throughput(mesg, sockfd, minimum_rate);
1625     return ret;
1626 }
1627 
1628 extern double g_message_data_minimum_troughput_default;
1629 
message_update_length_send_tcp_with_default_minimum_throughput(message_data * mesg,int sockfd)1630 static inline ssize_t message_update_length_send_tcp_with_default_minimum_throughput(message_data *mesg, int sockfd)
1631 {
1632     ssize_t ret = message_send_tcp_with_minimum_throughput(mesg, sockfd, g_message_data_minimum_troughput_default);
1633     return ret;
1634 }
1635 
1636 #else
message_update_tcp_length(message_data * mesg)1637 static inline void message_update_tcp_length(message_data *mesg)
1638 {
1639     u16 len = message_get_size_u16(mesg);
1640     SET_U16_AT(mesg->_buffer_tcp_len[0], htons(len));
1641 }
1642 
message_get_tcp_length(const message_data * mesg)1643 static inline u32 message_get_tcp_length(const message_data *mesg)
1644 {
1645     u16 len = GET_U16_AT(mesg->_buffer_tcp_len[0]);
1646     return ntohs(len);
1647 }
1648 
message_get_tcp_buffer_const(const message_data * mesg)1649 static inline const u8 *message_get_tcp_buffer_const(const message_data *mesg)
1650 {
1651     return mesg->_buffer_tcp_len;
1652 }
1653 
message_get_tcp_buffer(message_data * mesg)1654 static inline u8 *message_get_tcp_buffer(message_data *mesg)
1655 {
1656     return mesg->_buffer_tcp_len;
1657 }
1658 
message_recv_tcp(message_data * mesg,int sockfd)1659 static inline ssize_t message_recv_tcp(message_data *mesg, int sockfd)
1660 {
1661     ssize_t ret = readfully(sockfd, mesg->_buffer_tcp_len, 2);
1662 
1663     if(ret < 0)
1664     {
1665         return ret;
1666     }
1667 
1668     ret = message_get_tcp_length(mesg);
1669 
1670     if(ret > 0)
1671     {
1672         ret = readfully(sockfd, mesg->_buffer, ret);
1673 
1674         if(ISOK(ret))
1675         {
1676             message_set_size(mesg, ret);
1677         }
1678     }
1679 
1680     return ret;
1681 }
1682 
message_write_tcp(const message_data * mesg,output_stream * os)1683 static inline ssize_t message_write_tcp(const message_data *mesg, output_stream *os)
1684 {
1685     message_update_tcp_length(mesg);
1686     ssize_t ret = output_stream_write(os, message_get_tcp_buffer_const(mesg), message_get_size_u16(mesg) + 2);
1687     return ret;
1688 }
1689 
message_read_tcp(message_data * mesg,input_stream * is)1690 static inline ssize_t message_read_tcp(message_data *mesg, input_stream *is)
1691 {
1692     ssize_t ret = input_stream_read(is, mesg->_buffer_tcp_len, 2);
1693     if(ret < 0)
1694     {
1695         return ret;
1696     }
1697     ret = message_get_tcp_length(mesg);
1698     if(ret > 0)
1699     {
1700         ret = input_stream_read(is, message_get_buffer(mesg), ret);
1701 
1702         if(ISOK(ret))
1703         {
1704             message_set_size(mesg, ret);
1705         }
1706     }
1707     return ret;
1708 }
1709 
message_send_tcp(const message_data * mesg,int sockfd)1710 static inline ssize_t message_send_tcp(const message_data *mesg, int sockfd)
1711 {
1712     ssize_t ret = writefully(sockfd, message_get_tcp_buffer_const(mesg), message_get_size_u16(mesg) + 2);
1713     return ret;
1714 }
1715 
message_send_tcp_with_minimum_throughput(const message_data * mesg,int sockfd,double minimum_rate)1716 static inline ssize_t message_send_tcp_with_minimum_throughput(const message_data *mesg, int sockfd, double minimum_rate)
1717 {
1718     ssize_t ret = writefully_limited(sockfd, message_get_tcp_buffer_const(mesg), message_get_size_u16(mesg) + 2, minimum_rate);
1719     return ret;
1720 }
1721 
message_update_length_send_tcp_with_minimum_throughput(message_data * mesg,int sockfd,double minimum_rate)1722 static inline ssize_t message_update_length_send_tcp_with_minimum_throughput(message_data *mesg, int sockfd, double minimum_rate)
1723 {
1724     message_update_tcp_length(mesg);
1725     ssize_t ret = message_send_tcp_with_minimum_throughput(mesg, sockfd, minimum_rate);
1726     return ret;
1727 }
1728 
1729 extern double g_message_data_minimum_troughput_default;
1730 
message_update_length_send_tcp_with_default_minimum_throughput(message_data * mesg,int sockfd)1731 static inline ssize_t message_update_length_send_tcp_with_default_minimum_throughput(message_data *mesg, int sockfd)
1732 {
1733     message_update_tcp_length(mesg);
1734     ssize_t ret = message_send_tcp_with_minimum_throughput(mesg, sockfd, g_message_data_minimum_troughput_default);
1735     return ret;
1736 }
1737 
1738 #endif
1739 
message_set_id(message_data * mesg,u16 id)1740 static inline void message_set_id(message_data *mesg, u16 id)
1741 {
1742     MESSAGE_SET_ID(mesg->_buffer, id);
1743 }
1744 
message_make_truncated_empty_answer(message_data * mesg)1745 static inline void message_make_truncated_empty_answer(message_data *mesg)
1746 {
1747     message_set_truncated_answer(mesg);
1748     message_set_query_answer_authority_additional_counts_ne(mesg, 0, 0, 0, 0);
1749     message_set_size(mesg, DNS_HEADER_LENGTH);
1750 }
1751 
1752 /**
1753  * To be called on a message at the beginning of a TCP stream
1754  *
1755  * @param mesg
1756  */
1757 
message_tcp_serial_reset(message_data * mesg)1758 static inline void message_tcp_serial_reset(message_data *mesg)
1759 {
1760     mesg->_tcp_serial = 0;
1761 }
1762 
1763 /**
1764  * To be called on a message when reading a following TCP stream message
1765  *
1766  * @param mesg
1767  */
1768 
message_tcp_serial_increment(message_data * mesg)1769 static inline void message_tcp_serial_increment(message_data *mesg)
1770 {
1771     ++mesg->_tcp_serial;
1772 }
1773 
1774 ya_result message_query_tcp_with_timeout(message_data *mesg, const host_address *server, u8 to_sec);
1775 ya_result message_query_tcp_with_timeout_ex(message_data *mesg, const host_address *server, message_data *answer, u8 to_sec);
1776 ya_result message_query_tcp(message_data *mesg, const host_address *server);
1777 ya_result message_query_tcp_ex(message_data *mesg, const host_address *bindto, const host_address *server, message_data *answer);
1778 ya_result message_query_udp(message_data *mesg, const host_address *server);
1779 ya_result message_query_udp_with_timeout(message_data *mesg, const host_address *server, int seconds, int useconds);
1780 
1781 #define MESSAGE_QUERY_UDP_FLAG_RESET_ID 1
1782 
1783 ya_result message_query_udp_with_timeout_and_retries(message_data *mesg, const host_address *server, int seconds, int useconds, u8 retries, u8 flags);
1784 
1785 ya_result message_query(message_data *mesg, const host_address *server);
1786 
1787 ya_result message_query_serial(const u8 *origin, const host_address *server, u32 *serial_out);
1788 
1789 ya_result message_get_ixfr_query_serial(message_data *mesg, u32 *serialp);
1790 
1791 /**
1792  * Writes the edns0 (if present),
1793  * applies the TSIG for the right position in the stream (if needed),
1794  *
1795  * Write the message to the (tcp) stream.
1796  *
1797  * @param mesg
1798  * @param tcpos
1799  * @param pos
1800  * @return
1801  */
1802 
1803 #if ZDB_HAS_TSIG_SUPPORT
1804 ya_result message_terminate_then_write(message_data *mesg, output_stream *tcpos, tsig_tcp_message_position pos);
1805 #else
1806 ya_result message_terminate_then_write(message_data *mesg, output_stream *tcpos, int unused);
1807 #endif
1808 
1809 #if MESSAGE_PAYLOAD_IS_POINTER
1810 void message_init_ex(message_data* mesg, u32 mesg_size, void *buffer, size_t buffer_size);
1811 
message_data_with_buffer_init(message_data_with_buffer * mesg_buff)1812 static inline message_data *message_data_with_buffer_init(message_data_with_buffer *mesg_buff)
1813 {
1814     message_init_ex(&mesg_buff->message, sizeof(struct message_data_with_buffer), mesg_buff->_buffer, mesg_buff->_buffer_limit - mesg_buff->_buffer);
1815     return &mesg_buff->message;
1816 }
1817 #else
1818 void message_init(message_data* mesg);
1819 
message_data_with_buffer_init(message_data_with_buffer * mesg_buff)1820 static inline message_data *message_data_with_buffer_init(message_data_with_buffer *mesg_buff)
1821 {
1822     message_init(&mesg_buff->message);
1823     return &mesg_buff->message;
1824 }
1825 #endif
1826 
1827 /**
1828  * If pointer is NULL, the structure and buffer will be allocated together
1829  * Note that in the current implementation, 8 bytes are reserved for TCP
1830  */
1831 
1832 message_data* message_new_instance_ex(void *ptr, u32 message_size);    // should be size of edns0 or 64K for TCP
1833 
1834 message_data* message_new_instance(); // message_new_instance_ex(64K)
1835 
1836 void message_finalize(message_data *mesg);
1837 
1838 void message_free(message_data *mesg);
1839 
1840 /*
1841  * Does not clone the pool.
1842  */
1843 
1844 message_data* message_dup(const message_data *mesg);
1845 
1846 ya_result message_ixfr_query_get_serial(const message_data *mesg, u32 *serial);
1847 
1848 /**
1849  * Maps records in a message to easily access them afterward.
1850  *
1851  * @param map the message map to initialise
1852  * @param mesg the message to map
1853  *
1854  * @return an error code
1855  */
1856 
1857 ya_result message_map_init(message_map *map, const message_data *mesg);
1858 
1859 /**
1860  * Gets the fqdn of the record at index
1861  *
1862  * @param map
1863  * @param index
1864  * @param fqdn
1865  * @param fqdn_size
1866  *
1867  * @return an error code
1868  */
1869 
1870 ya_result message_map_get_fqdn(const message_map *map, int index, u8 *fqdn, int fqdn_size);
1871 
1872 /**
1873  * Gets the type class ttl rdata_size of the record at index
1874  *
1875  * @param map
1876  * @param index
1877  * @param tctr
1878  *
1879  * @return an error code
1880  */
1881 
1882 
1883 ya_result message_map_get_tctr(const message_map *map, int index, struct type_class_ttl_rdlen *tctr);
1884 
1885 /**
1886  * Gets the rdata of the record at index
1887  *
1888  * @param map
1889  * @param index
1890  * @param rdata
1891  * @param rdata_size
1892  *
1893  * @return the rdata size or an error code
1894  */
1895 
1896 ya_result message_map_get_rdata(const message_map *map, int index, u8 *rdata, int rdata_size);
1897 
1898 /**
1899  * Gets the type of the record at index
1900  *
1901  * @param map
1902  * @param index
1903  *
1904  * @return the record type or an error code
1905  */
1906 
1907 ya_result message_map_get_type(const message_map *map, int index);
1908 
1909 /**
1910  *
1911  * @param map
1912  *
1913  * @return the number of records mapped
1914  */
1915 
1916 int message_map_record_count(const message_map *map);
1917 
1918 /**
1919  * Returns the index of the next record with the given type
1920  * from, and including, a given index.
1921  *
1922  * @param map
1923  * @param index
1924  * @param type
1925  * @return
1926  */
1927 
1928 int message_map_get_next_record_from(const message_map *map, int index, u16 type);
1929 
1930 /**
1931  * Returns the index of the next record with the given type
1932  * from, and including, a given index in a given section (0 to 3).
1933  *
1934  * @param map
1935  * @param index
1936  * @param type
1937  * @return
1938  */
1939 
1940 int message_map_get_next_record_from_section(const message_map *map, int section, int index, u16 type);
1941 
1942 /**
1943  * Returns the base index of a section
1944  *
1945  * @param map
1946  * @param section
1947  * @return
1948  */
1949 
message_map_get_section_base(const message_map * map,int section)1950 static inline int message_map_get_section_base(const message_map *map, int section)
1951 {
1952     return map->section_base[section];
1953 }
1954 
1955 /**
1956  * Sorts records by section so that:
1957  * _ SOA is first,
1958  * _ NSEC is last,
1959  * _ NSEC3 labels are at the end,
1960  * _ RRSIG follows its RRSET
1961  *
1962  * @param map
1963  */
1964 
1965 void message_map_reorder(message_map *map);
1966 
1967 void message_map_print(const message_map *map, output_stream *os);
1968 
1969 /**
1970  * Releases the memory used by the map
1971  *
1972  * @param map
1973  */
1974 
1975 void message_map_finalize(message_map *map);
1976 
1977 /**
1978  * Gets the global edns0 maximum size
1979  *
1980  * @return
1981  */
1982 
1983 u16 message_edns0_getmaxsize();
1984 
message_set_rd_flag(message_data * mesg)1985 static inline void message_set_rd_flag(message_data *mesg)
1986 {
1987     MESSAGE_HIFLAGS(mesg->_buffer) |= RD_BITS;
1988 }
1989 
1990 struct logger_handle;
1991 
1992 void message_log(struct logger_handle *logger, int level, const message_data *mesg);
1993 
1994 ya_result message_print_format_multiline(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
1995 ya_result message_print_format_short(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
1996 ya_result message_print_format_wire(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
1997 ya_result message_print_format_wire_ext(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
1998 
1999 ya_result message_print_format_dig(output_stream *os_, const u8 *buffer, u32 length, u16 view_mode_with, long time_duration);
2000 ya_result message_print_format_dig_buffer(output_stream *os_, const u8 *buffer, u32 length, u16 view_mode_with);
2001 
2002 ya_result message_print_format_json(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
2003 ya_result message_print_format_json_buffer(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with);
2004 
2005 ya_result message_print_format_parse(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
2006 ya_result message_print_buffer_format_parse(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with);
2007 
2008 ya_result message_print_format_xml(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with, long time_duration);
2009 ya_result message_print_format_xml_buffer(output_stream *os_, const u8 *buffer, u16 length, u16 view_mode_with);
2010 
2011 #ifdef __cplusplus
2012 }
2013 #endif
2014 
2015 /** @} */
2016