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 * USE INCLUDES */
44 #include "dnscore/dnscore-config.h"
45
46 #include <unistd.h>
47 #include <stddef.h>
48 #include <fcntl.h>
49
50 #include "dnscore/message.h"
51 #include "dnscore/logger.h"
52 #include "dnscore/dnscore.h"
53 #include "dnscore/format.h"
54 #include "dnscore/fingerprint.h"
55 #include "dnscore/packet_reader.h"
56 #include "dnscore/packet_writer.h"
57 #include "dnscore/tsig.h"
58 #include "dnscore/fdtools.h"
59 #include "dnscore/tcp_io_stream.h"
60 #include "dnscore/counter_output_stream.h"
61 #include "dnscore/network.h"
62
63 #include "dnscore/thread_pool.h"
64
65 #if HAS_CTRL
66 #include "dnscore/ctrl-rfc.h"
67 #endif
68
69 /*------------------------------------------------------------------------------
70 * GLOBAL VARIABLES */
71
72 extern logger_handle *g_system_logger;
73 #define MODULE_MSG_HANDLE g_system_logger
74
75
76
77 #define SA_LOOP 3
78 #define SA_PRINT 4
79
80 /*------------------------------------------------------------------------------
81 * FUNCTIONS */
82
83 u16 edns0_maxsize = EDNS0_MAX_LENGTH;
84
85 double g_message_data_minimum_troughput_default = 0;
86
message_set_minimum_troughput_default(double rate)87 void message_set_minimum_troughput_default(double rate)
88 {
89 if(rate >= 0)
90 {
91 g_message_data_minimum_troughput_default = rate;
92 }
93 }
94
message_edns0_setmaxsize(u16 maxsize)95 void message_edns0_setmaxsize(u16 maxsize)
96 {
97 edns0_maxsize = maxsize;
98 }
99
message_edns0_getmaxsize()100 u16 message_edns0_getmaxsize()
101 {
102 return edns0_maxsize;
103 }
104
105 // Handles OPT and TSIG
106
message_process_adjust_buffer_size(message_data * mesg,u16 edns0_size)107 static inline void message_process_adjust_buffer_size(message_data *mesg, u16 edns0_size)
108 {
109 u32 mesg_buffer_size = message_get_buffer_size_max(mesg);
110 u32 query_buffer_size = edns0_size;
111 if(mesg_buffer_size > query_buffer_size)
112 {
113 mesg_buffer_size = query_buffer_size;
114 if(mesg_buffer_size < EDNS0_MIN_LENGTH)
115 {
116 mesg_buffer_size = EDNS0_MIN_LENGTH;
117 }
118 }
119 message_set_buffer_size(mesg, mesg_buffer_size);
120 }
121
122 static ya_result
message_process_additionals(message_data * mesg,u8 * s,u16 ar_count)123 message_process_additionals(message_data *mesg, u8* s, u16 ar_count)
124 {
125 (void)s;
126 /*
127 * @note: I've moved this in the main function (the one calling this one)
128 */
129
130 //yassert(ar_count != 0 && ar_count == message_get_additional_count(mesg));
131
132 u8 *buffer = mesg->_buffer;
133 ya_result ret;
134
135 ar_count = ntohs(MESSAGE_AR(buffer));
136
137 /*
138 * rfc2845
139 *
140 * If there is a TSIG then
141 * _ It must be put aside, safely
142 * _ It must be removed from the query
143 * _ It must be processed
144 *
145 * rfc2671
146 *
147 * Handle OPT
148 *
149 */
150
151 /*
152 * Read DNS name (decompression on)
153 * Read type (TSIG = 250)
154 * Read class (ANY)
155 * Read TTL (0)
156 * Read RDLEN
157 *
158 */
159
160 u32 query_end = message_get_size(mesg);
161
162 packet_unpack_reader_data purd;
163 purd.packet = buffer;
164 purd.packet_size = query_end;
165
166 if(mesg->_ar_start == NULL)
167 {
168 u32 ar_index = ntohs(MESSAGE_AN(buffer)) + ntohs(MESSAGE_NS(buffer));
169
170 purd.offset = DNS_HEADER_LENGTH; // header
171 packet_reader_skip_fqdn(&purd); // checked below
172 if(FAIL(packet_reader_skip(&purd, 4))) // type class
173 {
174 message_set_status(mesg, FP_ERROR_READING_QUERY);
175 return UNPROCESSABLE_MESSAGE;
176 }
177
178 while(ar_index > 0) /* Skip all until AR records */
179 {
180 /*
181 * It should be in this kind of processing that we read the EDNS0 flag
182 */
183
184 if(FAIL(ret = packet_reader_skip_record(&purd)))
185 {
186 message_set_status(mesg, FP_ERROR_READING_QUERY);
187 return UNPROCESSABLE_MESSAGE;
188 }
189
190 ar_index--;
191 }
192
193 query_end = purd.offset; // ready to remove all additionals in one fell swoop
194
195 mesg->_ar_start = &mesg->_buffer[purd.offset];
196 }
197 else
198 {
199 purd.offset = message_get_additional_section_ptr(mesg) - mesg->_buffer;
200 }
201
202 /* We are now at the start of the ar */
203
204 struct type_class_ttl_rdlen tctr;
205 u8 tsigname[MAX_DOMAIN_LENGTH];
206 #if DNSCORE_HAS_TSIG_SUPPORT
207 u32 record_offset;
208 #endif
209
210 while(ar_count-- > 0)
211 {
212 #if DNSCORE_HAS_TSIG_SUPPORT
213 record_offset = purd.offset;
214 #endif
215
216 if(FAIL(packet_reader_read_fqdn(&purd, tsigname, sizeof(tsigname))))
217 {
218 /* oops */
219
220 message_set_status(mesg, FP_ERROR_READING_QUERY);
221
222 return UNPROCESSABLE_MESSAGE;
223 }
224
225 if(packet_reader_read(&purd, &tctr, 10) == 10 ) // exact
226 {
227 /*
228 * EDNS (0)
229 */
230
231 if(tctr.qtype == TYPE_OPT)
232 {
233 /**
234 * Handle EDNS
235 */
236
237 if((tctr.ttl & NU32(0x00ff0000)) == 0) /* ensure version is 0 */
238 {
239 u32 rdlen = ntohs(tctr.rdlen);
240
241 #if DNSCORE_HAS_NSID_SUPPORT
242 if(rdlen != 0)
243 {
244 u32 next = purd.offset + rdlen;
245 for(s32 remain = (s32)rdlen; remain >= 4; remain -= 4)
246 {
247 u32 opt_type_size;
248
249 if(ISOK(packet_reader_read_u32(&purd, &opt_type_size))) // read the option-code and the option-length in one operation
250 {
251 if(opt_type_size == NU32(0x00030000)) // check if it's NSID
252 {
253 // nsid
254 mesg->_nsid = TRUE;
255 break;
256 }
257
258 u32 opt_type_len = ntohl(opt_type_size) & 0xffff;
259
260 if(FAIL(packet_reader_skip(&purd, opt_type_len))) // skip the data
261 {
262 return UNPROCESSABLE_MESSAGE;
263 }
264
265 remain -= opt_type_len;
266 }
267 else
268 {
269 break;
270 }
271 }
272
273 if(FAIL(packet_reader_skip(&purd, next - purd.offset)))
274 {
275 return UNPROCESSABLE_MESSAGE;
276 }
277 }
278 #else
279 if(FAIL(packet_reader_skip(&purd, rdlen)))
280 {
281 return UNPROCESSABLE_MESSAGE;
282 }
283 #endif
284 if(tsigname[0] == '\0')
285 {
286 message_process_adjust_buffer_size(mesg, ntohs(tctr.qclass));
287
288 mesg->_edns = TRUE;
289 mesg->_rcode_ext = tctr.ttl;
290 #if DEBUG
291 log_debug("EDNS: udp-size=%d rcode-ext=%08x desc=%04x", message_get_size(mesg), tctr.ttl, rdlen);
292 #endif
293 continue;
294 }
295 #if DEBUG
296 log_debug("OPT record is not processable (broken)");
297 #endif
298 return UNPROCESSABLE_MESSAGE;
299 }
300 else
301 {
302 message_set_status(mesg, FP_EDNS_BAD_VERSION);
303 message_process_adjust_buffer_size(mesg, ntohs(tctr.qclass));
304
305 mesg->_edns = TRUE;
306 mesg->_rcode_ext = 0;
307 #if DEBUG
308 log_debug("OPT record is not processable (not supported)");
309 #endif
310 return MAKE_DNSMSG_ERROR(FP_EDNS_BAD_VERSION);
311 }
312 }
313 #if DNSCORE_HAS_TSIG_SUPPORT
314 /*
315 * TSIG
316 */
317
318 else if(tctr.qtype == TYPE_TSIG)
319 {
320 if(ar_count == 0)
321 {
322 /*
323 * It looks like a TSIG ...
324 */
325
326 ya_result return_code;
327
328 if(message_isquery(mesg))
329 {
330 if(FAIL(return_code = tsig_process_query(mesg, &purd, record_offset, tsigname, &tctr)))
331 {
332 #if DEBUG
333 // this should be reported above
334 log_notice("%r query error from %{sockaddr}", return_code, message_get_sender_sa(mesg));
335 #endif
336 return return_code;
337 }
338 }
339 else
340 {
341 tsig_item *key = tsig_get(tsigname);
342
343 if(key != NULL)
344 {
345 if(FAIL(return_code = tsig_process(mesg, &purd, record_offset, key, &tctr)))
346 {
347 #if DEBUG
348 // this should be reported above
349 log_notice("%r answer error from %{sockaddr}", return_code, message_get_sender_sa(mesg));
350 #endif
351 return return_code;
352 }
353 }
354 else
355 {
356 log_notice("answer error from %{sockaddr}: TSIG when none expected", message_get_sender_sa(mesg));
357
358 message_set_status(mesg, FP_TSIG_UNEXPECTED);
359
360 return MAKE_DNSMSG_ERROR(FP_TSIG_UNEXPECTED);
361 }
362 }
363
364 break; /* we know there is no need to loop anymore */
365 }
366 else
367 {
368 /*
369 * Error: TSIG is not the last AR record
370 */
371
372 #if DEBUG
373 log_debug("TSIG record is not the last AR");
374 #endif
375
376 message_set_status(mesg, FP_TSIG_IS_NOT_LAST);
377
378 return UNPROCESSABLE_MESSAGE;
379 }
380 }
381 #endif
382 else
383 {
384 /* Unhandled AR TYPE */
385
386 log_debug("unhandled AR type %{dnstype}", &tctr.qtype);
387
388 message_set_status(mesg, FP_UNEXPECTED_RR_IN_QUERY);
389
390 return UNPROCESSABLE_MESSAGE;
391 }
392 }
393 } /* While there are AR to process */
394
395 message_set_additional_count_ne(mesg, 0);
396 message_set_size(mesg, query_end);
397
398 return SUCCESS;
399 }
400
401 /**
402 * Handles the OPT and TSIG records of an answer.
403 *
404 * @param mesg
405 * @param ar_count
406 * @return
407 */
408
409 static ya_result
message_process_answer_additionals(message_data * mesg,u16 ar_count)410 message_process_answer_additionals(message_data *mesg, u16 ar_count /* network order */ )
411 {
412 /*
413 * @note: I've moved this in the main function (the one calling this one)
414 */
415
416 yassert(ar_count != 0 && ar_count == message_get_additional_count_ne(mesg));
417
418 u8 *buffer = message_get_buffer(mesg);
419
420 ar_count = ntohs(ar_count);
421
422 /*
423 * rfc2845
424 *
425 * If there is a TSIG then
426 * _ It must be put aside, safely
427 * _ It must be removed from the query
428 * _ It must be processed
429 *
430 * rfc2671
431 *
432 * Handle OPT
433 *
434 */
435
436 /*
437 * Read DNS name (decompression on)
438 * Read type (TSIG = 250)
439 * Read class (ANY)
440 * Read TTL (0)
441 * Read RDLEN
442 *
443 */
444
445 u32 message_size = message_get_size(mesg);
446
447 packet_unpack_reader_data purd;
448 purd.packet = buffer;
449 purd.packet_size = message_size;
450 u16 ar_sub = 0;
451
452 if(mesg->_ar_start == NULL)
453 {
454 u32 ar_index = ntohs(MESSAGE_AN(buffer)) + ntohs(MESSAGE_NS(buffer));
455
456 purd.offset = DNS_HEADER_LENGTH; // header
457 packet_reader_skip_fqdn(&purd); // checked below
458 if(FAIL(packet_reader_skip_bytes(&purd, 4))) // type class
459 {
460 return UNPROCESSABLE_MESSAGE;
461 }
462
463 while(ar_index > 0) /* Skip all until AR records */
464 {
465 /*
466 * It should be in this kind of processing that we read the EDNS0 flag
467 */
468
469 if(FAIL(packet_reader_skip_record(&purd)))
470 {
471 return UNPROCESSABLE_MESSAGE;
472 }
473
474 ar_index--;
475 }
476
477 message_size = purd.offset;
478
479 mesg->_ar_start = &mesg->_buffer[purd.offset];
480 }
481 else
482 {
483 purd.offset = message_get_additional_section_ptr(mesg) - mesg->_buffer; // size up to additional sections
484 }
485
486 /* We are now at the start of the ar */
487
488 struct type_class_ttl_rdlen tctr;
489 u8 tsigname[MAX_DOMAIN_LENGTH];
490
491 #if DNSCORE_HAS_TSIG_SUPPORT
492 u32 record_offset;
493 #endif
494
495 while(ar_count-- > 0)
496 {
497 #if DNSCORE_HAS_TSIG_SUPPORT
498 record_offset = purd.offset;
499 #endif
500 if(FAIL(packet_reader_read_fqdn(&purd, tsigname, sizeof(tsigname))))
501 {
502 /* oops */
503
504 message_set_status(mesg, FP_ERROR_READING_QUERY);
505
506 return UNPROCESSABLE_MESSAGE;
507 }
508
509 if(packet_reader_read(&purd, &tctr, 10) == 10 ) // exact
510 {
511 /*
512 * EDNS (0)
513 */
514
515 if(tctr.qtype == TYPE_OPT)
516 {
517 /**
518 * Handle EDNS
519 */
520
521 if((tctr.ttl & NU32(0x00ff0000)) == 0) /* ensure version is 0 */
522 {
523 if(tsigname[0] == '\0')
524 {
525 ++ar_sub;
526
527 mesg->_edns = TRUE;
528 mesg->_rcode_ext = tctr.ttl;
529
530 log_debug("EDNS: udp-size=%d rcode-ext=%08x desc=%04x", message_get_buffer_size(mesg), tctr.ttl, ntohs(tctr.rdlen));
531 continue;
532 }
533 }
534 else
535 {
536 mesg->_edns = TRUE;
537 mesg->_rcode_ext = tctr.ttl;
538 }
539
540 log_debug("OPT record is not processable (broken or not supported)");
541
542 return UNPROCESSABLE_MESSAGE;
543 }
544 #if DNSCORE_HAS_TSIG_SUPPORT
545
546 /*
547 * TSIG
548 */
549
550 else if(tctr.qtype == TYPE_TSIG)
551 {
552 if(ar_count == 0)
553 {
554 /*
555 * It looks like a TSIG ...
556 */
557
558 ya_result return_code;
559
560 if(message_isquery(mesg))
561 {
562 if(FAIL(return_code = tsig_process_query(mesg, &purd, record_offset, tsigname, &tctr)))
563 {
564 log_err("%r query error from %{sockaddr}", return_code, message_get_sender_sa(mesg));
565 return UNPROCESSABLE_MESSAGE;
566 }
567 }
568 else // not a query (an answer)
569 {
570 if(message_has_tsig(mesg))
571 {
572 if(dnsname_equals(tsigname, message_tsig_get_name(mesg)))
573 {
574 if(FAIL(return_code = tsig_process_answer(mesg, &purd, record_offset, &tctr)))
575 {
576 log_err("%r answer error from %{sockaddr}", return_code, message_get_sender_sa(mesg));
577 return UNPROCESSABLE_MESSAGE;
578 }
579 }
580 else
581 {
582 log_err("TSIG name mismatch from %{sockaddr}", message_get_sender_sa(mesg));
583
584 return UNPROCESSABLE_MESSAGE;
585 }
586 }
587 else // no tsig
588 {
589 log_err("answer error from %{sockaddr}: TSIG when none expected", message_get_sender_sa(mesg));
590
591 message_set_status(mesg, FP_TSIG_UNEXPECTED);
592
593 return UNPROCESSABLE_MESSAGE;
594 }
595 }
596
597 break; /* we know there is no need to loop anymore */
598 }
599 else
600 {
601 /*
602 * Error: TSIG is not the last AR record
603 */
604
605 log_debug("TSIG record is not the last AR");
606
607 message_set_status(mesg, FP_TSIG_IS_NOT_LAST);
608
609 return UNPROCESSABLE_MESSAGE;
610 }
611 }
612 #endif
613 else
614 {
615 /* Unhandled AR TYPE */
616 #if DEBUG
617 log_debug("skipping AR type %{dnstype}", &tctr.qtype);
618 #endif
619 purd.offset += ntohs(tctr.rdlen);
620
621 message_size = purd.offset;
622 }
623 }
624 } /* While there are AR to process */
625
626 //message_sub_additional_count(mesg, 1);
627
628 message_set_additional_count_ne(mesg, 0);
629 message_set_size(mesg, message_size);
630
631 return SUCCESS;
632 }
633
634 /** \brief Processing DNS packet
635 *
636 * @param mesg
637 *
638 * @retval OK
639 * @return status of message is written in message_get_status(mesg)
640 */
641
642 /* Defines a mask and the expected result for the 4 first 16 bits of the header */
643 #ifdef WORDS_BIGENDIAN
644 #define MESSAGE_HEADER_MASK (( (u64) 0 ) | \
645 ( ((u64) ( QR_BITS | AA_BITS | RA_BITS | TC_BITS )) << 40 ) | \
646 ( ((u64) ( RA_BITS | RCODE_BITS )) << 32 ) | \
647 ( ((u64) 1LL) << 16 ))
648
649 #define MESSAGE_HEADER_RESULT ( ((u64) 1LL) << 16 )
650
651 /* Bind gives "RA" here (seems irrelevant, nonsense, but we need to accept it) */
652
653 #define NOTIFY_MESSAGE_HEADER_MASK (( (u64) 0LL ) | \
654 ( ((u64) ( TC_BITS )) << 40 ) | \
655 ( ((u64) 1LL) << 16 ))
656
657 #define NOTIFY_MESSAGE_HEADER_RESULT ( ((u64) 1LL) << 16 )
658
659 #else
660
661 #define MESSAGE_HEADER_MASK (( (u64) 0LL ) | \
662 ( ((u64) ( QR_BITS | AA_BITS | RA_BITS | TC_BITS )) << 16 ) | \
663 ( ((u64) ( RA_BITS | RCODE_BITS )) << 24 ) | \
664 ( ((u64) 1LL) << 40 ))
665
666 #define MESSAGE_HEADER_RESULT ( ((u64) 1LL) << 40 )
667
668 /* Bind gives "RA" here (seems irrelevant, nonsense, but we need to accept it) */
669
670 #define NOTIFY_MESSAGE_HEADER_MASK (( (u64) 0LL ) | \
671 ( ((u64) ( TC_BITS )) << 16 ) | \
672 ( ((u64) 1LL) << 40 ))
673
674 #define NOTIFY_MESSAGE_HEADER_RESULT ( ((u64) 1LL) << 40 )
675
676 #endif
677
678 /* EDF: this takes about 150 cycles [144;152] with peaks at 152 */
679
680 /**
681 * Canonises the query:
682 * _ copies the query fqdn lowercase
683 * _ copies the query type and class for easy access
684 *
685 * (should be renamed to message_query_canonise or something of that effect)
686 *
687 * @param mesg
688 * @return a pointer to the answer section (or more accurately, just after the class of the (first) query
689 */
690
691 static inline u8*
message_process_copy_fqdn(message_data * mesg)692 message_process_copy_fqdn(message_data *mesg)
693 {
694 u8 *src = message_get_query_section_ptr(mesg);
695 u8 *dst = &mesg->_canonised_fqdn[0];
696
697 u8 *base = dst;
698 u32 len;
699
700 for(;;)
701 {
702 len = *src++;
703 *dst++ = len;
704
705 if(len == 0)
706 {
707 break;
708 }
709
710 if( (len & 0xC0) == 0 )
711 {
712 const u8 * const limit = dst + len;
713
714 if(limit - base < MAX_DOMAIN_LENGTH)
715 {
716 do
717 {
718 *dst++ = LOCASE(*src++); /* Works with the dns character set */
719 }
720 while(dst < limit);
721 }
722 else
723 {
724 message_set_status(mesg, FP_NAME_TOO_LARGE);
725
726 DERROR_MSG("FP_NAME_TOO_LARGE");
727
728 return NULL;
729 }
730 }
731 else
732 {
733 message_set_status(mesg, ((len & 0xC0)==0xC0)?FP_QNAME_COMPRESSED:FP_NAME_FORMAT_ERROR);
734
735 return NULL;
736 }
737 }
738
739 /* Get qtype & qclass */
740
741 mesg->_query_type = GET_U16_AT(src[0]); /** @note : NATIVETYPE */
742 mesg->_query_class = GET_U16_AT(src[2]); /** @note : NATIVECLASS */
743
744 // the next section starts at &src[4]
745
746 return &src[4];
747 }
748
749 ya_result
message_process_query(message_data * mesg)750 message_process_query(message_data *mesg)
751 {
752 u8 *buffer = message_get_buffer(mesg);
753
754 /** CHECK DNS HEADER */
755 /** Drop dns packet if query is answer or does not have correct header length */
756
757 /*
758 * +5 <=> 1 qd record ar least
759 */
760
761 u64 *h64 = (u64*)buffer;
762 u64 m64 = MESSAGE_HEADER_MASK;
763 u64 r64 = MESSAGE_HEADER_RESULT;
764
765 if((message_get_size(mesg) < DNS_HEADER_LENGTH + 5) ||
766 (( *h64 & m64) != r64 ) )
767 {
768 /** Return if QDCOUNT is not 1
769 *
770 * @note Previous test was actually testing if QDCOUNT was > 1
771 * I assumed either 0 or >1 is wrong for us so I used the same trick than for QCCOUNT
772 */
773
774 if(MESSAGE_QR(buffer))
775 {
776 message_set_status(mesg, FP_QR_BIT_SET);
777 return INVALID_MESSAGE;
778 }
779
780 MESSAGE_FLAGS_AND(buffer, OPCODE_BITS|RD_BITS, 0);
781
782 if(NETWORK_ONE_16 != MESSAGE_QD(buffer))
783 {
784 if(0 == MESSAGE_QD(buffer))
785 {
786 DERROR_MSG("FP_QDCOUNT_IS_0");
787 message_set_status(mesg, FP_QDCOUNT_IS_0);
788 return INVALID_MESSAGE; /* will be dropped */
789 }
790 else
791 {
792 DERROR_MSG("FP_QDCOUNT_BIG_1");
793 message_set_status(mesg, FP_QDCOUNT_BIG_1);
794 }
795 }
796 else if(MESSAGE_NS(buffer) != 0)
797 {
798 message_set_status(mesg, FP_NSCOUNT_NOT_0);
799 }
800 else
801 {
802 message_set_status(mesg, FP_PACKET_DROPPED);
803 }
804
805 return UNPROCESSABLE_MESSAGE;
806 }
807
808 /**
809 * @note Past this point, a message could be processable.
810 * It's the right place to reset the message's defaults.
811 *
812 */
813
814 message_reset_buffer_size(mesg);
815 mesg->_ar_start = NULL;
816 #if DNSCORE_HAS_TSIG_SUPPORT
817 mesg->_tsig.tsig = NULL;
818 #endif
819 mesg->_rcode_ext = 0;
820 mesg->_edns = FALSE;
821 #if DNSCORE_HAS_NSID_SUPPORT
822 mesg->_nsid = FALSE;
823 #endif
824
825 u8 *s = message_process_copy_fqdn(mesg);
826
827 if(s == NULL)
828 {
829 message_set_status(mesg, FP_NAME_FORMAT_ERROR);
830 return UNPROCESSABLE_MESSAGE;
831 }
832
833 /*
834 * Handle the OPT and TSIG records
835 */
836
837 {
838 ya_result return_code;
839 u32 nsar_count;
840
841 if((nsar_count = MESSAGE_NSAR(buffer)) != 0)
842 {
843 if(FAIL(return_code = message_process_additionals(mesg, s, nsar_count)))
844 {
845 //message_set_size(mesg, s - buffer);
846
847 return return_code;
848 }
849 }
850
851 if(message_get_query_type(mesg) != TYPE_IXFR)
852 {
853 message_set_size(mesg, s - buffer);
854 }
855 }
856
857 /* cut the trash here */
858
859
860 /* At this point the TSIG has been computed and removed */
861 /* Clear zome bits */
862 message_apply_mask(mesg, ~(QR_BITS|TC_BITS|AA_BITS), ~(Z_BITS|AD_BITS|CD_BITS|RA_BITS|RCODE_BITS));
863 //MESSAGE_LOFLAGS(buffer) &= ~(Z_BITS|AD_BITS|CD_BITS|RCODE_BITS);
864
865 message_set_status(mesg, FP_MESG_OK);
866
867 return SUCCESS;
868 }
869
870 int
message_process(message_data * mesg)871 message_process(message_data *mesg)
872 {
873 u8 *buffer = message_get_buffer(mesg);
874
875 switch(MESSAGE_OP(buffer))
876 {
877 case OPCODE_QUERY:
878 {
879 /** CHECK DNS HEADER */
880 /** Drop dns packet if query is answer or does not have correct header length */
881
882 /*
883 * +5 <=> 1 qd record ar least
884 */
885
886 u64 *h64 = (u64*)buffer;
887 u64 m64 = MESSAGE_HEADER_MASK;
888 u64 r64 = MESSAGE_HEADER_RESULT;
889
890 if( (message_get_size(mesg) < DNS_HEADER_LENGTH + 5) ||
891 (( *h64 & m64) != r64 ) )
892 {
893 /** Return if QDCOUNT is not 1
894 *
895 * @note Previous test was actually testing if QDCOUNT was > 1
896 * I assumed either 0 or >1 is wrong for us so I used the same trick than for QCCOUNT
897 */
898
899 if(MESSAGE_QR(buffer))
900 {
901 message_set_status(mesg, FP_QR_BIT_SET);
902 return INVALID_MESSAGE;
903 }
904
905 MESSAGE_FLAGS_AND(buffer, OPCODE_BITS|RD_BITS, 0);
906
907 if(NETWORK_ONE_16 != MESSAGE_QD(buffer))
908 {
909 if(0 == MESSAGE_QD(buffer))
910 {
911 DERROR_MSG("FP_QDCOUNT_IS_0");
912
913 message_set_status(mesg, FP_QDCOUNT_IS_0);
914
915 return INVALID_MESSAGE; /* will be dropped */
916 }
917 else
918 {
919 message_set_status(mesg, FP_QDCOUNT_BIG_1);
920
921 DERROR_MSG("FP_QDCOUNT_BIG_1");
922 }
923 }
924 else if( MESSAGE_NS(buffer) != 0)
925 {
926 message_set_status(mesg, FP_NSCOUNT_NOT_0);
927 }
928 else
929 {
930 message_set_status(mesg, FP_PACKET_DROPPED);
931 }
932
933 return UNPROCESSABLE_MESSAGE;
934 }
935
936
937
938 /**
939 * @note Past this point, a message could be processable.
940 * It's the right place to reset the message's defaults.
941 *
942 */
943
944 message_reset_buffer_size(mesg);
945 mesg->_ar_start = NULL;
946 #if DNSCORE_HAS_TSIG_SUPPORT
947 mesg->_tsig.tsig = NULL;
948 #endif
949 mesg->_rcode_ext = 0;
950 mesg->_edns = FALSE;
951 #if DNSCORE_HAS_NSID_SUPPORT
952 mesg->_nsid = FALSE;
953 #endif
954 u8 *s = message_process_copy_fqdn(mesg);
955
956 if(s == NULL)
957 {
958 message_set_status(mesg, FP_NAME_FORMAT_ERROR);
959 return UNPROCESSABLE_MESSAGE;
960 }
961
962
963
964 /*
965 * Handle the OPT and TSIG records
966 */
967
968 {
969 ya_result return_code;
970 u32 nsar_count;
971
972 if((nsar_count = MESSAGE_NSAR(buffer)) != 0)
973 {
974 if(FAIL(return_code = message_process_additionals(mesg, s, nsar_count)))
975 {
976 message_set_size(mesg, s - buffer);
977
978 return return_code;
979 }
980 }
981
982 if(message_get_query_type(mesg) != TYPE_IXFR)
983 {
984 message_set_size(mesg, s - buffer);
985 }
986 }
987
988 /* At this point the TSIG has been computed and removed */
989 /* Clear zome bits */
990 message_apply_mask(mesg, ~(QR_BITS|TC_BITS|AA_BITS), ~(Z_BITS|RA_BITS|AD_BITS|CD_BITS|RCODE_BITS));
991
992 message_set_status(mesg, FP_MESG_OK);
993
994 return OK;
995 }
996 case OPCODE_NOTIFY:
997 {
998 MESSAGE_LOFLAGS(buffer) &= ~(Z_BITS|AD_BITS|CD_BITS);
999
1000
1001 /* ------------------------------------------------------------ */
1002
1003 /** CHECK DNS HEADER */
1004 /** Drop dns packet if query is answer or does not have correct header length */
1005
1006 /*
1007 * +5 <=> 1 qd record ar least
1008 */
1009
1010 u64 *h64 = (u64*)buffer;
1011 u64 m64 = NOTIFY_MESSAGE_HEADER_MASK;
1012 u64 r64 = NOTIFY_MESSAGE_HEADER_RESULT;
1013 /* ... A400 0001 ... */
1014 if( (message_get_size(mesg) < DNS_HEADER_LENGTH + 5) ||
1015 (( *h64 & m64) != r64 ) )
1016 {
1017 /** Return if QDCOUNT is not 1
1018 *
1019 * @note Previous test was actually testing if QDCOUNT was > 1
1020 * I assumed either 0 or >1 is wrong for us so I used the same trick than for QCCOUNT
1021 */
1022 MESSAGE_FLAGS_AND(buffer, OPCODE_BITS, 0);
1023
1024
1025 if(NETWORK_ONE_16 != MESSAGE_QD(buffer))
1026 {
1027 if(0 == MESSAGE_QD(buffer))
1028 {
1029 DERROR_MSG("FP_QDCOUNT_IS_0");
1030 message_set_status(mesg, FP_QDCOUNT_IS_0);
1031 return INVALID_MESSAGE;
1032 }
1033 else
1034 {
1035 message_set_status(mesg, FP_QDCOUNT_BIG_1);
1036
1037 DERROR_MSG("FP_QDCOUNT_BIG_1");
1038 }
1039 }
1040 else
1041 {
1042 message_set_status(mesg, FP_PACKET_DROPPED);
1043 }
1044
1045 return UNPROCESSABLE_MESSAGE;
1046 }
1047
1048
1049
1050 u8 *s = message_process_copy_fqdn(mesg);
1051
1052 if(s == NULL)
1053 {
1054 message_set_status(mesg, FP_NAME_FORMAT_ERROR);
1055 return UNPROCESSABLE_MESSAGE;
1056 }
1057
1058
1059
1060 /**
1061 * @note Past this point, a message could be processable.
1062 * It's the right place to reset the message's defaults.
1063 *
1064 */
1065
1066 message_reset_buffer_size(mesg);
1067 mesg->_ar_start = NULL;
1068 #if DNSCORE_HAS_TSIG_SUPPORT
1069 mesg->_tsig.tsig = NULL;
1070 #endif
1071 mesg->_rcode_ext = 0;
1072 mesg->_edns = FALSE;
1073 #if DNSCORE_HAS_NSID_SUPPORT
1074 mesg->_nsid = FALSE;
1075 #endif
1076 /*
1077 * If there is a TSIG, it is here ...
1078 */
1079
1080 #if DNSCORE_HAS_TSIG_SUPPORT
1081 {
1082 ya_result return_code;
1083 u16 ar_count;
1084
1085 if((ar_count = MESSAGE_AR(buffer)) != 0)
1086 {
1087 if(FAIL(return_code = message_process_additionals(mesg, s, ar_count)))
1088 {
1089 return return_code;
1090 }
1091 }
1092 }
1093 #endif
1094 /* At this point the TSIG has been computed and removed */
1095
1096 message_set_status(mesg, FP_MESG_OK);
1097
1098 return OK;
1099 }
1100 case OPCODE_UPDATE:
1101 {
1102 MESSAGE_LOFLAGS(buffer) &= ~(Z_BITS|AD_BITS|CD_BITS|RCODE_BITS);
1103
1104
1105 /* ------------------------------------------------------------ */
1106
1107 /** CHECK DNS HEADER */
1108 /** Drop dns packet if query is answer or does not have correct header length */
1109
1110 /*
1111 * +5 <=> 1 qd record ar least
1112 */
1113
1114 u64 *h64 = (u64*)buffer;
1115 u64 m64 = MESSAGE_HEADER_MASK;
1116 u64 r64 = MESSAGE_HEADER_RESULT;
1117
1118 if( (message_get_size(mesg) < DNS_HEADER_LENGTH + 5) ||
1119 (( *h64 & m64) != r64 ) )
1120 {
1121 /** Return if QDCOUNT is not 1
1122 *
1123 * @note Previous test was actually testing if QDCOUNT was > 1
1124 * I assumed either 0 or >1 is wrong for us so I used the same trick than for QCCOUNT
1125 */
1126
1127 if(MESSAGE_QR(buffer))
1128 {
1129 message_set_status(mesg, FP_QR_BIT_SET);
1130 return INVALID_MESSAGE;
1131 }
1132
1133 MESSAGE_FLAGS_AND(buffer, OPCODE_BITS, 0);
1134
1135 if(NETWORK_ONE_16 != MESSAGE_QD(buffer))
1136 {
1137 if(0 == MESSAGE_QD(buffer))
1138 {
1139 DERROR_MSG("FP_QDCOUNT_IS_0");
1140 message_set_status(mesg, FP_QDCOUNT_IS_0);
1141 return INVALID_MESSAGE;
1142 }
1143 else
1144 {
1145 DERROR_MSG("FP_QDCOUNT_BIG_1");
1146 message_set_status(mesg, FP_QDCOUNT_BIG_1);
1147 }
1148
1149 return UNPROCESSABLE_MESSAGE;
1150 }
1151
1152 message_set_status(mesg, FP_PACKET_DROPPED);
1153
1154 return UNPROCESSABLE_MESSAGE;
1155 }
1156
1157
1158
1159 u8 *s = message_process_copy_fqdn(mesg);
1160
1161 if(s == NULL)
1162 {
1163 message_set_status(mesg, FP_NAME_FORMAT_ERROR);
1164 return UNPROCESSABLE_MESSAGE;
1165 }
1166
1167
1168
1169 /**
1170 * @note Past this point, a message could be processable.
1171 * It's the right place to reset the message's defaults.
1172 *
1173 */
1174
1175 message_reset_buffer_size(mesg);
1176 mesg->_ar_start = NULL;
1177 #if DNSCORE_HAS_TSIG_SUPPORT
1178 mesg->_tsig.tsig = NULL;
1179 #endif
1180 mesg->_rcode_ext = 0;
1181 mesg->_edns = FALSE;
1182 #if DNSCORE_HAS_NSID_SUPPORT
1183 mesg->_nsid = FALSE;
1184 #endif
1185 /*
1186 * If there is a TSIG, it is here ...
1187 */
1188
1189 #if DNSCORE_HAS_TSIG_SUPPORT
1190 {
1191 ya_result return_code;
1192 u16 ar_count;
1193
1194 if((ar_count = MESSAGE_AR(buffer)) != 0)
1195 {
1196 if(FAIL(return_code = message_process_additionals(mesg, s, ar_count)))
1197 {
1198 return return_code;
1199 }
1200 }
1201 }
1202 #endif
1203
1204 /* At this point the TSIG has been computed and removed */
1205
1206 message_apply_mask(mesg, ~(QR_BITS|TC_BITS|AA_BITS), ~(RA_BITS|RCODE_BITS));
1207
1208 message_set_status(mesg, FP_MESG_OK);
1209
1210 return OK;
1211 }
1212 #if HAS_CTRL
1213 case OPCODE_CTRL:
1214 {
1215 MESSAGE_LOFLAGS(buffer) &= ~(Z_BITS|AD_BITS|CD_BITS|RCODE_BITS);
1216
1217 /*
1218 rdtsc_init(&mpb);
1219 */
1220 /* ------------------------------------------------------------ */
1221
1222 /** CHECK DNS HEADER */
1223 /** Drop dns packet if query is answer or does not have correct header length */
1224
1225 /*
1226 * +5 <=> 1 qd record ar least
1227 */
1228
1229 u64 *h64 = (u64*)buffer;
1230 u64 m64 = MESSAGE_HEADER_MASK;
1231 u64 r64 = MESSAGE_HEADER_RESULT;
1232
1233 if( (message_get_size(mesg) < DNS_HEADER_LENGTH + 5) ||
1234 (( *h64 & m64) != r64 ) )
1235 {
1236 /** Return if QDCOUNT is not 1
1237 *
1238 * @note Previous test was actually testing if QDCOUNT was > 1
1239 * I assumed either 0 or >1 is wrong for us so I used the same trick than for QCCOUNT
1240 */
1241
1242 if(MESSAGE_QR(buffer))
1243 {
1244 message_set_status(mesg, FP_QR_BIT_SET);
1245 return INVALID_MESSAGE;
1246 }
1247
1248 MESSAGE_FLAGS_AND(buffer, OPCODE_BITS, 0);
1249
1250 if(NETWORK_ONE_16 != MESSAGE_QD(buffer))
1251 {
1252 if(0 == MESSAGE_QD(buffer))
1253 {
1254 DERROR_MSG("FP_QDCOUNT_IS_0");
1255 message_set_status(mesg, FP_QDCOUNT_IS_0);
1256 return INVALID_MESSAGE;
1257 }
1258 else
1259 {
1260 DERROR_MSG("FP_QDCOUNT_BIG_1");
1261 message_set_status(mesg, FP_QDCOUNT_BIG_1);
1262 }
1263
1264 return UNPROCESSABLE_MESSAGE;
1265 }
1266
1267 message_set_status(mesg, FP_PACKET_DROPPED);
1268
1269 return UNPROCESSABLE_MESSAGE;
1270 }
1271
1272
1273
1274 u8 *s = message_process_copy_fqdn(mesg);
1275
1276 if(s == NULL)
1277 {
1278 message_set_status(mesg, FP_NAME_FORMAT_ERROR);
1279 return UNPROCESSABLE_MESSAGE;
1280 }
1281
1282
1283
1284 /**
1285 * @note Past this point, a message could be processable.
1286 * It's the right place to reset the message's defaults.
1287 *
1288 */
1289
1290 message_reset_buffer_size(mesg);
1291 mesg->_ar_start = NULL;
1292 #if DNSCORE_HAS_TSIG_SUPPORT
1293 message_tsig_clear_key(mesg);
1294 #endif
1295 mesg->_rcode_ext = 0;
1296 mesg->_edns = FALSE;
1297 #if DNSCORE_HAS_NSID_SUPPORT
1298 mesg->_nsid = FALSE;
1299 #endif
1300 /*
1301 * If there is a TSIG, it is here ...
1302 */
1303
1304 #if DNSCORE_HAS_TSIG_SUPPORT
1305 {
1306 ya_result return_code;
1307 u16 ar_count;
1308
1309 if((ar_count = MESSAGE_AR(buffer)) != 0)
1310 {
1311 if(FAIL(return_code = message_process_additionals(mesg, s, ar_count)))
1312 {
1313 return return_code;
1314 }
1315 }
1316 }
1317 #endif
1318
1319 /* At this point the TSIG has been computed and removed */
1320
1321 message_apply_mask(mesg, ~(QR_BITS|TC_BITS|AA_BITS), ~(RA_BITS|RCODE_BITS));
1322
1323 message_set_status(mesg, FP_MESG_OK);
1324
1325 return OK;
1326 }
1327 #endif // HAS_CTRL
1328 default:
1329 {
1330 u8 hf = MESSAGE_HIFLAGS(buffer);
1331 if((hf & QR_BITS) == 0)
1332 {
1333 MESSAGE_LOFLAGS(buffer) &= ~(Z_BITS|AD_BITS|CD_BITS|RCODE_BITS);
1334 MESSAGE_FLAGS_AND(buffer, OPCODE_BITS, 0);
1335
1336 message_reset_buffer_size(mesg);
1337 mesg->_ar_start = NULL;
1338 #if DNSCORE_HAS_TSIG_SUPPORT
1339 mesg->_tsig.tsig = NULL;
1340 #endif
1341 mesg->_rcode_ext = 0;
1342 mesg->_edns = FALSE;
1343 #if DNSCORE_HAS_NSID_SUPPORT
1344 mesg->_nsid = FALSE;
1345 #endif
1346 message_set_status(mesg, FP_NOT_SUPP_OPC);
1347 message_set_size(mesg, DNS_HEADER_LENGTH);
1348 SET_U32_AT(mesg->_buffer[4],0); /* aligned to 32 bits, so two 32 bits instead of one 64 */
1349 SET_U32_AT(mesg->_buffer[8],0);
1350
1351 /* reserved for future use */
1352
1353 return UNPROCESSABLE_MESSAGE;
1354 }
1355 else
1356 {
1357 message_set_status(mesg, FP_PACKET_DROPPED);
1358
1359 return INVALID_MESSAGE;
1360 }
1361 }
1362 }
1363 }
1364
1365 int
message_process_lenient(message_data * mesg)1366 message_process_lenient(message_data *mesg)
1367 {
1368 if(message_get_size(mesg) < DNS_HEADER_LENGTH)
1369 {
1370 return UNPROCESSABLE_MESSAGE;
1371 }
1372 /*
1373 if(message_istruncated(mesg))
1374 {
1375 return MESSAGE_TRUNCATED;
1376 }
1377 */
1378 u8 *s = message_process_copy_fqdn(mesg);
1379
1380 if(s == NULL)
1381 {
1382 return UNPROCESSABLE_MESSAGE;
1383 }
1384
1385 /**
1386 * @note Past this point, a message could be processable.
1387 * It's the right place to reset the message's defaults.
1388 *
1389 */
1390
1391 message_reset_buffer_size(mesg);
1392 mesg->_ar_start = NULL;
1393 mesg->_rcode_ext = 0;
1394 mesg->_edns = FALSE;
1395 #if DNSCORE_HAS_NSID_SUPPORT
1396 mesg->_nsid = FALSE;
1397 #endif
1398
1399 /*
1400 * Handle the OPT and TSIG records
1401 */
1402
1403 {
1404 ya_result return_code;
1405 u16 ar_count_ne;
1406
1407 if((ar_count_ne = message_get_additional_count_ne(mesg)) != 0)
1408 {
1409 if(FAIL(return_code = message_process_answer_additionals(mesg, ar_count_ne)))
1410 {
1411 return return_code;
1412 }
1413 }
1414 #if DNSCORE_HAS_TSIG_SUPPORT
1415 else
1416 {
1417 mesg->_tsig.tsig = NULL;
1418
1419 /* cut the trash here */
1420 /*message_set_size(mesg, s - buffer);(*/
1421 }
1422 #endif
1423 }
1424
1425
1426
1427 /* At this point the TSIG has been computed and removed */
1428
1429 //message_set_status(mesg, FP_MESG_OK);
1430 message_set_status(mesg, (mesg->_buffer[3] & 0xf));
1431
1432 return SUCCESS;
1433 }
1434
1435 static ya_result
message_answer_verify_additionals(message_data * mesg,packet_unpack_reader_data * purd,int ar_count)1436 message_answer_verify_additionals(message_data *mesg, packet_unpack_reader_data *purd, int ar_count)
1437 {
1438 /* We are now at the start of the ar */
1439
1440 struct type_class_ttl_rdlen *tctr;
1441 #if DNSCORE_HAS_TSIG_SUPPORT
1442 u32 record_offset;
1443 u8 fqdn[MAX_DOMAIN_LENGTH];
1444 #endif
1445
1446 while(ar_count-- > 0)
1447 {
1448 #if DNSCORE_HAS_TSIG_SUPPORT
1449 record_offset = purd->offset;
1450 #endif
1451
1452 if(FAIL(packet_reader_read_fqdn(purd, fqdn, sizeof(fqdn))))
1453 {
1454 /* oops */
1455
1456 message_set_status(mesg, FP_ERROR_READING_QUERY);
1457
1458 return UNPROCESSABLE_MESSAGE;
1459 }
1460
1461 if(packet_reader_available(purd) < 10)
1462 {
1463 message_set_status(mesg, FP_ERROR_READING_QUERY);
1464
1465 return UNPROCESSABLE_MESSAGE;
1466 }
1467
1468 tctr = (struct type_class_ttl_rdlen*)packet_reader_get_next_u8_ptr_const(purd);
1469
1470 purd->offset += 10;
1471
1472 switch(tctr->qtype)
1473 {
1474 /*
1475 * EDNS (0)
1476 */
1477
1478 case TYPE_OPT:
1479 {
1480 /**
1481 * Handle EDNS
1482 */
1483
1484 message_sub_additional_count(mesg, 1);
1485
1486 if((tctr->ttl & NU32(0x00ff0000)) == 0) /* ensure version is 0 */
1487 {
1488 if(fqdn[0] == '\0')
1489 {
1490 message_set_buffer_size(mesg, edns0_maxsize); /* our own limit, taken from the config file */
1491 mesg->_edns = TRUE;
1492 mesg->_rcode_ext = tctr->ttl;
1493
1494 log_debug("EDNS: udp-size=%d rcode-ext=%08x desc=%04x", message_get_size(mesg), tctr->ttl, ntohs(tctr->rdlen));
1495 continue;
1496 }
1497 }
1498 else
1499 {
1500 message_set_status(mesg, FP_EDNS_BAD_VERSION);
1501 message_set_buffer_size(mesg, edns0_maxsize);
1502 mesg->_edns = TRUE;
1503 mesg->_rcode_ext = 0;
1504
1505 break;
1506 }
1507
1508 log_debug("OPT record is not processable (broken or not supported)");
1509
1510 return UNPROCESSABLE_MESSAGE;
1511 }
1512 #if DNSCORE_HAS_TSIG_SUPPORT
1513
1514 /*
1515 * TSIG
1516 */
1517
1518 case TYPE_TSIG:
1519 {
1520 if(ar_count == 0)
1521 {
1522 /*
1523 * It looks like a TSIG ...
1524 */
1525
1526 ya_result return_code;
1527
1528 if(message_has_tsig(mesg))
1529 {
1530 if(dnsname_equals(fqdn, message_tsig_get_name(mesg)))
1531 {
1532 if(FAIL(return_code = tsig_process_answer(mesg, purd, record_offset, tctr)))
1533 {
1534 log_err("%r answer error from %{sockaddr}", return_code, message_get_sender_sa(mesg));
1535
1536 return return_code;
1537 }
1538 }
1539 else
1540 {
1541 log_err("TSIG name mismatch from %{sockaddr}", message_get_sender_sa(mesg));
1542
1543 return UNPROCESSABLE_MESSAGE;
1544 }
1545 }
1546 else // no tsig
1547 {
1548 log_err("answer error from %{sockaddr}: TSIG when none expected", message_get_sender_sa(mesg));
1549
1550 message_set_status(mesg, FP_TSIG_UNEXPECTED);
1551
1552 return UNPROCESSABLE_MESSAGE;
1553 }
1554
1555 return SUCCESS; /* we know there is no need to loop anymore */
1556 }
1557 else
1558 {
1559 /*
1560 * Error: TSIG is not the last AR record
1561 */
1562
1563 log_debug("TSIG record is not the last AR");
1564
1565 message_set_status(mesg, FP_TSIG_IS_NOT_LAST);
1566
1567 return UNPROCESSABLE_MESSAGE;
1568 }
1569 }
1570 #endif
1571 default:
1572 {
1573 /* Unhandled AR TYPE */
1574 #if DEBUG
1575 log_debug("skipping AR type %{dnstype}", &tctr->qtype);
1576 #endif
1577 purd->offset += ntohs(tctr->rdlen);
1578 break;
1579 }
1580 }
1581 } /* While there are AR to process */
1582
1583 return SUCCESS;
1584 }
1585
1586 int
message_answer_verify(message_data * mesg)1587 message_answer_verify(message_data *mesg)
1588 {
1589 if(message_get_size(mesg) < DNS_HEADER_LENGTH)
1590 {
1591 return UNPROCESSABLE_MESSAGE;
1592 }
1593
1594 u8 *after_query_section;
1595
1596 if(message_get_query_count_ne(mesg) != 0)
1597 {
1598 after_query_section = message_process_copy_fqdn(mesg); // canonises the query fqdn and fetches its type and class
1599
1600 if(after_query_section == NULL)
1601 {
1602 return UNPROCESSABLE_MESSAGE;
1603 }
1604 }
1605 else
1606 {
1607 if(mesg->_tcp_serial == 0) // needed at the beginning of the stream
1608 {
1609 return UNPROCESSABLE_MESSAGE;
1610 }
1611
1612 after_query_section = message_get_query_section_ptr(mesg); // as there is no query section
1613 }
1614
1615 /**
1616 * @note Past this point, a message could be processable.
1617 * It's the right place to reset the message's defaults.
1618 *
1619 */
1620
1621 u16 ar_count_ne;
1622
1623 if((ar_count_ne = message_get_additional_count_ne(mesg)) != 0)
1624 {
1625 // find the additional section
1626
1627 packet_unpack_reader_data purd;
1628 purd.packet = message_get_buffer_const(mesg);
1629 purd.packet_size = message_get_size(mesg);
1630 purd.offset = after_query_section - purd.packet;
1631
1632 // skip all records before the additional section
1633
1634 for(int ar_index = message_get_answer_count(mesg) + message_get_authority_count(mesg); ar_index > 0; --ar_index)
1635 {
1636 if(FAIL(packet_reader_skip_record(&purd)))
1637 {
1638 return UNPROCESSABLE_MESSAGE;
1639 }
1640 }
1641
1642 mesg->_ar_start = &mesg->_buffer[purd.offset];
1643
1644 // ar_start is ready
1645
1646 message_answer_verify_additionals(mesg, &purd, ntohs(ar_count_ne));
1647 }
1648 else
1649 {
1650 mesg->_ar_start = NULL;
1651 mesg->_rcode_ext = 0;
1652 mesg->_edns = FALSE;
1653 #if DNSCORE_HAS_NSID_SUPPORT
1654 mesg->_nsid = FALSE;
1655 #endif
1656 }
1657
1658 message_set_status(mesg, FP_MESG_OK);
1659
1660 return OK;
1661 }
1662
1663
1664 void
message_transform_to_error(message_data * mesg)1665 message_transform_to_error(message_data *mesg)
1666 {
1667 if(!mesg->_edns)
1668 {
1669 message_set_answer(mesg);
1670 message_or_rcode(mesg, message_get_status(mesg));
1671
1672 if(message_get_status(mesg) == RCODE_FORMERR)
1673 {
1674 SET_U32_AT(mesg->_buffer[4],0); /* aligned to 32 bits, so two 32 bits instead of one 64 */
1675 SET_U32_AT(mesg->_buffer[8],0);
1676
1677 message_set_size(mesg, DNS_HEADER_LENGTH);
1678 }
1679 else
1680 {
1681 }
1682 }
1683 else
1684 {
1685 /* 00 0029 0200 EE 00 00000000 */
1686
1687 if(message_get_status(mesg) == RCODE_FORMERR)
1688 {
1689 SET_U32_AT(mesg->_buffer[4],0); /* aligned to 32 bits, so two 32 bits instead of one 64 */
1690 SET_U32_AT(mesg->_buffer[8],0);
1691
1692 message_set_size(mesg, DNS_HEADER_LENGTH);
1693 }
1694 else
1695 {
1696 message_set_size(mesg, message_get_additional_section_ptr(mesg) - mesg->_buffer);
1697 }
1698
1699 message_set_answer(mesg);
1700 message_set_rcode(mesg, message_get_status(mesg) & 15);
1701
1702 /* #AR = 1 */
1703 mesg->_buffer[DNS_HEADER_LENGTH - 1] = 1; /* AR count was 0, now it is 1 */
1704
1705 /* append opt *//* */
1706 u8 *buffer = message_get_buffer_limit(mesg);
1707 buffer[ 0] = 0;
1708 buffer[ 1] = 0;
1709 buffer[ 2] = 0x29;
1710 buffer[ 3] = edns0_maxsize>>8;
1711 buffer[ 4] = edns0_maxsize;
1712 buffer[ 5] = message_get_status(mesg) >> 4; // status is updated here
1713 buffer[ 6] = mesg->_rcode_ext >> 16;
1714 buffer[ 7] = mesg->_rcode_ext >> 8;
1715 buffer[ 8] = mesg->_rcode_ext;
1716
1717 #if DNSCORE_HAS_NSID_SUPPORT
1718 if(!message_has_nsid(mesg))
1719 {
1720 buffer[ 9] = 0;
1721 buffer[10] = 0;
1722
1723 buffer += EDNS0_RECORD_SIZE;
1724 }
1725 else
1726 {
1727 buffer += EDNS0_RECORD_SIZE - 2;
1728 memcpy(buffer, edns0_rdatasize_nsid_option_wire, edns0_rdatasize_nsid_option_wire_size);
1729 buffer += edns0_rdatasize_nsid_option_wire_size;
1730 }
1731 #else
1732 buffer[ 9] = 0;
1733 buffer[10] = 0;
1734
1735 buffer += EDNS0_RECORD_SIZE;
1736 #endif
1737 message_set_size(mesg, buffer - mesg->_buffer);
1738 }
1739 }
1740
1741 void
message_transform_to_signed_error(message_data * mesg)1742 message_transform_to_signed_error(message_data *mesg)
1743 {
1744 message_transform_to_error(mesg);
1745
1746 if(message_has_tsig(mesg))
1747 {
1748 tsig_sign_answer(mesg);
1749 }
1750 }
1751
1752 void
message_make_query(message_data * mesg,u16 id,const u8 * qname,u16 qtype,u16 qclass)1753 message_make_query(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass)
1754 {
1755 #ifdef WORDS_BIGENDIAN
1756 SET_U64_AT(mesg->_buffer[0], 0x0000000000010000LL);
1757 SET_U32_AT(mesg->_buffer[8], 0);
1758 #else
1759 SET_U64_AT(mesg->_buffer[0], 0x0000010000000000LL);
1760 SET_U32_AT(mesg->_buffer[8], 0);
1761 #endif
1762 message_set_id(mesg, id);
1763
1764 dnsname_canonize(qname, mesg->_canonised_fqdn);
1765
1766 ya_result qname_len = dnsname_len(qname);
1767 u8 *tc = message_get_query_section_ptr(mesg);
1768 memcpy(tc, qname, qname_len);
1769 tc += qname_len;
1770 SET_U16_AT(tc[0], qtype);
1771 tc += 2;
1772 SET_U16_AT(tc[0], qclass);
1773 tc += 2;
1774 #if DNSCORE_HAS_TSIG_SUPPORT
1775 mesg->_tsig.tsig = NULL;
1776 #endif
1777
1778 mesg->_ar_start = tc;
1779 message_reset_buffer_size(mesg);
1780 message_set_size(mesg, tc - message_get_buffer_const(mesg));
1781 message_set_status(mesg, FP_MESG_OK);
1782 mesg->_rcode_ext = 0;
1783 }
1784
1785 void
message_make_query_ex(message_data * mesg,u16 id,const u8 * qname,u16 qtype,u16 qclass,u16 flags)1786 message_make_query_ex(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass, u16 flags)
1787 {
1788 #ifdef WORDS_BIGENDIAN
1789 SET_U64_AT(mesg->_buffer[0], 0x0000000000010000LL);
1790 SET_U32_AT(mesg->_buffer[8], 0);
1791 #else
1792 SET_U64_AT(mesg->_buffer[0], 0x0000010000000000LL);
1793 SET_U32_AT(mesg->_buffer[8], 0);
1794 #endif
1795 message_set_id(mesg, id);
1796
1797 dnsname_canonize(qname, mesg->_canonised_fqdn);
1798
1799 ya_result qname_len = dnsname_len(qname);
1800 u8 *tc = message_get_query_section_ptr(mesg);
1801 memcpy(tc, qname, qname_len);
1802 tc += qname_len;
1803 SET_U16_AT(tc[0], qtype);
1804 tc += 2;
1805 SET_U16_AT(tc[0], qclass);
1806 tc += 2;
1807
1808 mesg->_ar_start = tc;
1809 message_set_size(mesg, tc - message_get_buffer_const(mesg));
1810 mesg->_rcode_ext = 0;
1811
1812 message_set_status(mesg, FP_MESG_OK);
1813 #if DNSCORE_HAS_TSIG_SUPPORT
1814 message_tsig_clear_key(mesg);
1815 #endif
1816
1817 if(mesg->_edns || (flags != 0))
1818 {
1819 message_set_additional_count_ne(mesg, NETWORK_ONE_16);
1820
1821 mesg->_rcode_ext |= MESSAGE_EDNS0_DNSSEC;
1822
1823 u8 *buffer = message_get_buffer_limit(mesg);
1824 buffer[ 0] = 0;
1825 buffer[ 1] = 0; // TYPE
1826 buffer[ 2] = 0x29; //
1827 buffer[ 3] = edns0_maxsize >> 8; // CLASS = SIZE
1828 buffer[ 4] = edns0_maxsize; //
1829 buffer[ 5] = message_get_status(mesg) >> 4; // extended RCODE & FLAGS
1830 buffer[ 6] = mesg->_rcode_ext >> 16;
1831 buffer[ 7] = mesg->_rcode_ext >> 8;
1832 buffer[ 8] = mesg->_rcode_ext;
1833 buffer[ 9] = 0; // RDATA descriptor
1834 buffer[10] = 0;
1835
1836 message_increase_size(mesg, 11);
1837 }
1838 }
1839
1840 void
message_make_query_ex_with_edns0(message_data * mesg,u16 id,const u8 * qname,u16 qtype,u16 qclass,u32 edns0_ttl)1841 message_make_query_ex_with_edns0(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass, u32 edns0_ttl)
1842 {
1843 #ifdef WORDS_BIGENDIAN
1844 SET_U64_AT(mesg->_buffer[0], 0x0000000000010000LL);
1845 SET_U32_AT(mesg->_buffer[8], 0);
1846 #else
1847 SET_U64_AT(mesg->_buffer[0], 0x0000010000000000LL);
1848 SET_U32_AT(mesg->_buffer[8], 0);
1849 #endif
1850 message_set_id(mesg, id);
1851
1852 dnsname_canonize(qname, mesg->_canonised_fqdn);
1853
1854 ya_result qname_len = dnsname_len(qname);
1855 u8 *tc = message_get_query_section_ptr(mesg);
1856 memcpy(tc, qname, qname_len);
1857 tc += qname_len;
1858 SET_U16_AT(tc[0], qtype);
1859 tc += 2;
1860 SET_U16_AT(tc[0], qclass);
1861 tc += 2;
1862
1863 mesg->_ar_start = tc;
1864 message_set_size(mesg, tc - message_get_buffer_const(mesg));
1865 mesg->_rcode_ext = edns0_ttl;
1866
1867 message_set_status(mesg, FP_MESG_OK);
1868 #if DNSCORE_HAS_TSIG_SUPPORT
1869 message_tsig_clear_key(mesg);
1870 #endif
1871
1872 message_set_additional_count_ne(mesg, NETWORK_ONE_16);
1873 // mesg->_rcode_ext |= MESSAGE_EDNS0_DNSSEC;
1874
1875 u8 *buffer = message_get_buffer_limit(mesg);
1876 buffer[ 0] = 0;
1877 buffer[ 1] = 0; // TYPE
1878 buffer[ 2] = 0x29; //
1879 buffer[ 3] = edns0_maxsize >> 8; // CLASS = SIZE
1880 buffer[ 4] = edns0_maxsize; //
1881 buffer[ 5] = message_get_status(mesg) >> 4; // extended RCODE & FLAGS
1882 buffer[ 6] = edns0_ttl >> 16;
1883 buffer[ 7] = edns0_ttl >> 8;
1884 buffer[ 8] = edns0_ttl;
1885 buffer[ 9] = 0; // RDATA descriptor
1886 buffer[10] = 0;
1887
1888 message_increase_size(mesg, 11);
1889 }
1890
message_make_message(message_data * mesg,u16 id,const u8 * qname,u16 qtype,u16 qclass,packet_writer * uninitialised_packet_writer)1891 void message_make_message(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass, packet_writer *uninitialised_packet_writer)
1892 {
1893 assert(uninitialised_packet_writer != NULL);
1894 assert(packet_writer_get_offset(uninitialised_packet_writer) <= message_get_buffer_size_max(mesg));
1895
1896 #ifdef WORDS_BIGENDIAN
1897 SET_U64_AT(mesg->_buffer[0], 0x0000000000010000LL);
1898 SET_U32_AT(mesg->_buffer[8], 0);
1899 #else
1900 SET_U64_AT(mesg->_buffer[0], 0x0000010000000000LL);
1901 SET_U32_AT(mesg->_buffer[8], 0);
1902 #endif
1903 message_set_id(mesg, id);
1904
1905 dnsname_canonize(qname, mesg->_canonised_fqdn);
1906
1907 packet_writer_create(uninitialised_packet_writer, message_get_buffer(mesg), DNSPACKET_MAX_LENGTH);
1908
1909 packet_writer_add_fqdn(uninitialised_packet_writer, qname);
1910 packet_writer_add_u16(uninitialised_packet_writer, qtype);
1911 packet_writer_add_u16(uninitialised_packet_writer, qclass);
1912 #if DNSCORE_HAS_TSIG_SUPPORT
1913 message_tsig_clear_key(mesg);
1914 #endif
1915
1916 message_set_size(mesg, packet_writer_get_offset(uninitialised_packet_writer));
1917 mesg->_ar_start = message_get_buffer_limit(mesg);
1918
1919 message_reset_buffer_size(mesg);
1920
1921 message_set_status(mesg, FP_MESG_OK);
1922 }
1923
1924 void
message_make_notify(message_data * mesg,u16 id,const u8 * qname,u16 qtype,u16 qclass)1925 message_make_notify(message_data *mesg, u16 id, const u8 *qname, u16 qtype, u16 qclass)
1926 {
1927 #ifdef WORDS_BIGENDIAN
1928 SET_U64_AT(mesg->_buffer[0], 0x0000240000010000LL); // notify + AA
1929 SET_U32_AT(mesg->_buffer[8], 0);
1930 #else
1931 SET_U64_AT(mesg->_buffer[0], 0x0000010000240000LL); // notify + AA
1932 SET_U32_AT(mesg->_buffer[8], 0);
1933 #endif
1934 message_set_id(mesg, id);
1935
1936 dnsname_canonize(qname, mesg->_canonised_fqdn);
1937
1938 ya_result qname_len = dnsname_len(qname);
1939 u8 *tc = message_get_query_section_ptr(mesg);
1940 memcpy(tc, qname, qname_len);
1941 tc += qname_len;
1942 SET_U16_AT(tc[0], qtype);
1943 tc += 2;
1944 SET_U16_AT(tc[0], qclass);
1945 tc += 2;
1946 #if DNSCORE_HAS_TSIG_SUPPORT
1947 message_tsig_clear_key(mesg);
1948 #endif
1949
1950 message_set_size(mesg, tc - message_get_buffer_const(mesg));
1951 mesg->_ar_start = tc;
1952 message_set_status(mesg, FP_MESG_OK);
1953 }
1954
1955 void
message_make_ixfr_query(message_data * mesg,u16 id,const u8 * qname,u32 soa_ttl,u16 soa_rdata_size,const u8 * soa_rdata)1956 message_make_ixfr_query(message_data *mesg, u16 id, const u8 *qname, u32 soa_ttl, u16 soa_rdata_size, const u8 *soa_rdata)
1957 {
1958 packet_writer pw;
1959
1960 #ifdef WORDS_BIGENDIAN
1961 SET_U64_AT(mesg->_buffer[0], 0x0000000000010000LL);
1962 SET_U32_AT(mesg->_buffer[8], 0x00010000);
1963 #else
1964 SET_U64_AT(mesg->_buffer[0], 0x0000010000000000LL);
1965 SET_U32_AT(mesg->_buffer[8], 0x00000100);
1966 #endif
1967
1968 message_set_id(mesg, id);
1969
1970 dnsname_canonize(qname, mesg->_canonised_fqdn);
1971
1972 packet_writer_create(&pw, message_get_buffer(mesg), message_get_buffer_size_max(mesg));
1973
1974 packet_writer_add_fqdn(&pw, qname);
1975 packet_writer_add_u16(&pw, TYPE_IXFR);
1976 packet_writer_add_u16(&pw, CLASS_IN);
1977
1978 packet_writer_add_fqdn(&pw, qname);
1979 packet_writer_add_u16(&pw, TYPE_SOA);
1980 packet_writer_add_u16(&pw, CLASS_IN);
1981 packet_writer_add_u32(&pw, htonl(soa_ttl));
1982 packet_writer_add_rdata(&pw, TYPE_SOA, soa_rdata, soa_rdata_size);
1983
1984 #if DNSCORE_HAS_TSIG_SUPPORT
1985 message_tsig_clear_key(mesg);
1986 #endif
1987 mesg->_ar_start = &mesg->_buffer[packet_writer_get_offset(&pw)];
1988 message_reset_buffer_size(mesg);
1989 message_set_size(mesg, packet_writer_get_offset(&pw));
1990 message_set_status(mesg, FP_MESG_OK);
1991 }
1992
1993 #if DNSCORE_HAS_TSIG_SUPPORT
1994
1995 ya_result
message_sign_answer_by_name(message_data * mesg,const u8 * tsig_name)1996 message_sign_answer_by_name(message_data *mesg, const u8 *tsig_name)
1997 {
1998 const tsig_item *key = tsig_get(tsig_name);
1999
2000 return message_sign_answer(mesg, key);
2001 }
2002
2003 ya_result
message_sign_query_by_name(message_data * mesg,const u8 * tsig_name)2004 message_sign_query_by_name(message_data *mesg, const u8 *tsig_name)
2005 {
2006 const tsig_item *key = tsig_get(tsig_name);
2007
2008 return message_sign_query(mesg, key);
2009 }
2010
2011 ya_result
message_sign_query_by_name_with_epoch_and_fudge(message_data * mesg,const u8 * tsig_name,s64 epoch,u16 fudge)2012 message_sign_query_by_name_with_epoch_and_fudge(message_data *mesg, const u8 *tsig_name, s64 epoch, u16 fudge)
2013 {
2014 const tsig_item *key = tsig_get(tsig_name);
2015
2016 return message_sign_query_with_epoch_and_fudge(mesg, key, epoch, fudge);
2017 }
2018
2019 ya_result
message_sign_answer(message_data * mesg,const tsig_item * key)2020 message_sign_answer(message_data *mesg, const tsig_item *key)
2021 {
2022 if(key != NULL)
2023 {
2024 ZEROMEMORY(&mesg->_tsig, sizeof(message_tsig));
2025
2026 mesg->_tsig.tsig = key;
2027 mesg->_tsig.mac_size = mesg->_tsig.tsig->mac_size;
2028
2029 u64 now = time(NULL);
2030 mesg->_tsig.timehi = htons((u16)(now >> 32));
2031 mesg->_tsig.timelo = htonl((u32)now);
2032
2033 mesg->_tsig.fudge = htons(300); /* 5m */
2034
2035 mesg->_tsig.mac_algorithm = key->mac_algorithm;
2036
2037 mesg->_tsig.original_id = message_get_id(mesg);
2038
2039 ya_result ret = tsig_sign_answer(mesg);
2040 return ret;
2041 }
2042
2043 return TSIG_BADKEY;
2044 }
2045
2046 ya_result
message_sign_query(message_data * mesg,const tsig_item * key)2047 message_sign_query(message_data *mesg, const tsig_item *key)
2048 {
2049 if(key != NULL)
2050 {
2051 ZEROMEMORY(&mesg->_tsig, sizeof(message_tsig));
2052
2053 mesg->_tsig.tsig = key;
2054 mesg->_tsig.mac_size = mesg->_tsig.tsig->mac_size;
2055
2056 u64 now = time(NULL);
2057 mesg->_tsig.timehi = htons((u16)(now >> 32));
2058 mesg->_tsig.timelo = htonl((u32)now);
2059
2060 mesg->_tsig.fudge = htons(300); /* 5m */
2061
2062 mesg->_tsig.mac_algorithm = key->mac_algorithm;
2063
2064 mesg->_tsig.original_id = message_get_id(mesg);
2065
2066 // mesg->tsig.error = 0; zeromem
2067 // mesg->tsig.other_len = 0; zeromem
2068
2069 return tsig_sign_query(mesg);
2070 }
2071
2072 return TSIG_BADKEY;
2073 }
2074
2075 ya_result
message_sign_query_with_epoch_and_fudge(message_data * mesg,const tsig_item * key,s64 epoch,u16 fudge)2076 message_sign_query_with_epoch_and_fudge(message_data *mesg, const tsig_item *key, s64 epoch, u16 fudge)
2077 {
2078 if(key != NULL)
2079 {
2080 ZEROMEMORY(&mesg->_tsig, sizeof(message_tsig));
2081
2082 mesg->_tsig.tsig = key;
2083 mesg->_tsig.mac_size = mesg->_tsig.tsig->mac_size;
2084
2085 mesg->_tsig.timehi = htons((u16)(epoch >> 32));
2086 mesg->_tsig.timelo = htonl((u32)epoch);
2087
2088 mesg->_tsig.fudge = htons(fudge); /* 5m */
2089
2090 mesg->_tsig.mac_algorithm = key->mac_algorithm;
2091
2092 mesg->_tsig.original_id = message_get_id(mesg);
2093
2094 // mesg->tsig.error = 0; zeromem
2095 // mesg->tsig.other_len = 0; zeromem
2096
2097 return tsig_sign_query(mesg);
2098 }
2099
2100 return TSIG_BADKEY;
2101 }
2102
2103
2104 #endif
2105
2106 void
message_make_error(message_data * mesg,u16 error_code)2107 message_make_error(message_data *mesg, u16 error_code)
2108 {
2109 MESSAGE_FLAGS_OR(mesg->_buffer, QR_BITS, error_code);
2110 #ifdef WORDS_BIGENDIAN
2111 SET_U32_AT(mesg->_buffer[4], 0x00010000);
2112 SET_U32_AT(mesg->_buffer[8], 0x00000000);
2113 #else
2114 SET_U32_AT(mesg->_buffer[4], 0x00000100);
2115 SET_U32_AT(mesg->_buffer[8], 0x00000000);
2116 #endif
2117
2118 message_reset_buffer_size(mesg);
2119 // + 4 is for TYPE + CLASS
2120 message_set_size(mesg, DNS_HEADER_LENGTH + 4 + dnsname_len(message_get_query_section_ptr(mesg)));
2121 mesg->_ar_start = message_get_buffer_limit(mesg);
2122 message_set_status(mesg, (finger_print)error_code);
2123 }
2124
2125 void
message_make_signed_error(message_data * mesg,u16 error_code)2126 message_make_signed_error(message_data *mesg, u16 error_code)
2127 {
2128 message_make_error(mesg, error_code);
2129
2130 if(message_has_tsig(mesg))
2131 {
2132 tsig_sign_answer(mesg);
2133 }
2134 }
2135
2136 ya_result
message_make_error_and_reply_tcp(message_data * mesg,u16 error_code,int tcpfd)2137 message_make_error_and_reply_tcp(message_data *mesg, u16 error_code, int tcpfd)
2138 {
2139 ya_result ret;
2140
2141 message_make_signed_error(mesg, error_code);
2142
2143 if(ISOK(ret = message_send_tcp(mesg, tcpfd)))
2144 {
2145 //
2146 }
2147 else
2148 {
2149 tcp_set_abortive_close(tcpfd);
2150 }
2151
2152 return ret;
2153 }
2154
2155 ssize_t
message_make_error_and_reply_tcp_with_default_minimum_throughput(message_data * mesg,u16 error_code,int tcpfd)2156 message_make_error_and_reply_tcp_with_default_minimum_throughput(message_data *mesg, u16 error_code, int tcpfd)
2157 {
2158 ssize_t ret;
2159 message_make_signed_error(mesg, error_code);
2160
2161 ret = message_update_length_send_tcp_with_default_minimum_throughput(mesg, tcpfd);
2162
2163 return ret;
2164 }
2165
2166 /**
2167 * Creates an answer with an OPT error code
2168 */
2169
2170 void
message_make_error_ext(message_data * mesg,u32 error_code)2171 message_make_error_ext(message_data *mesg, u32 error_code)
2172 {
2173 MESSAGE_FLAGS_OR(mesg->_buffer, QR_BITS, error_code & 0x0f);
2174 #ifdef WORDS_BIGENDIAN
2175 SET_U32_AT(mesg->_buffer[4], 0x00010000);
2176 SET_U32_AT(mesg->_buffer[8], 0x00000000);
2177 #else
2178 SET_U32_AT(mesg->_buffer[4], 0x00000100);
2179 SET_U32_AT(mesg->_buffer[8], 0x00000000);
2180 #endif
2181
2182 message_reset_buffer_size(mesg);
2183 // + 4 is for TYPE + CLASS
2184 size_t query_section_size = DNS_HEADER_LENGTH + 4 + dnsname_len(message_get_query_section_ptr(mesg));
2185 mesg->_ar_start = &mesg->_buffer[query_section_size];
2186
2187 // the upper 8 bits of the error code are to be put in OPT
2188
2189 u8 *edns0 = mesg->_ar_start;
2190 edns0[0] = 0;
2191 SET_U16_AT(edns0[1], TYPE_OPT);
2192 SET_U16_AT(edns0[3], htons(message_edns0_getmaxsize()));
2193 SET_U32_AT(edns0[5], (((error_code & 0xff0) << 24) | (message_get_rcode_ext(mesg) & 0x00ffffff)));
2194 SET_U16_AT(edns0[9], 0);
2195 message_set_size(mesg, query_section_size + 11);
2196 message_set_status(mesg, (finger_print)error_code);
2197 }
2198
2199 ya_result
message_query_tcp(message_data * mesg,const host_address * server)2200 message_query_tcp(message_data *mesg, const host_address *server)
2201 {
2202 /* connect the server */
2203
2204 ya_result return_value;
2205
2206 if(ISOK(return_value = message_set_sender_from_host_address(mesg, server)))
2207 {
2208 int sockfd;
2209
2210 if((sockfd = socket(message_get_sender_sa(mesg)->sa_family, SOCK_STREAM, 0)) >=0)
2211 {
2212 fd_setcloseonexec(sockfd);
2213
2214 socklen_t sa_len = return_value;
2215
2216 if(connect(sockfd, message_get_sender_sa(mesg), sa_len) == 0)
2217 {
2218 #if DEBUG
2219 log_debug("sending %d+2 bytes to %{sockaddr} (tcp)", message_get_size(mesg), message_get_sender(mesg));
2220 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(mesg), message_get_size(mesg), 16, OSPRINT_DUMP_HEXTEXT);
2221 #endif
2222 if(message_send_tcp(mesg, sockfd) == (ssize_t)message_get_size(mesg) + 2)
2223 {
2224 u16 tcp_len;
2225
2226 shutdown(sockfd, SHUT_WR);
2227
2228 if(readfully(sockfd, &tcp_len, 2) == 2)
2229 {
2230 tcp_len = ntohs(tcp_len);
2231
2232 if(readfully(sockfd, message_get_buffer(mesg), tcp_len) == tcp_len)
2233 {
2234 /*
2235 * test the answser
2236 * test the TSIG if any
2237 */
2238
2239 message_set_size(mesg, tcp_len);
2240 #if DEBUG
2241 log_debug("received %d bytes from %{sockaddr} (tcp)", message_get_size(mesg), message_get_sender(mesg));
2242 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(mesg), message_get_size(mesg), 16, OSPRINT_DUMP_HEXTEXT);
2243 #endif
2244 return_value = message_process_lenient(mesg);
2245 }
2246 }
2247 }
2248 }
2249 else
2250 {
2251 // Linux quirk ...
2252
2253 if(errno != EINPROGRESS)
2254 {
2255 return_value = ERRNO_ERROR;
2256 }
2257 else
2258 {
2259 return_value = MAKE_ERRNO_ERROR(ETIMEDOUT);
2260 }
2261 }
2262
2263 shutdown(sockfd, SHUT_RDWR);
2264
2265 tcp_set_abortive_close(sockfd);
2266
2267 close_ex(sockfd);
2268 }
2269 else
2270 {
2271 return_value = ERRNO_ERROR;
2272 }
2273 }
2274
2275 return return_value;
2276 }
2277
2278 ya_result
message_query_tcp_ex(message_data * mesg,const host_address * bindto,const host_address * server,message_data * answer)2279 message_query_tcp_ex(message_data *mesg, const host_address *bindto, const host_address *server, message_data *answer)
2280 {
2281 /* connect the server */
2282
2283 ya_result ret;
2284 socklen_t sa_len;
2285 socketaddress sa;
2286
2287 if((mesg == NULL) || (server == NULL) || (answer == NULL))
2288 {
2289 return UNEXPECTED_NULL_ARGUMENT_ERROR;
2290 }
2291
2292 if(bindto != NULL)
2293 {
2294 ret = host_address2sockaddr(bindto, &sa);
2295 if(FAIL(ret))
2296 {
2297 return ret;
2298 }
2299
2300 sa_len = (socklen_t)ret;
2301 }
2302
2303 if(ISOK(ret = message_set_sender_from_host_address(mesg, server)))
2304 {
2305 int sockfd;
2306
2307 if((sockfd = socket(message_get_sender_sa(mesg)->sa_family, SOCK_STREAM, 0)) >=0)
2308 {
2309 fd_setcloseonexec(sockfd);
2310
2311 if(bindto != NULL)
2312 {
2313 int on = 1;
2314 if(FAIL(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on))))
2315 {
2316 ret = ERRNO_ERROR;
2317 close(sockfd);
2318 return ret;
2319 }
2320
2321 if(FAIL(setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (void *) &on, sizeof(on))))
2322 {
2323 ret = ERRNO_ERROR;
2324 close(sockfd);
2325 return ret;
2326 }
2327
2328 if(bind(sockfd, &sa.sa, sa_len) < 0)
2329 {
2330 ret = ERRNO_ERROR;
2331 close_ex(sockfd);
2332 return ret;
2333 }
2334 }
2335
2336 if(connect(sockfd, message_get_sender_sa(mesg), message_get_sender_size(mesg)) == 0)
2337 {
2338 #if DEBUG
2339 log_debug("sending %d bytes to %{sockaddr} (tcp)", message_get_size(mesg), message_get_sender(mesg));
2340 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(mesg), message_get_size(mesg), 16, OSPRINT_DUMP_HEXTEXT);
2341 #endif
2342 if(message_send_tcp(mesg, sockfd) == (ssize_t)message_get_size(mesg) + 2)
2343 {
2344 u16 tcp_len;
2345
2346 shutdown(sockfd, SHUT_WR);
2347
2348 if(readfully(sockfd, &tcp_len, 2) == 2)
2349 {
2350 tcp_len = ntohs(tcp_len);
2351
2352 if(readfully(sockfd, message_get_buffer(answer), tcp_len) == tcp_len)
2353 {
2354 /*
2355 * test the answser
2356 * test the TSIG if any
2357 */
2358
2359 message_set_size(answer, tcp_len);
2360 #if DNSCORE_HAS_TSIG_SUPPORT
2361 message_tsig_copy_from(answer, mesg);
2362 #endif
2363 message_copy_sender_from(answer, mesg);
2364 #if DEBUG
2365 log_debug("received %d bytes from %{sockaddr} (tcp)", message_get_size(answer), message_get_sender_sa(answer));
2366 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(answer), message_get_size(answer), 16, OSPRINT_DUMP_HEXTEXT);
2367 #endif
2368 ret = message_process_lenient(answer);
2369 }
2370 }
2371 }
2372 }
2373 else
2374 {
2375 // Linux quirk ...
2376
2377 if(errno != EINPROGRESS)
2378 {
2379 ret = ERRNO_ERROR;
2380 }
2381 else
2382 {
2383 ret = MAKE_ERRNO_ERROR(ETIMEDOUT);
2384 }
2385 }
2386
2387 shutdown(sockfd, SHUT_RDWR);
2388
2389 tcp_set_abortive_close(sockfd);
2390
2391 close_ex(sockfd);
2392 }
2393 else
2394 {
2395 ret = ERRNO_ERROR;
2396 }
2397 }
2398
2399 return ret;
2400 }
2401
2402 ya_result
message_query_tcp_with_timeout(message_data * mesg,const host_address * address,u8 to_sec)2403 message_query_tcp_with_timeout(message_data *mesg, const host_address *address, u8 to_sec)
2404 {
2405 ya_result ret;
2406
2407 if((mesg == NULL) || (address == NULL))
2408 {
2409 return UNEXPECTED_NULL_ARGUMENT_ERROR;
2410 }
2411
2412 input_stream is;
2413 output_stream os;
2414
2415 if(ISOK(ret = tcp_input_output_stream_connect_host_address(address, &is, &os, to_sec)))
2416 {
2417 int sockfd = fd_input_stream_get_filedescriptor(&is);
2418
2419 tcp_set_sendtimeout(sockfd, to_sec, 0);
2420 tcp_set_recvtimeout(sockfd, to_sec, 0);
2421
2422 if(ISOK(ret = message_write_tcp(mesg, &os)))
2423 {
2424 output_stream_flush(&os);
2425
2426 shutdown(sockfd, SHUT_WR);
2427
2428 u16 id = message_get_id(mesg);
2429 #if DEBUG
2430 message_debug_trash_buffer(mesg);
2431 #endif
2432 u16 len;
2433 #if DEBUG
2434 len = ~0;
2435 #endif
2436 if(ISOK(ret = input_stream_read_nu16(&is, &len)))
2437 {
2438 if (ISOK(ret = input_stream_read_fully(&is, message_get_buffer(mesg), len)))
2439 {
2440 message_set_size(mesg, ret);
2441
2442 if(message_get_id(mesg) != id)
2443 {
2444 ret = MESSAGE_HAS_WRONG_ID;
2445 }
2446 else if(!message_isanswer(mesg))
2447 {
2448 ret = MESSAGE_IS_NOT_AN_ANSWER;
2449 }
2450 else if(message_get_rcode(mesg) != RCODE_NOERROR)
2451 {
2452 ret = MAKE_DNSMSG_ERROR(message_get_rcode(mesg));
2453 }
2454 }
2455 else
2456 {
2457 message_set_size(mesg, 0);
2458 }
2459 }
2460 }
2461
2462 shutdown(sockfd, SHUT_RDWR);
2463
2464 tcp_set_abortive_close(sockfd);
2465
2466 output_stream_close(&os);
2467 output_stream_close(&is);
2468 }
2469
2470 return ret;
2471 }
2472
2473 ya_result
message_query_tcp_with_timeout_ex(message_data * mesg,const host_address * server,message_data * answer,u8 to_sec)2474 message_query_tcp_with_timeout_ex(message_data *mesg, const host_address *server, message_data *answer, u8 to_sec)
2475 {
2476 /* connect the server */
2477
2478 ya_result return_value;
2479
2480 if(ISOK(return_value = message_set_sender_from_host_address(mesg, server)))
2481 {
2482 int sockfd;
2483
2484 if((sockfd = socket(message_get_sender_sa(mesg)->sa_family, SOCK_STREAM, 0)) >=0)
2485 {
2486 fd_setcloseonexec(sockfd);
2487
2488 socklen_t sa_len = return_value;
2489
2490 if(connect(sockfd, message_get_sender_sa(mesg), sa_len) == 0)
2491 {
2492 #if 1 // DEBUG
2493 log_debug("sending %d bytes to %{sockaddr} (tcp)", message_get_size(mesg), message_get_sender(mesg));
2494 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(mesg), message_get_size(mesg), 16, OSPRINT_DUMP_HEXTEXT);
2495 #endif
2496 tcp_set_sendtimeout(sockfd, to_sec, 0);
2497 tcp_set_recvtimeout(sockfd, to_sec, 0);
2498
2499 ssize_t n = message_send_tcp(mesg, sockfd);
2500
2501 if(n == (ssize_t)message_get_size(mesg) + 2)
2502 {
2503 u16 tcp_len;
2504
2505 shutdown(sockfd, SHUT_WR);
2506
2507 n = readfully(sockfd, &tcp_len, 2);
2508
2509 if(n == 2)
2510 {
2511 tcp_len = ntohs(tcp_len);
2512
2513 n = readfully(sockfd, message_get_buffer(answer), tcp_len);
2514
2515 if(n == tcp_len)
2516 {
2517 /*
2518 * test the answser
2519 * test the TSIG if any
2520 */
2521
2522 message_set_size(answer, tcp_len);
2523 #if DNSCORE_HAS_TSIG_SUPPORT
2524 message_tsig_copy_from(answer, mesg);
2525 #endif
2526 message_copy_sender_from(answer, mesg);
2527 #if DEBUG
2528 log_debug("received %d bytes from %{sockaddr} (tcp)", message_get_size(answer), message_get_sender_sa(answer));
2529 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(answer), message_get_size(answer), 16, OSPRINT_DUMP_HEXTEXT);
2530 #endif
2531 return_value = message_process_lenient(answer);
2532 }
2533 else
2534 {
2535 return_value = UNEXPECTED_EOF;
2536 }
2537 }
2538 else
2539 {
2540 return_value = UNEXPECTED_EOF;
2541 }
2542 }
2543 else
2544 {
2545 return_value = UNABLE_TO_COMPLETE_FULL_WRITE;
2546 }
2547 }
2548 else
2549 {
2550 // Linux quirk ...
2551
2552 if(errno != EINPROGRESS)
2553 {
2554 return_value = ERRNO_ERROR;
2555 }
2556 else
2557 {
2558 return_value = MAKE_ERRNO_ERROR(ETIMEDOUT);
2559 }
2560 }
2561
2562 shutdown(sockfd, SHUT_RDWR);
2563
2564 tcp_set_abortive_close(sockfd);
2565
2566 close_ex(sockfd);
2567 }
2568 else
2569 {
2570 return_value = ERRNO_ERROR;
2571 }
2572 }
2573
2574 return return_value;
2575 }
2576
2577 ya_result
message_query_udp(message_data * mesg,const host_address * server)2578 message_query_udp(message_data *mesg, const host_address *server)
2579 {
2580 ya_result return_code = SUCCESS;
2581
2582 int seconds = 0;
2583 int useconds = 500000;
2584
2585 yassert(mesg != NULL);
2586 yassert(server != NULL);
2587
2588 return_code = message_query_udp_with_timeout(mesg, server, seconds, useconds);
2589
2590 return return_code;
2591 }
2592
2593 ya_result
message_query_udp_with_timeout_and_retries(message_data * mesg,const host_address * server,int seconds,int useconds,u8 retries,u8 flags)2594 message_query_udp_with_timeout_and_retries(message_data *mesg, const host_address *server, int seconds, int useconds, u8 retries, u8 flags)
2595 {
2596 ya_result return_value = SUCCESS;
2597 random_ctx rndctx = thread_pool_get_random_ctx();
2598 u16 id;
2599
2600 for(u8 countdown = retries; countdown > 0; )
2601 {
2602 if (flags & MESSAGE_QUERY_UDP_FLAG_RESET_ID)
2603 {
2604 id = (u16)random_next(rndctx);
2605 message_set_id(mesg, id);
2606 }
2607 else
2608 {
2609 id = message_get_id(mesg);
2610 }
2611
2612 if(ISOK(return_value = message_query_udp_with_timeout(mesg, server, seconds, useconds)))
2613 {
2614 if(message_get_id(mesg) != id)
2615 {
2616 return_value = MESSAGE_HAS_WRONG_ID;
2617 }
2618 else if(!message_isanswer(mesg))
2619 {
2620 return_value = MESSAGE_IS_NOT_AN_ANSWER;
2621 }
2622 else if(message_get_rcode(mesg) != RCODE_NOERROR)
2623 {
2624 return_value = MAKE_DNSMSG_ERROR(message_get_rcode(mesg));
2625 }
2626
2627 break;
2628 }
2629
2630 if(return_value == MAKE_ERRNO_ERROR(EINTR))
2631 {
2632 continue;
2633 }
2634
2635 if(return_value != MAKE_ERRNO_ERROR(EAGAIN) || countdown <= 0)
2636 {
2637 /*
2638 * Do not retry for any other kind of error
2639 */
2640
2641 break;
2642 }
2643
2644 countdown--;
2645
2646 usleep_ex(10000); /* 10 ms */
2647
2648 /*
2649 if (flags & CHANGE_NAME_SERVER)
2650 {
2651 }
2652 */
2653 }
2654
2655 return return_value;
2656 }
2657
2658 ya_result
message_query_udp_with_timeout(message_data * mesg,const host_address * server,int seconds,int useconds)2659 message_query_udp_with_timeout(message_data *mesg, const host_address *server, int seconds, int useconds)
2660 {
2661 yassert(mesg != NULL);
2662 yassert(server != NULL);
2663
2664 /* connect the server */
2665
2666 ya_result ret;
2667
2668 u16 id;
2669 bool has_fqdn = FALSE;
2670 u8 fqdn[MAX_DOMAIN_LENGTH + 1];
2671
2672 if(ISOK(ret = message_set_sender_from_host_address(mesg, server)))
2673 {
2674 int sockfd;
2675
2676 if((sockfd = socket(message_get_sender_sa(mesg)->sa_family, SOCK_DGRAM, 0)) >=0)
2677 {
2678 fd_setcloseonexec(sockfd);
2679
2680 tcp_set_recvtimeout(sockfd, seconds, useconds); /* half a second for UDP is a lot ... */
2681
2682 int send_size = message_get_size(mesg);
2683
2684 ssize_t n;
2685
2686 if((n = message_send_udp(mesg, sockfd)) == send_size)
2687 {
2688 id = message_get_id(mesg);
2689
2690 if(message_get_query_count_ne(mesg) != 0)
2691 {
2692 has_fqdn = TRUE;
2693 dnsname_copy(fqdn, message_get_buffer_const(mesg) + 12);
2694 }
2695
2696 message_data_with_buffer recv_mesg_buff;
2697 message_data *recv_mesg = message_data_with_buffer_init(&recv_mesg_buff);
2698
2699 //recv_mesg._tsig.hmac = mesg->_tsig.hmac;
2700
2701 s64 time_limit = seconds;
2702 time_limit *= ONE_SECOND_US;
2703 time_limit += useconds;
2704 time_limit += timeus();
2705
2706 ret = SUCCESS;
2707
2708 while((n = message_recv_udp(recv_mesg, sockfd)) >= 0)
2709 {
2710 #if DEBUG
2711 log_memdump_ex(g_system_logger, MSG_DEBUG5, message_get_buffer_const(recv_mesg), n, 16, OSPRINT_DUMP_HEXTEXT);
2712 #endif
2713 // check the id is right
2714
2715 if(message_get_id(recv_mesg) == id)
2716 {
2717 // check that the sender is the one we spoke to
2718
2719 if(sockaddr_equals(message_get_sender_sa(mesg), message_get_sender_sa(recv_mesg)))
2720 {
2721 message_tsig_copy_from(recv_mesg, mesg);
2722
2723 if(ISOK(ret = message_process_lenient(recv_mesg)))
2724 {
2725 // check the domain is right
2726
2727 if(!has_fqdn || dnsname_equals(fqdn, message_get_canonised_fqdn(recv_mesg)))
2728 {
2729 // everything checks up
2730
2731 message_copy_sender_from(mesg, recv_mesg);
2732 mesg->_ar_start = &mesg->_buffer[recv_mesg->_ar_start - recv_mesg->_buffer];
2733 mesg->_iovec.iov_len = recv_mesg->_iovec.iov_len;
2734 mesg->_rcode_ext = recv_mesg->_rcode_ext;
2735 mesg->_status = recv_mesg->_status;
2736
2737 if(mesg->_buffer_size < mesg->_iovec.iov_len)
2738 {
2739 mesg->_buffer_size = mesg->_iovec.iov_len;
2740 }
2741
2742 mesg->_query_type = recv_mesg->_query_type;
2743 mesg->_query_class = recv_mesg->_query_class;
2744 mesg->_edns = recv_mesg->_edns;
2745 mesg->_nsid = recv_mesg->_nsid;
2746
2747 if((mesg->_control_buffer_size = recv_mesg->_control_buffer_size) > 0)
2748 {
2749 memcpy(mesg->_msghdr_control_buffer, recv_mesg->_msghdr_control_buffer, recv_mesg->_control_buffer_size);
2750 }
2751
2752 dnsname_copy(mesg->_canonised_fqdn, recv_mesg->_canonised_fqdn);
2753
2754 memcpy(mesg->_buffer, recv_mesg->_buffer, recv_mesg->_iovec.iov_len);
2755
2756 break;
2757 }
2758 else
2759 {
2760 ret = MESSAGE_UNEXPECTED_ANSWER_DOMAIN;
2761 }
2762 }
2763
2764 // ret is set to an error
2765 }
2766 else
2767 {
2768 ret = INVALID_MESSAGE;
2769 }
2770 }
2771 else
2772 {
2773 ret = MESSAGE_HAS_WRONG_ID;
2774 }
2775
2776 s64 time_now = timeus();
2777
2778 if(time_now >= time_limit)
2779 {
2780 ret = MAKE_ERRNO_ERROR(EAGAIN);
2781 break;
2782 }
2783
2784 s64 time_remaining = time_limit - time_now;
2785
2786 tcp_set_recvtimeout(sockfd, time_remaining / 1000000ULL, time_remaining % 1000000ULL); /* half a second for UDP is a lot ... */
2787 }
2788
2789 message_finalize(recv_mesg);
2790
2791 //recv_mesg._tsig.hmac = NULL;
2792
2793 if((n < 0) && ISOK(ret))
2794 {
2795 ret = ERRNO_ERROR;
2796 }
2797
2798 /* timeout */
2799 }
2800 else
2801 {
2802 ret = (n < 0)?n:ERROR;
2803 }
2804
2805 close_ex(sockfd);
2806 }
2807 else
2808 {
2809 ret = ERRNO_ERROR;
2810 }
2811 }
2812
2813 return ret;
2814 }
2815
2816 ya_result
message_query(message_data * mesg,const host_address * server)2817 message_query(message_data *mesg, const host_address *server)
2818 {
2819 ya_result ret;
2820 size_t size;
2821 u8 header_copy[12];
2822
2823 // keep a copy of the state, in case there is truncation
2824
2825 size = message_get_size(mesg);
2826 memcpy(header_copy, mesg->_buffer, sizeof(header_copy));
2827
2828 if(ISOK(ret = message_query_udp_with_timeout_and_retries(mesg, server, 1, 0, 3, 0)))
2829 {
2830 if(message_istruncated(mesg))
2831 {
2832 message_set_size(mesg, size);
2833 memcpy(mesg->_buffer, header_copy, sizeof(header_copy));
2834
2835 ret = message_query_tcp_with_timeout(mesg, server, 3);
2836 }
2837 }
2838
2839 return ret;
2840 }
2841
2842 ya_result
message_ixfr_query_get_serial(const message_data * mesg,u32 * serial)2843 message_ixfr_query_get_serial(const message_data *mesg, u32 *serial)
2844 {
2845 packet_unpack_reader_data purd;
2846 ya_result return_value;
2847
2848 u8 domain_fqdn[MAX_DOMAIN_LENGTH];
2849 u8 soa_fqdn[MAX_DOMAIN_LENGTH];
2850
2851 packet_reader_init_from_message(&purd, mesg);
2852
2853 /* Keep only the query */
2854
2855 if(ISOK(return_value = packet_reader_read_fqdn(&purd, domain_fqdn, sizeof(domain_fqdn))))
2856 {
2857 purd.offset += 4;
2858
2859 /* Get the queried serial */
2860
2861 if(ISOK(return_value = packet_reader_read_fqdn(&purd, soa_fqdn, sizeof(soa_fqdn))))
2862 {
2863 if(dnsname_equals(domain_fqdn, soa_fqdn))
2864 {
2865 u16 soa_type;
2866 u16 soa_class;
2867 u32 soa_ttl;
2868 u16 soa_rdata_size;
2869 u32 soa_serial;
2870
2871 if(ISOK(return_value = packet_reader_read_u16(&purd, &soa_type)))
2872 {
2873 if(soa_type == TYPE_SOA)
2874 {
2875 if(packet_reader_available(&purd) > 2 + 4 + 2)
2876 {
2877 packet_reader_read_u16_unchecked(&purd, &soa_class); // checked
2878 packet_reader_read_u32_unchecked(&purd, &soa_ttl); // checked
2879 packet_reader_read_u16_unchecked(&purd, &soa_rdata_size); // checked
2880
2881 if(ISOK(return_value = packet_reader_skip_fqdn(&purd)))
2882 {
2883 if(ISOK(return_value = packet_reader_skip_fqdn(&purd)))
2884 {
2885 if(ISOK(return_value = packet_reader_read_u32(&purd, &soa_serial)))
2886 {
2887 *serial=ntohl(soa_serial);
2888 }
2889 }
2890 }
2891 }
2892 else
2893 {
2894 return_value = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
2895 }
2896 }
2897 else
2898 {
2899 return_value = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
2900 }
2901 }
2902 }
2903 else
2904 {
2905 return_value = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
2906 }
2907 }
2908 }
2909
2910 return return_value;
2911 }
2912
2913 ya_result
message_query_serial(const u8 * origin,const host_address * server,u32 * serial_out)2914 message_query_serial(const u8 *origin, const host_address *server, u32 *serial_out)
2915 {
2916 yassert(origin != NULL);
2917 yassert(server != NULL);
2918 yassert(serial_out != NULL);
2919
2920 /* do an SOA query */
2921
2922 ya_result ret;
2923
2924 random_ctx rndctx = thread_pool_get_random_ctx();
2925 message_data_with_buffer soa_query_mesg_buff;
2926 message_data *soa_query_mesg = message_data_with_buffer_init(&soa_query_mesg_buff);
2927
2928 for(u16 countdown = 5; countdown > 0; )
2929 {
2930 u16 id = (u16)random_next(rndctx);
2931
2932 message_make_query(soa_query_mesg, id, origin, TYPE_SOA, CLASS_IN);
2933
2934 if(ISOK(ret = message_query_udp(soa_query_mesg, server)))
2935 {
2936 const u8 *buffer = message_get_buffer_const(soa_query_mesg);
2937
2938 if(MESSAGE_QR(buffer))
2939 {
2940 if(MESSAGE_ID(buffer) == id)
2941 {
2942 if(MESSAGE_RCODE(buffer) == RCODE_NOERROR)
2943 {
2944 if((MESSAGE_QD(buffer) == NETWORK_ONE_16) && ((MESSAGE_AN(buffer) == NETWORK_ONE_16) || (MESSAGE_NS(buffer) == NETWORK_ONE_16)))
2945 {
2946 packet_unpack_reader_data pr;
2947 packet_reader_init_from_message_at(&pr, soa_query_mesg, DNS_HEADER_LENGTH); // scan-build false positive: if message_query_udp returns no-error, then soa_query_mesg.received is set
2948 packet_reader_skip_fqdn(&pr); // checked below
2949 packet_reader_skip(&pr, 4); // checked below
2950
2951 if(!packet_reader_eof(&pr))
2952 {
2953 u8 tmp[MAX_DOMAIN_LENGTH];
2954
2955 /* read and expect an SOA */
2956
2957 if(ISOK(packet_reader_read_fqdn(&pr, tmp, sizeof(tmp))))
2958 {
2959 if(dnsname_equals(tmp, origin))
2960 {
2961 struct type_class_ttl_rdlen tctr;
2962
2963 if(packet_reader_read(&pr, &tctr, 10) == 10) // exact
2964 {
2965 if((tctr.qtype == TYPE_SOA) && (tctr.qclass == CLASS_IN))
2966 {
2967 if(ISOK(ret = packet_reader_skip_fqdn(&pr)))
2968 {
2969 if(ISOK(ret = packet_reader_skip_fqdn(&pr)))
2970 {
2971 if(packet_reader_read(&pr, tmp, 4) == 4) // exact
2972 {
2973 *serial_out = ntohl(GET_U32_AT(tmp[0]));
2974
2975 return SUCCESS;
2976 }
2977 }
2978 }
2979 }
2980 else
2981 {
2982 ret = MESSAGE_UNEXPECTED_ANSWER_TYPE_CLASS;
2983 }
2984 }
2985 else
2986 {
2987 ret = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
2988 }
2989 }
2990 else
2991 {
2992 ret = MESSAGE_UNEXPECTED_ANSWER_DOMAIN;
2993 }
2994 }
2995 else
2996 {
2997 ret = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
2998 }
2999 }
3000 else
3001 {
3002 ret = MAKE_DNSMSG_ERROR(RCODE_FORMERR);
3003 }
3004 }
3005 else
3006 {
3007 ret = INVALID_MESSAGE;
3008 }
3009 }
3010 else
3011 {
3012 ret = MAKE_DNSMSG_ERROR(message_get_rcode(soa_query_mesg));
3013 }
3014 }
3015 else
3016 {
3017 ret = MESSAGE_HAS_WRONG_ID;
3018 }
3019 }
3020 else
3021 {
3022 ret = MESSAGE_IS_NOT_AN_ANSWER;
3023 }
3024
3025 break;
3026 }
3027
3028 if(ret == MAKE_ERRNO_ERROR(EINTR))
3029 {
3030 continue;
3031 }
3032
3033 if(ret != MAKE_ERRNO_ERROR(EAGAIN) || countdown <= 0)
3034 {
3035 /*
3036 * Do not retry for any other kind of error
3037 */
3038
3039 break;
3040 }
3041
3042 countdown--;
3043
3044 usleep_ex(10000); /* 10 ms */
3045 }
3046
3047 return ret; // fake positive, ret has been initialised
3048 }
3049
3050 #if MESSAGE_PAYLOAD_IS_POINTER
3051
message_init_ex(message_data * mesg,u32 mesg_size,void * buffer,size_t buffer_size)3052 void message_init_ex(message_data* mesg, u32 mesg_size, void *buffer, size_t buffer_size)
3053 {
3054 ZEROMEMORY(mesg, offsetof(message_data, _msghdr_control_buffer)); // includes the tsig structure
3055 mesg->_msghdr.msg_name = &mesg->_sender;
3056 mesg->_msghdr.msg_namelen = sizeof(mesg->_sender);
3057 mesg->_msghdr.msg_iov = &mesg->_iovec;
3058 mesg->_msghdr.msg_iovlen = 1;
3059 #ifndef WIN32
3060 mesg->_msghdr.msg_control = NULL;
3061 mesg->_msghdr.msg_controllen = 0;
3062 #else
3063 mesg->_msghdr.msg_control.buf = NULL;
3064 mesg->_msghdr.msg_control.len = 0;
3065 #endif
3066 mesg->_msghdr.msg_flags = 0;
3067 //mesg->_msghdr.msg_control = mesg->_msghdr_control_buffer;
3068 //mesg->_msghdr.msg_controllen = sizeof(mesg->_msghdr_control_buffer);
3069 #if MESSAGE_PAYLOAD_IS_POINTER
3070 //
3071 #else
3072 mesg->_iovec.iov_base = mesg->_buffer;
3073 #endif
3074 mesg->_iovec.iov_len = buffer_size;
3075
3076 #if MESSAGE_PAYLOAD_IS_POINTER
3077 mesg->_message_data_size = mesg_size;
3078 #endif
3079
3080 mesg->_control_buffer_size = sizeof(mesg->_msghdr_control_buffer);
3081 mesg->_buffer_size = buffer_size;
3082 mesg->_buffer_size_limit = buffer_size;
3083 mesg->_tsig.hmac = NULL;
3084
3085 #if MESSAGE_PAYLOAD_IS_POINTER
3086 mesg->_buffer = (u8*)buffer;
3087
3088 mesg->_iovec.iov_base = mesg->_buffer;
3089 #if DEBUG
3090 memset(buffer,0x5a, buffer_size);
3091 #endif
3092 #else
3093 #if DEBUG
3094 memset(&mesg->_buffer,0x5a, mesg->_buffer_size_limit);
3095 #endif
3096 #endif
3097 }
3098
3099 #else // MESSAGE_PAYLOAD_IS_POINTER
3100
message_init(message_data * mesg)3101 void message_init(message_data* mesg)
3102 {
3103 ZEROMEMORY(mesg, offsetof(message_data, _msghdr_control_buffer));
3104 mesg->_msghdr.msg_name = &mesg->_sender;
3105 mesg->_msghdr.msg_namelen = sizeof(mesg->_sender);
3106 mesg->_msghdr.msg_iov = &mesg->_iovec;
3107 mesg->_msghdr.msg_iovlen = 1;
3108 mesg->_msghdr.msg_control = NULL;
3109 mesg->_msghdr.msg_controllen = 0;
3110 mesg->_msghdr.msg_flags = 0;
3111 //mesg->_msghdr.msg_control = mesg->_msghdr_control_buffer;
3112 //mesg->_msghdr.msg_controllen = sizeof(mesg->_msghdr_control_buffer);
3113 mesg->_iovec.iov_base = mesg->_buffer;
3114 mesg->_iovec.iov_len = NETWORK_BUFFER_SIZE;
3115 mesg->_control_buffer_size = sizeof(mesg->_msghdr_control_buffer);
3116 mesg->_buffer_size = NETWORK_BUFFER_SIZE;
3117 mesg->_buffer_size_limit = NETWORK_BUFFER_SIZE;
3118 mesg->_tsig.hmac = NULL;
3119 #if DEBUG
3120 memset(&mesg->_buffer,0x5a, mesg->_buffer_size_limit);
3121 #endif
3122 }
3123
3124 #endif
3125
3126 /**
3127 * If pointer is NULL, the structure and buffer will be allocated together
3128 * Note that in the current implementation, 8 bytes are reserved for TCP
3129 */
3130
3131 message_data*
message_new_instance_ex(void * ptr,u32 message_size)3132 message_new_instance_ex(void *ptr, u32 message_size) // should be size of edns0 or 64K for TCP
3133 {
3134 message_data *mesg;
3135 if(ptr == NULL)
3136 {
3137 u8 *tmp;
3138 size_t message_data_size = ((sizeof(message_data) + 7) & ~7) + message_size;
3139 MALLOC_OBJECT_ARRAY_OR_DIE(tmp, u8, message_data_size, MESGDATA_TAG);
3140 ptr = &tmp[(sizeof(message_data) + 7) & ~7];
3141 mesg = (message_data*)tmp;
3142 message_init_ex(mesg, message_data_size, ptr, message_size);
3143 }
3144 else
3145 {
3146 MALLOC_OBJECT_OR_DIE(mesg, message_data, MESGDATA_TAG); // legit
3147 message_init_ex(mesg, sizeof(message_data), ptr, message_size);
3148 }
3149 return mesg;
3150 }
3151
3152 message_data*
message_new_instance()3153 message_new_instance()
3154 {
3155 message_data *mesg;
3156 mesg = message_new_instance_ex(NULL, 65536);
3157 return mesg;
3158 }
3159
message_finalize(message_data * mesg)3160 void message_finalize(message_data *mesg)
3161 {
3162 if(mesg->_tsig.hmac != NULL)
3163 {
3164 hmac_free(mesg->_tsig.hmac);
3165 mesg->_tsig.hmac = NULL;
3166 }
3167 if(mesg->_tsig.other != NULL)
3168 {
3169 free(mesg->_tsig.other);
3170 }
3171 }
3172
message_free(message_data * mesg)3173 void message_free(message_data *mesg)
3174 {
3175 if(mesg != NULL)
3176 {
3177 message_finalize(mesg);
3178 free(mesg); // legit
3179 }
3180 }
3181
3182 /*
3183 * Does not clone the pool.
3184 */
3185
3186 message_data*
message_dup(const message_data * mesg)3187 message_dup(const message_data *mesg)
3188 {
3189 size_t message_size = message_get_size(mesg);
3190 if(message_size > mesg->_buffer_size_limit)
3191 {
3192 return NULL;
3193 }
3194
3195 message_data *clone = message_new_instance_ex(NULL, mesg->_buffer_size_limit + 8);
3196 if(message_get_additional_section_ptr_const(mesg) != NULL)
3197 {
3198 message_set_additional_section_ptr(clone,
3199 &clone->_buffer[
3200 message_get_additional_section_ptr_const(mesg) - message_get_buffer_const(mesg)
3201 ]);
3202 }
3203
3204 memcpy(&clone->_rcode_ext, &mesg->_rcode_ext,
3205 offsetof(message_data, _msghdr_control_buffer)
3206 );
3207
3208 message_copy_sender_from(clone, mesg);
3209 #ifndef WIN32
3210 memcpy(clone->_msghdr_control_buffer, mesg->_msghdr_control_buffer, mesg->_msghdr.msg_controllen);
3211 #else
3212 memcpy(clone->_msghdr_control_buffer, mesg->_msghdr_control_buffer, mesg->_msghdr.msg_control.len);
3213 #endif
3214
3215 dnsname_copy(clone->_canonised_fqdn, message_get_canonised_fqdn(mesg));
3216 #if !MESSAGE_PAYLOAD_IS_POINTER
3217 SET_U16_AT(clone->_buffer_tcp_len[0], GET_U16_AT(mesg->_buffer_tcp_len[0]));
3218 #endif
3219 memcpy(message_get_buffer(clone), message_get_buffer_const(mesg), message_size);
3220 message_set_size(clone, message_size);
3221
3222 return clone;
3223 }
3224
message_log(logger_handle * logger,int level,const message_data * mesg)3225 void message_log(logger_handle *logger, int level, const message_data *mesg)
3226 {
3227 ya_result ret;
3228 int index = 0;
3229 rdata_desc rrdesc = {0, 0, NULL};
3230 struct type_class_ttl_rdlen *tctrp;
3231 u8 rr[32768];
3232
3233 logger_handle_msg(logger,level, "to: %{sockaddr}", message_get_sender_sa(mesg));
3234 logger_handle_msg(logger,level, "id: %i ", message_get_id(mesg));
3235 logger_handle_msg(logger,level, "flags: %02x %02x opcode: %s rcode: %s", message_get_flags_hi(mesg), message_get_flags_lo(mesg), dns_message_opcode_get_name(message_get_opcode(mesg) >> OPCODE_SHIFT), dns_message_rcode_get_name(message_get_rcode(mesg)));
3236 logger_handle_msg(logger,level, "qr: %i, an: %i, ns: %i, ar: %i",
3237 message_get_query_count(mesg), message_get_answer_count(mesg),
3238 message_get_authority_count(mesg), message_get_additional_count(mesg));
3239 packet_unpack_reader_data pr;
3240 packet_reader_init_from_message(&pr, mesg);
3241
3242 /* fqdn + type + class */
3243 for(u16 qc = message_get_query_count(mesg); qc > 0; --qc)
3244 {
3245 if(FAIL(ret = packet_reader_read_zone_record(&pr, rr, sizeof(rr))))
3246 {
3247 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3248 return;
3249 }
3250
3251 u16 *type_class = (u16*)&rr[dnsname_len(rr)];
3252
3253 logger_handle_msg(logger,level, "Q%3i: %{dnsname} %{dnstype} %{dnsclass}", index++, rr, &type_class[0], &type_class[1]);
3254 }
3255
3256 if((message_get_opcode(mesg) == OPCODE_QUERY) || (message_get_opcode(mesg) == OPCODE_NOTIFY))
3257 {
3258 for(int section = 1; section <= 3; ++section)
3259 {
3260 index = 0;
3261
3262 for(u16 sc = message_get_section_count(mesg, section); sc > 0; --sc)
3263 {
3264 if(FAIL(ret = packet_reader_read_record(&pr, rr, sizeof(rr))))
3265 {
3266 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3267 return;
3268 }
3269
3270 tctrp = (struct type_class_ttl_rdlen *)&rr[dnsname_len(rr)];
3271 rrdesc.type = tctrp->qtype;
3272 rrdesc.len = ntohs(tctrp->rdlen);
3273 rrdesc.rdata = &((u8*)tctrp)[10];
3274
3275 logger_handle_msg(logger, level, "%c%3i: %{dnsname} %i %{typerdatadesc}", "QANa"[section], index++, rr, ntohl(tctrp->ttl), &rrdesc);
3276 }
3277 }
3278 }
3279 else if(message_get_opcode(mesg) == OPCODE_UPDATE)
3280 {
3281 for(int section = 1; section <= 3; ++section)
3282 {
3283 index = 0;
3284
3285 for(u16 sc = message_get_section_count(mesg, section); sc > 0; --sc)
3286 {
3287 u8 *rdata_buffer;
3288 s32 rttl;
3289 u16 rtype;
3290 u16 rclass;
3291 u16 rdata_buffer_size;
3292 u16 rdata_size;
3293
3294 if(FAIL(ret = packet_reader_read_fqdn(&pr, rr, sizeof(rr))))
3295 {
3296 return;
3297 }
3298
3299 rdata_buffer = &rr[ret];
3300 rdata_buffer_size = sizeof(rr) - ret;
3301
3302 if(FAIL(ret = packet_reader_read_u16(&pr, &rtype)))
3303 {
3304 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3305 return;
3306 }
3307
3308 if(FAIL(ret = packet_reader_read_u16(&pr, &rclass)))
3309 {
3310 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3311 return;;
3312 }
3313
3314 if(FAIL(ret = packet_reader_read_u32(&pr, (u32*)&rttl)))
3315 {
3316 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3317 return;;
3318 }
3319
3320 rttl = ntohl(rttl);
3321
3322 if(FAIL(ret = packet_reader_read_u16(&pr, &rdata_size)))
3323 {
3324 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3325 return;;
3326 }
3327
3328 rdata_size = ntohs(rdata_size);
3329
3330 if(rclass != TYPE_ANY)
3331 {
3332 if(FAIL(ret = packet_reader_read_rdata(&pr, rtype, rdata_size, rdata_buffer, rdata_buffer_size))) // fixed buffer
3333 {
3334 logger_handle_msg(logger, MSG_ERR, "failed to read zone record: %r", ret);
3335 return;
3336 }
3337
3338 rrdesc.type = rtype;
3339 rrdesc.len = rdata_size;
3340 rrdesc.rdata = rdata_buffer;
3341
3342 logger_handle_msg(logger, level, "%c%3i: %{dnsname} %i %{dnsclass} %{typerdatadesc}", "QANa"[section], index++, rr, rttl, &rclass, &rrdesc);
3343 }
3344 else
3345 {
3346 logger_handle_msg(logger, level, "%c%3i: %{dnsname} %i %{dnsclass} %{dnstype}", "QANa"[section], index++, rr, rttl, &rclass, &rtype);
3347 }
3348 }
3349 }
3350 }
3351 }
3352
3353 ya_result
message_get_ixfr_query_serial(message_data * mesg,u32 * serialp)3354 message_get_ixfr_query_serial(message_data *mesg, u32 *serialp)
3355 {
3356 packet_unpack_reader_data purd;
3357 ya_result ret;
3358 u16 qtype;
3359
3360 packet_reader_init_from_message(&purd, mesg);
3361
3362 if(FAIL(ret = packet_reader_skip_fqdn(&purd)))
3363 {
3364 return ret;
3365 }
3366
3367 if(FAIL(ret = packet_reader_read_u16(&purd, &qtype)))
3368 {
3369 return ret;
3370 }
3371
3372 if(qtype != TYPE_IXFR)
3373 {
3374 return ERROR; // not an IXFR
3375 }
3376
3377 if(FAIL(ret = packet_reader_skip(&purd, 2)))
3378 {
3379 return ret;
3380 }
3381
3382 message_set_size(mesg, purd.offset);
3383
3384 /* Get the queried serial */
3385
3386 if(FAIL(ret = packet_reader_skip_fqdn(&purd)))
3387 {
3388 return ret;
3389 }
3390
3391 if(FAIL(ret = packet_reader_skip(&purd, 10)))
3392 {
3393 return ret;
3394 }
3395
3396 if(FAIL(ret = packet_reader_skip_fqdn(&purd)))
3397 {
3398 return ret;
3399 }
3400
3401 if(FAIL(ret = packet_reader_skip_fqdn(&purd)))
3402 {
3403 return ret;
3404 }
3405
3406 if(serialp != NULL)
3407 {
3408 if(FAIL(ret = packet_reader_read_u32(&purd, serialp)))
3409 {
3410 return ret;
3411 }
3412
3413 *serialp = ntohl(*serialp);
3414 }
3415
3416 return SUCCESS;
3417 }
3418
3419 #if DNSCORE_HAS_TSIG_SUPPORT
3420 ya_result
message_terminate_then_write(message_data * mesg,output_stream * tcpos,tsig_tcp_message_position pos)3421 message_terminate_then_write(message_data *mesg, output_stream *tcpos, tsig_tcp_message_position pos)
3422 #else
3423 ya_result
3424 message_terminate_then_write(message_data *mesg, output_stream *tcpos, int unused)
3425 #endif
3426 {
3427 ya_result ret;
3428
3429 #if !DNSCORE_HAS_TSIG_SUPPORT
3430 #pragma message("TSIG SUPPORT HAS BEEN DISABLED")
3431 (void)unused;
3432 #endif
3433
3434 if(message_is_edns0(mesg)) // Dig does a TCP query with EDNS0
3435 {
3436 /* 00 00 29 SS SS rr vv 80 00 00 00 */
3437
3438 u8 *buffer = message_get_buffer_limit(mesg);
3439 buffer[ 0] = 0;
3440 buffer[ 1] = 0;
3441 buffer[ 2] = 0x29;
3442 buffer[ 3] = edns0_maxsize >> 8;
3443 buffer[ 4] = edns0_maxsize;
3444 buffer[ 5] = message_get_status(mesg) >> 4;
3445 buffer[ 6] = mesg->_rcode_ext >> 16;
3446 buffer[ 7] = mesg->_rcode_ext >> 8;
3447 buffer[ 8] = mesg->_rcode_ext;
3448 buffer[ 9] = 0;
3449 buffer[10] = 0;
3450
3451 message_increase_size(mesg, 11);
3452
3453 message_set_additional_count_ne(mesg, NU16(1));
3454 }
3455 else
3456 {
3457 message_set_additional_count_ne(mesg, 0);
3458 }
3459
3460 #if DNSCORE_HAS_TSIG_SUPPORT
3461 if(message_has_tsig(mesg))
3462 {
3463 if(FAIL(ret = tsig_sign_tcp_message(mesg, pos)))
3464 {
3465 return ret;
3466 }
3467 }
3468 #endif
3469
3470 ret = message_write_tcp(mesg, tcpos);
3471
3472 return ret;
3473 }
3474
3475 /**
3476 * Maps records in a message to easily access them afterward.
3477 *
3478 * @param map the message map to initialise
3479 * @param mesg the message to map
3480 * @param tight do two passes to use the least amount of memory possible
3481 *
3482 * @return an error code
3483 */
3484
3485 ya_result
message_map_init(message_map * map,const message_data * mesg)3486 message_map_init(message_map *map, const message_data *mesg)
3487 {
3488 map->mesg = mesg;
3489
3490 packet_unpack_reader_data purd;
3491
3492 packet_reader_init_from_message(&purd, mesg);
3493
3494 ya_result ret;
3495
3496 u16 qc = message_get_query_count(mesg);
3497 u16 an = message_get_answer_count(mesg);
3498 u16 ns = message_get_authority_count(mesg);
3499 u16 ar = message_get_additional_count(mesg);
3500
3501 int total = qc;
3502 total += an;
3503 total += ns;
3504 total += ar;
3505
3506 ptr_vector_init_ex(&map->records, total);
3507
3508 int i;
3509
3510 for(i = 0; i < qc; ++i)
3511 {
3512 ptr_vector_append(&map->records, (void*)packet_reader_get_next_u8_ptr_const(&purd));
3513 packet_reader_skip_fqdn(&purd); // checked below
3514 if(FAIL(ret = packet_reader_skip(&purd, 4)))
3515 {
3516 message_map_finalize(map);
3517 return ret;
3518 }
3519 }
3520
3521 for(; i < total; ++i)
3522 {
3523 ptr_vector_append(&map->records, (void*)packet_reader_get_next_u8_ptr_const(&purd));
3524
3525 if(FAIL(ret = packet_reader_skip_record(&purd)))
3526 {
3527 message_map_finalize(map);
3528 return ret;
3529 }
3530 }
3531
3532 ret = ptr_vector_size(&map->records);
3533
3534 map->section_base[0] = 0;
3535 map->section_base[1] = message_get_section_count(map->mesg, 0) + map->section_base[0];
3536 map->section_base[2] = message_get_section_count(map->mesg, 1) + map->section_base[1];
3537 map->section_base[3] = message_get_section_count(map->mesg, 2) + map->section_base[2];
3538
3539 return ret;
3540 }
3541
3542 /**
3543 * Gets the fqdn of the record at index
3544 *
3545 * @param map
3546 * @param index
3547 * @param fqdn
3548 * @param fqdn_size
3549 *
3550 * @return an error code
3551 */
3552
3553 ya_result
message_map_get_fqdn(const message_map * map,int index,u8 * fqdn,int fqdn_size)3554 message_map_get_fqdn(const message_map *map, int index, u8 *fqdn, int fqdn_size)
3555 {
3556 if((index >= 0) && (index <= ptr_vector_last_index(&map->records)))
3557 {
3558 if(dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3559 ptr_vector_get(&map->records, index), fqdn, fqdn_size) != NULL)
3560 {
3561 return SUCCESS;
3562 }
3563 }
3564
3565 return ERROR;
3566 }
3567
3568 /**
3569 * Gets the type class ttl rdata_size of the record at index
3570 *
3571 * @param map
3572 * @param index
3573 * @param tctr
3574 *
3575 * @return an error code
3576 */
3577
3578
3579 ya_result
message_map_get_tctr(const message_map * map,int index,struct type_class_ttl_rdlen * tctr)3580 message_map_get_tctr(const message_map *map, int index, struct type_class_ttl_rdlen *tctr)
3581 {
3582 if((index >= 0) && (index <= ptr_vector_last_index(&map->records)))
3583 {
3584 const u8 *p;
3585 if((p = dnsname_skip_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3586 ptr_vector_get(&map->records, index))) != NULL)
3587 {
3588 if(index >= map->section_base[1])
3589 {
3590 if(message_get_buffer_limit_const(map->mesg) - p >= 10)
3591 {
3592 memcpy(tctr, p, 10);
3593
3594 return SUCCESS;
3595 }
3596 }
3597 else
3598 {
3599 if(message_get_buffer_limit_const(map->mesg) - p >= 4)
3600 {
3601 memcpy(tctr, p, 4);
3602 tctr->ttl = 0;
3603 tctr->rdlen = 0;
3604
3605 return SUCCESS;
3606 }
3607 }
3608 }
3609 }
3610
3611 return ERROR;
3612 }
3613
3614 /**
3615 * Gets the rdata of the record at index
3616 *
3617 * @param map
3618 * @param index
3619 * @param rdata
3620 * @param rdata_size
3621 *
3622 * @return the rdata size or an error code
3623 */
3624
3625 ya_result
message_map_get_rdata(const message_map * map,int index,u8 * rdata,int rdata_size)3626 message_map_get_rdata(const message_map *map, int index, u8 *rdata, int rdata_size)
3627 {
3628 if((index >= (int)map->section_base[1]) && (index <= ptr_vector_last_index(&map->records)))
3629 {
3630 const u8 *p;
3631 if((p = dnsname_skip_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3632 ptr_vector_get(&map->records, index))) != NULL)
3633 {
3634 if(message_get_buffer_limit_const(map->mesg) - p >= 10)
3635 {
3636 const u8 *rdata_base = rdata;
3637 size_t d;
3638
3639 u16 rtype = GET_U16_AT_P(p);
3640 p += 8;
3641 u16 n = ntohs(GET_U16_AT_P(p));
3642 p += 2;
3643
3644 if(message_get_buffer_limit_const(map->mesg) - p >= n)
3645 {
3646 switch(rtype)
3647 {
3648 /******************************************************************************
3649 * The types that requires special handling (dname compression)
3650 ******************************************************************************/
3651
3652 case TYPE_MX:
3653 case TYPE_AFSDB:
3654 {
3655 if(rdata_size < 3) // minimal expected size
3656 {
3657 return INVALID_RECORD;
3658 }
3659
3660 SET_U16_AT_P(rdata, GET_U16_AT_P(p));
3661 rdata += 2;
3662 rdata_size -= 2;
3663 p += 2;
3664 }
3665
3666 FALLTHROUGH // fall through
3667
3668 case TYPE_NS:
3669 case TYPE_CNAME:
3670 case TYPE_DNAME:
3671 case TYPE_PTR:
3672 case TYPE_MB:
3673 case TYPE_MD:
3674 case TYPE_MF:
3675 case TYPE_MG:
3676 case TYPE_MR:
3677 {
3678 if((p = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3679 p, rdata, rdata_size)) != NULL)
3680 {
3681 return p - rdata_base;
3682 }
3683
3684 return INVALID_RECORD;
3685 }
3686 case TYPE_SOA:
3687 {
3688 if((p = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3689 p, rdata, rdata_size)) != NULL)
3690 {
3691 d = dnsname_len(rdata);
3692 rdata += d;
3693 rdata_size -= d;
3694
3695 if((p = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3696 p, rdata, rdata_size)) != NULL)
3697 {
3698 d = dnsname_len(rdata);
3699
3700 rdata += d;
3701 rdata_size -= d;
3702
3703 if(rdata_size >= 20)
3704 {
3705 memcpy(rdata, p, 20);
3706 return &rdata[20] - rdata_base;
3707 }
3708 }
3709 }
3710
3711 return INVALID_RECORD;
3712 }
3713 case TYPE_RRSIG: /* not supposed to be compressed */
3714 {
3715 if(rdata_size > RRSIG_RDATA_HEADER_LEN)
3716 {
3717 const u8 *p_base = p;
3718 memcpy(rdata, p, RRSIG_RDATA_HEADER_LEN);
3719 rdata += RRSIG_RDATA_HEADER_LEN;
3720 rdata_size -= RRSIG_RDATA_HEADER_LEN;
3721 p += RRSIG_RDATA_HEADER_LEN;
3722
3723 if((p = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3724 p, rdata, rdata_size)) != NULL)
3725 {
3726 d = dnsname_len(rdata);
3727 rdata += d;
3728 //rdata_size -= d;
3729 d = p - p_base;
3730 memcpy(rdata, p, d);
3731
3732 return &rdata[d] - rdata_base;
3733 }
3734 }
3735
3736 return INVALID_RECORD;
3737 }
3738 case TYPE_NSEC: /* not supposed to be compressed */
3739 {
3740 const u8 *p_base = p;
3741 if((p = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3742 p, rdata, rdata_size)) != NULL)
3743 {
3744 d = dnsname_len(rdata);
3745 rdata += d;
3746 //rdata_size -= d;
3747 d = p - p_base;
3748 memcpy(rdata, p, d);
3749
3750 return &rdata[d] - rdata_base;
3751 }
3752
3753 return INVALID_RECORD;
3754 }
3755
3756 default:
3757 {
3758 if(rdata_size >= n)
3759 {
3760 memcpy(rdata, p, n);
3761 return n;
3762 }
3763
3764 return INVALID_RECORD;
3765 }
3766 } // switch type
3767 }
3768 }
3769 }
3770 }
3771
3772 return ERROR;
3773 }
3774
3775 /**
3776 * Gets the type of the record at index
3777 *
3778 * @param map
3779 * @param index
3780 *
3781 * @return the record type or an error code
3782 */
3783
3784 ya_result
message_map_get_type(const message_map * map,int index)3785 message_map_get_type(const message_map *map, int index)
3786 {
3787 if((index >= 0) && (index <= ptr_vector_last_index(&map->records)))
3788 {
3789 const u8 *p;
3790 if((p = dnsname_skip_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg),
3791 ptr_vector_get(&map->records, index))) != NULL)
3792 {
3793 if(message_get_buffer_limit_const(map->mesg) - p >= 2)
3794 {
3795 u16 rtype = GET_U16_AT_P(p);
3796
3797 return rtype;
3798 }
3799 }
3800 }
3801
3802 return ERROR;
3803 }
3804
3805 /**
3806 *
3807 * @param map
3808 *
3809 * @return the number of records mapped
3810 */
3811
3812 int
message_map_record_count(const message_map * map)3813 message_map_record_count(const message_map *map)
3814 {
3815 int size = ptr_vector_size(&map->records);
3816 return size;
3817 }
3818
3819 /**
3820 * Returns the index of the next record with the given type
3821 * from, and including, a given index.
3822 *
3823 * @param map
3824 * @param index
3825 * @param type
3826 * @return
3827 */
3828
3829 int
message_map_get_next_record_from(const message_map * map,int index,u16 type)3830 message_map_get_next_record_from(const message_map *map, int index, u16 type)
3831 {
3832 ya_result ret;
3833
3834 for(;;)
3835 {
3836 ret = message_map_get_type(map, index);
3837
3838 if(ret == type)
3839 {
3840 return index;
3841 }
3842
3843 if(FAIL(ret))
3844 {
3845 return ret;
3846 }
3847
3848 ++index;
3849 }
3850 }
3851
3852 /**
3853 * Returns the index of the next record with the given type
3854 * from, and including, a given index in a given section (0 to 3).
3855 *
3856 * @param map
3857 * @param index
3858 * @param type
3859 * @return
3860 */
3861
3862 int
message_map_get_next_record_from_section(const message_map * map,int section,int index,u16 type)3863 message_map_get_next_record_from_section(const message_map *map, int section, int index, u16 type)
3864 {
3865 if(index < 0)
3866 {
3867 return INVALID_ARGUMENT_ERROR;
3868 }
3869
3870 u16 sc = message_get_section_count(map->mesg, section);
3871
3872 if(index >= sc)
3873 {
3874 return INVALID_ARGUMENT_ERROR;
3875 }
3876
3877 ya_result ret;
3878
3879 do
3880 {
3881 ret = message_map_get_type(map, map->section_base[section] + index);
3882
3883 if(ret == type)
3884 {
3885 return index;
3886 }
3887
3888 if(FAIL(ret))
3889 {
3890 return ret;
3891 }
3892
3893 ++index;
3894 }
3895 while(index < sc);
3896
3897 return ERROR;
3898 }
3899
3900 /**
3901 * Releases the memory used by the map
3902 *
3903 * @param map
3904 */
3905
3906 void
message_map_finalize(message_map * map)3907 message_map_finalize(message_map *map)
3908 {
3909 ptr_vector_destroy(&map->records);
3910 }
3911
3912 static int
message_map_reorder_remap_type(int t,int ct)3913 message_map_reorder_remap_type(int t, int ct)
3914 {
3915 int r;
3916 switch(t)
3917 {
3918 case TYPE_SOA:
3919 r = 0 << 1;
3920 break;
3921 case TYPE_NSEC:
3922 r = 0x7ffe << 1;
3923 break;
3924 case TYPE_NSEC3:
3925 r = 0x7fff << 1;
3926 break;
3927 case TYPE_RRSIG:
3928 r = message_map_reorder_remap_type(ct, 0) + 1;
3929 break;
3930 default:
3931 r = (ntohs(t) + 0x1000) << 1;
3932 break;
3933 }
3934 return r;
3935 }
3936
3937 static int
message_map_reorder_comparator(const void * rra,const void * rrb,void * ctx)3938 message_map_reorder_comparator(const void *rra, const void *rrb, void *ctx)
3939 {
3940 const u8 *pa = (const u8*)rra;
3941 const u8 *pb = (const u8*)rrb;
3942 message_map *map = (message_map *)ctx;
3943 struct type_class_ttl_rdlen tctra;
3944 struct type_class_ttl_rdlen tctrb;
3945 u16 ctypea;
3946 u16 ctypeb;
3947 u8 fqdna[256];
3948 u8 fqdnb[256];
3949
3950 if(rra == rrb)
3951 {
3952 return 0;
3953 }
3954
3955 pa = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg), rra, fqdna, sizeof(fqdna));
3956 memcpy(&tctra, pa, 10);
3957 pa += 10;
3958 if(tctra.qtype == TYPE_RRSIG)
3959 {
3960 ctypea = GET_U16_AT_P(pa);
3961 }
3962 else
3963 {
3964 ctypea = 0;
3965 }
3966
3967 pa += 10;
3968
3969 pb = dnsname_expand_compressed(message_get_buffer_const(map->mesg), message_get_size(map->mesg), rrb, fqdnb, sizeof(fqdnb));
3970 memcpy(&tctrb, pb, 10);
3971 pb += 10;
3972 if(tctrb.qtype == TYPE_RRSIG)
3973 {
3974 ctypeb = GET_U16_AT_P(pb);
3975 }
3976 else
3977 {
3978 ctypeb = 0;
3979 }
3980
3981 tctra.rdlen = ntohs(tctra.rdlen);
3982 tctrb.rdlen = ntohs(tctrb.rdlen);
3983 int rdata_size_d = tctra.rdlen;
3984 int rdata_size_min = MIN(tctra.rdlen, tctrb.rdlen);
3985 rdata_size_d -= tctrb.rdlen;
3986 int d;
3987
3988 bool n3a = (tctra.qtype == TYPE_NSEC3) || (ctypea == TYPE_NSEC3);
3989 bool n3b = (tctrb.qtype == TYPE_NSEC3) || (ctypeb == TYPE_NSEC3);
3990
3991 if(n3a)
3992 {
3993 if(n3b)
3994 {
3995 // both are NSEC3 related: normal sort
3996 }
3997 else
3998 {
3999 // the NSEC3 one is after the normal one
4000 return 1;
4001 }
4002 }
4003 else // the first one is not NSEC3 related
4004 {
4005 if(n3b)
4006 {
4007 // the second one is: it comes after the normal one
4008 return -1;
4009 }
4010 else
4011 {
4012 // none are NSEC3 related: normal sort
4013 }
4014 }
4015
4016 d = dnsname_compare(fqdna, fqdnb);
4017
4018 if(d == 0)
4019 {
4020 // let's avoid lot's of if-then-else
4021
4022 int ta = message_map_reorder_remap_type(tctra.qtype, ctypea);
4023 int tb = message_map_reorder_remap_type(tctrb.qtype, ctypeb);
4024
4025 d = ta - tb;
4026
4027 if(d == 0)
4028 {
4029 d = memcmp(pa, pb, rdata_size_min);
4030
4031 if(d == 0)
4032 {
4033 d = rdata_size_d;
4034 }
4035 }
4036 }
4037
4038 return d;
4039 }
4040
4041 /**
4042 * Sorts records by section so that:
4043 * _ SOA is first,
4044 * _ NSEC is last,
4045 * _ NSEC3 labels are at the end,
4046 * _ RRSIG follows its RRSET
4047 *
4048 * @param map
4049 */
4050
4051 void
message_map_reorder(message_map * map)4052 message_map_reorder(message_map *map)
4053 {
4054 // apply message_map_reorder_comparator to sections 1, 2 and 3.
4055 ptr_vector fakev;
4056 for(int section = 1; section < 4; ++section)
4057 {
4058 int sc = message_get_section_count(map->mesg, section);
4059 if(sc > 1)
4060 {
4061 fakev.data = &map->records.data[map->section_base[section]];
4062 fakev.offset = sc - 1;
4063 fakev.size = fakev.offset + 1;
4064 ptr_vector_qsort_r(&fakev, message_map_reorder_comparator, map);
4065 }
4066 }
4067 }
4068
4069 void
message_map_print(const message_map * map,output_stream * os)4070 message_map_print(const message_map *map, output_stream *os)
4071 {
4072 osformat(os, ";; opcode: %s, status: %s, id: %i, flags:",
4073 dns_message_opcode_get_name(message_get_opcode(map->mesg) >> OPCODE_SHIFT),
4074 dns_message_rcode_get_name(message_get_rcode(map->mesg)),
4075 ntohs(message_get_id(map->mesg)));
4076
4077 u8 h = message_get_flags_hi(map->mesg);
4078 if(h & QR_BITS) output_stream_write(os, "qr ", 3);
4079 if(h & AA_BITS) output_stream_write(os, "aa ", 3);
4080 if(h & TC_BITS) output_stream_write(os, "tc ", 3);
4081 if(h & RD_BITS) output_stream_write(os, "rd ", 3);
4082
4083 u8 l = message_get_flags_hi(map->mesg);
4084
4085 if(l & RA_BITS) output_stream_write(os, "ra ", 3);
4086 if(l & AD_BITS) output_stream_write(os, "ad ", 3);
4087 if(l & CD_BITS) output_stream_write(os, "cd ", 3);
4088
4089 osformatln(os, "\n;; SECTION: [%i ,%i, %i, %i]",
4090 message_get_section_count(map->mesg, 0),
4091 message_get_section_count(map->mesg, 1),
4092 message_get_section_count(map->mesg, 2),
4093 message_get_section_count(map->mesg, 3));
4094
4095 struct type_class_ttl_rdlen tctr;
4096 u8 tmp[1024];
4097
4098 int i = 0;
4099
4100 for(int section = 0; section < 4; ++section)
4101 {
4102 osformatln(os, ";; SECTION %i:", section);
4103
4104 for(int n = message_get_section_count(map->mesg, section); n > 0; --n)
4105 {
4106 message_map_get_fqdn(map, i, tmp, sizeof(tmp));
4107 if(ISOK(message_map_get_tctr(map, i, &tctr)))
4108 {
4109 osformat(os, "%{dnsname} %9i %{dnsclass} %{dnstype} ", tmp, ntohl(tctr.ttl), &tctr.qclass, &tctr.qtype);
4110
4111 if(section > 0)
4112 {
4113 int rdata_size = message_map_get_rdata(map, i, tmp, sizeof(tmp));
4114
4115 rdata_desc rd = {tctr.qtype, rdata_size, tmp};
4116 osformat(os, "%{rdatadesc}", &rd);
4117 }
4118 osprintln(os, "");
4119
4120 ++i;
4121 }
4122 else
4123 {
4124 osformatln(os, "%{dnsname} READ FAILURE\n", tmp);
4125 break;
4126 }
4127 }
4128
4129 osprintln(os, "");
4130 }
4131 }
4132
message_send_udp_debug(const message_data * mesg,int sockfd)4133 s32 message_send_udp_debug(const message_data *mesg, int sockfd)
4134 {
4135 log_info("message_send_udp(%p, %i) through %{sockaddr}", mesg, sockfd, mesg->_msghdr.msg_name);
4136
4137 s32 n;
4138
4139 while((n = sendmsg(sockfd, &mesg->_msghdr, 0)) < 0)
4140 {
4141 int err = errno;
4142
4143 if(err != EINTR)
4144 {
4145 return MAKE_ERRNO_ERROR(err);
4146 }
4147 }
4148
4149 return n;
4150 }
4151
message_send_tcp(const message_data * mesg,int sockfd)4152 ssize_t message_send_tcp(const message_data *mesg, int sockfd)
4153 {
4154 ssize_t ret;
4155 struct msghdr tcp_msghdr;
4156 struct iovec tcp_data[2];
4157 u16 tcp_len = message_get_size_u16(mesg);
4158 u16 tcp_native_len = htons(tcp_len);
4159
4160 tcp_data[0].iov_base = &tcp_native_len;
4161 tcp_data[0].iov_len = 2;
4162 tcp_data[1].iov_base = mesg->_buffer;
4163 tcp_data[1].iov_len = tcp_len;
4164 tcp_msghdr.msg_name = mesg->_msghdr.msg_name;
4165 tcp_msghdr.msg_namelen = mesg->_msghdr.msg_namelen;
4166 tcp_msghdr.msg_iov = &tcp_data[0];
4167 tcp_msghdr.msg_iovlen = 2;
4168 tcp_msghdr.msg_control = mesg->_msghdr.msg_control;
4169 tcp_msghdr.msg_controllen = mesg->_msghdr.msg_controllen;
4170 tcp_msghdr.msg_flags = 0;
4171
4172 s32 remain = tcp_len + 2;
4173
4174 #if DEBUG
4175 s32 again = 0;
4176 #endif
4177
4178 for(;;)
4179 {
4180 ret = sendmsg(sockfd, &tcp_msghdr, 0);
4181
4182 if(ret < 0)
4183 {
4184 int err = ERRNO_ERROR;
4185 if(err == MAKE_ERRNO_ERROR(EINTR))
4186 {
4187 continue;
4188 }
4189
4190 if(err == MAKE_ERRNO_ERROR(EAGAIN))
4191 {
4192 #if DEBUG
4193 ++again;
4194 #endif
4195 usleep(100);
4196 continue;
4197 }
4198
4199 ret = err;
4200
4201 break;
4202 }
4203
4204 remain -= ret;
4205
4206 if(remain == 0)
4207 {
4208 break;
4209 }
4210
4211 while(tcp_msghdr.msg_iovlen > 0)
4212 {
4213 if((size_t)ret < tcp_msghdr.msg_iov[0].iov_len)
4214 {
4215 u8* p = (u8*)tcp_msghdr.msg_iov[0].iov_base;
4216 p += ret;
4217 tcp_msghdr.msg_iov[0].iov_base = p;
4218 tcp_msghdr.msg_iov[0].iov_len -= (size_t)ret;
4219 break;
4220 }
4221 else
4222 {
4223 ret -= (size_t)tcp_msghdr.msg_iov[0].iov_len;
4224
4225 ++tcp_msghdr.msg_iov;
4226 --tcp_msghdr.msg_iovlen;
4227
4228 if(ret == 0)
4229 {
4230 break;
4231 }
4232 }
4233 }
4234 }
4235
4236 #if DEBUG
4237 if(again > 0)
4238 {
4239 log_debug("message_send_tcp: again=%i", again);
4240 }
4241 #endif
4242
4243 return ret;
4244 }
4245
4246 /** @} */
4247