126 explicit MdnsClient(
const std::string& service_instance_name =
"", uint16_t service_port = 0);
137 const std::map<std::string, std::string>& txt_records = {});
152 std::vector<MdnsService>
get_recent_services(std::chrono::seconds max_age = std::chrono::seconds(300))
const;
162 std::string service_instance_name_;
163 uint16_t service_port_;
164 std::string service_type_;
165 std::map<std::string, std::string> txt_records_;
169 std::string local_hostname_;
170 std::string local_ip_address_;
173 std::atomic<bool> running_;
174 std::atomic<bool> announcing_;
175 std::atomic<bool> discovering_;
176 std::thread receiver_thread_;
177 std::thread announcer_thread_;
178 std::thread querier_thread_;
181 std::condition_variable shutdown_cv_;
182 std::mutex shutdown_mutex_;
185 mutable std::mutex services_mutex_;
186 std::map<std::string, MdnsService> discovered_services_;
190 std::chrono::seconds announcement_interval_;
191 std::chrono::seconds query_interval_;
194 mutable std::mt19937 rng_;
197 bool create_multicast_socket();
198 bool join_multicast_group();
199 bool leave_multicast_group();
200 void close_multicast_socket();
203 void receiver_loop();
204 void announcer_loop();
208 void handle_received_packet(
const std::vector<uint8_t>& packet,
const std::string& sender_ip);
209 void process_mdns_message(
const DnsMessage& message,
const std::string& sender_ip);
210 void process_query(
const DnsMessage& query,
const std::string& sender_ip);
211 void process_response(
const DnsMessage& response,
const std::string& sender_ip);
214 void extract_service_from_response(
const DnsMessage& response,
const std::string& sender_ip);
215 bool is_librats_service(
const std::string& service_name)
const;
216 void add_or_update_service(
const MdnsService& service);
224 DnsResourceRecord create_ptr_record(
const std::string& service_type,
const std::string& instance_name, uint32_t ttl = 120);
225 DnsResourceRecord create_srv_record(
const std::string& instance_name,
const std::string& hostname, uint16_t port, uint32_t ttl = 120);
226 DnsResourceRecord create_txt_record(
const std::string& instance_name,
const std::map<std::string, std::string>& txt_data, uint32_t ttl = 120);
227 DnsResourceRecord create_a_record(
const std::string& hostname,
const std::string& ip_address, uint32_t ttl = 120);
230 std::vector<uint8_t> serialize_dns_message(
const DnsMessage& message);
231 bool deserialize_dns_message(
const std::vector<uint8_t>& data,
DnsMessage& message);
232 bool read_resource_records(
const std::vector<uint8_t>& data,
size_t& offset,
233 uint16_t count, std::vector<DnsResourceRecord>& records);
236 void write_dns_name(std::vector<uint8_t>& buffer,
const std::string& name);
237 std::string read_dns_name(
const std::vector<uint8_t>& buffer,
size_t& offset);
238 void write_uint16(std::vector<uint8_t>& buffer, uint16_t value);
239 void write_uint32(std::vector<uint8_t>& buffer, uint32_t value);
240 uint16_t read_uint16(
const std::vector<uint8_t>& buffer,
size_t& offset);
241 uint32_t read_uint32(
const std::vector<uint8_t>& buffer,
size_t& offset);
244 std::vector<uint8_t> encode_txt_record(
const std::map<std::string, std::string>& txt_data);
245 std::map<std::string, std::string> decode_txt_record(
const std::vector<uint8_t>& txt_data);
248 std::vector<uint8_t> encode_srv_record(uint16_t priority, uint16_t weight, uint16_t port,
const std::string& target);
249 bool decode_srv_record(
const std::vector<uint8_t>& full_packet,
size_t data_offset,
250 uint16_t& priority, uint16_t& weight, uint16_t& port, std::string& target);
253 std::string get_local_hostname();
254 std::string get_local_ip_address();
255 std::string create_service_instance_name(
const std::string& instance_name);
256 std::string extract_instance_name_from_service(
const std::string& service_name);
257 bool send_multicast_packet(
const std::vector<uint8_t>& packet);
260 bool is_valid_dns_name(
const std::string& name)
const;
261 std::string normalize_dns_name(
const std::string& name)
const;