90 socklen_t client_addr_len =
sizeof(client_addr);
93 int fd = this->
socket_->get_fd();
102 if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
103 ESP_LOGE(TAG,
"recvfrom failed: %d", errno);
108 ESP_LOGVV(TAG,
"Received %d bytes from %s:%d",
len, inet_ntoa(client_addr.
sin_addr), ntohs(client_addr.
sin_port));
110 if (
len <
static_cast<ssize_t>(
sizeof(DNSHeader) + 1)) {
111 ESP_LOGV(TAG,
"Request too short: %d",
len);
116 DNSHeader *header = (DNSHeader *) this->
buffer_;
117 uint16_t
flags = ntohs(header->flags);
118 uint16_t
qd_count = ntohs(header->qd_count);
122 ESP_LOGV(TAG,
"Not a standard query: flags=0x%04X, qd_count=%d",
flags,
qd_count);
127 uint8_t *ptr = this->
buffer_ +
sizeof(DNSHeader);
130 while (ptr <
end && *ptr != 0) {
131 uint8_t label_len = *ptr;
132 if (label_len > 63) {
136 if (ptr + label_len + 1 >
end) {
139 ptr += label_len + 1;
143 if (ptr >=
end || *ptr != 0) {
149 if (ptr +
sizeof(DNSQuestion) >
end) {
154 DNSQuestion *question = (DNSQuestion *) ptr;
155 uint16_t qtype = ntohs(question->type);
156 uint16_t qclass = ntohs(question->dns_class);
159 if (qtype != DNS_QTYPE_A || qclass != DNS_QCLASS_IN) {
160 ESP_LOGV(TAG,
"Not an A query: type=0x%04X, class=0x%04X", qtype, qclass);
165 header->flags = htons(DNS_QR_FLAG | 0x8000);
166 header->an_count = htons(1);
169 size_t question_len = (ptr +
sizeof(DNSQuestion)) - this->
buffer_ -
sizeof(DNSHeader);
170 size_t answer_offset =
sizeof(DNSHeader) + question_len;
173 if (answer_offset +
sizeof(DNSAnswer) >
sizeof(this->
buffer_)) {
174 ESP_LOGW(TAG,
"Response too large");
178 DNSAnswer *answer = (DNSAnswer *) (this->
buffer_ + answer_offset);
181 answer->ptr_offset = htons(0xC000 |
sizeof(DNSHeader));
182 answer->type = htons(DNS_QTYPE_A);
183 answer->dns_class = htons(DNS_QCLASS_IN);
184 answer->ttl = htonl(DNS_ANSWER_TTL);
185 answer->addr_len = htons(4);
189 answer->ip_addr = addr.addr;
191 size_t response_len = answer_offset +
sizeof(DNSAnswer);
197 ESP_LOGV(TAG,
"Send failed: %d", errno);
199 ESP_LOGV(TAG,
"Sent %d bytes", sent);
socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port)
Set a sockaddr to the any address and specified port for the IP version used by socket_ip().