Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compressed dns #3769

Merged
merged 4 commits into from
Mar 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ boards.local.txt
*.gcno
*.gcda
*.o
*.a
21 changes: 20 additions & 1 deletion libraries/ESP8266WiFi/src/include/UdpContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extern "C" {
void esp_yield();
void esp_schedule();
#include "lwip/init.h" // LWIP_VERSION_
#include <assert.h>
}


Expand Down Expand Up @@ -143,6 +144,21 @@ class UdpContext
return _rx_buf->len - _rx_buf_offset;
}

size_t tell() const
{
return _rx_buf_offset;
}

void seek(const size_t pos)
{
assert(isValidOffset(pos));
_rx_buf_offset = pos;
}

bool isValidOffset(const size_t pos) const {
return (pos <= _rx_buf->len);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.
Since you are going to use this offset, would'nt it be pos < _rx_buf->len ?
Sorry I don't mean to be pushy :]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not at all, I appreciate your comments, I just havn't had much time to do more than fix them during breaks at work today =D
The check on line 222 in the 'read' function checks if the offset is at least equal to the limit, which should give that to set the buffer as "fully read", the offset should be set just past the limit, i.e. equal to the length. I figured "finished reading" was a valid use-case and thus a valid offset.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation

}

uint32_t getRemoteAddress()
{
if (!_rx_buf)
Expand Down Expand Up @@ -203,7 +219,7 @@ class UdpContext

int read()
{
if (!_rx_buf || _rx_buf_offset == _rx_buf->len)
if (!_rx_buf || _rx_buf_offset >= _rx_buf->len)
return -1;

char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
Expand Down Expand Up @@ -361,6 +377,9 @@ class UdpContext
void _consume(size_t size)
{
_rx_buf_offset += size;
if (_rx_buf_offset > _rx_buf->len) {
_rx_buf_offset = _rx_buf->len;
}
}

void _recv(udp_pcb *upcb, pbuf *pb,
Expand Down
88 changes: 68 additions & 20 deletions libraries/ESP8266mDNS/ESP8266mDNS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,15 +542,33 @@ void MDNSResponder::_parsePacket(){
while (numAnswers--) {
// Read name
stringsRead = 0;
size_t last_bufferpos = 0;
do {
tmp8 = _conn_read8();
if (tmp8 & 0xC0) { // Compressed pointer (not supported)
tmp8 = _conn_read8();
break;
}
if (tmp8 == 0x00) { // End of name
break;
}
if (tmp8 & 0xC0) { // Compressed pointer
uint16_t offset = ((((uint16_t)tmp8) & ~0xC0) << 8) | _conn_read8();
if (_conn->isValidOffset(offset)) {
last_bufferpos = _conn->tell();
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.print("Compressed pointer, jumping from ");
DEBUG_ESP_PORT.print(last_bufferpos);
DEBUG_ESP_PORT.print(" to ");
DEBUG_ESP_PORT.println(offset);
#endif
_conn->seek(offset);
tmp8 = _conn_read8();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you reading tmp8 twice (here and in L568) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I forgot to remove the second one. Fixed.

}
else {
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.print("Skipping malformed compressed pointer");
#endif
tmp8 = _conn_read8();
break;
}
}
if(stringsRead > 3){
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.println("failed to read the response name");
Expand All @@ -577,6 +595,14 @@ void MDNSResponder::_parsePacket(){
}
stringsRead++;
} while (true);
if (last_bufferpos > 0)
{
_conn->seek(last_bufferpos);
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.print("Compressed pointer, jumping back to ");
DEBUG_ESP_PORT.println(last_bufferpos);
#endif
}

uint16_t answerType = _conn_read16(); // Read type
uint16_t answerClass = _conn_read16(); // Read class
Expand Down Expand Up @@ -635,33 +661,55 @@ void MDNSResponder::_parsePacket(){
uint16_t answerPrio = _conn_read16(); // Read priority
uint16_t answerWeight = _conn_read16(); // Read weight
answerPort = _conn_read16(); // Read port
last_bufferpos = 0;

(void) answerPrio;
(void) answerWeight;

// Read hostname
tmp8 = _conn_read8();
if (tmp8 & 0xC0) { // Compressed pointer (not supported)
if (tmp8 & 0xC0) { // Compressed pointer
uint16_t offset = ((((uint16_t)tmp8) & ~0xC0) << 8) | _conn_read8();
if (_conn->isValidOffset(offset)) {
last_bufferpos = _conn->tell();
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.println("Skipping compressed pointer");
DEBUG_ESP_PORT.print("Compressed pointer, jumping from ");
DEBUG_ESP_PORT.print(last_bufferpos);
DEBUG_ESP_PORT.print(" to ");
DEBUG_ESP_PORT.println(offset);
#endif
tmp8 = _conn_read8();
}

else {
_conn_readS(answerHostName, tmp8);
answerHostName[tmp8] = '\0';
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.printf("SRV %d ", tmp8);
for (int n = 0; n < tmp8; n++) {
DEBUG_ESP_PORT.printf("%02x ", answerHostName[n]);
_conn->seek(offset);
tmp8 = _conn_read8();
}
DEBUG_ESP_PORT.printf("\n%s\n", answerHostName);
else {
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.print("Skipping malformed compressed pointer");
#endif
if (answerRdlength - (6 + 1 + tmp8) > 0) { // Skip any remaining rdata
_conn_readS(hostName, answerRdlength - (6 + 1 + tmp8));
tmp8 = _conn_read8();
break;
}
}
_conn_readS(answerHostName, tmp8);
answerHostName[tmp8] = '\0';
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.printf("SRV %d ", tmp8);
for (int n = 0; n < tmp8; n++) {
DEBUG_ESP_PORT.printf("%02x ", answerHostName[n]);
}
DEBUG_ESP_PORT.printf("\n%s\n", answerHostName);
#endif
if (last_bufferpos > 0)
{
_conn->seek(last_bufferpos);
tmp8 = 2; // Size of compression octets
#ifdef DEBUG_ESP_MDNS_RX
DEBUG_ESP_PORT.print("Compressed pointer, jumping back to ");
DEBUG_ESP_PORT.println(last_bufferpos);
#endif
}
if (answerRdlength - (6 + 1 + tmp8) > 0) { // Skip any remaining rdata
_conn_readS(hostName, answerRdlength - (6 + 1 + tmp8));
}
}

else if (answerType == MDNS_TYPE_A) {
Expand All @@ -675,7 +723,7 @@ void MDNSResponder::_parsePacket(){
DEBUG_ESP_PORT.printf("Ignoring unsupported type %02x\n", tmp8);
#endif
for (int n = 0; n < answerRdlength; n++)
(void)_conn_read8();
(void)_conn_read8();
}

if ((partsCollected == 0x0F) && serviceMatch) {
Expand Down