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