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 std::stringstream data;
160 data.rdbuf ()->pubsetbuf (_buffer.get (), size);
161
162 DnsPacket packet;
163 _message.deserialize (packet, data);
164 packet.src = from.ip ();
165 packet.dest = _socket.localEndpoint ().ip ();
166 packet.port = from.port ();
167
168 if ((packet.flags & 0x8000) == 0)
169 {
170 this->onQuery (packet);
171 }
172 }
173 }
174
180 int send (DnsPacket& packet)
181 {
182 std::stringstream data;
183 if (_message.serialize (packet, data) == -1)
184 {
185 // LCOV_EXCL_START
187 return -1;
188 // LCOV_EXCL_STOP
189 }
190
191 std::string buffer = data.str ();
192 if (buffer.size () > Protocol::maxMsgSize)
193 {
194 // LCOV_EXCL_START
196 return -1;
197 // LCOV_EXCL_STOP
198 }
199
200 if (_socket.writeTo (buffer.data (), buffer.size (), {packet.dest, packet.port}) == -1)
201 {
202 return -1; // LCOV_EXCL_LINE
203 }
204
205 return 0;
206 };
207
209 static constexpr size_t _headerSize = 12;
210
213
216
219
221 std::unique_ptr<char[]> _buffer;
222 };
223
227 template <typename Protocol>
229 {
230 public:
233
235 using DnsNotify = std::function<void (const DnsPacket&)>;
236
239
242
248 explicit BasicDatagramPeer (unsigned int ifindex, Reactor& reactor = ReactorThread::reactor ())
249 : BasicDatagramNameServer<Protocol> (reactor)
250#ifdef DEBUG
251 , onSuccess (defaultOnSuccess)
252 , onFailure (defaultOnFailure)
253#else
254 , onSuccess (nullptr)
255 , onFailure (nullptr)
256#endif
257 , _ifindex (ifindex)
258 {
259 }
260
266 explicit BasicDatagramPeer (const std::string& interface, Reactor& reactor = ReactorThread::reactor ())
267 : BasicDatagramPeer<Protocol> (if_nametoindex (interface.c_str ()), reactor)
268 {
269 }
270
275 BasicDatagramPeer (const BasicDatagramPeer& other) = delete;
276
283
289
296
300 virtual ~BasicDatagramPeer () noexcept = default;
301
302 using BasicDatagramNameServer<Protocol>::bind;
303
309 int bind (int family) noexcept
310 {
311 IpAddress maddress = Protocol::multicastAddress (family);
312 Endpoint endpoint{IpAddress (family), Protocol::defaultPort};
313
314 if ((this->_socket.opened () == false) && (this->_socket.open (endpoint.protocol ()) == -1))
315 {
316 return -1; // LCOV_EXCL_LINE
317 }
318
319 if (this->_socket.setOption (Socket::ReusePort, 1) == -1)
320 {
321 // LCOV_EXCL_START
322 this->close ();
323 return -1;
324 // LCOV_EXCL_STOP
325 }
326
327 if (this->_socket.bind (endpoint) == -1)
328 {
329 // LCOV_EXCL_START
330 this->close ();
331 return -1;
332 // LCOV_EXCL_STOP
333 }
334
335 if (endpoint.protocol ().family () == AF_INET6)
336 {
337 ipv6_mreq mreq{};
338 ::memcpy (&mreq.ipv6mr_multiaddr, maddress.addr (), maddress.length ());
339 mreq.ipv6mr_interface = _ifindex;
340 if (::setsockopt (this->_socket.handle (), IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) ==
341 -1)
342 {
343 // LCOV_EXCL_START
344 lastError = std::error_code (errno, std::generic_category ());
345 this->close ();
346 return -1;
347 // LCOV_EXCL_STOP
348 }
349 if (::setsockopt (this->_socket.handle (), IPPROTO_IPV6, IPV6_MULTICAST_IF, &_ifindex,
350 sizeof (_ifindex)) == -1)
351 {
352 // LCOV_EXCL_START
353 lastError = std::error_code (errno, std::generic_category ());
354 this->close ();
355 return -1;
356 // LCOV_EXCL_STOP
357 }
358 }
359 else
360 {
361 // LCOV_EXCL_START: IPv4 multicast not supported by github action containers.
362 ip_mreqn mreq{};
363 ::memcpy (&mreq.imr_multiaddr, maddress.addr (), maddress.length ());
364 mreq.imr_ifindex = static_cast<int> (_ifindex);
365 if (::setsockopt (this->_socket.handle (), IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof (mreq)) == -1)
366 {
367 lastError = std::error_code (errno, std::generic_category ());
368 this->close ();
369 return -1;
370 }
371 if (::setsockopt (this->_socket.handle (), IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof (mreq)) == -1)
372 {
373 lastError = std::error_code (errno, std::generic_category ());
374 this->close ();
375 return -1;
376 }
377 // LCOV_EXCL_STOP
378 }
379
380#ifndef DEBUG
381 if (this->_socket.setOption (Socket::MulticastLoop, 0) == -1)
382 {
383 // LCOV_EXCL_START
384 this->close ();
385 return -1;
386 // LCOV_EXCL_STOP
387 }
388#endif
389
390 this->_reactor.addHandler (this->_socket.handle (), this);
391
392 return 0;
393 }
394
400 int probe (const std::vector<ResourceRecord>& records)
401 {
402 if (records.empty ())
403 {
405 return -1;
406 }
407
408 DnsPacket packet{};
409 packet.id = 0;
410 packet.flags = 0;
411 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
412 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
413 packet.port = Protocol::defaultPort;
414
415 for (auto const& record : records)
416 {
417 QuestionRecord question;
418 question.host = record.host;
420 question.dnsclass = DnsMessage::RecordClass::IN | 0x8000;
421 packet.questions.push_back (question);
422
423 packet.authorities.push_back (record);
424 }
425
426 return this->send (packet);
427 }
428
434 int announce (const std::vector<ResourceRecord>& records)
435 {
436 if (records.empty ())
437 {
439 return -1;
440 }
441
442 DnsPacket packet{};
443 packet.id = 0;
444 packet.flags = (uint16_t (1) << 15) | (uint16_t (1) << 10);
445 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
446 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
447 packet.port = Protocol::defaultPort;
448
449 for (auto const& record : records)
450 {
451 packet.answers.push_back (record);
452 }
453
454 return this->send (packet);
455 }
456
462 int goodbye (const std::vector<ResourceRecord>& records)
463 {
464 if (records.empty ())
465 {
467 return -1;
468 }
469
470 DnsPacket packet{};
471 packet.id = 0;
472 packet.flags = (uint16_t (1) << 15) | (uint16_t (1) << 10);
473 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
474 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
475 packet.port = Protocol::defaultPort;
476
477 for (auto const& record : records)
478 {
479 ResourceRecord goodbye = record;
480 goodbye.ttl = 0;
481 packet.answers.push_back (goodbye);
482 }
483
484 return this->send (packet);
485 }
486
492 int browse (const std::string& serviceType)
493 {
494 if (serviceType.empty ())
495 {
497 return -1;
498 }
499
500 DnsPacket packet{};
501 packet.id = 0;
502 packet.flags = 0;
503 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
504 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
505 packet.port = Protocol::defaultPort;
506
507 QuestionRecord question;
508 question.host = serviceType;
511 packet.questions.push_back (question);
512
513 return this->send (packet);
514 }
515
523 IpAddressList resolveAllAddress (const std::string& host, int family,
524 std::chrono::milliseconds timeout = std::chrono::seconds (5))
525 {
526 if (host.empty ())
527 {
528 return {};
529 }
530
531 DnsPacket packet{};
532 packet.id = join::randomize<uint16_t> ();
533 packet.flags = 1 << 8;
534
535 QuestionRecord question;
536 question.host = host;
537 question.type = (family == AF_INET6) ? DnsMessage::RecordType::AAAA : DnsMessage::RecordType::A;
539 packet.questions.push_back (question);
540
541 if (query (packet, timeout) == -1)
542 {
543 return {};
544 }
545
546 IpAddressList addresses;
547
548 for (auto const& answer : packet.answers)
549 {
550 if (!answer.addr.isWildcard () && (answer.type == question.type))
551 {
552 addresses.push_back (answer.addr);
553 }
554 }
555
556 return addresses;
557 }
558
565 IpAddressList resolveAllAddress (const std::string& host,
566 std::chrono::milliseconds timeout = std::chrono::seconds (5))
567 {
568 IpAddressList addresses;
569
570 for (auto const& family : {AF_INET, AF_INET6})
571 {
572 IpAddressList tmp = resolveAllAddress (host, family, timeout);
573 addresses.insert (addresses.end (), tmp.begin (), tmp.end ());
574 }
575
576 return addresses;
577 }
578
586 IpAddress resolveAddress (const std::string& host, int family,
587 std::chrono::milliseconds timeout = std::chrono::seconds (5))
588 {
589 for (auto const& address : resolveAllAddress (host, family, timeout))
590 {
591 return address;
592 }
593
594 return IpAddress (family);
595 }
596
603 IpAddress resolveAddress (const std::string& host, std::chrono::milliseconds timeout = std::chrono::seconds (5))
604 {
605 for (auto const& address : resolveAllAddress (host, timeout))
606 {
607 return address;
608 }
609
610 return {};
611 }
612
620 std::chrono::milliseconds timeout = std::chrono::seconds (5))
621 {
622 if (address.isWildcard ())
623 {
624 return {};
625 }
626
627 DnsPacket packet{};
628 packet.id = join::randomize<uint16_t> ();
629 packet.flags = 1 << 8;
630
631 QuestionRecord question;
632 question.host = address.toArpa ();
635 packet.questions.push_back (question);
636
637 if (query (packet, timeout) == -1)
638 {
639 return {};
640 }
641
642 AliasList aliases;
643
644 for (auto const& answer : packet.answers)
645 {
646 if (!answer.name.empty () && (answer.type == DnsMessage::RecordType::PTR))
647 {
648 aliases.insert (answer.name);
649 }
650 }
651
652 return aliases;
653 }
654
661 std::string resolveName (const IpAddress& address, std::chrono::milliseconds timeout = std::chrono::seconds (5))
662 {
663 for (auto const& alias : resolveAllName (address, timeout))
664 {
665 return alias;
666 }
667
668 return {};
669 }
670
675 virtual void onAnnouncement (const DnsPacket& packet) = 0;
676
677 protected:
682 void onReadable ([[maybe_unused]] int fd) override final
683 {
684 Endpoint from;
685 ssize_t size = this->_socket.readFrom (this->_buffer.get (), Protocol::maxMsgSize, &from);
686 if (size >= int (this->_headerSize))
687 {
688 std::stringstream data;
689 data.rdbuf ()->pubsetbuf (this->_buffer.get (), size);
690
691 DnsPacket packet;
692 this->_message.deserialize (packet, data);
693 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
694 packet.src = from.ip ();
695 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
696 packet.port = from.port ();
697
698 if ((packet.flags & 0x8000) == 0)
699 {
700 bool unicast = false;
701 for (auto const& q : packet.questions)
702 {
703 if (q.dnsclass & 0x8000)
704 {
705 unicast = true;
706 break;
707 }
708 }
709
710 if (!unicast)
711 {
712 packet.src = IpAddress (mcast.addr (), mcast.length (), _ifindex);
713 }
714
715 this->onQuery (packet);
716 return;
717 }
718
719 {
721
722 auto it = _pending.find (packet.id);
723 if (it != _pending.end ())
724 {
725 it->second->packet = packet;
726 it->second->ec = DnsMessage::decodeError (packet.flags & 0x000F);
727 it->second->cond.signal ();
728 return;
729 }
730 }
731
732 onAnnouncement (packet);
733 }
734 }
735
736#ifdef DEBUG
737 /*
738 * @brief default callback called when a lookup sequence succeed.
739 * @param packet DNS packet.
740 */
741 static void defaultOnSuccess (const DnsPacket& packet)
742 {
743 std::cout << std::endl;
744 std::cout << "PEER: " << packet.dest << "#" << packet.port << std::endl;
745
746 std::cout << std::endl;
747 std::cout << ";; QUESTION SECTION: " << std::endl;
748 for (auto const& question : packet.questions)
749 {
750 std::cout << question.host;
751 std::cout << " " << DnsMessage::typeName (question.type);
752 std::cout << " " << DnsMessage::className (question.dnsclass);
753 std::cout << std::endl;
754 }
755
756 std::cout << std::endl;
757 std::cout << ";; ANSWER SECTION: " << std::endl;
758 for (auto const& answer : packet.answers)
759 {
760 std::cout << answer.host;
761 std::cout << " " << DnsMessage::typeName (answer.type);
762 std::cout << " " << DnsMessage::className (answer.dnsclass);
763 std::cout << " " << answer.ttl;
764 if (answer.type == DnsMessage::RecordType::A)
765 {
766 std::cout << " " << answer.addr;
767 }
768 else if (answer.type == DnsMessage::RecordType::PTR)
769 {
770 std::cout << " " << answer.name;
771 }
772 else if (answer.type == DnsMessage::RecordType::AAAA)
773 {
774 std::cout << " " << answer.addr;
775 }
776 std::cout << std::endl;
777 }
778 }
779
780 /*
781 * @brief default callback called when a lookup sequence failed.
782 * @param packet DNS packet.
783 */
784 static void defaultOnFailure (const DnsPacket& packet)
785 {
786 std::cout << std::endl;
787 std::cout << "PEER: " << packet.dest << "#" << packet.port << std::endl;
788
789 std::cout << std::endl;
790 std::cout << ";; QUESTION SECTION: " << std::endl;
791 for (auto const& question : packet.questions)
792 {
793 std::cout << question.host;
794 std::cout << " " << DnsMessage::typeName (question.type);
795 std::cout << " " << DnsMessage::className (question.dnsclass);
796 std::cout << std::endl;
797 }
798
799 std::cout << std::endl;
800 std::cout << lastError.message () << std::endl;
801 }
802#endif
803
809 void notify (const DnsNotify& func, const DnsPacket& packet) const noexcept
810 {
811 if (func)
812 {
813 func (packet);
814 }
815 }
816
823 int query (DnsPacket& packet, std::chrono::milliseconds timeout)
824 {
825 IpAddress mcast = Protocol::multicastAddress (this->_socket.family ());
826 packet.dest = IpAddress (mcast.addr (), mcast.length (), _ifindex);
827 packet.port = Protocol::defaultPort;
828
829 std::stringstream data;
830 if (this->_message.serialize (packet, data) == -1)
831 {
832 // LCOV_EXCL_START
834 return -1;
835 // LCOV_EXCL_STOP
836 }
837
838 std::string buffer = data.str ();
839 if (buffer.size () > Protocol::maxMsgSize)
840 {
841 // LCOV_EXCL_START
843 return -1;
844 // LCOV_EXCL_STOP
845 }
846
848
849 auto inserted = _pending.emplace (packet.id, std::make_unique<PendingRequest> ());
850 if (!inserted.second)
851 {
852 // LCOV_EXCL_START
854 notify (onFailure, packet);
855 return -1;
856 // LCOV_EXCL_STOP
857 }
858
859 if (this->_socket.writeTo (buffer.data (), buffer.size (), {packet.dest, packet.port}) == -1)
860 {
861 // LCOV_EXCL_START
862 _pending.erase (inserted.first);
863 notify (onFailure, packet);
864 return -1;
865 // LCOV_EXCL_STOP
866 }
867
868 if (!inserted.first->second->cond.timedWait (lock, timeout))
869 {
870 // LCOV_EXCL_START
871 _pending.erase (inserted.first);
872 lastError = make_error_code (Errc::TimedOut);
873 notify (onFailure, packet);
874 return -1;
875 // LCOV_EXCL_STOP
876 }
877
878 auto pendingReq = std::move (inserted.first->second);
879 _pending.erase (inserted.first);
880
881 if (pendingReq->ec)
882 {
883 // LCOV_EXCL_START
884 lastError = pendingReq->ec;
885 notify (onFailure, packet);
886 return -1;
887 // LCOV_EXCL_STOP
888 }
889
890 packet = std::move (pendingReq->packet);
891 notify (onSuccess, packet);
892
893 return 0;
894 }
895
897 unsigned int _ifindex;
898
901 {
904 std::error_code ec;
905 };
906
908 std::unordered_map<uint16_t, std::unique_ptr<PendingRequest>> _pending;
909
912 };
913}
914
915#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:212
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:221
Reactor & _reactor
event loop reactor.
Definition nameserver.hpp:218
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:215
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:180
static constexpr size_t _headerSize
DNS message header size.
Definition nameserver.hpp:209
typename Protocol::Endpoint Endpoint
Definition nameserver.hpp:46
mDNS peer.
Definition nameserver.hpp:229
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:523
int probe(const std::vector< ResourceRecord > &records)
probe the local network for the presence of a service.
Definition nameserver.hpp:400
typename BasicDatagramNameServer< Protocol >::Socket Socket
Definition nameserver.hpp:231
virtual ~BasicDatagramPeer() noexcept=default
destroy instance.
BasicDatagramPeer(unsigned int ifindex, Reactor &reactor=ReactorThread::reactor())
construct the mDNS peer instance.
Definition nameserver.hpp:248
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:603
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:492
typename BasicDatagramNameServer< Protocol >::Endpoint Endpoint
Definition nameserver.hpp:232
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:586
void onReadable(int fd) override final
method called when data are ready to be read on handle.
Definition nameserver.hpp:682
AliasList resolveAllName(const IpAddress &address, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve all host address.
Definition nameserver.hpp:619
int query(DnsPacket &packet, std::chrono::milliseconds timeout)
serialize and send a DNS query, waiting for a response.
Definition nameserver.hpp:823
std::unordered_map< uint16_t, std::unique_ptr< PendingRequest > > _pending
synchronous requests indexed by sequence number.
Definition nameserver.hpp:908
std::string resolveName(const IpAddress &address, std::chrono::milliseconds timeout=std::chrono::seconds(5))
resolve host address.
Definition nameserver.hpp:661
DnsNotify onFailure
callback called when a lookup sequence failed.
Definition nameserver.hpp:241
DnsNotify onSuccess
callback called when a lookup sequence succeed.
Definition nameserver.hpp:238
void notify(const DnsNotify &func, const DnsPacket &packet) const noexcept
safe way to notify DNS events.
Definition nameserver.hpp:809
int goodbye(const std::vector< ResourceRecord > &records)
send a goodbye message.
Definition nameserver.hpp:462
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:266
int announce(const std::vector< ResourceRecord > &records)
announce the presence of a service on the local network.
Definition nameserver.hpp:434
int bind(int family) noexcept
bind the socket to specified address family.
Definition nameserver.hpp:309
std::function< void(const DnsPacket &)> DnsNotify
DNS notification callback type.
Definition nameserver.hpp:235
Mutex _syncMutex
protection mutex.
Definition nameserver.hpp:911
unsigned int _ifindex
interface index.
Definition nameserver.hpp:897
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:565
condition variable class.
Definition condition.hpp:42
DNS message codec.
Definition dns_message.hpp:105
int serialize(const DnsPacket &packet, std::stringstream &data) const
serialize a DNS packet into a byte stream.
Definition dns_message.hpp:174
static std::string className(uint16_t recordClass)
get record class name.
Definition dns_message.hpp:360
@ A
Definition dns_message.hpp:112
@ PTR
Definition dns_message.hpp:116
@ ANY
Definition dns_message.hpp:121
@ AAAA
Definition dns_message.hpp:119
int deserialize(DnsPacket &packet, std::stringstream &data) const
deserialize a DNS packet from a byte stream.
Definition dns_message.hpp:235
static std::error_code decodeError(uint16_t error) noexcept
convert DNS error to system error code.
Definition dns_message.hpp:311
@ IN
Definition dns_message.hpp:129
static std::string typeName(uint16_t recordType)
get record type name.
Definition dns_message.hpp:336
Event handler interface class.
Definition reactor.hpp:48
IPv6, IPv4 address class.
Definition ip_address.hpp:51
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:584
Reactor class.
Definition reactor.hpp:156
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:434
std::unordered_set< std::string > AliasList
list of aliases.
Definition dns_message.hpp:46
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:45
Definition error.hpp:144
pending synchronous request.
Definition nameserver.hpp:901
std::error_code ec
Definition nameserver.hpp:904
DnsPacket packet
Definition nameserver.hpp:903
Condition cond
Definition nameserver.hpp:902
DNS packet.
Definition dns_message.hpp:89
uint16_t id
Definition dns_message.hpp:90
uint16_t flags
Definition dns_message.hpp:91
uint16_t port
Definition dns_message.hpp:94
std::vector< QuestionRecord > questions
Definition dns_message.hpp:95
IpAddress src
Definition dns_message.hpp:92
IpAddress dest
Definition dns_message.hpp:93
std::vector< ResourceRecord > answers
Definition dns_message.hpp:96
question record.
Definition dns_message.hpp:58
std::string host
Definition dns_message.hpp:59
uint16_t type
Definition dns_message.hpp:60
uint16_t dnsclass
Definition dns_message.hpp:61
resource record.
Definition dns_message.hpp:68
uint32_t ttl
Definition dns_message.hpp:69
IpAddress address
Definition tcp_acceptor_test.cpp:35