join 1.0
lightweight network framework library
Loading...
Searching...
No Matches
nameserver.hpp
Go to the documentation of this file.
1
25#ifndef JOIN_FABRIC_NAMESERVER_HPP
26#define JOIN_FABRIC_NAMESERVER_HPP
27
28// libjoin.
31#include <join/dns_protocol.hpp>
32#include <join/dns_message.hpp>
33#include <join/condition.hpp>
34#include <join/reactor.hpp>
35
36namespace join
37{
41 template <typename Protocol>
43 {
44 public:
45 using Socket = typename Protocol::Socket;
46 using Endpoint = typename Protocol::Endpoint;
47
53 : _reactor (reactor)
54 , _buffer (std::make_unique<char[]> (Protocol::maxMsgSize))
55 {
56 }
57
63
70
76
83
87 virtual ~BasicDatagramNameServer () noexcept = default;
88
94 virtual int bind (const Endpoint& endpoint) noexcept
95 {
96 if (_socket.bind (endpoint) == -1)
97 {
98 return -1; // LCOV_EXCL_LINE
99 }
100
101 _reactor.addHandler (_socket.handle (), this);
102
103 return 0;
104 }
105
109 virtual void close () noexcept
110 {
111 _reactor.delHandler (_socket.handle ());
112 _socket.close ();
113 }
114
124 int reply (const DnsPacket& query, const std::vector<ResourceRecord>& answers = {},
125 const std::vector<ResourceRecord>& authorities = {},
126 const std::vector<ResourceRecord>& additionals = {}, uint16_t rcode = 0)
127 {
128 DnsPacket packet{};
129 packet.id = query.id;
130 packet.flags = (uint16_t (1) << 15) | (query.flags & 0x7800) | (uint16_t (1) << 10) | (rcode & 0x000F);
131 packet.dest = query.src;
132 packet.port = query.port;
133
134 packet.questions = query.questions;
135 packet.answers = answers;
136 packet.authorities = authorities;
137 packet.additionals = additionals;
138
139 return send (packet);
140 }
141
146 virtual void onQuery (const DnsPacket& packet) = 0;
147
148 protected:
153 virtual void onReadable ([[maybe_unused]] int fd) override
154 {
155 Endpoint from;
156 ssize_t size = _socket.readFrom (_buffer.get (), Protocol::maxMsgSize, &from);
157 if (size >= int (_headerSize))
158 {
159 DnsPacket packet;
160 if (_message.deserialize (packet, _buffer.get (), static_cast<size_t> (size)) == -1)
161 {
162 return;
163 }
164
165 packet.src = from.ip ();
166 packet.dest = _socket.localEndpoint ().ip ();
167 packet.port = from.port ();
168
169 if ((packet.flags & 0x8000) == 0)
170 {
171 this->onQuery (packet);
172 }
173 }
174 }
175
181 int send (DnsPacket& packet)
182 {
183 char buffer[Protocol::maxMsgSize];
184 ssize_t size = _message.serialize (packet, buffer, sizeof (buffer));
185 if (size == -1)
186 {
187 return -1; // LCOV_EXCL_LINE
188 }
189
190 if (_socket.writeTo (buffer, static_cast<size_t> (size), {packet.dest, packet.port}) == -1)
191 {
192 return -1; // LCOV_EXCL_LINE
193 }
194
195 return 0;
196 };
197
199 static constexpr size_t _headerSize = 12;
200
203
206
209
211 std::unique_ptr<char[]> _buffer;
212 };
213
217 template <typename Protocol>
219 {
220 public:
223
225 using DnsNotify = std::function<void (const DnsPacket&)>;
226
229
232
238 explicit BasicDatagramPeer (unsigned int ifindex, Reactor& reactor = ReactorThread::reactor ())
239 : BasicDatagramNameServer<Protocol> (reactor)
240#ifdef DEBUG
241 , onSuccess (defaultOnSuccess)
242 , onFailure (defaultOnFailure)
243#else
244 , onSuccess (nullptr)
245 , onFailure (nullptr)
246#endif
247 , _ifindex (ifindex)
248 {
249 }
250
256 explicit BasicDatagramPeer (const std::string& interface, Reactor& reactor = ReactorThread::reactor ())
257 : BasicDatagramPeer<Protocol> (if_nametoindex (interface.c_str ()), reactor)
258 {
259 }
260
265 BasicDatagramPeer (const BasicDatagramPeer& other) = delete;
266
273
279
286
290 virtual ~BasicDatagramPeer () noexcept = default;
291
292 using BasicDatagramNameServer<Protocol>::bind;
293
299 int bind (int family) noexcept
300 {
301 IpAddress maddress = Protocol::multicastAddress (family);
302 Endpoint endpoint{IpAddress (family), Protocol::defaultPort};
303
304 if ((this->_socket.opened () == false) && (this->_socket.open (endpoint.protocol ()) == -1))
305 {
306 return -1; // LCOV_EXCL_LINE
307 }
308
309 if (this->_socket.setOption (Socket::ReusePort, 1) == -1)
310 {
311 // LCOV_EXCL_START
312 this->close ();
313 return -1;
314 // LCOV_EXCL_STOP
315 }
316
317 if (this->_socket.bind (endpoint) == -1)
318 {
319 // LCOV_EXCL_START
320 this->close ();
321 return -1;
322 // LCOV_EXCL_STOP
323 }
324
325 if (endpoint.protocol ().family () == AF_INET6)
326 {
327 ipv6_mreq mreq{};
328 ::memcpy (&mreq.ipv6mr_multiaddr, maddress.addr (), maddress.length ());
329 mreq.ipv6mr_interface = _ifindex;
330 if (::setsockopt (this->_socket.handle (), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) ==
331 -1)
332 {
333 // LCOV_EXCL_START
334 lastError = std::error_code (errno, std::generic_category ());
335 this->close ();
336 return -1;
337 // LCOV_EXCL_STOP
338 }
339 if (::setsockopt (this->_socket.handle (), IPPROTO_IPV6, IPV6_MULTICAST_IF, &_ifindex,
340 sizeof (_ifindex)) == -1)
341 {
342 // LCOV_EXCL_START
343 lastError = std::error_code (errno, std::generic_category ());
344 this->close ();
345 return -1;
346 // LCOV_EXCL_STOP
347 }
348 }
349 else
350 {
351 // LCOV_EXCL_START: IPv4 multicast not supported by github action containers.
352 ip_mreqn mreq{};
353 ::memcpy (&mreq.imr_multiaddr, maddress.addr (), maddress.length ());
354 mreq.imr_ifindex = static_cast<int> (_ifindex);
355 if (::setsockopt (this->_socket.handle (), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) == -1)
356 {
357 lastError = std::error_code (errno, std::generic_category ());
358 this->close ();
359 return -1;
360 }
361 if (::setsockopt (this->_socket.handle (), IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof (mreq)) == -1)
362 {
363 lastError = std::error_code (errno, std::generic_category ());
364 this->close ();
365 return -1;
366 }
367 // LCOV_EXCL_STOP
368 }
369
370#ifndef DEBUG
371 if (this->_socket.setOption (Socket::MulticastLoop, 0) == -1)
372 {
373 // LCOV_EXCL_START
374 this->close ();
375 return -1;
376 // LCOV_EXCL_STOP
377 }
378#endif
379
380 this->_reactor.addHandler (this->_socket.handle (), this);
381
382 return 0;
383 }
384
390 int probe (const std::vector<ResourceRecord>& records)
391 {
392 if (records.empty ())
393 {
395 return -1;
396 }
397
398 DnsPacket packet{};
399 packet.id = 0;
400 packet.flags = 0;
401 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
402 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
403 packet.port = Protocol::defaultPort;
404
405 for (auto const& record : records)
406 {
407 QuestionRecord question;
408 question.host = record.host;
410 question.dnsclass = DnsMessage::RecordClass::IN | 0x8000;
411 packet.questions.push_back (question);
412
413 packet.authorities.push_back (record);
414 }
415
416 return this->send (packet);
417 }
418
424 int announce (const std::vector<ResourceRecord>& records)
425 {
426 if (records.empty ())
427 {
429 return -1;
430 }
431
432 DnsPacket packet{};
433 packet.id = 0;
434 packet.flags = (uint16_t (1) << 15) | (uint16_t (1) << 10);
435 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
436 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
437 packet.port = Protocol::defaultPort;
438
439 for (auto const& record : records)
440 {
441 packet.answers.push_back (record);
442 }
443
444 return this->send (packet);
445 }
446
452 int goodbye (const std::vector<ResourceRecord>& records)
453 {
454 if (records.empty ())
455 {
457 return -1;
458 }
459
460 DnsPacket packet{};
461 packet.id = 0;
462 packet.flags = (uint16_t (1) << 15) | (uint16_t (1) << 10);
463 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
464 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
465 packet.port = Protocol::defaultPort;
466
467 for (auto const& record : records)
468 {
469 ResourceRecord goodbye = record;
470 goodbye.ttl = 0;
471 packet.answers.push_back (goodbye);
472 }
473
474 return this->send (packet);
475 }
476
482 int browse (const std::string& serviceType)
483 {
484 if (serviceType.empty ())
485 {
487 return -1;
488 }
489
490 DnsPacket packet{};
491 packet.id = 0;
492 packet.flags = 0;
493 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
494 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
495 packet.port = Protocol::defaultPort;
496
497 QuestionRecord question;
498 question.host = serviceType;
501 packet.questions.push_back (question);
502
503 return this->send (packet);
504 }
505
513 IpAddressList resolveAllAddress (const std::string& host, int family,
514 std::chrono::milliseconds timeout = std::chrono::seconds (5))
515 {
516 if (host.empty ())
517 {
518 return {};
519 }
520
521 DnsPacket packet{};
522 packet.id = join::randomize<uint16_t> ();
523 packet.flags = 1 << 8;
524
525 QuestionRecord question;
526 question.host = host;
527 question.type = (family == AF_INET6) ? DnsMessage::RecordType::AAAA : DnsMessage::RecordType::A;
529 packet.questions.push_back (question);
530
531 if (query (packet, timeout) == -1)
532 {
533 return {};
534 }
535
536 IpAddressList addresses;
537
538 for (auto const& answer : packet.answers)
539 {
540 if (!answer.addr.isWildcard () && (answer.type == question.type))
541 {
542 addresses.push_back (answer.addr);
543 }
544 }
545
546 return addresses;
547 }
548
555 IpAddressList resolveAllAddress (const std::string& host,
556 std::chrono::milliseconds timeout = std::chrono::seconds (5))
557 {
558 IpAddressList addresses;
559
560 for (auto const& family : {AF_INET, AF_INET6})
561 {
562 IpAddressList tmp = resolveAllAddress (host, family, timeout);
563 addresses.insert (addresses.end (), tmp.begin (), tmp.end ());
564 }
565
566 return addresses;
567 }
568
576 IpAddress resolveAddress (const std::string& host, int family,
577 std::chrono::milliseconds timeout = std::chrono::seconds (5))
578 {
579 for (auto const& address : resolveAllAddress (host, family, timeout))
580 {
581 return address;
582 }
583
584 return IpAddress (family);
585 }
586
593 IpAddress resolveAddress (const std::string& host, std::chrono::milliseconds timeout = std::chrono::seconds (5))
594 {
595 for (auto const& address : resolveAllAddress (host, timeout))
596 {
597 return address;
598 }
599
600 return {};
601 }
602
610 std::chrono::milliseconds timeout = std::chrono::seconds (5))
611 {
612 if (address.isWildcard ())
613 {
614 return {};
615 }
616
617 DnsPacket packet{};
618 packet.id = join::randomize<uint16_t> ();
619 packet.flags = 1 << 8;
620
621 QuestionRecord question;
622 question.host = address.toArpa ();
625 packet.questions.push_back (question);
626
627 if (query (packet, timeout) == -1)
628 {
629 return {};
630 }
631
632 AliasList aliases;
633
634 for (auto const& answer : packet.answers)
635 {
636 if (!answer.name.empty () && (answer.type == DnsMessage::RecordType::PTR))
637 {
638 aliases.insert (answer.name);
639 }
640 }
641
642 return aliases;
643 }
644
651 std::string resolveName (const IpAddress& address, std::chrono::milliseconds timeout = std::chrono::seconds (5))
652 {
653 for (auto const& alias : resolveAllName (address, timeout))
654 {
655 return alias;
656 }
657
658 return {};
659 }
660
665 virtual void onAnnouncement (const DnsPacket& packet) = 0;
666
667 protected:
672 void onReadable ([[maybe_unused]] int fd) override final
673 {
674 Endpoint from;
675 ssize_t size = this->_socket.readFrom (this->_buffer.get (), Protocol::maxMsgSize, &from);
676 if (size >= int (this->_headerSize))
677 {
678 DnsPacket packet;
679 if (this->_message.deserialize (packet, this->_buffer.get (), static_cast<size_t> (size)) == -1)
680 {
681 return;
682 }
683
684 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
685 packet.src = from.ip ();
686 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
687 packet.port = from.port ();
688
689 if ((packet.flags & 0x8000) == 0)
690 {
691 bool unicast = false;
692 for (auto const& q : packet.questions)
693 {
694 if (q.dnsclass & 0x8000)
695 {
696 unicast = true;
697 break;
698 }
699 }
700
701 if (!unicast)
702 {
703 packet.src = IpAddress (mcast.addr (), mcast.length (), _ifindex);
704 }
705
706 this->onQuery (packet);
707 return;
708 }
709
710 {
712
713 auto it = _pending.find (packet.id);
714 if (it != _pending.end ())
715 {
716 it->second->packet = packet;
717 it->second->ec = DnsMessage::decodeError (packet.flags & 0x000F);
718 it->second->cond.signal ();
719 return;
720 }
721 }
722
723 onAnnouncement (packet);
724 }
725 }
726
727#ifdef DEBUG
728 /*
729 * @brief default callback called when a lookup sequence succeed.
730 * @param packet DNS packet.
731 */
732 static void defaultOnSuccess (const DnsPacket& packet)
733 {
734 std::cout << std::endl;
735 std::cout << "PEER: " << packet.dest << "#" << packet.port << std::endl;
736
737 std::cout << std::endl;
738 std::cout << ";; QUESTION SECTION: " << std::endl;
739 for (auto const& question : packet.questions)
740 {
741 std::cout << question.host;
742 std::cout << " " << DnsMessage::typeName (question.type);
743 std::cout << " " << DnsMessage::className (question.dnsclass);
744 std::cout << std::endl;
745 }
746
747 std::cout << std::endl;
748 std::cout << ";; ANSWER SECTION: " << std::endl;
749 for (auto const& answer : packet.answers)
750 {
751 std::cout << answer.host;
752 std::cout << " " << DnsMessage::typeName (answer.type);
753 std::cout << " " << DnsMessage::className (answer.dnsclass);
754 std::cout << " " << answer.ttl;
755 if (answer.type == DnsMessage::RecordType::A)
756 {
757 std::cout << " " << answer.addr;
758 }
759 else if (answer.type == DnsMessage::RecordType::PTR)
760 {
761 std::cout << " " << answer.name;
762 }
763 else if (answer.type == DnsMessage::RecordType::AAAA)
764 {
765 std::cout << " " << answer.addr;
766 }
767 std::cout << std::endl;
768 }
769 }
770
771 /*
772 * @brief default callback called when a lookup sequence failed.
773 * @param packet DNS packet.
774 */
775 static void defaultOnFailure (const DnsPacket& packet)
776 {
777 std::cout << std::endl;
778 std::cout << "PEER: " << packet.dest << "#" << packet.port << std::endl;
779
780 std::cout << std::endl;
781 std::cout << ";; QUESTION SECTION: " << std::endl;
782 for (auto const& question : packet.questions)
783 {
784 std::cout << question.host;
785 std::cout << " " << DnsMessage::typeName (question.type);
786 std::cout << " " << DnsMessage::className (question.dnsclass);
787 std::cout << std::endl;
788 }
789
790 std::cout << std::endl;
791 std::cout << lastError.message () << std::endl;
792 }
793#endif
794
800 void notify (const DnsNotify& func, const DnsPacket& packet) const noexcept
801 {
802 if (func)
803 {
804 func (packet);
805 }
806 }
807
814 int query (DnsPacket& packet, std::chrono::milliseconds timeout)
815 {
816 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
817 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
818 packet.port = Protocol::defaultPort;
819
820 char buffer[Protocol::maxMsgSize];
821 ssize_t size = this->_message.serialize (packet, buffer, sizeof (buffer));
822 if (size == -1)
823 {
824 return -1; // LCOV_EXCL_LINE
825 }
826
828
829 auto inserted = _pending.emplace (packet.id, std::make_unique<PendingRequest> ());
830 if (!inserted.second)
831 {
832 // LCOV_EXCL_START
834 notify (onFailure, packet);
835 return -1;
836 // LCOV_EXCL_STOP
837 }
838
839 if (this->_socket.writeTo (buffer, static_cast<size_t> (size), {packet.dest, packet.port}) == -1)
840 {
841 // LCOV_EXCL_START
842 _pending.erase (inserted.first);
843 notify (onFailure, packet);
844 return -1;
845 // LCOV_EXCL_STOP
846 }
847
848 if (!inserted.first->second->cond.timedWait (lock, timeout))
849 {
850 // LCOV_EXCL_START
851 _pending.erase (inserted.first);
852 lastError = make_error_code (Errc::TimedOut);
853 notify (onFailure, packet);
854 return -1;
855 // LCOV_EXCL_STOP
856 }
857
858 auto pendingReq = std::move (inserted.first->second);
859 _pending.erase (inserted.first);
860
861 if (pendingReq->ec)
862 {
863 // LCOV_EXCL_START
864 lastError = pendingReq->ec;
865 notify (onFailure, packet);
866 return -1;
867 // LCOV_EXCL_STOP
868 }
869
870 packet = std::move (pendingReq->packet);
871 notify (onSuccess, packet);
872
873 return 0;
874 }
875
877 unsigned int _ifindex;
878
881 {
884 std::error_code ec;
885 };
886
888 std::unordered_map<uint16_t, std::unique_ptr<PendingRequest>> _pending;
889
892 };
893}
894
895#endif
basic DNS name server over datagram socket.
Definition nameserver.hpp:43
int reply(const DnsPacket &query, const std::vector< ResourceRecord > &answers={}, const std::vector< ResourceRecord > &authorities={}, const std::vector< ResourceRecord > &additionals={}, uint16_t rcode=0)
reply to a DNS query.
Definition nameserver.hpp:124
virtual void close() noexcept
close the socket and unregister from the reactor.
Definition nameserver.hpp:109
typename Protocol::Socket Socket
Definition nameserver.hpp:45
BasicDatagramNameServer(Reactor &reactor=ReactorThread::reactor())
construct the name server instance.
Definition nameserver.hpp:52
DnsMessage _message
DNS message codec.
Definition nameserver.hpp:202
virtual int bind(const Endpoint &endpoint) noexcept
bind the socket to the given endpoint and register with the reactor.
Definition nameserver.hpp:94
BasicDatagramNameServer(const BasicDatagramNameServer &other)=delete
copy constructor.
std::unique_ptr< char[]> _buffer
reception buffer.
Definition nameserver.hpp:211
Reactor & _reactor
event loop reactor.
Definition nameserver.hpp:208
virtual ~BasicDatagramNameServer() noexcept=default
destroy instance.
virtual void onQuery(const DnsPacket &packet)=0
method called when a DNS query is received.
Socket _socket
underlying socket.
Definition nameserver.hpp:205
virtual void onReadable(int fd) override
method called when data are ready to be read on handle.
Definition nameserver.hpp:153
BasicDatagramNameServer & operator=(const BasicDatagramNameServer &other)=delete
copy assignment operator.
BasicDatagramNameServer(BasicDatagramNameServer &&other)=delete
move constructor.
int send(DnsPacket &packet)
serialize and send a DNS packet.
Definition nameserver.hpp:181
static constexpr size_t _headerSize
DNS message header size.
Definition nameserver.hpp:199
typename Protocol::Endpoint Endpoint
Definition nameserver.hpp:46
mDNS peer.
Definition nameserver.hpp:219
IpAddressList resolveAllAddress(const std::string &host, int family, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host name and return all IP addresses found.
Definition nameserver.hpp:513
int probe(const std::vector< ResourceRecord > &records)
probe the local network for the presence of a service.
Definition nameserver.hpp:390
typename BasicDatagramNameServer< Protocol >::Socket Socket
Definition nameserver.hpp:221
virtual ~BasicDatagramPeer() noexcept=default
destroy instance.
BasicDatagramPeer(unsigned int ifindex, Reactor &reactor=ReactorThread::reactor())
construct the mDNS peer instance.
Definition nameserver.hpp:238
BasicDatagramPeer(BasicDatagramPeer &&other)=delete
move constructor.
IpAddress resolveAddress(const std::string &host, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host name.
Definition nameserver.hpp:593
BasicDatagramPeer(const BasicDatagramPeer &other)=delete
copy constructor.
virtual void onAnnouncement(const DnsPacket &packet)=0
method called when a DNS query is received.
int browse(const std::string &serviceType)
browse for services on the local network.
Definition nameserver.hpp:482
typename BasicDatagramNameServer< Protocol >::Endpoint Endpoint
Definition nameserver.hpp:222
IpAddress resolveAddress(const std::string &host, int family, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host name using address family.
Definition nameserver.hpp:576
void onReadable(int fd) override final
method called when data are ready to be read on handle.
Definition nameserver.hpp:672
AliasList resolveAllName(const IpAddress &address, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve all host address.
Definition nameserver.hpp:609
int query(DnsPacket &packet, std::chrono::milliseconds timeout)
serialize and send a DNS query, waiting for a response.
Definition nameserver.hpp:814
std::unordered_map< uint16_t, std::unique_ptr< PendingRequest > > _pending
synchronous requests indexed by sequence number.
Definition nameserver.hpp:888
std::string resolveName(const IpAddress &address, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host address.
Definition nameserver.hpp:651
DnsNotify onFailure
callback called when a lookup sequence failed.
Definition nameserver.hpp:231
DnsNotify onSuccess
callback called when a lookup sequence succeed.
Definition nameserver.hpp:228
void notify(const DnsNotify &func, const DnsPacket &packet) const noexcept
safe way to notify DNS events.
Definition nameserver.hpp:800
int goodbye(const std::vector< ResourceRecord > &records)
send a goodbye message.
Definition nameserver.hpp:452
BasicDatagramPeer & operator=(const BasicDatagramPeer &other)=delete
copy assignment operator.
BasicDatagramPeer(const std::string &interface, Reactor &reactor=ReactorThread::reactor())
construct the mDNS peer instance.
Definition nameserver.hpp:256
int announce(const std::vector< ResourceRecord > &records)
announce the presence of a service on the local network.
Definition nameserver.hpp:424
int bind(int family) noexcept
bind the socket to specified address family.
Definition nameserver.hpp:299
std::function< void(const DnsPacket &)> DnsNotify
DNS notification callback type.
Definition nameserver.hpp:225
Mutex _syncMutex
protection mutex.
Definition nameserver.hpp:891
unsigned int _ifindex
interface index.
Definition nameserver.hpp:877
IpAddressList resolveAllAddress(const std::string &host, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host name and return all IP addresses found.
Definition nameserver.hpp:555
condition variable class.
Definition condition.hpp:42
DNS message codec.
Definition dns_message.hpp:104
int deserialize(DnsPacket &packet, const char *data, size_t size) const
deserialize a DNS packet from a buffer.
Definition dns_message.hpp:228
static std::string className(uint16_t recordClass)
get record class name.
Definition dns_message.hpp:356
@ A
Definition dns_message.hpp:111
@ PTR
Definition dns_message.hpp:115
@ ANY
Definition dns_message.hpp:120
@ AAAA
Definition dns_message.hpp:118
ssize_t serialize(const DnsPacket &packet, char *data, size_t maxSize) const
serialize a DNS packet into a buffer.
Definition dns_message.hpp:174
static std::error_code decodeError(uint16_t error) noexcept
convert DNS error to system error code.
Definition dns_message.hpp:307
@ IN
Definition dns_message.hpp:128
static std::string typeName(uint16_t recordType)
get record type name.
Definition dns_message.hpp:332
Event handler interface class.
Definition reactor.hpp:51
IPv6, IPv4 address class.
Definition ip_address.hpp:52
socklen_t length() const
get the size in byte of the internal address structure.
Definition ip_address.cpp:1268
const void * addr() const
get the internal address structure.
Definition ip_address.cpp:1259
class used to protect shared data from being simultaneously accessed by multiple threads.
Definition mutex.hpp:37
static Reactor & reactor()
get the global Reactor instance.
Definition reactor.cpp:612
Reactor class.
Definition reactor.hpp:159
int delHandler(int fd, bool sync=true) noexcept
delete handler from reactor.
Definition reactor.cpp:156
int addHandler(int fd, EventHandler *handler, bool wantRead=true, bool wantWrite=false, bool sync=true) noexcept
add handler to reactor.
Definition reactor.cpp:101
class owning a mutex for the duration of a scoped block.
Definition mutex.hpp:249
Definition acceptor.hpp:32
std::unordered_set< std::string > AliasList
list of aliases.
Definition dns_message.hpp:45
Type randomize()
create a random number.
Definition utils.hpp:402
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
std::vector< IpAddress > IpAddressList
List of IP address.
Definition ip_address.hpp:46
Definition error.hpp:144
pending synchronous request.
Definition nameserver.hpp:881
std::error_code ec
Definition nameserver.hpp:884
DnsPacket packet
Definition nameserver.hpp:883
Condition cond
Definition nameserver.hpp:882
DNS packet.
Definition dns_message.hpp:88
uint16_t id
Definition dns_message.hpp:89
uint16_t flags
Definition dns_message.hpp:90
uint16_t port
Definition dns_message.hpp:93
std::vector< QuestionRecord > questions
Definition dns_message.hpp:94
IpAddress src
Definition dns_message.hpp:91
IpAddress dest
Definition dns_message.hpp:92
std::vector< ResourceRecord > answers
Definition dns_message.hpp:95
question record.
Definition dns_message.hpp:57
std::string host
Definition dns_message.hpp:58
uint16_t type
Definition dns_message.hpp:59
uint16_t dnsclass
Definition dns_message.hpp:60
resource record.
Definition dns_message.hpp:67
uint32_t ttl
Definition dns_message.hpp:68
IpAddress address
Definition tcp_acceptor_test.cpp:35