|
@@ -1,146 +1,146 @@
|
|
|
-#include "MulticastDnsClientImpl.h"
|
|
|
|
|
-#include "MalformedPacket.h"
|
|
|
|
|
-#include "Packet.h"
|
|
|
|
|
-#include <Logging.h>
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
-namespace Network {
|
|
|
|
|
-namespace Dns {
|
|
|
|
|
-
|
|
|
|
|
-MulticastDnsClientImpl::MulticastDnsClientImpl(std::function<void(const std::vector<ResourceRecordImpl>&)> callback) :
|
|
|
|
|
- m_timer(m_ioService),
|
|
|
|
|
- m_responseBuffer(1024),
|
|
|
|
|
- m_socket(m_ioService, asio::ip::udp::v4()),
|
|
|
|
|
- m_multicastEndpoint(asio::ip::address::from_string("224.0.0.251"), 5353),
|
|
|
|
|
- m_callback(callback)
|
|
|
|
|
-{
|
|
|
|
|
- m_socket.set_option(asio::socket_base::reuse_address(true));
|
|
|
|
|
- m_socket.set_option(asio::ip::multicast::join_group(m_multicastEndpoint.address()));
|
|
|
|
|
- m_socket.set_option(asio::ip::multicast::hops(255));
|
|
|
|
|
- m_socket.bind(asio::ip::udp::endpoint(asio::ip::udp::v4(), 5353));
|
|
|
|
|
-
|
|
|
|
|
- m_thread = std::thread([&] { m_ioService.run(); });
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-MulticastDnsClientImpl::~MulticastDnsClientImpl()
|
|
|
|
|
-{
|
|
|
|
|
- m_ioService.stop();
|
|
|
|
|
- m_thread.join();
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::Query(const QueryImpl& query)
|
|
|
|
|
-{
|
|
|
|
|
- m_query = query;
|
|
|
|
|
- m_iterations = 3;
|
|
|
|
|
- SendQuery();
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::SetTimer(int milliseconds)
|
|
|
|
|
-{
|
|
|
|
|
- m_timer.cancel();
|
|
|
|
|
- m_timer.expires_from_now(std::chrono::milliseconds(milliseconds));
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::SendQuery()
|
|
|
|
|
-{
|
|
|
|
|
- if (m_iterations == 0)
|
|
|
|
|
- return;
|
|
|
|
|
- m_iterations--;
|
|
|
|
|
-
|
|
|
|
|
- Packet packet;
|
|
|
|
|
- packet.AddQuery(m_query);
|
|
|
|
|
-
|
|
|
|
|
- auto data = std::make_shared<Data>(packet.GetData());
|
|
|
|
|
-
|
|
|
|
|
- m_socket.async_send_to(
|
|
|
|
|
- asio::buffer(data->GetPtr(), data->GetLength()),
|
|
|
|
|
- m_multicastEndpoint,
|
|
|
|
|
- std::bind(&MulticastDnsClientImpl::HandleQuerySent, this,
|
|
|
|
|
- std::placeholders::_1,
|
|
|
|
|
- data
|
|
|
|
|
- )
|
|
|
|
|
- );
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::HandleQuerySent(const asio::error_code & error, std::shared_ptr<Data> data)
|
|
|
|
|
-{
|
|
|
|
|
- if (error == asio::error::operation_aborted)
|
|
|
|
|
- {
|
|
|
|
|
- SendQuery();
|
|
|
|
|
- }
|
|
|
|
|
- else if (error)
|
|
|
|
|
- {
|
|
|
|
|
- std::stringstream ss;
|
|
|
|
|
- ss << "MulticastDnsClientImpl::HandleQuerySent: " << error.message();
|
|
|
|
|
- Logging::Log(Logging::Severity::Error, ss.str());
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- SetTimer(1000);
|
|
|
|
|
- m_timer.async_wait(std::bind(
|
|
|
|
|
- &MulticastDnsClientImpl::HandleQueryTimeout, this,
|
|
|
|
|
- std::placeholders::_1
|
|
|
|
|
- ));
|
|
|
|
|
- ReceiveQuery();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::ReceiveQuery()
|
|
|
|
|
-{
|
|
|
|
|
- m_socket.async_receive_from(
|
|
|
|
|
- asio::buffer(m_responseBuffer),
|
|
|
|
|
- m_receiveEndpoint,
|
|
|
|
|
- std::bind(&MulticastDnsClientImpl::HandleQueryResponse, this,
|
|
|
|
|
- std::placeholders::_1,
|
|
|
|
|
- std::placeholders::_2
|
|
|
|
|
- )
|
|
|
|
|
- );
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::HandleQueryResponse(const asio::error_code & error, std::size_t size)
|
|
|
|
|
-{
|
|
|
|
|
- if (error == asio::error::operation_aborted)
|
|
|
|
|
- {
|
|
|
|
|
- SendQuery();
|
|
|
|
|
- }
|
|
|
|
|
- else if (error)
|
|
|
|
|
- {
|
|
|
|
|
- std::stringstream ss;
|
|
|
|
|
- ss << "MulticastDnsClientImpl::HandleQueryResponse: " << error.message();
|
|
|
|
|
- Logging::Log(Logging::Severity::Error, ss.str());
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- try
|
|
|
|
|
- {
|
|
|
|
|
- Packet packet(DataReader(m_responseBuffer.data(), size), 0);
|
|
|
|
|
- if (packet.GetQuery())
|
|
|
|
|
- m_callback(packet.GetAnswers());
|
|
|
|
|
- }
|
|
|
|
|
- catch(MalformedPacket& mp)
|
|
|
|
|
- {
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- ReceiveQuery();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-void MulticastDnsClientImpl::HandleQueryTimeout(const asio::error_code & error)
|
|
|
|
|
-{
|
|
|
|
|
- if (error == asio::error::operation_aborted)
|
|
|
|
|
- {
|
|
|
|
|
- }
|
|
|
|
|
- else if (error)
|
|
|
|
|
- {
|
|
|
|
|
- std::stringstream ss;
|
|
|
|
|
- ss << "MulticastDnsClientImpl::HandleQueryTimeout: " << error.message();
|
|
|
|
|
- Logging::Log(Logging::Severity::Error, ss.str());
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- m_socket.cancel();
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-} // namespace Dns
|
|
|
|
|
-} // namespace Network
|
|
|
|
|
|
|
+#include "MulticastDnsClientImpl.h"
|
|
|
|
|
+#include "MalformedPacket.h"
|
|
|
|
|
+#include "Packet.h"
|
|
|
|
|
+#include <Logging.h>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+namespace Network {
|
|
|
|
|
+namespace Dns {
|
|
|
|
|
+
|
|
|
|
|
+MulticastDnsClientImpl::MulticastDnsClientImpl(std::function<void(const std::vector<ResourceRecordImpl>&)> callback) :
|
|
|
|
|
+ m_timer(m_ioService),
|
|
|
|
|
+ m_responseBuffer(1024),
|
|
|
|
|
+ m_socket(m_ioService, asio::ip::udp::v4()),
|
|
|
|
|
+ m_multicastEndpoint(asio::ip::address::from_string("224.0.0.251"), 5353),
|
|
|
|
|
+ m_callback(callback)
|
|
|
|
|
+{
|
|
|
|
|
+ m_socket.set_option(asio::socket_base::reuse_address(true));
|
|
|
|
|
+ m_socket.set_option(asio::ip::multicast::join_group(m_multicastEndpoint.address()));
|
|
|
|
|
+ m_socket.set_option(asio::ip::multicast::hops(255));
|
|
|
|
|
+ m_socket.bind(asio::ip::udp::endpoint(asio::ip::udp::v4(), 5353));
|
|
|
|
|
+
|
|
|
|
|
+ m_thread = std::thread([&] { m_ioService.run(); });
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+MulticastDnsClientImpl::~MulticastDnsClientImpl()
|
|
|
|
|
+{
|
|
|
|
|
+ m_ioService.stop();
|
|
|
|
|
+ m_thread.join();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::Query(const QueryImpl& query)
|
|
|
|
|
+{
|
|
|
|
|
+ m_query = query;
|
|
|
|
|
+ m_iterations = 3;
|
|
|
|
|
+ SendQuery();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::SetTimer(int milliseconds)
|
|
|
|
|
+{
|
|
|
|
|
+ m_timer.cancel();
|
|
|
|
|
+ m_timer.expires_from_now(std::chrono::milliseconds(milliseconds));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::SendQuery()
|
|
|
|
|
+{
|
|
|
|
|
+ if (m_iterations == 0)
|
|
|
|
|
+ return;
|
|
|
|
|
+ m_iterations--;
|
|
|
|
|
+
|
|
|
|
|
+ Packet packet;
|
|
|
|
|
+ packet.AddQuery(m_query);
|
|
|
|
|
+
|
|
|
|
|
+ auto data = std::make_shared<Data>(packet.GetData());
|
|
|
|
|
+
|
|
|
|
|
+ m_socket.async_send_to(
|
|
|
|
|
+ asio::buffer(data->GetPtr(), data->GetLength()),
|
|
|
|
|
+ m_multicastEndpoint,
|
|
|
|
|
+ std::bind(&MulticastDnsClientImpl::HandleQuerySent, this,
|
|
|
|
|
+ std::placeholders::_1,
|
|
|
|
|
+ data
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::HandleQuerySent(const asio::error_code & error, std::shared_ptr<Data> data)
|
|
|
|
|
+{
|
|
|
|
|
+ if (error == asio::error::operation_aborted)
|
|
|
|
|
+ {
|
|
|
|
|
+ SendQuery();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (error)
|
|
|
|
|
+ {
|
|
|
|
|
+ std::stringstream ss;
|
|
|
|
|
+ ss << "MulticastDnsClientImpl::HandleQuerySent: " << error.message();
|
|
|
|
|
+ Logging::Log(Logging::Severity::Error, ss.str());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ SetTimer(1000);
|
|
|
|
|
+ m_timer.async_wait(std::bind(
|
|
|
|
|
+ &MulticastDnsClientImpl::HandleQueryTimeout, this,
|
|
|
|
|
+ std::placeholders::_1
|
|
|
|
|
+ ));
|
|
|
|
|
+ ReceiveQuery();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::ReceiveQuery()
|
|
|
|
|
+{
|
|
|
|
|
+ m_socket.async_receive_from(
|
|
|
|
|
+ asio::buffer(m_responseBuffer),
|
|
|
|
|
+ m_receiveEndpoint,
|
|
|
|
|
+ std::bind(&MulticastDnsClientImpl::HandleQueryResponse, this,
|
|
|
|
|
+ std::placeholders::_1,
|
|
|
|
|
+ std::placeholders::_2
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::HandleQueryResponse(const asio::error_code & error, std::size_t size)
|
|
|
|
|
+{
|
|
|
|
|
+ if (error == asio::error::operation_aborted)
|
|
|
|
|
+ {
|
|
|
|
|
+ SendQuery();
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (error)
|
|
|
|
|
+ {
|
|
|
|
|
+ std::stringstream ss;
|
|
|
|
|
+ ss << "MulticastDnsClientImpl::HandleQueryResponse: " << error.message();
|
|
|
|
|
+ Logging::Log(Logging::Severity::Error, ss.str());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ Packet packet(DataReader(m_responseBuffer.data(), size), 0);
|
|
|
|
|
+ if (packet.GetQuery())
|
|
|
|
|
+ m_callback(packet.GetAnswers());
|
|
|
|
|
+ }
|
|
|
|
|
+ catch(MalformedPacket& mp)
|
|
|
|
|
+ {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ReceiveQuery();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void MulticastDnsClientImpl::HandleQueryTimeout(const asio::error_code & error)
|
|
|
|
|
+{
|
|
|
|
|
+ if (error == asio::error::operation_aborted)
|
|
|
|
|
+ {
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (error)
|
|
|
|
|
+ {
|
|
|
|
|
+ std::stringstream ss;
|
|
|
|
|
+ ss << "MulticastDnsClientImpl::HandleQueryTimeout: " << error.message();
|
|
|
|
|
+ Logging::Log(Logging::Severity::Error, ss.str());
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ m_socket.cancel();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+} // namespace Dns
|
|
|
|
|
+} // namespace Network
|