Skip to content

Commit e50dfef

Browse files
committed
DNSServer drop dynamically allocated member structs
DNSHeader and DNSQuestion structs could be created on stack no need to keep it as obj members
1 parent d8b8993 commit e50dfef

File tree

2 files changed

+49
-76
lines changed

2 files changed

+49
-76
lines changed

libraries/DNSServer/src/DNSServer.cpp

Lines changed: 44 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,9 @@
99
#define DEBUG_OUTPUT Serial
1010
#endif
1111

12-
DNSServer::DNSServer() : _port(0), _ttl(htonl(DNS_DEFAULT_TTL)), _errorReplyCode(DNSReplyCode::NonExistentDomain)
13-
{
14-
_dnsHeader = new DNSHeader();
15-
_dnsQuestion = new DNSQuestion();
16-
}
12+
DNSServer::DNSServer() : _port(0), _ttl(htonl(DNS_DEFAULT_TTL)), _errorReplyCode(DNSReplyCode::NonExistentDomain){}
1713

18-
DNSServer::~DNSServer()
19-
{
20-
if (_dnsHeader) {
21-
delete _dnsHeader;
22-
_dnsHeader = nullptr;
23-
}
24-
if (_dnsQuestion) {
25-
delete _dnsQuestion;
26-
_dnsQuestion = nullptr;
27-
}
28-
}
14+
DNSServer::~DNSServer(){}
2915

3016
bool DNSServer::start(const uint16_t &port, const String &domainName,
3117
const IPAddress &resolvedIP)
@@ -37,6 +23,7 @@ bool DNSServer::start(const uint16_t &port, const String &domainName,
3723
_resolvedIP[2] = resolvedIP[2];
3824
_resolvedIP[3] = resolvedIP[3];
3925
downcaseAndRemoveWwwPrefix(_domainName);
26+
_udp.close();
4027
_udp.onPacket([this](AsyncUDPPacket& pkt){ this->_handleUDP(pkt); });
4128
return _udp.listen(_port);
4229
}
@@ -64,70 +51,58 @@ void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName)
6451

