mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-06 05:21:22 +03:00
Compressed dns (#3769)
* Add UdpContext seek and tell * Add support for DNS compressed messages * mDNS compressed pointer: Validate offset before jumping
This commit is contained in:
parent
836c7da8cc
commit
461c922586
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,3 +19,4 @@ boards.local.txt
|
|||||||
*.gcno
|
*.gcno
|
||||||
*.gcda
|
*.gcda
|
||||||
*.o
|
*.o
|
||||||
|
*.a
|
||||||
|
@ -27,6 +27,7 @@ extern "C" {
|
|||||||
void esp_yield();
|
void esp_yield();
|
||||||
void esp_schedule();
|
void esp_schedule();
|
||||||
#include "lwip/init.h" // LWIP_VERSION_
|
#include "lwip/init.h" // LWIP_VERSION_
|
||||||
|
#include <assert.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,6 +144,21 @@ public:
|
|||||||
return _rx_buf->len - _rx_buf_offset;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t getRemoteAddress()
|
uint32_t getRemoteAddress()
|
||||||
{
|
{
|
||||||
if (!_rx_buf)
|
if (!_rx_buf)
|
||||||
@ -203,7 +219,7 @@ public:
|
|||||||
|
|
||||||
int read()
|
int read()
|
||||||
{
|
{
|
||||||
if (!_rx_buf || _rx_buf_offset == _rx_buf->len)
|
if (!_rx_buf || _rx_buf_offset >= _rx_buf->len)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
|
char c = reinterpret_cast<char*>(_rx_buf->payload)[_rx_buf_offset];
|
||||||
@ -361,6 +377,9 @@ private:
|
|||||||
void _consume(size_t size)
|
void _consume(size_t size)
|
||||||
{
|
{
|
||||||
_rx_buf_offset += 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,
|
void _recv(udp_pcb *upcb, pbuf *pb,
|
||||||
|
@ -542,15 +542,33 @@ void MDNSResponder::_parsePacket(){
|
|||||||
while (numAnswers--) {
|
while (numAnswers--) {
|
||||||
// Read name
|
// Read name
|
||||||
stringsRead = 0;
|
stringsRead = 0;
|
||||||
|
size_t last_bufferpos = 0;
|
||||||
do {
|
do {
|
||||||
tmp8 = _conn_read8();
|
tmp8 = _conn_read8();
|
||||||
if (tmp8 & 0xC0) { // Compressed pointer (not supported)
|
|
||||||
tmp8 = _conn_read8();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (tmp8 == 0x00) { // End of name
|
if (tmp8 == 0x00) { // End of name
|
||||||
break;
|
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();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
|
DEBUG_ESP_PORT.print("Skipping malformed compressed pointer");
|
||||||
|
#endif
|
||||||
|
tmp8 = _conn_read8();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(stringsRead > 3){
|
if(stringsRead > 3){
|
||||||
#ifdef DEBUG_ESP_MDNS_RX
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
DEBUG_ESP_PORT.println("failed to read the response name");
|
DEBUG_ESP_PORT.println("failed to read the response name");
|
||||||
@ -577,6 +595,14 @@ void MDNSResponder::_parsePacket(){
|
|||||||
}
|
}
|
||||||
stringsRead++;
|
stringsRead++;
|
||||||
} while (true);
|
} 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 answerType = _conn_read16(); // Read type
|
||||||
uint16_t answerClass = _conn_read16(); // Read class
|
uint16_t answerClass = _conn_read16(); // Read class
|
||||||
@ -635,32 +661,54 @@ void MDNSResponder::_parsePacket(){
|
|||||||
uint16_t answerPrio = _conn_read16(); // Read priority
|
uint16_t answerPrio = _conn_read16(); // Read priority
|
||||||
uint16_t answerWeight = _conn_read16(); // Read weight
|
uint16_t answerWeight = _conn_read16(); // Read weight
|
||||||
answerPort = _conn_read16(); // Read port
|
answerPort = _conn_read16(); // Read port
|
||||||
|
last_bufferpos = 0;
|
||||||
|
|
||||||
(void) answerPrio;
|
(void) answerPrio;
|
||||||
(void) answerWeight;
|
(void) answerWeight;
|
||||||
|
|
||||||
// Read hostname
|
// Read hostname
|
||||||
tmp8 = _conn_read8();
|
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
|
#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
|
#endif
|
||||||
tmp8 = _conn_read8();
|
_conn->seek(offset);
|
||||||
|
tmp8 = _conn_read8();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
|
DEBUG_ESP_PORT.print("Skipping malformed compressed pointer");
|
||||||
|
#endif
|
||||||
|
tmp8 = _conn_read8();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_conn_readS(answerHostName, tmp8);
|
||||||
else {
|
answerHostName[tmp8] = '\0';
|
||||||
_conn_readS(answerHostName, tmp8);
|
|
||||||
answerHostName[tmp8] = '\0';
|
|
||||||
#ifdef DEBUG_ESP_MDNS_RX
|
#ifdef DEBUG_ESP_MDNS_RX
|
||||||
DEBUG_ESP_PORT.printf("SRV %d ", tmp8);
|
DEBUG_ESP_PORT.printf("SRV %d ", tmp8);
|
||||||
for (int n = 0; n < tmp8; n++) {
|
for (int n = 0; n < tmp8; n++) {
|
||||||
DEBUG_ESP_PORT.printf("%02x ", answerHostName[n]);
|
DEBUG_ESP_PORT.printf("%02x ", answerHostName[n]);
|
||||||
}
|
}
|
||||||
DEBUG_ESP_PORT.printf("\n%s\n", answerHostName);
|
DEBUG_ESP_PORT.printf("\n%s\n", answerHostName);
|
||||||
#endif
|
#endif
|
||||||
if (answerRdlength - (6 + 1 + tmp8) > 0) { // Skip any remaining rdata
|
if (last_bufferpos > 0)
|
||||||
_conn_readS(hostName, answerRdlength - (6 + 1 + tmp8));
|
{
|
||||||
}
|
_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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +723,7 @@ void MDNSResponder::_parsePacket(){
|
|||||||
DEBUG_ESP_PORT.printf("Ignoring unsupported type %02x\n", tmp8);
|
DEBUG_ESP_PORT.printf("Ignoring unsupported type %02x\n", tmp8);
|
||||||
#endif
|
#endif
|
||||||
for (int n = 0; n < answerRdlength; n++)
|
for (int n = 0; n < answerRdlength; n++)
|
||||||
(void)_conn_read8();
|
(void)_conn_read8();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((partsCollected == 0x0F) && serviceMatch) {
|
if ((partsCollected == 0x0F) && serviceMatch) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user