11#include <promeki/config.h>
12#if PROMEKI_ENABLE_MDNS
34PROMEKI_NAMESPACE_BEGIN
39class NetworkInterfaceMonitor;
99class MdnsManager :
public Thread {
100 PROMEKI_OBJECT(MdnsManager, Thread)
103 static constexpr uint16_t DefaultPort = 5353;
106 static constexpr size_t DefaultMaxPacketSize = 9000;
119 static constexpr unsigned int DefaultTickIntervalMs = 1000;
122 static Ipv4Address ipv4Group() {
return Ipv4Address(224, 0, 0, 251); }
125 static Ipv6Address ipv6Group();
134 enum class IpFamily : uint8_t {
141 void setIpFamily(IpFamily family);
144 IpFamily ipFamily()
const {
return _ipFamily; }
164 using PacketHook = Function<void(NetworkInterface iface,
165 SocketAddress sender,
169 explicit MdnsManager(ObjectBase *parent =
nullptr);
172 ~MdnsManager()
override;
183 void setPort(uint16_t port);
186 uint16_t port()
const {
return _port; }
201 void setAutoTrackInterfaces(
bool enable);
204 bool autoTrackInterfaces()
const {
return _autoTrackInterfaces; }
217 void setIncludeLoopback(
bool include);
220 bool includeLoopback()
const {
return _includeLoopback; }
229 void setMaxPacketSize(
size_t bytes);
232 size_t maxPacketSize()
const {
return _maxPacketSize; }
243 void setTickInterval(
unsigned int ms);
246 unsigned int tickInterval()
const {
return _tickIntervalMs; }
287 Error sendQuery(
const String &name, uint16_t recordType,
288 uint16_t transactionId = 0,
289 bool unicastResponse =
false);
300 Error sendMetaQuery();
303 static String metaBrowseFqdn() {
304 return String(
"_services._dns-sd._udp.local.");
328 Error sendQueryWithKnownAnswers(
const String &name, uint16_t recordType,
329 const List<MdnsRecord> &knownAnswers,
330 uint16_t transactionId = 0);
347 static Buffer buildQuery(
const String &name, uint16_t recordType,
348 uint16_t transactionId = 0,
349 bool unicastResponse =
false);
358 static Buffer buildQueryWithKnownAnswers(
const String &name, uint16_t recordType,
359 const List<MdnsRecord> &knownAnswers,
360 uint16_t transactionId = 0,
361 bool unicastResponse =
false);
372 void registerBrowser(MdnsBrowser *browser);
383 void registerPublisher(MdnsPublisher *publisher);
393 void unregisterPublisher(MdnsPublisher *publisher);
403 void registerTypeBrowser(MdnsTypeBrowser *typeBrowser);
411 void unregisterTypeBrowser(MdnsTypeBrowser *typeBrowser);
426 Error writeMulticast(
const Buffer &packet,
bool ipv6);
444 void unregisterBrowser(MdnsBrowser *browser);
456 void setPacketHook(PacketHook hook);
478 int registerPacketObserver(PacketHook observer);
489 void unregisterPacketObserver(
int handle);
521 Error start(
const NetworkInterface::List &ifaces);
534 bool isActive()
const {
return _active.value(); }
537 NetworkInterface::List joinedInterfaces()
const;
545 uint64_t datagramCount()
const {
return _datagramCount.value(); }
548 uint64_t byteCount()
const {
return _byteCount.value(); }
559 UdpSocket *socket()
const {
return _socket.get(); }
568 UdpSocket *socketV6()
const {
return _socketV6.get(); }
571 PROMEKI_SIGNAL(interfaceAdded, NetworkInterface);
573 PROMEKI_SIGNAL(interfaceRemoved, NetworkInterface);
575 PROMEKI_SIGNAL(receiveError, Error);
582 Error openAndJoin(
const NetworkInterface::List &ifaces);
583 Error openSocket(
bool ipv6);
584 Error joinGroups(
const NetworkInterface::List &ifaces,
int *joined);
585 Error joinGroupsOnInterface(
const NetworkInterface &iface,
int *joined);
586 void closeAndLeave();
587 NetworkInterface::List selectAllMulticastInterfaces()
const;
588 bool acceptInterface(
const NetworkInterface &iface)
const;
589 NetworkInterface interfaceFromIfIndex(
unsigned int ifindex)
const;
594 int sendOnSocketPerInterface(UdpSocket *sock,
const Buffer &pkt,
595 const SocketAddress &dest);
603 void handleSocketEvents(UdpSocket *sock, uint32_t events);
620 void attachInterfaceMonitor();
621 void detachInterfaceMonitor();
622 void onInterfaceAppeared(
const NetworkInterface &iface);
623 void onInterfaceDisappeared(
const NetworkInterface &iface);
625 UdpSocket::UPtr _socket;
626 UdpSocket::UPtr _socketV6;
627 MulticastManager _multicastManager;
628 NetworkInterface::List _joinedInterfaces;
635 Map<unsigned int, NetworkInterface> _byIfIndex;
636 mutable Mutex _interfacesMtx;
637 PacketHook _packetHook;
638 struct PacketObserver {
642 List<PacketObserver> _packetObservers;
643 mutable Mutex _packetObserversMtx;
644 Atomic<int> _nextObserverHandle;
645 List<MdnsBrowser *> _browsers;
646 mutable Mutex _browsersMtx;
647 List<MdnsPublisher *> _publishers;
648 mutable Mutex _publishersMtx;
649 List<MdnsTypeBrowser *> _typeBrowsers;
650 mutable Mutex _typeBrowsersMtx;
651 UniquePtr<NetworkInterfaceMonitor> _ifMonitor;
653 uint16_t _port = DefaultPort;
654 bool _includeLoopback =
true;
655 bool _autoTrackInterfaces =
true;
656 IpFamily _ipFamily = IpFamily::Both;
657 size_t _maxPacketSize = DefaultMaxPacketSize;
658 unsigned int _tickIntervalMs = DefaultTickIntervalMs;
660 Atomic<bool> _active;
661 Atomic<uint64_t> _datagramCount;
662 Atomic<uint64_t> _byteCount;