6552
void DNSServer::_handleUDP(AsyncUDPPacket& pkt)
6653
{
67-
size_t _currentPacketSize = pkt.length();
68-
if (_currentPacketSize < DNS_HEADER_SIZE) return;
54+
size_t currentPacketSize = pkt.length();
55+
if (currentPacketSize < DNS_HEADER_SIZE) return;
6956

7057
// get DNS header (beginning of message)
71-
memcpy( _dnsHeader, pkt.data(), DNS_HEADER_SIZE );
72-
if (_dnsHeader->QR != DNS_QR_QUERY) return; // ignore non-query mesages
58+
DNSHeader dnsHeader;
59+
DNSQuestion dnsQuestion;
60+
memcpy( &dnsHeader, pkt.data(), DNS_HEADER_SIZE );
61+
if (dnsHeader.QR != DNS_QR_QUERY) return; // ignore non-query mesages
7362

74-
if ( requestIncludesOnlyOneQuestion() )
63+
if ( requestIncludesOnlyOneQuestion(dnsHeader) )
7564
{
65+
/*
66+
// The QName has a variable length, maximum 255 bytes and is comprised of multiple labels.
67+
// Each label contains a byte to describe its length and the label itself. The list of
68+
// labels terminates with a zero-valued byte. In "github.com", we have two labels "github" & "com"
69+
*/
7670
char * enoflbls = strchr((const char*)pkt.data() + DNS_HEADER_SIZE, 0); // find end_of_label marker
7771
++enoflbls; // include null terminator
78-
_dnsQuestion->QName = pkt.data() + DNS_HEADER_SIZE; // we can reference labels from the request
79-
_dnsQuestion->QNameLength = enoflbls - (char*)pkt.data() - DNS_HEADER_SIZE;
72+
dnsQuestion.QName = pkt.data() + DNS_HEADER_SIZE; // we can reference labels from the request
73+
dnsQuestion.QNameLength = enoflbls - (char*)pkt.data() - DNS_HEADER_SIZE;
8074
/*
8175
check if we aint going out of pkt bounds
8276
proper dns req should have label terminator at least 4 bytes before end of packet
8377
*/
84-
if (_dnsQuestion->QNameLength > _currentPacketSize - sizeof(_dnsQuestion->QType) - sizeof(_dnsQuestion->QClass)) return; // malformed packet
78+
if (dnsQuestion.QNameLength > currentPacketSize - sizeof(dnsQuestion.QType) - sizeof(dnsQuestion.QClass)) return; // malformed packet
8579

8680
// Copy the QType and QClass
87-
memcpy( &_dnsQuestion->QType, enoflbls, sizeof(_dnsQuestion->QType) );
88-
memcpy( &_dnsQuestion->QClass, enoflbls + sizeof(_dnsQuestion->QType), sizeof(_dnsQuestion->QClass) );
89-
90-
/*
91-
// The QName has a variable length, maximum 255 bytes and is comprised of multiple labels.
92-
// Each label contains a byte to describe its length and the label itself. The list of
93-
// labels terminates with a zero-valued byte. In "github.com", we have two labels "github" & "com"
94-
// Iterate through the labels and copy them as they come into a single buffer (for simplicity's sake)
95-
_dnsQuestion->QNameLength = 0 ;
96-
while ( _buffer[ DNS_HEADER_SIZE + _dnsQuestion->QNameLength ] != 0 )
97-
{
98-
memcpy( (void*) &_dnsQuestion->QName[_dnsQuestion->QNameLength], (void*) &_buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength], _buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength] + 1 ) ;
99-
_dnsQuestion->QNameLength += _buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength] + 1 ;
100-
}
101-
_dnsQuestion->QName[_dnsQuestion->QNameLength] = 0 ;
102-
_dnsQuestion->QNameLength++ ;
103-
104-
// Copy the QType and QClass
105-
memcpy( &_dnsQuestion->QType, (void*) &_buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength], sizeof(_dnsQuestion->QType) ) ;
106-
memcpy( &_dnsQuestion->QClass, (void*) &_buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength + sizeof(_dnsQuestion->QType)], sizeof(_dnsQuestion->QClass) ) ;
107-
*/
81+
memcpy( &dnsQuestion.QType, enoflbls, sizeof(dnsQuestion.QType) );
82+
memcpy( &dnsQuestion.QClass, enoflbls + sizeof(dnsQuestion.QType), sizeof(dnsQuestion.QClass) );
10883
}
109-
84+
11085
// will reply with IP only to "*" or if doman matches without www. subdomain
111-
if (_dnsHeader->OPCode == DNS_OPCODE_QUERY &&
112-
requestIncludesOnlyOneQuestion() &&
86+
if (dnsHeader.OPCode == DNS_OPCODE_QUERY &&
87+
requestIncludesOnlyOneQuestion(dnsHeader) &&
11388
(_domainName == "*" ||
114-
getDomainNameWithoutWwwPrefix((const char*)pkt.data() + DNS_HEADER_SIZE, _dnsQuestion->QNameLength) == _domainName)
89+
getDomainNameWithoutWwwPrefix((const char*)pkt.data() + DNS_HEADER_SIZE, dnsQuestion.QNameLength) == _domainName)
11590
)
11691
{
117-
replyWithIP(pkt);
92+
replyWithIP(pkt, dnsHeader, dnsQuestion);
11893
return;
11994
}
12095

12196
// otherwise reply with custom code
122-
replyWithCustomCode(pkt);
97+
replyWithCustomCode(pkt, dnsHeader);
12398
}
12499

125-
bool DNSServer::requestIncludesOnlyOneQuestion()
100+
bool DNSServer::requestIncludesOnlyOneQuestion(DNSHeader& dnsHeader)
126101
{
127-
return ntohs(_dnsHeader->QDCount) == 1 &&
128-
_dnsHeader->ANCount == 0 &&
129-
_dnsHeader->NSCount == 0 &&
130-
_dnsHeader->ARCount == 0;
102+
return ntohs(dnsHeader.QDCount) == 1 &&
103+
dnsHeader.ANCount == 0 &&
104+
dnsHeader.NSCount == 0 &&
105+
dnsHeader.ARCount == 0;
131106
}
132107

133108

@@ -164,20 +139,20 @@ String DNSServer::getDomainNameWithoutWwwPrefix(const char* start, size_t len)
164139
}
165140
}
166141

