// // Created by robin on 2/12/18. // #include "dns-client/QDnsAxfrClient.h" namespace QDns { namespace Client { QDnsAxfrClient::QDnsAxfrClient(const QString& zone, const QHostAddress& host, quint16 port, QObject *parent) : QObject(parent) , m_zone(zone) , m_status(AxfrStatus::FirstSOA) , m_udpClient(new QDns::Client::QDnsUdpClient(host, port, this)) , m_tcpClient(new QDns::Client::QDnsTcpClient(host, port, this)) { connect(m_udpClient, &QDnsClient::onStateChanged, this, &QDnsAxfrClient::onClientStateChanged); connect(m_tcpClient, &QDnsClient::onStateChanged, this, &QDnsAxfrClient::onClientStateChanged); connect(m_udpClient, &QDnsClient::onAnswer, this, &QDnsAxfrClient::onClientAnswer); connect(m_tcpClient, &QDnsClient::onAnswer, this, &QDnsAxfrClient::onClientAnswer); connect(m_udpClient, &QDnsClient::onError, this, &QDnsAxfrClient::onClientError); connect(m_tcpClient, &QDnsClient::onError, this, &QDnsAxfrClient::onClientError); } void QDnsAxfrClient::transfer() { m_status = AxfrStatus::FirstSOA; m_records.clear(); m_udpClient->connectToHost(); m_tcpClient->connectToHost(); } void QDnsAxfrClient::onClientStateChanged(const QDnsClient::OnStateChangedParams& params) { if (m_udpClient->getState() == QDnsClient::ClientState::Connected && m_tcpClient->getState() == QDnsClient::ClientState::Connected) { auto axfrQuery = QDns::Base::QDnsPacket::makeSimpleQuery(m_zone, QDns::Base::QDnsBase::RecordType::AXFR); m_tcpClient->query(axfrQuery); } } void QDnsAxfrClient::onClientAnswer(const QDnsClient::OnAnswerParams& params) { processPacket(params.answer); } void QDnsAxfrClient::onClientError(const QDnsClient::OnErrorParams ¶ms) { if (params.error == QDns::Client::QDnsClient::ErrorCode::UnknownId) { processPacket(params.answer); } else { emit onError(OnErrorParams { 0, ErrorCode::ClientError, params }); } } void QDnsAxfrClient::processPacket(const QDns::Base::QDnsPacket& packet) { if (m_status == AxfrStatus::FirstSOA) { if (packet.getHeader().getAnswerCount() == 1 && packet.getAnswerRecords().first().getType() == QDns::Base::QDnsBase::RecordType::SOA) { m_status = AxfrStatus::Records; m_records.append(packet.getAnswerRecords()); } else { emit onError(OnErrorParams { 0, ErrorCode::NoFirstSOA }); } } else if (m_status == AxfrStatus::Records) { if (packet.getHeader().getAnswerCount() == 1 && packet.getAnswerRecords().first().getType() == QDns::Base::QDnsBase::RecordType::SOA) { m_status = AxfrStatus::LastSOA; m_udpClient->disconnectFromHost(); m_tcpClient->disconnectFromHost(); emit onAnswer(OnAnswerParams { 0, m_records }); } else { m_records.append(packet.getAnswerRecords()); } } else { emit onError(OnErrorParams { 0, ErrorCode::ExtraRecords }); } } } }