Browse Source

Added QDnsAxfrClient

develop
Robin Thoni 6 years ago
parent
commit
6316ff8cab

+ 8
- 1
src/modules/dns-client/CMakeLists.txt View File

@@ -12,7 +12,14 @@ find_package(Qt5Core REQUIRED)
12 12
 find_package(Qt5Network REQUIRED)
13 13
 
14 14
 add_library(${PROJECT_NAME}
15
-        src/QDnsClient.cpp includes/dns-client/QDnsClient.h src/QDnsUdpClient.cpp includes/dns-client/QDnsUdpClient.h src/QDnsTcpClient.cpp includes/dns-client/QDnsTcpClient.h)
15
+        src/QDnsClient.cpp
16
+        includes/dns-client/QDnsClient.h
17
+        src/QDnsUdpClient.cpp
18
+        includes/dns-client/QDnsUdpClient.h
19
+        src/QDnsTcpClient.cpp
20
+        includes/dns-client/QDnsTcpClient.h
21
+        src/QDnsAxfrClient.cpp
22
+        includes/dns-client/QDnsAxfrClient.h)
16 23
 
17 24
 target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Network qdnsagg-dns-base)
18 25
 

+ 83
- 0
src/modules/dns-client/includes/dns-client/QDnsAxfrClient.h View File

@@ -0,0 +1,83 @@
1
+//
2
+// Created by robin on 2/12/18.
3
+//
4
+
5
+#ifndef QDNSAGG_QDNSAXFRCLIENT_H
6
+#define QDNSAGG_QDNSAXFRCLIENT_H
7
+
8
+#include <QObject>
9
+#include <QHostAddress>
10
+#include "QDnsUdpClient.h"
11
+#include "QDnsTcpClient.h"
12
+
13
+namespace QDns
14
+{
15
+    namespace Client
16
+    {
17
+        class QDnsAxfrClient : public QObject
18
+        {
19
+        Q_OBJECT
20
+        public:
21
+            enum ErrorCode
22
+            {
23
+                Unknown = 0,
24
+                ClientError = 1,
25
+                NoFirstSOA = 2,
26
+                NoLastSOA = 3,
27
+                ExtraRecords = 4
28
+            };
29
+            Q_ENUM(ErrorCode)
30
+
31
+            struct OnAnswerParams
32
+            {
33
+                quint64 reserved;
34
+                QList<QDns::Base::QDnsResourceRecord> records;
35
+            };
36
+
37
+            struct OnErrorParams
38
+            {
39
+                quint64 reserved;
40
+                ErrorCode error;
41
+                QDnsClient::OnErrorParams clientError;
42
+            };
43
+
44
+            explicit QDnsAxfrClient(const QString& zone, const QHostAddress& host, quint16 port = 53, QObject* parent = nullptr);
45
+
46
+        signals:
47
+            void onAnswer(OnAnswerParams);
48
+            void onError(OnErrorParams);
49
+
50
+        public slots:
51
+            void transfer();
52
+
53
+        private slots:
54
+            void onClientStateChanged(const QDnsClient::OnStateChangedParams& params);
55
+
56
+            void onClientAnswer(const QDnsClient::OnAnswerParams& params);
57
+
58
+            void onClientError(const QDnsClient::OnErrorParams& params);
59
+
60
+        private:
61
+            enum AxfrStatus
62
+            {
63
+                FirstSOA,
64
+                Records,
65
+                LastSOA
66
+            };
67
+
68
+            void processPacket(const QDns::Base::QDnsPacket& packet);
69
+
70
+            QString m_zone;
71
+
72
+            AxfrStatus m_status;
73
+
74
+            QDns::Client::QDnsUdpClient* m_udpClient;
75
+
76
+            QDns::Client::QDnsTcpClient* m_tcpClient;
77
+
78
+            QList<QDns::Base::QDnsResourceRecord> m_records;
79
+        };
80
+    }
81
+}
82
+
83
+#endif //QDNSAGG_QDNSAXFRCLIENT_H

+ 114
- 0
src/modules/dns-client/src/QDnsAxfrClient.cpp View File

