| 590 | } |
| 591 | |
| 592 | static void BuildResponsePacket(const RawDnsResponseRecord* records, uint32_t record_count, bool compress_names, std::vector<uint8_t>* buffer) |
| 593 | { |
| 594 | buffer->clear(); |
| 595 | WriteU16(buffer, 0); |
| 596 | WriteU16(buffer, DNS_FLAG_RESPONSE); |
| 597 | WriteU16(buffer, 0); |
| 598 | WriteU16(buffer, (uint16_t) record_count); |
| 599 | WriteU16(buffer, 0); |
| 600 | WriteU16(buffer, 0); |
| 601 | |
| 602 | std::map<std::string, uint16_t> suffix_offsets; |
| 603 | std::map<std::string, uint16_t>* offsets = compress_names ? &suffix_offsets : 0; |
| 604 | |
| 605 | for (uint32_t i = 0; i < record_count; ++i) |
| 606 | { |
| 607 | const RawDnsResponseRecord& record = records[i]; |
| 608 | WriteNameCompressed(buffer, record.m_Name, offsets); |
| 609 | WriteU16(buffer, record.m_Type); |
| 610 | WriteU16(buffer, record.m_Class); |
| 611 | WriteU32(buffer, record.m_Ttl); |
| 612 | |
| 613 | const uint32_t rdlength_offset = (uint32_t) buffer->size(); |
| 614 | WriteU16(buffer, 0); |
| 615 | const uint32_t rdata_start = (uint32_t) buffer->size(); |
| 616 | |
| 617 | switch (record.m_Type) |
| 618 | { |
| 619 | case DNS_TYPE_PTR: |
| 620 | { |
| 621 | WriteNameCompressed(buffer, record.m_PtrName, offsets); |
| 622 | break; |
| 623 | } |
| 624 | case DNS_TYPE_SRV: |
| 625 | { |
| 626 | WriteU16(buffer, 0); |
| 627 | WriteU16(buffer, 0); |
| 628 | WriteU16(buffer, record.m_Port); |
| 629 | WriteNameCompressed(buffer, record.m_Target, offsets); |
| 630 | break; |
| 631 | } |
| 632 | case DNS_TYPE_TXT: |
| 633 | { |
| 634 | for (uint32_t txt_i = 0; txt_i < record.m_TxtCount; ++txt_i) |
| 635 | { |
| 636 | char kv[320]; |
| 637 | dmSnPrintf(kv, sizeof(kv), "%s=%s", |
| 638 | record.m_Txt[txt_i].m_Key, |
| 639 | record.m_Txt[txt_i].m_Value ? record.m_Txt[txt_i].m_Value : ""); |
| 640 | const uint32_t len = (uint32_t) strlen(kv); |
| 641 | buffer->push_back((uint8_t) len); |
| 642 | buffer->insert(buffer->end(), kv, kv + len); |
| 643 | } |
| 644 | |
| 645 | if (record.m_TxtCount == 0) |
| 646 | { |
| 647 | buffer->push_back(0); |
| 648 | } |
| 649 | break; |