Send a multicast response for QM query and other mDNS fixes
* Send a multicast response if it is a QM query * Use the NSEC record in the style which mDNS demands * Shuffle the code a bit and allow sending of A response... * Made the A record work * Now gets TTLs right and (I think) handles multiple questions
This commit is contained in:
parent
8705b9e5a2
commit
f0c1034308
|
@ -57,8 +57,12 @@
|
||||||
#define MDNS_DBG(...) do {} while (0)
|
#define MDNS_DBG(...) do {} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
#define MDNS_NAME_LENGTH 68 //68
|
#define MDNS_NAME_LENGTH 68 //68
|
||||||
|
|
||||||
|
#define DNS_RRTYPE_NSEC 47
|
||||||
|
|
||||||
static const char* service_name_with_suffix = NULL;
|
static const char* service_name_with_suffix = NULL;
|
||||||
#define DNS_SD_SERVICE "_services._dns-sd._udp.local"
|
#define DNS_SD_SERVICE "_services._dns-sd._udp.local"
|
||||||
#define PUCK_SERVICE_LENGTH 30
|
#define PUCK_SERVICE_LENGTH 30
|
||||||
|
@ -176,12 +180,12 @@ PACK_STRUCT_END
|
||||||
|
|
||||||
PACK_STRUCT_BEGIN
|
PACK_STRUCT_BEGIN
|
||||||
/** MDNS answer message structure */
|
/** MDNS answer message structure */
|
||||||
struct mdns_auth {
|
struct mdns_a_rr {
|
||||||
PACK_STRUCT_FIELD(u32_t src);
|
PACK_STRUCT_FIELD(u32_t src);
|
||||||
}PACK_STRUCT_STRUCT;
|
}PACK_STRUCT_STRUCT;
|
||||||
PACK_STRUCT_END
|
PACK_STRUCT_END
|
||||||
|
|
||||||
#define SIZEOF_MDNS_AUTH 4
|
#define SIZEOF_MDNS_A_RR 4
|
||||||
PACK_STRUCT_BEGIN
|
PACK_STRUCT_BEGIN
|
||||||
/** MDNS service registration message structure */
|
/** MDNS service registration message structure */
|
||||||
struct mdns_service {
|
struct mdns_service {
|
||||||
|
@ -222,19 +226,31 @@ static u8_t *mdns_payload;
|
||||||
* @return 0: names equal; 1: names differ
|
* @return 0: names equal; 1: names differ
|
||||||
*/
|
*/
|
||||||
static u8_t ICACHE_FLASH_ATTR
|
static u8_t ICACHE_FLASH_ATTR
|
||||||
mdns_compare_name(unsigned char *query, unsigned char *response) {
|
mdns_compare_name(unsigned char *query, unsigned char *response, unsigned char *pktbase) {
|
||||||
unsigned char n;
|
unsigned char n;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
n = *response++;
|
n = *response++;
|
||||||
/** @see RFC 1035 - 4.1.4. Message compression */
|
/** @see RFC 1035 - 4.1.4. Message compression */
|
||||||
if ((n & 0xc0) == 0xc0) {
|
if ((n & 0xc0) == 0xc0) {
|
||||||
/* Compressed name */
|
n = ((n << 8) + *response) & 0x3fff;
|
||||||
break;
|
if (n < response - pktbase) {
|
||||||
|
response = pktbase + n;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Not compressed name */
|
/* Not compressed name */
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
if ((*query) != (*response)) {
|
char q = *query;
|
||||||
|
if (q >= 'A' && q <= 'Z') {
|
||||||
|
q = q + 'a' - 'A';
|
||||||
|
}
|
||||||
|
char r = *response;
|
||||||
|
if (r >= 'A' && r <= 'Z') {
|
||||||
|
r = r + 'a' - 'A';
|
||||||
|
}
|
||||||
|
if (q != r) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
++response;
|
++response;
|
||||||
|
@ -272,6 +288,26 @@ mdns_namelen(u8_t *p, unsigned int maxlen) {
|
||||||
return p - orig;
|
return p - orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy an unencoded name into an encoded name */
|
||||||
|
static unsigned char *copy_and_encode_name(unsigned char *ptr, const char *name) {
|
||||||
|
while (*name) {
|
||||||
|
const char *p = name;
|
||||||
|
while (*p != '.' && *p) {
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
*ptr++ = p - name;
|
||||||
|
memcpy(ptr, name, p - name);
|
||||||
|
ptr += p - name;
|
||||||
|
if (!*p) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
name = p + 1;
|
||||||
|
}
|
||||||
|
*ptr++ = 0;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static err_t send_packet(struct pbuf *p, struct ip_addr *dst_addr, u16_t dst_port, u8_t *addr_ptr) {
|
static err_t send_packet(struct pbuf *p, struct ip_addr *dst_addr, u16_t dst_port, u8_t *addr_ptr) {
|
||||||
err_t err;
|
err_t err;
|
||||||
/* send dns packet */
|
/* send dns packet */
|
||||||
|
@ -325,13 +361,14 @@ mdns_send_service_type(u16_t id, struct ip_addr *dst_addr, u16_t dst_port) {
|
||||||
err_t err;
|
err_t err;
|
||||||
struct mdns_hdr *hdr;
|
struct mdns_hdr *hdr;
|
||||||
struct mdns_answer ans;
|
struct mdns_answer ans;
|
||||||
struct mdns_auth auth;
|
struct mdns_a_rr a_rr;
|
||||||
struct mdns_service serv;
|
struct mdns_service serv;
|
||||||
struct pbuf *p ,*p_sta;
|
struct pbuf *p ,*p_sta;
|
||||||
char *query, *nptr;
|
char *query, *nptr;
|
||||||
const char *pHostname;
|
const char *pHostname;
|
||||||
struct netif * sta_netif = NULL;
|
struct netif * sta_netif = NULL;
|
||||||
struct netif * ap_netif = NULL;
|
struct netif * ap_netif = NULL;
|
||||||
|
int max_ttl = dst_addr ? 10 : 7200;
|
||||||
char tmpBuf[PUCK_DATASHEET_SIZE + PUCK_SERVICE_LENGTH];
|
char tmpBuf[PUCK_DATASHEET_SIZE + PUCK_SERVICE_LENGTH];
|
||||||
u8_t n;
|
u8_t n;
|
||||||
u16_t length = 0;
|
u16_t length = 0;
|
||||||
|
@ -368,7 +405,7 @@ mdns_send_service_type(u16_t id, struct ip_addr *dst_addr, u16_t dst_port) {
|
||||||
|
|
||||||
ans.type = htons(DNS_RRTYPE_PTR);
|
ans.type = htons(DNS_RRTYPE_PTR);
|
||||||
ans.class = htons(DNS_RRCLASS_IN);
|
ans.class = htons(DNS_RRCLASS_IN);
|
||||||
ans.ttl = htonl(3600);
|
ans.ttl = htonl(min(max_ttl, 3600));
|
||||||
ans.len = htons(os_strlen(service_name_with_suffix) + 1 +1 );
|
ans.len = htons(os_strlen(service_name_with_suffix) + 1 +1 );
|
||||||
length = 0;
|
length = 0;
|
||||||
|
|
||||||
|
@ -418,12 +455,13 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
struct mdns_hdr *hdr;
|
struct mdns_hdr *hdr;
|
||||||
struct mdns_answer ans;
|
struct mdns_answer ans;
|
||||||
struct mdns_service serv;
|
struct mdns_service serv;
|
||||||
struct mdns_auth auth;
|
struct mdns_a_rr a_rr;
|
||||||
struct pbuf *p ,*p_sta;
|
struct pbuf *p ,*p_sta;
|
||||||
char *query, *nptr;
|
char *query, *nptr;
|
||||||
char *query_end;
|
char *query_end;
|
||||||
const char *pHostname;
|
const char *pHostname;
|
||||||
const char *name = info->host_name;
|
const char *name = info->host_name;
|
||||||
|
int max_ttl = dst_addr ? 10 : 7200;
|
||||||
u8_t n;
|
u8_t n;
|
||||||
u8_t i = 0;
|
u8_t i = 0;
|
||||||
u16_t length = 0;
|
u16_t length = 0;
|
||||||
|
@ -443,6 +481,7 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
hdr->id = htons(id);
|
hdr->id = htons(id);
|
||||||
hdr->flags1 = DNS_FLAG1_RESPONSE;
|
hdr->flags1 = DNS_FLAG1_RESPONSE;
|
||||||
hdr->numanswers = htons(4);
|
hdr->numanswers = htons(4);
|
||||||
|
hdr->numextrarr = htons(1);
|
||||||
query = (char*) hdr + SIZEOF_DNS_HDR;
|
query = (char*) hdr + SIZEOF_DNS_HDR;
|
||||||
query_end = (char *) p->payload + p->tot_len;
|
query_end = (char *) p->payload + p->tot_len;
|
||||||
c_strlcpy(tmpBuf, service_name_with_suffix, sizeof(tmpBuf));
|
c_strlcpy(tmpBuf, service_name_with_suffix, sizeof(tmpBuf));
|
||||||
|
@ -474,7 +513,7 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
|
|
||||||
ans.type = htons(DNS_RRTYPE_PTR);
|
ans.type = htons(DNS_RRTYPE_PTR);
|
||||||
ans.class = htons(DNS_RRCLASS_IN);
|
ans.class = htons(DNS_RRCLASS_IN);
|
||||||
ans.ttl = htonl(300);
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
length = os_strlen(ms_info->host_desc) + MDNS_LENGTH_ADD + 1;
|
length = os_strlen(ms_info->host_desc) + MDNS_LENGTH_ADD + 1;
|
||||||
ans.len = htons(length);
|
ans.len = htons(length);
|
||||||
length = 0;
|
length = 0;
|
||||||
|
@ -508,7 +547,7 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
/* fill the answer */
|
/* fill the answer */
|
||||||
ans.type = htons(DNS_RRTYPE_TXT);
|
ans.type = htons(DNS_RRTYPE_TXT);
|
||||||
ans.class = htons(dns_class);
|
ans.class = htons(dns_class);
|
||||||
ans.ttl = htonl(300);
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
// length = os_strlen(TXT_DATA) + MDNS_LENGTH_ADD + 1;
|
// length = os_strlen(TXT_DATA) + MDNS_LENGTH_ADD + 1;
|
||||||
const char *attributes[12];
|
const char *attributes[12];
|
||||||
int attr_count = 0;
|
int attr_count = 0;
|
||||||
|
@ -541,7 +580,8 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
query = query + SIZEOF_DNS_ANSWER;
|
query = query + SIZEOF_DNS_ANSWER;
|
||||||
// Check enough space in the packet
|
// Check enough space in the packet
|
||||||
const char *end_of_packet = query + length + 2 + SIZEOF_DNS_ANSWER + SIZEOF_MDNS_SERVICE +
|
const char *end_of_packet = query + length + 2 + SIZEOF_DNS_ANSWER + SIZEOF_MDNS_SERVICE +
|
||||||
os_strlen(ms_info->host_name) + 7 + 1 + 2 + SIZEOF_DNS_ANSWER + SIZEOF_MDNS_AUTH;
|
os_strlen(ms_info->host_name) + 7 + 1 + 2 + SIZEOF_DNS_ANSWER + SIZEOF_MDNS_A_RR +
|
||||||
|
2 + SIZEOF_DNS_ANSWER + 5;
|
||||||
|
|
||||||
if (query_end <= end_of_packet) {
|
if (query_end <= end_of_packet) {
|
||||||
MDNS_DBG("Too much data to send\n");
|
MDNS_DBG("Too much data to send\n");
|
||||||
|
@ -577,7 +617,7 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
|
|
||||||
ans.type = htons(DNS_RRTYPE_SRV);
|
ans.type = htons(DNS_RRTYPE_SRV);
|
||||||
ans.class = htons(dns_class);
|
ans.class = htons(dns_class);
|
||||||
ans.ttl = htonl(300);
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
c_strlcpy(tmpBuf,ms_info->host_name, sizeof(tmpBuf));
|
c_strlcpy(tmpBuf,ms_info->host_name, sizeof(tmpBuf));
|
||||||
c_strlcat(tmpBuf, ".", sizeof(tmpBuf));
|
c_strlcat(tmpBuf, ".", sizeof(tmpBuf));
|
||||||
c_strlcat(tmpBuf, MDNS_LOCAL, sizeof(tmpBuf));
|
c_strlcat(tmpBuf, MDNS_LOCAL, sizeof(tmpBuf));
|
||||||
|
@ -620,7 +660,7 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
|
|
||||||
ans.type = htons(DNS_RRTYPE_A);
|
ans.type = htons(DNS_RRTYPE_A);
|
||||||
ans.class = htons(dns_class);
|
ans.class = htons(dns_class);
|
||||||
ans.ttl = htonl(300);
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
ans.len = htons(DNS_IP_ADDR_LEN);
|
ans.len = htons(DNS_IP_ADDR_LEN);
|
||||||
|
|
||||||
MEMCPY( query, &ans, SIZEOF_DNS_ANSWER);
|
MEMCPY( query, &ans, SIZEOF_DNS_ANSWER);
|
||||||
|
@ -633,15 +673,33 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
|
|
||||||
/* fill the payload of the mDNS message */
|
/* fill the payload of the mDNS message */
|
||||||
/* set the local IP address */
|
/* set the local IP address */
|
||||||
auth.src = 0;
|
a_rr.src = 0;
|
||||||
MEMCPY( query, &auth, SIZEOF_MDNS_AUTH);
|
MEMCPY( query, &a_rr, SIZEOF_MDNS_A_RR);
|
||||||
u8_t *addr_ptr = query + ((char *) &auth.src - (char *) &auth);
|
u8_t *addr_ptr = query + ((char *) &a_rr.src - (char *) &a_rr);
|
||||||
/* resize the query */
|
/* resize the query */
|
||||||
query = query + SIZEOF_MDNS_AUTH;
|
query = query + SIZEOF_MDNS_A_RR;
|
||||||
|
|
||||||
|
// Append the NSEC record that says we only have an A record
|
||||||
|
*query++ = 0xc0 + (hostname_offset >> 8);
|
||||||
|
*query++ = hostname_offset & 0xff;
|
||||||
|
|
||||||
|
ans.type = htons(DNS_RRTYPE_NSEC);
|
||||||
|
ans.class = htons(dns_class);
|
||||||
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
|
ans.len = htons(5);
|
||||||
|
|
||||||
|
MEMCPY( query, &ans, SIZEOF_DNS_ANSWER);
|
||||||
|
query = query + SIZEOF_DNS_ANSWER;
|
||||||
|
*query++ = 0xc0 + (hostname_offset >> 8);
|
||||||
|
*query++ = hostname_offset & 0xff;
|
||||||
|
*query++ = 0;
|
||||||
|
*query++ = 1;
|
||||||
|
*query++ = 0x40;
|
||||||
|
|
||||||
|
|
||||||
//MDNS_DBG("Final ptr=%x\n", query);
|
//MDNS_DBG("Final ptr=%x\n", query);
|
||||||
|
|
||||||
// increment by sizeof_mdns_auth
|
// increment by sizeof_mdns_a_rr
|
||||||
|
|
||||||
/* set the name of the authority field.
|
/* set the name of the authority field.
|
||||||
* The same name as the Query using the offset address*/
|
* The same name as the Query using the offset address*/
|
||||||
|
@ -650,6 +708,13 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
pbuf_realloc(p, (query) - ((char*) (p->payload)));
|
pbuf_realloc(p, (query) - ((char*) (p->payload)));
|
||||||
|
|
||||||
err = send_packet(p, dst_addr, dst_port, addr_ptr);
|
err = send_packet(p, dst_addr, dst_port, addr_ptr);
|
||||||
|
|
||||||
|
if (!dst_addr) {
|
||||||
|
// this is being sent multicast...
|
||||||
|
// so reset the timer
|
||||||
|
os_timer_disarm(&mdns_timer);
|
||||||
|
os_timer_arm(&mdns_timer, 1000 * 280, 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
MDNS_DBG("ERR_MEM \n");
|
MDNS_DBG("ERR_MEM \n");
|
||||||
err = ERR_MEM;
|
err = ERR_MEM;
|
||||||
|
@ -658,6 +723,137 @@ mdns_send_service(struct nodemcu_mdns_info *info, u16_t id, struct ip_addr *dst_
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *append_nsec_record(char *query, u32_t actual_rr, int max_ttl) {
|
||||||
|
struct mdns_answer ans;
|
||||||
|
|
||||||
|
ans.type = htons(DNS_RRTYPE_NSEC);
|
||||||
|
ans.class = htons(DNS_RRCLASS_IN);
|
||||||
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
|
ans.len = htons(9);
|
||||||
|
|
||||||
|
MEMCPY( query, &ans, SIZEOF_DNS_ANSWER);
|
||||||
|
char *rr_len = query + ((char *) &ans.len - (char *) &ans) + 1;
|
||||||
|
query = query + SIZEOF_DNS_ANSWER;
|
||||||
|
*query++ = 0xc0;
|
||||||
|
*query++ = sizeof(struct mdns_hdr);
|
||||||
|
*query++ = 0;
|
||||||
|
char *bm_len = query;
|
||||||
|
*query++ = 5;
|
||||||
|
char *abase = query;
|
||||||
|
*query++ = 0;
|
||||||
|
*query++ = 0;
|
||||||
|
*query++ = 0;
|
||||||
|
*query++ = 0;
|
||||||
|
*query++ = 0;
|
||||||
|
|
||||||
|
while (actual_rr > 0) {
|
||||||
|
int v = actual_rr & 255;
|
||||||
|
|
||||||
|
if (v < 5 * 8) {
|
||||||
|
abase[v >> 3] |= 0x80 >> (v & 7);
|
||||||
|
|
||||||
|
actual_rr = actual_rr >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (query[-1] == 0) {
|
||||||
|
query--;
|
||||||
|
(*bm_len)--;
|
||||||
|
(*rr_len)--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sends an empty response -- this is used when we doin't have an RR to send
|
||||||
|
* but the name exists
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mdns_send_no_rr(struct mdns_hdr *req, const char *name, u32_t actual_rr, struct ip_addr *dst_addr, u16_t dst_port) {
|
||||||
|
int max_ttl = dst_addr ? 10 : 7200;
|
||||||
|
struct pbuf *p;
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT,
|
||||||
|
SIZEOF_DNS_HDR + MDNS_MAX_NAME_LENGTH * 2 + SIZEOF_DNS_QUERY, PBUF_RAM);
|
||||||
|
if (p != NULL) {
|
||||||
|
LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);
|
||||||
|
/* fill dns header */
|
||||||
|
struct mdns_hdr *hdr = (struct mdns_hdr*) p->payload;
|
||||||
|
os_memset(hdr, 0, SIZEOF_DNS_HDR);
|
||||||
|
hdr->id = req->id;
|
||||||
|
hdr->flags1 = DNS_FLAG1_RESPONSE;
|
||||||
|
hdr->numextrarr = htons(1);
|
||||||
|
char *query = (char*) hdr + SIZEOF_DNS_HDR;
|
||||||
|
char *query_end = (char *) p->payload + p->tot_len;
|
||||||
|
// Now copy over the dns name
|
||||||
|
int len = strlen(name);
|
||||||
|
|
||||||
|
if (query_end - query >= len + SIZEOF_DNS_QUERY + 15) {
|
||||||
|
query = copy_and_encode_name((char *) (hdr + 1), name);
|
||||||
|
|
||||||
|
query = append_nsec_record(query, actual_rr, max_ttl);
|
||||||
|
|
||||||
|
// Set the length code correctly
|
||||||
|
pbuf_realloc(p, query - ((char*) (p->payload)));
|
||||||
|
|
||||||
|
send_packet(p, dst_addr, dst_port, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This sends a single A record and the NSEC record as additional
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
mdns_send_a_rr(struct mdns_hdr *req, const char *name, struct ip_addr *dst_addr, u16_t dst_port) {
|
||||||
|
int max_ttl = dst_addr ? 10 : 7200;
|
||||||
|
struct pbuf *p;
|
||||||
|
p = pbuf_alloc(PBUF_TRANSPORT,
|
||||||
|
SIZEOF_DNS_HDR + MDNS_MAX_NAME_LENGTH * 2 + SIZEOF_DNS_QUERY, PBUF_RAM);
|
||||||
|
if (p != NULL) {
|
||||||
|
LWIP_ASSERT("pbuf must be in one piece", p->next == NULL);
|
||||||
|
/* fill dns header */
|
||||||
|
struct mdns_hdr *hdr = (struct mdns_hdr*) p->payload;
|
||||||
|
os_memset(hdr, 0, SIZEOF_DNS_HDR);
|
||||||
|
hdr->id = req->id;
|
||||||
|
hdr->flags1 = DNS_FLAG1_RESPONSE;
|
||||||
|
hdr->numanswers = htons(1);
|
||||||
|
hdr->numextrarr = htons(1);
|
||||||
|
char *query = (char*) hdr + SIZEOF_DNS_HDR;
|
||||||
|
char *query_end = (char *) p->payload + p->tot_len;
|
||||||
|
// Now copy over the dns name
|
||||||
|
int len = strlen(name) + 1;
|
||||||
|
|
||||||
|
if (query_end - query >= len + SIZEOF_DNS_QUERY + 4 + 2 + 4 + 15) {
|
||||||
|
query = copy_and_encode_name((char *) (hdr + 1), name);
|
||||||
|
|
||||||
|
struct mdns_answer ans;
|
||||||
|
|
||||||
|
ans.type = htons(DNS_RRTYPE_A);
|
||||||
|
ans.class = htons(DNS_RRCLASS_IN);
|
||||||
|
ans.ttl = htonl(min(max_ttl, 300));
|
||||||
|
ans.len = htons(4);
|
||||||
|
|
||||||
|
MEMCPY( query, &ans, SIZEOF_DNS_ANSWER);
|
||||||
|
query = query + SIZEOF_DNS_ANSWER;
|
||||||
|
char *addr_ptr = query;
|
||||||
|
query += 4;
|
||||||
|
|
||||||
|
// Now add the NSEC record
|
||||||
|
*query++ = 0xc0;
|
||||||
|
*query++ = sizeof(*hdr);
|
||||||
|
query = append_nsec_record(query, DNS_RRTYPE_A, max_ttl);
|
||||||
|
|
||||||
|
// Set the length code correctly
|
||||||
|
pbuf_realloc(p, query - ((char*) (p->payload)));
|
||||||
|
|
||||||
|
send_packet(p, dst_addr, dst_port, addr_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive input function for DNS response packets arriving for the dns UDP pcb.
|
* Receive input function for DNS response packets arriving for the dns UDP pcb.
|
||||||
*
|
*
|
||||||
|
@ -695,52 +891,78 @@ mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
|
||||||
nquestions = htons(hdr->numquestions);
|
nquestions = htons(hdr->numquestions);
|
||||||
//nanswers = htons(hdr->numanswers);
|
//nanswers = htons(hdr->numanswers);
|
||||||
/* if we have a question send an answer if necessary */
|
/* if we have a question send an answer if necessary */
|
||||||
if (nquestions > 0) {
|
u8_t qno;
|
||||||
|
u8_t *qptr = (u8_t *) (hdr + 1);
|
||||||
|
u8_t *qend = mdns_payload + p->tot_len;
|
||||||
|
for (qno = 0; qno < nquestions && qptr < qend; qno++) {
|
||||||
|
char tmpBuf[PUCK_DATASHEET_SIZE + PUCK_SERVICE_LENGTH];
|
||||||
struct mdns_query qry;
|
struct mdns_query qry;
|
||||||
|
|
||||||
int namelen = mdns_namelen((u8_t *) (hdr + 1), p->tot_len);
|
int namelen = mdns_namelen(qptr, qend - qptr);
|
||||||
|
|
||||||
memcpy(&qry, namelen + (u8_t *) (hdr + 1), sizeof(qry));
|
memcpy(&qry, namelen + qptr, sizeof(qry));
|
||||||
|
|
||||||
u16_t qry_type = ntohs(qry.type);
|
u16_t qry_type = ntohs(qry.type);
|
||||||
|
|
||||||
|
if (port == 5353 && (ntohs(qry.class) & 0x8000) == 0) {
|
||||||
|
addr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32_t actual_rr = 0;
|
||||||
|
|
||||||
|
const char *no_rr_name = NULL;
|
||||||
|
|
||||||
/* MDNS_DS_DOES_NAME_CHECK */
|
/* MDNS_DS_DOES_NAME_CHECK */
|
||||||
/* Check if the name in the "question" part match with the name of the MDNS DS service. */
|
/* Check if the name in the "question" part match with the name of the MDNS DS service. */
|
||||||
if (mdns_compare_name((unsigned char *) DNS_SD_SERVICE,
|
if (mdns_compare_name((unsigned char *) DNS_SD_SERVICE,
|
||||||
(unsigned char *) mdns_payload + SIZEOF_DNS_HDR) == 0) {
|
(unsigned char *) qptr, (unsigned char *) hdr) == 0) {
|
||||||
if (qry_type == DNS_RRTYPE_PTR || qry_type == DNS_RRTYPE_ANY) {
|
if (qry_type == DNS_RRTYPE_PTR || qry_type == DNS_RRTYPE_ANY) {
|
||||||
mdns_send_service_type(i, addr, port);
|
mdns_send_service_type(i, addr, port);
|
||||||
}
|
} else {
|
||||||
|
no_rr_name = DNS_SD_SERVICE;
|
||||||
|
actual_rr = DNS_RRTYPE_PTR;
|
||||||
|
}
|
||||||
} else if (mdns_compare_name((unsigned char *) service_name_with_suffix,
|
} else if (mdns_compare_name((unsigned char *) service_name_with_suffix,
|
||||||
(unsigned char *) mdns_payload + SIZEOF_DNS_HDR) == 0) {
|
(unsigned char *) qptr, (unsigned char *) hdr) == 0) {
|
||||||
|
if (qry_type == DNS_RRTYPE_PTR || qry_type == DNS_RRTYPE_ANY) {
|
||||||
if (qry_type == DNS_RRTYPE_PTR || qry_type == DNS_RRTYPE_ANY) {
|
mdns_send_service(info, i, addr, port);
|
||||||
mdns_send_service(info, i, addr, port);
|
} else {
|
||||||
}
|
no_rr_name = service_name_with_suffix;
|
||||||
|
actual_rr = DNS_RRTYPE_PTR;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
char tmpBuf[PUCK_DATASHEET_SIZE + PUCK_SERVICE_LENGTH];
|
|
||||||
c_strlcpy(tmpBuf,ms_info->host_name, sizeof(tmpBuf));
|
c_strlcpy(tmpBuf,ms_info->host_name, sizeof(tmpBuf));
|
||||||
c_strlcat(tmpBuf, ".", sizeof(tmpBuf));
|
c_strlcat(tmpBuf, ".", sizeof(tmpBuf));
|
||||||
c_strlcat(tmpBuf, MDNS_LOCAL, sizeof(tmpBuf));
|
c_strlcat(tmpBuf, MDNS_LOCAL, sizeof(tmpBuf));
|
||||||
|
no_rr_name = tmpBuf;
|
||||||
|
|
||||||
if (mdns_compare_name((unsigned char *) tmpBuf,
|
if (mdns_compare_name((unsigned char *) tmpBuf,
|
||||||
(unsigned char *) mdns_payload + SIZEOF_DNS_HDR) == 0) {
|
(unsigned char *) qptr, (unsigned char *) hdr) == 0) {
|
||||||
if (qry_type == DNS_RRTYPE_A || qry_type == DNS_RRTYPE_ANY) {
|
if (qry_type == DNS_RRTYPE_A || qry_type == DNS_RRTYPE_ANY) {
|
||||||
mdns_send_service(info, i, addr, port);
|
mdns_send_a_rr(hdr, tmpBuf, addr, port);
|
||||||
}
|
} else {
|
||||||
|
actual_rr = DNS_RRTYPE_A;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c_strlcpy(tmpBuf,ms_info->host_desc, sizeof(tmpBuf));
|
c_strlcpy(tmpBuf,ms_info->host_desc, sizeof(tmpBuf));
|
||||||
c_strlcat(tmpBuf, ".", sizeof(tmpBuf));
|
c_strlcat(tmpBuf, ".", sizeof(tmpBuf));
|
||||||
c_strlcat(tmpBuf, service_name_with_suffix, sizeof(tmpBuf));
|
c_strlcat(tmpBuf, service_name_with_suffix, sizeof(tmpBuf));
|
||||||
if (mdns_compare_name((unsigned char *) tmpBuf,
|
if (mdns_compare_name((unsigned char *) tmpBuf,
|
||||||
(unsigned char *) mdns_payload + SIZEOF_DNS_HDR) == 0) {
|
(unsigned char *) qptr, (unsigned char *) hdr) == 0) {
|
||||||
if (qry_type == DNS_RRTYPE_TXT || qry_type == DNS_RRTYPE_SRV || qry_type == DNS_RRTYPE_ANY) {
|
if (qry_type == DNS_RRTYPE_TXT || qry_type == DNS_RRTYPE_SRV || qry_type == DNS_RRTYPE_ANY) {
|
||||||
mdns_send_service(info, i, addr, port);
|
mdns_send_service(info, i, addr, port);
|
||||||
}
|
} else {
|
||||||
|
actual_rr = (DNS_RRTYPE_TXT << 8) + DNS_RRTYPE_SRV;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actual_rr) {
|
||||||
|
mdns_send_no_rr(hdr, no_rr_name, actual_rr, addr, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
qptr += namelen + sizeof(qry); // Now points to next question
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memerr1:
|
memerr1:
|
||||||
|
@ -908,7 +1130,7 @@ nodemcu_mdns_init(struct nodemcu_mdns_info *info) {
|
||||||
//MDNS_DBG("About to start timer\n");
|
//MDNS_DBG("About to start timer\n");
|
||||||
os_timer_disarm(&mdns_timer);
|
os_timer_disarm(&mdns_timer);
|
||||||
os_timer_setfn(&mdns_timer, (os_timer_func_t *)mdns_reg,ms_info);
|
os_timer_setfn(&mdns_timer, (os_timer_func_t *)mdns_reg,ms_info);
|
||||||
os_timer_arm(&mdns_timer, 1000 * 120, 1);
|
os_timer_arm(&mdns_timer, 1000 * 280, 1);
|
||||||
/* kick off the first one right away */
|
/* kick off the first one right away */
|
||||||
mdns_reg_handler_restart();
|
mdns_reg_handler_restart();
|
||||||
mdns_reg(ms_info);
|
mdns_reg(ms_info);
|
||||||
|
|
Loading…
Reference in New Issue