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.
29#include <join/dnsmessage.hpp>
30#include <join/condition.hpp>
31#include <join/reactor.hpp>
32#include <join/socket.hpp>
33
34namespace join
35{
39 template <typename Protocol>
40 class BasicDatagramNameServer : public Protocol::Socket, public EventHandler
41 {
42 public:
43 using Socket = typename Protocol::Socket;
44 using Endpoint = typename Protocol::Endpoint;
45
51 : Socket ()
52 , _reactor (reactor)
53 , _buffer (std::make_unique<char[]> (Protocol::maxMsgSize))
54 {
55 }
56
62
69
75
82
86 virtual ~BasicDatagramNameServer () noexcept = default;
87
93 virtual int bind (const Endpoint& endpoint) noexcept override
94 {
95 if (Socket::bind (endpoint) == -1)
96 {
97 return -1; // LCOV_EXCL_LINE
98 }
99
100 _reactor.addHandler (this->handle (), this);
101
102 return 0;
103 }
104
108 virtual void close () noexcept override
109 {
110 _reactor.delHandler (this->handle ());
111 Socket::close ();
112 }
113
123 int reply (const DnsPacket& query, const std::vector<ResourceRecord>& answers = {},
124 const std::vector<ResourceRecord>& authorities = {},
125 const std::vector<ResourceRecord>& additionals = {}, uint16_t rcode = 0)
126 {
127 DnsPacket packet{};
128 packet.id = query.id;
129 packet.flags = (uint16_t (1) << 15) | (query.flags & 0x7800) | (uint16_t (1) << 10) | (rcode & 0x000F);
130 packet.dest = query.src;
131 packet.port = query.port;
132
133 packet.questions = query.questions;
134 packet.answers = answers;
135 packet.authorities = authorities;
136 packet.additionals = additionals;
137
138 return send (packet);
139 }
140
145 virtual void onQuery (const DnsPacket& packet) = 0;
146
147 protected:
152 virtual void onReadable ([[maybe_unused]] int fd) override
153 {
154 Endpoint from;
155 int size = this->readFrom (_buffer.get (), Protocol::maxMsgSize, &from);
156 if (size >= int (_headerSize))
157 {
158 std::stringstream data;
159 data.rdbuf ()->pubsetbuf (_buffer.get (), size);
160
161 DnsPacket packet;
162 _message.deserialize (packet, data);
163 packet.src = from.ip ();
164 packet.dest = this->localEndpoint ().ip ();
165 packet.port = from.port ();
166
167 if ((packet.flags & 0x8000) == 0)
168 {
169 this->onQuery (packet);
170 }
171 }
172 }
173
179 int send (DnsPacket& packet)
180 {
181 std::stringstream data;
182 if (_message.serialize (packet, data) == -1)
183 {
184 // LCOV_EXCL_START
186 return -1;
187 // LCOV_EXCL_STOP
188 }
189
190 std::string buffer = data.str ();
191 if (buffer.size () > Protocol::maxMsgSize)
192 {
193 // LCOV_EXCL_START
195 return -1;
196 // LCOV_EXCL_STOP
197 }
198
199 if (this->writeTo (buffer.data (), buffer.size (), {packet.dest, packet.port}) == -1)
200 {
201 return -1; // LCOV_EXCL_LINE
202 }
203
204 return 0;
205 };
206
208 static constexpr size_t _headerSize = 12;
209
212
215
217 std::unique_ptr<char[]> _buffer;
218 };
219
223 template <typename Protocol>
225 {
226 public:
229
231 using DnsNotify = std::function<void (const DnsPacket&)>;
232
235
238
244 explicit BasicDatagramPeer (unsigned int ifindex, Reactor& reactor = ReactorThread::reactor ())
245 : BasicDatagramNameServer<Protocol> (reactor)
246#ifdef DEBUG
247 , onSuccess (defaultOnSuccess)
248 , onFailure (defaultOnFailure)
249#else
250 , onSuccess (nullptr)
251 , onFailure (nullptr)
252#endif
253 , _ifindex (ifindex)
254 {
255 }
256
262 explicit BasicDatagramPeer (const std::string& interface, Reactor& reactor = ReactorThread::reactor ())
263 : BasicDatagramPeer<Protocol> (if_nametoindex (interface.c_str ()), reactor)
264 {
265 }
266
271 BasicDatagramPeer (const BasicDatagramPeer& other) = delete;
272
279
285
292
296 virtual ~BasicDatagramPeer () noexcept = default;
297
298 using BasicDatagramNameServer<Protocol>::bind;
299
305 int bind (int family) noexcept
306 {
307 IpAddress maddress = Protocol::multicastAddress (family);
308 Endpoint endpoint{IpAddress (family), Protocol::defaultPort};
309
310 if ((this->_state == Socket::State::Closed) && (this->open (endpoint.protocol ()) == -1))
311 {
312 return -1; // LCOV_EXCL_LINE
313 }
314
315 if (this->setOption (Socket::ReusePort, 1) == -1)
316 {
317 // LCOV_EXCL_START
318 this->close ();
319 return -1;
320 // LCOV_EXCL_STOP
321 }
322
323 if (Socket::bind (endpoint) == -1)
324 {
325 // LCOV_EXCL_START
326 this->close ();
327 return -1;
328 // LCOV_EXCL_STOP
329 }
330
331 if (endpoint.protocol ().family () == AF_INET6)
332 {
333 ipv6_mreq mreq{};
334 ::memcpy (&mreq.ipv6mr_multiaddr, maddress.addr (), maddress.length ());
335 mreq.ipv6mr_interface = _ifindex;
336 if (::setsockopt (this->handle (), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) == -1)
337 {
338 // LCOV_EXCL_START
339 lastError = std::error_code (errno, std::generic_category ());
340 this->close ();
341 return -1;
342 // LCOV_EXCL_STOP
343 }
344 if (::setsockopt (this->handle (), IPPROTO_IPV6, IPV6_MULTICAST_IF, &_ifindex, sizeof (_ifindex)) == -1)
345 {
346 // LCOV_EXCL_START
347 lastError = std::error_code (errno, std::generic_category ());
348 this->close ();
349 return -1;
350 // LCOV_EXCL_STOP
351 }
352 }
353 else
354 {
355 // LCOV_EXCL_START: IPv4 multicast not supported by github action containers.
356 ip_mreqn mreq{};
357 ::memcpy (&mreq.imr_multiaddr, maddress.addr (), maddress.length ());
358 mreq.imr_ifindex = static_cast<int> (_ifindex);
359 if (::setsockopt (this->handle (), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) == -1)
360 {
361 lastError = std::error_code (errno, std::generic_category ());
362 this->close ();
363 return -1;
364 }
365 if (::setsockopt (this->handle (), IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof (mreq)) == -1)
366 {
367 lastError = std::error_code (errno, std::generic_category ());
368 this->close ();
369 return -1;
370 }
371 // LCOV_EXCL_STOP
372 }
373
374#ifndef DEBUG
375 if (this->setOption (Socket::MulticastLoop, 0) == -1)
376 {
377 // LCOV_EXCL_START
378 this->close ();
379 return -1;
380 // LCOV_EXCL_STOP
381 }
382#endif
383
384 this->_reactor.addHandler (this->handle (), this);
385
386 return 0;
387 }
388
394 int probe (const std::vector<ResourceRecord>& records)
395 {
396 if (records.empty ())
397 {
399 return -1;
400 }
401
402 DnsPacket packet{};
403 packet.id = 0;
404 packet.flags = 0;
405 IpAddress mcast = Protocol::multicastAddress (this->family ());
406 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
407 packet.port = Protocol::defaultPort;
408
409 for (auto const& record : records)
410 {
411 QuestionRecord question;
412 question.host = record.host;
414 question.dnsclass = DnsMessage::RecordClass::IN | 0x8000;
415 packet.questions.push_back (question);
416
417 packet.authorities.push_back (record);
418 }
419
420 return this->send (packet);
421 }
422
428 int announce (const std::vector<ResourceRecord>& records)
429 {
430 if (records.empty ())
431 {
433 return -1;
434 }
435
436 DnsPacket packet{};
437 packet.id = 0;
438 packet.flags = (uint16_t (1) << 15) | (uint16_t (1) << 10);
439 IpAddress mcast = Protocol::multicastAddress (this->family ());
440 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
441 packet.port = Protocol::defaultPort;
442
443 for (auto const& record : records)
444 {
445 packet.answers.push_back (record);
446 }
447
448 return this->send (packet);
449 }
450
456 int goodbye (const std::vector<ResourceRecord>& records)
457 {
458 if (records.empty ())
459 {
461 return -1;
462 }
463
464 DnsPacket packet{};
465 packet.id = 0;
466 packet.flags = (uint16_t (1) << 15) | (uint16_t (1) << 10);
467 IpAddress mcast = Protocol::multicastAddress (this->family ());
468 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
469 packet.port = Protocol::defaultPort;
470
471 for (auto const& record : records)
472 {
473 ResourceRecord goodbye = record;
474 goodbye.ttl = 0;
475 packet.answers.push_back (goodbye);
476 }
477
478 return this->send (packet);
479 }
480
486 int browse (const std::string& serviceType)
487 {
488 if (serviceType.empty ())
489 {
491 return -1;
492 }
493
494 DnsPacket packet{};
495 packet.id = 0;
496 packet.flags = 0;
497 IpAddress mcast = Protocol::multicastAddress (this->family ());
498 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
499 packet.port = Protocol::defaultPort;
500
501 QuestionRecord question;
502 question.host = serviceType;
505 packet.questions.push_back (question);
506
507 return this->send (packet);
508 }
509
517 IpAddressList resolveAllAddress (const std::string& host, int family,
518 std::chrono::milliseconds timeout = std::chrono::seconds (5))
519 {
520 if (host.empty ())
521 {
522 return {};
523 }
524
525 DnsPacket packet{};
526 packet.id = join::randomize<uint16_t> ();
527 packet.flags = 1 << 8;
528
529 QuestionRecord question;
530 question.host = host;
531 question.type = (family == AF_INET6) ? DnsMessage::RecordType::AAAA : DnsMessage::RecordType::A;
533 packet.questions.push_back (question);
534
535 if (query (packet, timeout) == -1)
536 {
537 return {};
538 }
539
540 IpAddressList addresses;
541
542 for (auto const& answer : packet.answers)
543 {
544 if (!answer.addr.isWildcard () && (answer.type == question.type))
545 {
546 addresses.push_back (answer.addr);
547 }
548 }
549
550 return addresses;
551 }
552
559 IpAddressList resolveAllAddress (const std::string& host,
560 std::chrono::milliseconds timeout = std::chrono::seconds (5))
561 {
562 IpAddressList addresses;
563
564 for (auto const& family : {AF_INET, AF_INET6})
565 {
566 IpAddressList tmp = resolveAllAddress (host, family, timeout);
567 addresses.insert (addresses.end (), tmp.begin (), tmp.end ());
568 }
569
570 return addresses;
571 }
572
580 IpAddress resolveAddress (const std::string& host, int family,
581 std::chrono::milliseconds timeout = std::chrono::seconds (5))
582 {
583 for (auto const& address : resolveAllAddress (host, family, timeout))
584 {
585 return address;
586 }
587
588 return IpAddress (family);
589 }
590
597 IpAddress resolveAddress (const std::string& host, std::chrono::milliseconds timeout = std::chrono::seconds (5))
598 {
599 for (auto const& address : resolveAllAddress (host, timeout))
600 {
601 return address;
602 }
603
604 return {};
605 }
606
614 std::chrono::milliseconds timeout = std::chrono::seconds (5))
615 {
616 if (address.isWildcard ())
617 {
618 return {};
619 }
620
621 DnsPacket packet{};
622 packet.id = join::randomize<uint16_t> ();
623 packet.flags = 1 << 8;
624
625 QuestionRecord question;
626 question.host = address.toArpa ();
629 packet.questions.push_back (question);
630
631 if (query (packet, timeout) == -1)
632 {
633 return {};
634 }
635
636 AliasList aliases;
637
638 for (auto const& answer : packet.answers)
639 {
640 if (!answer.name.empty () && (answer.type == DnsMessage::RecordType::PTR))
641 {
642 aliases.insert (answer.name);
643 }
644 }
645
646 return aliases;
647 }
648
655 std::string resolveName (const IpAddress& address, std::chrono::milliseconds timeout = std::chrono::seconds (5))
656 {
657 for (auto const& alias : resolveAllName (address, timeout))
658 {
659 return alias;
660 }
661
662 return {};
663 }
664
669 virtual void onAnnouncement (const DnsPacket& packet) = 0;
670
671 protected:
676 void onReadable ([[maybe_unused]] int fd) override final
677 {
678 Endpoint from;
679 int size = this->readFrom (this->_buffer.get (), Protocol::maxMsgSize, &from);
680 if (size >= int (this->_headerSize))
681 {
682 std::stringstream data;
683 data.rdbuf ()->pubsetbuf (this->_buffer.get (), size);
684
685 DnsPacket packet;
686 this->_message.deserialize (packet, data);
687 IpAddress mcast = Protocol::multicastAddress (this->family ());
688 packet.src = from.ip ();
689 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
690 packet.port = from.port ();
691
692 if ((packet.flags & 0x8000) == 0)
693 {
694 bool unicast = false;
695 for (auto const& q : packet.questions)
696 {
697 if (q.dnsclass & 0x8000)
698 {
699 unicast = true;
700 break;
701 }
702 }
703
704 if (!unicast)
705 {
706 packet.src = IpAddress (mcast.addr (), mcast.length (), _ifindex);
707 }
708
709 this->onQuery (packet);
710 return;
711 }
712
713 {
715
716 auto it = _pending.find (packet.id);
717 if (it != _pending.end ())
718 {
719 it->second->packet = packet;
720 it->second->ec = DnsMessage::decodeError (packet.flags & 0x000F);
721 it->second->cond.signal ();
722 return;
723 }
724 }
725
726 onAnnouncement (packet);
727 }
728 }
729
730#ifdef DEBUG
731 /*
732 * @brief default callback called when a lookup sequence succeed.
733 * @param packet DNS packet.
734 */
735 static void defaultOnSuccess (const DnsPacket& packet)
736 {
737 std::cout << std::endl;
738 std::cout << "PEER: " << packet.dest << "#" << packet.port << std::endl;
739
740 std::cout << std::endl;
741 std::cout << ";; QUESTION SECTION: " << std::endl;
742 for (auto const& question : packet.questions)
743 {
744 std::cout << question.host;
745 std::cout << " " << DnsMessage::typeName (question.type);
746 std::cout << " " << DnsMessage::className (question.dnsclass);
747 std::cout << std::endl;
748 }
749
750 std::cout << std::endl;
751 std::cout << ";; ANSWER SECTION: " << std::endl;
752 for (auto const& answer : packet.answers)
753 {
754 std::cout << answer.host;
755 std::cout << " " << DnsMessage::typeName (answer.type);
756 std::cout << " " << DnsMessage::className (answer.dnsclass);
757 std::cout << " " << answer.ttl;
758 if (answer.type == DnsMessage::RecordType::A)
759 {
760 std::cout << " " << answer.addr;
761 }
762 else if (answer.type == DnsMessage::RecordType::PTR)
763 {
764 std::cout << " " << answer.name;
765 }
766 else if (answer.type == DnsMessage::RecordType::AAAA)
767 {
768 std::cout << " " << answer.addr;
769 }
770 std::cout << std::endl;
771 }
772 }
773
774 /*
775 * @brief default callback called when a lookup sequence failed.
776 * @param packet DNS packet.
777 */
778 static void defaultOnFailure (const DnsPacket& packet)
779 {
780 std::cout << std::endl;
781 std::cout << "PEER: " << packet.dest << "#" << packet.port << std::endl;
782
783 std::cout << std::endl;
784 std::cout << ";; QUESTION SECTION: " << std::endl;
785 for (auto const& question : packet.questions)
786 {
787 std::cout << question.host;
788 std::cout << " " << DnsMessage::typeName (question.type);
789 std::cout << " " << DnsMessage::className (question.dnsclass);
790 std::cout << std::endl;
791 }
792
793 std::cout << std::endl;
794 std::cout << lastError.message () << std::endl;
795 }
796#endif
797
803 void notify (const DnsNotify& func, const DnsPacket& packet) const noexcept
804 {
805 if (func)
806 {
807 func (packet);
808 }
809 }
810
817 int query (DnsPacket& packet, std::chrono::milliseconds timeout)
818 {
819 IpAddress mcast = Protocol::multicastAddress (this->family ());
820 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
821 packet.port = Protocol::defaultPort;
822
823 std::stringstream data;
824 if (this->_message.serialize (packet, data) == -1)
825 {
826 // LCOV_EXCL_START
828 return -1;
829 // LCOV_EXCL_STOP
830 }
831
832 std::string buffer = data.str ();
833 if (buffer.size () > Protocol::maxMsgSize)
834 {
835 // LCOV_EXCL_START
837 return -1;
838 // LCOV_EXCL_STOP
839 }
840
842
843 auto inserted = _pending.emplace (packet.id, std::make_unique<PendingRequest> ());
844 if (!inserted.second)
845 {
846 // LCOV_EXCL_START
848 notify (onFailure, packet);
849 return -1;
850 // LCOV_EXCL_STOP
851 }
852
853 if (this->writeTo (buffer.data (), buffer.size (), {packet.dest, packet.port}) == -1)
854 {
855 // LCOV_EXCL_START
856 _pending.erase (inserted.first);
857 notify (onFailure, packet);
858 return -1;
859 // LCOV_EXCL_STOP
860 }
861
862 if (!inserted.first->second->cond.timedWait (lock, timeout))
863 {
864 // LCOV_EXCL_START
865 _pending.erase (inserted.first);
866 lastError = make_error_code (Errc::TimedOut);
867 notify (onFailure, packet);
868 return -1;
869 // LCOV_EXCL_STOP
870 }
871
872 auto pendingReq = std::move (inserted.first->second);
873 _pending.erase (inserted.first);
874
875 if (pendingReq->ec)
876 {
877 // LCOV_EXCL_START
878 lastError = pendingReq->ec;
879 notify (onFailure, packet);
880 return -1;
881 // LCOV_EXCL_STOP
882 }
883
884 packet = std::move (pendingReq->packet);
885 notify (onSuccess, packet);
886
887 return 0;
888 }
889
891 unsigned int _ifindex;
892
895 {
898 std::error_code ec;
899 };
900
902 std::unordered_map<uint16_t, std::unique_ptr<PendingRequest>> _pending;
903
906 };
907}
908
909#endif
basic DNS name server over datagram socket.
Definition nameserver.hpp:41
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:123
typename Protocol::Socket Socket
Definition nameserver.hpp:43
BasicDatagramNameServer(Reactor &reactor=ReactorThread::reactor())
construct the name server instance.
Definition nameserver.hpp:50
DnsMessage _message
DNS message codec.
Definition nameserver.hpp:211
virtual void close() noexcept override
close the socket and unregister from the reactor.
Definition nameserver.hpp:108
BasicDatagramNameServer(const BasicDatagramNameServer &other)=delete
copy constructor.
std::unique_ptr< char[]> _buffer
reception buffer.
Definition nameserver.hpp:217
virtual int bind(const Endpoint &endpoint) noexcept override
bind the socket to the given endpoint and register with the reactor.
Definition nameserver.hpp:93
Reactor & _reactor
event loop reactor.
Definition nameserver.hpp:214
virtual ~BasicDatagramNameServer() noexcept=default
destroy instance.
virtual void onQuery(const DnsPacket &packet)=0
method called when a DNS query is received.
virtual void onReadable(int fd) override
method called when data are ready to be read on handle.
Definition nameserver.hpp:152
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:179
static constexpr size_t _headerSize
DNS message header size.
Definition nameserver.hpp:208
typename Protocol::Endpoint Endpoint
Definition nameserver.hpp:44
mDNS peer.
Definition nameserver.hpp:225
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:517
int probe(const std::vector< ResourceRecord > &records)
probe the local network for the presence of a service.
Definition nameserver.hpp:394
typename BasicDatagramNameServer< Protocol >::Socket Socket
Definition nameserver.hpp:227
virtual ~BasicDatagramPeer() noexcept=default
destroy instance.
BasicDatagramPeer(unsigned int ifindex, Reactor &reactor=ReactorThread::reactor())
construct the mDNS peer instance.
Definition nameserver.hpp:244
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:597
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:486
typename BasicDatagramNameServer< Protocol >::Endpoint Endpoint
Definition nameserver.hpp:228
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:580
void onReadable(int fd) override final
method called when data are ready to be read on handle.
Definition nameserver.hpp:676
AliasList resolveAllName(const IpAddress &address, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve all host address.
Definition nameserver.hpp:613
int query(DnsPacket &packet, std::chrono::milliseconds timeout)
serialize and send a DNS query, waiting for a response.
Definition nameserver.hpp:817
std::unordered_map< uint16_t, std::unique_ptr< PendingRequest > > _pending
synchronous requests indexed by sequence number.
Definition nameserver.hpp:902
std::string resolveName(const IpAddress &address, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host address.
Definition nameserver.hpp:655
DnsNotify onFailure
callback called when a lookup sequence failed.
Definition nameserver.hpp:237
DnsNotify onSuccess
callback called when a lookup sequence succeed.
Definition nameserver.hpp:234
void notify(const DnsNotify &func, const DnsPacket &packet) const noexcept
safe way to notify DNS events.
Definition nameserver.hpp:803
int goodbye(const std::vector< ResourceRecord > &records)
send a goodbye message.
Definition nameserver.hpp:456
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:262
int announce(const std::vector< ResourceRecord > &records)
announce the presence of a service on the local network.
Definition nameserver.hpp:428
int bind(int family) noexcept
bind the socket to specified address family.
Definition nameserver.hpp:305
std::function< void(const DnsPacket &)> DnsNotify
DNS notification callback type.
Definition nameserver.hpp:231
Mutex _syncMutex
protection mutex.
Definition nameserver.hpp:905
unsigned int _ifindex
interface index.
Definition nameserver.hpp:891
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:559
condition variable class.
Definition condition.hpp:42
DNS message codec.
Definition dnsmessage.hpp:105
int serialize(const DnsPacket &packet, std::stringstream &data) const
serialize a DNS packet into a byte stream.
Definition dnsmessage.hpp:174
static std::string className(uint16_t recordClass)
get record class name.
Definition dnsmessage.hpp:360
@ A
Definition dnsmessage.hpp:112
@ PTR
Definition dnsmessage.hpp:116
@ ANY
Definition dnsmessage.hpp:121
@ AAAA
Definition dnsmessage.hpp:119
int deserialize(DnsPacket &packet, std::stringstream &data) const
deserialize a DNS packet from a byte stream.
Definition dnsmessage.hpp:235
static std::error_code decodeError(uint16_t error) noexcept
convert DNS error to system error code.
Definition dnsmessage.hpp:311
@ IN
Definition dnsmessage.hpp:129
static std::string typeName(uint16_t recordType)
get record type name.
Definition dnsmessage.hpp:336
Event handler interface class.
Definition reactor.hpp:46
IPv6, IPv4 address class.
Definition ipaddress.hpp:51
socklen_t length() const
get the size in byte of the internal address structure.
Definition ipaddress.cpp:1268
const void * addr() const
get the internal address structure.
Definition ipaddress.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:514
Reactor class.
Definition reactor.hpp:129
int delHandler(int fd, bool sync=true) noexcept
delete handler from reactor.
Definition reactor.cpp:155
int addHandler(int fd, EventHandler *handler, bool wantRead=true, bool wantWrite=false, bool sync=true) noexcept
add handler to reactor.
Definition reactor.cpp:100
class owning a mutex for the duration of a scoped block.
Definition mutex.hpp:246
Definition acceptor.hpp:32
std::enable_if_t< std::numeric_limits< Type >::is_integer, Type > randomize()
create a random number.
Definition utils.hpp:403
std::unordered_set< std::string > AliasList
list of aliases.
Definition dnsmessage.hpp:46
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:150
std::vector< IpAddress > IpAddressList
List of IP address.
Definition ipaddress.hpp:45
Definition error.hpp:137
pending synchronous request.
Definition nameserver.hpp:895
std::error_code ec
Definition nameserver.hpp:898
DnsPacket packet
Definition nameserver.hpp:897
Condition cond
Definition nameserver.hpp:896
DNS packet.
Definition dnsmessage.hpp:89
uint16_t id
Definition dnsmessage.hpp:90
uint16_t flags
Definition dnsmessage.hpp:91
uint16_t port
Definition dnsmessage.hpp:94
std::vector< QuestionRecord > questions
Definition dnsmessage.hpp:95
IpAddress src
Definition dnsmessage.hpp:92
IpAddress dest
Definition dnsmessage.hpp:93
std::vector< ResourceRecord > answers
Definition dnsmessage.hpp:96
question record.
Definition dnsmessage.hpp:58
std::string host
Definition dnsmessage.hpp:59
uint16_t type
Definition dnsmessage.hpp:60
uint16_t dnsclass
Definition dnsmessage.hpp:61
resource record.
Definition dnsmessage.hpp:68
uint32_t ttl
Definition dnsmessage.hpp:69
IpAddress address
Definition tcpacceptor_test.cpp:35