@@ -0,0 +1,114 @@
1
+//
2
+// Created by robin on 2/12/18.
3
+//
4
+
5
+#include "dns-client/QDnsAxfrClient.h"
6
+
7
+namespace QDns
8
+{
9
+    namespace Client
10
+    {
11
+        QDnsAxfrClient::QDnsAxfrClient(const QString& zone, const QHostAddress& host, quint16 port, QObject *parent)
12
+                : QObject(parent)
13
+                , m_zone(zone)
14
+                , m_status(AxfrStatus::FirstSOA)
15
+                , m_udpClient(new QDns::Client::QDnsUdpClient(host, port, this))
16
+                , m_tcpClient(new QDns::Client::QDnsTcpClient(host, port, this))
17
+        {
18
+            connect(m_udpClient, &QDnsClient::onStateChanged, this, &QDnsAxfrClient::onClientStateChanged);
19
+            connect(m_tcpClient, &QDnsClient::onStateChanged, this, &QDnsAxfrClient::onClientStateChanged);
20
+            connect(m_udpClient, &QDnsClient::onAnswer, this, &QDnsAxfrClient::onClientAnswer);
21
+            connect(m_tcpClient, &QDnsClient::onAnswer, this, &QDnsAxfrClient::onClientAnswer);
22
+            connect(m_udpClient, &QDnsClient::onError, this, &QDnsAxfrClient::onClientError);
23
+            connect(m_tcpClient, &QDnsClient::onError, this, &QDnsAxfrClient::onClientError);
24
+        }
25
+
26
+        void QDnsAxfrClient::transfer()
27
+        {
28
+            m_status = AxfrStatus::FirstSOA;
29
+            m_records.clear();
30
+            m_udpClient->connectToHost();
31
+            m_tcpClient->connectToHost();
32
+        }
33
+
34
+        void QDnsAxfrClient::onClientStateChanged(const QDnsClient::OnStateChangedParams& params)
35
+        {
36
+            if (m_udpClient->getState() == QDnsClient::ClientState::Connected
37
+                && m_tcpClient->getState() == QDnsClient::ClientState::Connected)
38
+            {
39
+                auto axfrQuery = QDns::Base::QDnsPacket::makeSimpleQuery(m_zone, QDns::Base::QDnsBase::RecordType::AXFR);
40
+                m_tcpClient->query(axfrQuery);
41
+            }
42
+        }
43
+
44
+        void QDnsAxfrClient::onClientAnswer(const QDnsClient::OnAnswerParams& params)
45
+        {
46
+            processPacket(params.answer);
47
+        }
48
+
49
+        void QDnsAxfrClient::onClientError(const QDnsClient::OnErrorParams &params)
50
+        {
51
+            if (params.error == QDns::Client::QDnsClient::ErrorCode::UnknownId)
52
+            {
53
+                processPacket(params.answer);
54
+            }
55
+            else
56
+            {
57
+                emit onError(OnErrorParams
58
+                                     {
59
+                                             0,
60
+                                             ErrorCode::ClientError,
61
+                                             params
62
+                                     });
63
+            }
64
+        }
65
+
66
+        void QDnsAxfrClient::processPacket(const QDns::Base::QDnsPacket& packet)
67
+        {
68
+            if (m_status == AxfrStatus::FirstSOA)
69
+            {
70
+                if (packet.getHeader().getAnswerCount() == 1 &&
71
+                    packet.getAnswerRecords().first().getType() == QDns::Base::QDnsBase::RecordType::SOA)
72
+                {
73
+                    m_status = AxfrStatus::Records;
74
+                    m_records.append(packet.getAnswerRecords());
75
+                }
76
+                else
77
+                {
78
+                    emit onError(OnErrorParams
79
+                                         {
80
+                                                 0,
81
+                                                 ErrorCode::NoFirstSOA
82
+                                         });
83
+                }
84
+            }
85
+            else if (m_status == AxfrStatus::Records)
86
+            {
87
+                if (packet.getHeader().getAnswerCount() == 1 &&
88
+                    packet.getAnswerRecords().first().getType() == QDns::Base::QDnsBase::RecordType::SOA)
89
+                {
90
+                    m_status = AxfrStatus::LastSOA;
91
+                    m_udpClient->disconnectFromHost();
92
+                    m_tcpClient->disconnectFromHost();
93
+                    emit onAnswer(OnAnswerParams
94
+                                          {
95
+                                                  0,
96
+                                                  m_records
97
+                                          });
98
+                }
99
+                else
100
+                {
101
+                    m_records.append(packet.getAnswerRecords());
102
+                }
103
+            }
104
+            else
105
+            {
106
+                emit onError(OnErrorParams
107
+                                     {
108
+                                             0,
109
+                                             ErrorCode::ExtraRecords
110
+                                     });
111
+            }
112
+        }
113
+    }
114
+}

Loading…
Cancel
Save