@@ -542,15 +542,33 @@ void MDNSResponder::_parsePacket(){
542
542
while (numAnswers--) {
543
543
// Read name
544
544
stringsRead = 0 ;
545
+ size_t last_bufferpos = 0 ;
545
546
do {
546
547
tmp8 = _conn_read8 ();
547
- if (tmp8 & 0xC0 ) { // Compressed pointer (not supported)
548
- tmp8 = _conn_read8 ();
549
- break ;
550
- }
551
548
if (tmp8 == 0x00 ) { // End of name
552
549
break ;
553
550
}
551
+ if (tmp8 & 0xC0 ) { // Compressed pointer
552
+ uint16_t offset = ((((uint16_t )tmp8) & ~0xC0 ) << 8 ) | _conn_read8 ();
553
+ if (_conn->isValidOffset (offset)) {
554
+ last_bufferpos = _conn->tell ();
555
+ #ifdef DEBUG_ESP_MDNS_RX
556
+ DEBUG_ESP_PORT.print (" Compressed pointer, jumping from " );
557
+ DEBUG_ESP_PORT.print (last_bufferpos);
558
+ DEBUG_ESP_PORT.print (" to " );
559
+ DEBUG_ESP_PORT.println (offset);
560
+ #endif
561
+ _conn->seek (offset);
562
+ tmp8 = _conn_read8 ();
563
+ }
564
+ else {
565
+ #ifdef DEBUG_ESP_MDNS_RX
566
+ DEBUG_ESP_PORT.print (" Skipping malformed compressed pointer" );
567
+ #endif
568
+ tmp8 = _conn_read8 ();
569
+ break ;
570
+ }
571
+ }
554
572
if (stringsRead > 3 ){
555
573
#ifdef DEBUG_ESP_MDNS_RX
556
574
DEBUG_ESP_PORT.println (" failed to read the response name" );
@@ -577,6 +595,14 @@ void MDNSResponder::_parsePacket(){
577
595
}
578
596
stringsRead++;
579
597
} while (true );
598
+ if (last_bufferpos > 0 )
599
+ {
600
+ _conn->seek (last_bufferpos);
601
+ #ifdef DEBUG_ESP_MDNS_RX
602
+ DEBUG_ESP_PORT.print (" Compressed pointer, jumping back to " );
603
+ DEBUG_ESP_PORT.println (last_bufferpos);
604
+ #endif
605
+ }
580
606
581
607
uint16_t answerType = _conn_read16 (); // Read type
582
608
uint16_t answerClass = _conn_read16 (); // Read class
@@ -635,33 +661,55 @@ void MDNSResponder::_parsePacket(){
635
661
uint16_t answerPrio = _conn_read16 (); // Read priority
636
662
uint16_t answerWeight = _conn_read16 (); // Read weight
637
663
answerPort = _conn_read16 (); // Read port
664
+ last_bufferpos = 0 ;
638
665
639
666
(void ) answerPrio;
640
667
(void ) answerWeight;
641
668
642
669
// Read hostname
643
670
tmp8 = _conn_read8 ();
644
- if (tmp8 & 0xC0 ) { // Compressed pointer (not supported)
671
+ if (tmp8 & 0xC0 ) { // Compressed pointer
672
+ uint16_t offset = ((((uint16_t )tmp8) & ~0xC0 ) << 8 ) | _conn_read8 ();
673
+ if (_conn->isValidOffset (offset)) {
674
+ last_bufferpos = _conn->tell ();
645
675
#ifdef DEBUG_ESP_MDNS_RX
646
- DEBUG_ESP_PORT.println (" Skipping compressed pointer" );
676
+ DEBUG_ESP_PORT.print (" Compressed pointer, jumping from " );
677
+ DEBUG_ESP_PORT.print (last_bufferpos);
678
+ DEBUG_ESP_PORT.print (" to " );
679
+ DEBUG_ESP_PORT.println (offset);
647
680
#endif
648
- tmp8 = _conn_read8 ();
649
- }
650
-
651
- else {
652
- _conn_readS (answerHostName, tmp8);
653
- answerHostName[tmp8] = ' \0 ' ;
654
- #ifdef DEBUG_ESP_MDNS_RX
655
- DEBUG_ESP_PORT.printf (" SRV %d " , tmp8);
656
- for (int n = 0 ; n < tmp8; n++) {
657
- DEBUG_ESP_PORT.printf (" %02x " , answerHostName[n]);
681
+ _conn->seek (offset);
682
+ tmp8 = _conn_read8 ();
658
683
}
659
- DEBUG_ESP_PORT.printf (" \n %s\n " , answerHostName);
684
+ else {
685
+ #ifdef DEBUG_ESP_MDNS_RX
686
+ DEBUG_ESP_PORT.print (" Skipping malformed compressed pointer" );
660
687
#endif
661
- if (answerRdlength - ( 6 + 1 + tmp8) > 0 ) { // Skip any remaining rdata
662
- _conn_readS (hostName, answerRdlength - ( 6 + 1 + tmp8)) ;
688
+ tmp8 = _conn_read8 ();
689
+ break ;
663
690
}
664
691
}
692
+ _conn_readS (answerHostName, tmp8);
693
+ answerHostName[tmp8] = ' \0 ' ;
694
+ #ifdef DEBUG_ESP_MDNS_RX
695
+ DEBUG_ESP_PORT.printf (" SRV %d " , tmp8);
696
+ for (int n = 0 ; n < tmp8; n++) {
697
+ DEBUG_ESP_PORT.printf (" %02x " , answerHostName[n]);
698
+ }
699
+ DEBUG_ESP_PORT.printf (" \n %s\n " , answerHostName);
700
+ #endif
701
+ if (last_bufferpos > 0 )
702
+ {
703
+ _conn->seek (last_bufferpos);
704
+ tmp8 = 2 ; // Size of compression octets
705
+ #ifdef DEBUG_ESP_MDNS_RX
706
+ DEBUG_ESP_PORT.print (" Compressed pointer, jumping back to " );
707
+ DEBUG_ESP_PORT.println (last_bufferpos);
708
+ #endif
709
+ }
710
+ if (answerRdlength - (6 + 1 + tmp8) > 0 ) { // Skip any remaining rdata
711
+ _conn_readS (hostName, answerRdlength - (6 + 1 + tmp8));
712
+ }
665
713
}
666
714
667
715
else if (answerType == MDNS_TYPE_A) {
@@ -675,7 +723,7 @@ void MDNSResponder::_parsePacket(){
675
723
DEBUG_ESP_PORT.printf (" Ignoring unsupported type %02x\n " , tmp8);
676
724
#endif
677
725
for (int n = 0 ; n < answerRdlength; n++)
678
- (void )_conn_read8 ();
726
+ (void )_conn_read8 ();
679
727
}
680
728
681
729
if ((partsCollected == 0x0F ) && serviceMatch) {
0 commit comments