167-
void DNSServer::replyWithIP(AsyncUDPPacket& req)
142+
void DNSServer::replyWithIP(AsyncUDPPacket& req, DNSHeader& dnsHeader, DNSQuestion& dnsQuestion)
168143
{
169144
AsyncUDPMessage rpl;
170145

171146
// Change the type of message to a response and set the number of answers equal to
172147
// the number of questions in the header
173-
_dnsHeader->QR = DNS_QR_RESPONSE;
174-
_dnsHeader->ANCount = _dnsHeader->QDCount;
175-
rpl.write( (unsigned char*) _dnsHeader, DNS_HEADER_SIZE ) ;
148+
dnsHeader.QR = DNS_QR_RESPONSE;
149+
dnsHeader.ANCount = dnsHeader.QDCount;
150+
rpl.write( (unsigned char*) &dnsHeader, DNS_HEADER_SIZE ) ;
176151

177152
// Write the question
178-
rpl.write(_dnsQuestion->QName, _dnsQuestion->QNameLength) ;
179-
rpl.write( (uint8_t*) &_dnsQuestion->QType, 2 ) ;
180-
rpl.write( (uint8_t*) &_dnsQuestion->QClass, 2 ) ;
153+
rpl.write(dnsQuestion.QName, dnsQuestion.QNameLength) ;
154+
rpl.write( (uint8_t*) &dnsQuestion.QType, 2 ) ;
155+
rpl.write( (uint8_t*) &dnsQuestion.QClass, 2 ) ;
181156

182157
// Write the answer
183158
// Use DNS name compression : instead of repeating the name in this RNAME occurence,
@@ -199,17 +174,17 @@ void DNSServer::replyWithIP(AsyncUDPPacket& req)
199174

200175
#ifdef DEBUG_ESP_DNS
201176
DEBUG_OUTPUT.printf("DNS responds: %s for %s\n",
202-
IPAddress(_resolvedIP).toString().c_str(), getDomainNameWithoutWwwPrefix((const char*)rpl.data() + DNS_HEADER_SIZE, _dnsQuestion->QNameLength).c_str() );
177+
IPAddress(_resolvedIP).toString().c_str(), getDomainNameWithoutWwwPrefix((const char*)rpl.data() + DNS_HEADER_SIZE, dnsQuestion.QNameLength).c_str() );
203178
#endif
204179
}
205180

206-
void DNSServer::replyWithCustomCode(AsyncUDPPacket& req)
181+
void DNSServer::replyWithCustomCode(AsyncUDPPacket& req, DNSHeader& dnsHeader)
207182
{
208-
_dnsHeader->QR = DNS_QR_RESPONSE;
209-
_dnsHeader->RCode = (uint16_t)_errorReplyCode;
210-
_dnsHeader->QDCount = 0;
183+
dnsHeader.QR = DNS_QR_RESPONSE;
184+
dnsHeader.RCode = (uint16_t)_errorReplyCode;
185+
dnsHeader.QDCount = 0;
211186

212187
AsyncUDPMessage rpl(sizeof(DNSHeader));
213-
rpl.write((unsigned char*)_dnsHeader, sizeof(DNSHeader));
188+
rpl.write((unsigned char*)&dnsHeader, sizeof(DNSHeader));
214189
_udp.sendTo(rpl, req.remoteIP(), req.remotePort());
215190
}

libraries/DNSServer/src/DNSServer.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ struct DNSHeader
5959
uint16_t Flags;
6060
};
6161
uint16_t QDCount; // number of question entries
62-
uint16_t ANCount; // number of answer entries
62+
uint16_t ANCount; // number of ANswer entries
6363
uint16_t NSCount; // number of authority entries
64-
uint16_t ARCount; // number of resource entries
64+
uint16_t ARCount; // number of Additional Resource entries
6565
};
6666

6767
struct DNSQuestion
@@ -95,8 +95,6 @@ class DNSServer
9595
DNSReplyCode _errorReplyCode;
9696
String _domainName;
9797
unsigned char _resolvedIP[4];
98-
DNSHeader* _dnsHeader;
99-
DNSQuestion* _dnsQuestion ;
10098

10199

102100
void downcaseAndRemoveWwwPrefix(String &domainName);
@@ -110,9 +108,9 @@ class DNSServer
110108
* @return String
111109
*/
112110
String getDomainNameWithoutWwwPrefix(const char* start, size_t len);
113-
bool requestIncludesOnlyOneQuestion();
114-
void replyWithIP(AsyncUDPPacket& req);
115-
void replyWithCustomCode(AsyncUDPPacket& req);
111+
inline bool requestIncludesOnlyOneQuestion(DNSHeader& dnsHeader);
112+
void replyWithIP(AsyncUDPPacket& req, DNSHeader& dnsHeader, DNSQuestion& dnsQuestion);
113+
inline void replyWithCustomCode(AsyncUDPPacket& req, DNSHeader& dnsHeader);
116114
void _handleUDP(AsyncUDPPacket& pkt);
117115
};
118116
#endif

0 commit comments

Comments
 (0)