1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-07 16:23:38 +03:00

[Issue #3145] ESP8266mDNS: Improve compliance with DNS-SD RFC6763

- When the "_services._dns_sd._udp.local" meta-query is received, an
enumeration of services types is now returned (e.g. "_http._tcp.local")
instead of an enumeration of instances (e.g.
"MyService._http._tcp.local").  This is consistent with Section 9 of the
RFC.

- When a response is sent, the response records are now properly
partitioned as either answers or additional records.  Only response
records that were explicitly requested as a result of the questions
should be treated as answers.  This is consistent with Section 12 of the
RFC.

- The "MDNSResponder::advertiseServices()" method has been removed as it
was declared as "private" and is no longer being called.  This method
was sending a response on multiple interfaces when available, but this
wasn't really necessary since the interface from which the request was
received that caused it to be invoked is known.
This commit is contained in:
Christopher Cooper 2017-04-24 09:30:35 -05:00 committed by Ivan Grokhotkov
parent 2450ec6803
commit 0c66c8a88f
2 changed files with 272 additions and 181 deletions

View File

@ -450,6 +450,21 @@ uint16_t MDNSResponder::_getServicePort(char *name, char *proto){
return 0; return 0;
} }
IPAddress MDNSResponder::_getRequestMulticastInterface(){
struct ip_info ip_info;
bool match_ap = false;
if (wifi_get_opmode() & SOFTAP_MODE) {
struct ip_info remote_ip_info;
remote_ip_info.ip.addr = _conn->getRemoteAddress();
wifi_get_ip_info(SOFTAP_IF, &ip_info);
if (ip_info.ip.addr && ip_addr_netcmp(&remote_ip_info.ip, &ip_info.ip, &ip_info.netmask))
match_ap = true;
}
if (!match_ap)
wifi_get_ip_info(STATION_IF, &ip_info);
return IPAddress(ip_info.ip.addr);
}
void MDNSResponder::_parsePacket(){ void MDNSResponder::_parsePacket(){
int i; int i;
char tmp; char tmp;
@ -759,7 +774,8 @@ void MDNSResponder::_parsePacket(){
protoParsed = true; protoParsed = true;
} else if(strcmp("services", serviceName) == 0 && strcmp("_dns-sd", protoName) == 0){ } else if(strcmp("services", serviceName) == 0 && strcmp("_dns-sd", protoName) == 0){
_conn->flush(); _conn->flush();
advertiseServices(); IPAddress interface = _getRequestMulticastInterface();
_replyToTypeEnumRequest(interface);
return; return;
} else { } else {
#ifdef MDNS_DEBUG_ERR #ifdef MDNS_DEBUG_ERR
@ -854,28 +870,26 @@ void MDNSResponder::_parsePacket(){
Serial.printf("\n"); Serial.printf("\n");
#endif #endif
} }
uint8_t questionMask = 0;
uint8_t responseMask = 0; uint8_t responseMask = 0;
for(i=0;i<question;i++){ for(i=0;i<question;i++){
if(questions[i] == MDNS_TYPE_A) responseMask |= 0x1; if(questions[i] == MDNS_TYPE_A) {
else if(questions[i] == MDNS_TYPE_SRV) responseMask |= 0x3; questionMask |= 0x1;
else if(questions[i] == MDNS_TYPE_TXT) responseMask |= 0x4; responseMask |= 0x1;
else if(questions[i] == MDNS_TYPE_PTR) responseMask |= 0xF; } else if(questions[i] == MDNS_TYPE_SRV) {
questionMask |= 0x2;
responseMask |= 0x3;
} else if(questions[i] == MDNS_TYPE_TXT) {
questionMask |= 0x4;
responseMask |= 0x4;
} else if(questions[i] == MDNS_TYPE_PTR) {
questionMask |= 0x8;
responseMask |= 0xF;
}
} }
struct ip_info ip_info; IPAddress interface = _getRequestMulticastInterface();
bool match_ap = false; return _replyToInstanceRequest(questionMask, responseMask, serviceName, protoName, servicePort, interface);
if (wifi_get_opmode() & SOFTAP_MODE) {
struct ip_info remote_ip_info;
remote_ip_info.ip.addr = _conn->getRemoteAddress();
wifi_get_ip_info(SOFTAP_IF, &ip_info);
if (ip_info.ip.addr && ip_addr_netcmp(&remote_ip_info.ip, &ip_info.ip, &ip_info.netmask))
match_ap = true;
}
if (!match_ap)
wifi_get_ip_info(STATION_IF, &ip_info);
uint32_t ip = ip_info.ip.addr;
return _reply(responseMask, serviceName, protoName, servicePort, ip);
} }
void MDNSResponder::enableArduino(uint16_t port, bool auth){ void MDNSResponder::enableArduino(uint16_t port, bool auth){
@ -887,35 +901,103 @@ void MDNSResponder::enableArduino(uint16_t port, bool auth){
addServiceTxt("arduino", "tcp", "auth_upload", (auth) ? "yes":"no"); addServiceTxt("arduino", "tcp", "auth_upload", (auth) ? "yes":"no");
} }
size_t MDNSResponder::advertiseServices(){ void MDNSResponder::_replyToTypeEnumRequest(IPAddress multicastInterface) {
MDNSService* servicePtr; MDNSService* servicePtr;
struct ip_info ip_info;
uint32_t ip;
size_t i = 0;
for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) { for (servicePtr = _services; servicePtr; servicePtr = servicePtr->_next) {
if(servicePtr->_port > 0){ if(servicePtr->_port > 0){
wifi_get_ip_info(SOFTAP_IF, &ip_info); char *service = servicePtr->_name;
ip = ip_info.ip.addr; char *proto = servicePtr->_proto;
if (ip) uint16_t port = servicePtr->_port;
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port, ip);
wifi_get_ip_info(STATION_IF, &ip_info);
ip = ip_info.ip.addr;
if (ip)
_reply(0x0F, servicePtr->_name, servicePtr->_proto, servicePtr->_port, ip);
i++;
}
}
return i;
}
void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint16_t port, uint32_t ip) {
int i;
if(replyMask == 0) return;
#ifdef MDNS_DEBUG_TX #ifdef MDNS_DEBUG_TX
Serial.printf("TX: mask:%01X, service:%s, proto:%s, port:%u\n", replyMask, service, proto, port); Serial.printf("TX: service:%s, proto:%s\n", service, proto);
#endif
char sdHostName[] = "_services";
size_t sdHostNameLen = 9;
char sdServiceName[] = "_dns-sd";
size_t sdServiceNameLen = 7;
char sdProtoName[] = "_udp";
size_t sdProtoNameLen = 4;
char underscore[] = "_";
// build service name with _
char serviceName[os_strlen(service) + 2];
os_strcpy(serviceName, underscore);
os_strcat(serviceName, service);
size_t serviceNameLen = os_strlen(serviceName);
//build proto name with _
char protoName[5];
os_strcpy(protoName, underscore);
os_strcat(protoName, proto);
size_t protoNameLen = 4;
//local string
char localName[] = "local";
size_t localNameLen = 5;
//terminator
char terminator[] = "\0";
//Write the header
_conn->flush();
uint8_t head[12] = {
0x00, 0x00, //ID = 0
0x84, 0x00, //Flags = response + authoritative answer
0x00, 0x00, //Question count
0x00, 0x01, //Answer count
0x00, 0x00, //Name server records
0x00, 0x00, //Additional records
};
_conn->append(reinterpret_cast<const char*>(head), 12);
// Send the Name field (ie. "_services._dns-sd._udp.local")
_conn->append(reinterpret_cast<const char*>(&sdHostNameLen), 1); // length of "_services"
_conn->append(reinterpret_cast<const char*>(sdHostName), sdHostNameLen); // "_services"
_conn->append(reinterpret_cast<const char*>(&sdServiceNameLen), 1); // length of "_dns-sd"
_conn->append(reinterpret_cast<const char*>(sdServiceName), sdServiceNameLen);// "_dns-sd"
_conn->append(reinterpret_cast<const char*>(&sdProtoNameLen), 1); // length of "_udp"
_conn->append(reinterpret_cast<const char*>(sdProtoName), sdProtoNameLen); // "_udp"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
//Send the type, class, ttl and rdata length
uint8_t ptrDataLen = serviceNameLen + protoNameLen + localNameLen + 4; // 4 is three label sizes and the terminator
uint8_t ptrAttrs[10] = {
0x00, 0x0c, //PTR record query
0x00, 0x01, //Class IN
0x00, 0x00, 0x11, 0x94, //TTL 4500
0x00, ptrDataLen, //RData length
};
_conn->append(reinterpret_cast<const char*>(ptrAttrs), 10);
//Send the RData (ie. "_http._tcp.local")
_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // length of "_http"
_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // length of "_tcp"
_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
ip_addr_t ifaddr;
ifaddr.addr = multicastInterface;
_conn->setMulticastInterface(ifaddr);
_conn->send();
}
}
}
void MDNSResponder::_replyToInstanceRequest(uint8_t questionMask, uint8_t responseMask, char * service, char *proto, uint16_t port, IPAddress multicastInterface) {
int i;
if(questionMask == 0) return;
if(responseMask == 0) return;
#ifdef MDNS_DEBUG_TX
Serial.printf("TX: qmask:%01X, rmask:%01X, service:%s, proto:%s, port:%u\n", questionMask, responseMask, service, proto, port);
#endif #endif
@ -946,9 +1028,13 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
//terminator //terminator
char terminator[] = "\0"; char terminator[] = "\0";
uint8_t answerMask = responseMask & questionMask;
uint8_t answerCount = 0; uint8_t answerCount = 0;
uint8_t additionalMask = responseMask & ~questionMask;
uint8_t additionalCount = 0;
for(i=0;i<4;i++){ for(i=0;i<4;i++){
if(replyMask & (1 << i)) answerCount++; if(answerMask & (1 << i)) answerCount++;
if(additionalMask & (1 << i)) additionalCount++;
} }
@ -960,18 +1046,20 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
0x00, 0x00, //Question count 0x00, 0x00, //Question count
0x00, answerCount, //Answer count 0x00, answerCount, //Answer count
0x00, 0x00, //Name server records 0x00, 0x00, //Name server records
0x00, 0x00, //Additional records 0x00, additionalCount, //Additional records
}; };
_conn->append(reinterpret_cast<const char*>(head), 12); _conn->append(reinterpret_cast<const char*>(head), 12);
for(int responseSection = 0; responseSection < 2; ++responseSection) {
// PTR Response // PTR Response
if(replyMask & 0x8){ if((responseSection == 0 ? answerMask : additionalMask) & 0x8){
// Send the Name field (ie. "_http._tcp.local") // Send the Name field (ie. "_http._tcp.local")
_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // length of "_http"
_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // lenght of "_tcp" _conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // length of "_tcp"
_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp" _conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
@ -980,33 +1068,33 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
uint8_t ptrAttrs[10] = { uint8_t ptrAttrs[10] = {
0x00, 0x0c, //PTR record query 0x00, 0x0c, //PTR record query
0x00, 0x01, //Class IN 0x00, 0x01, //Class IN
0x00, 0x00, 0x11, 0x94, //TTL 4500 0x00, 0x00, 0x00, 0x78, //TTL 120
0x00, ptrDataLen, //RData length 0x00, ptrDataLen, //RData length
}; };
_conn->append(reinterpret_cast<const char*>(ptrAttrs), 10); _conn->append(reinterpret_cast<const char*>(ptrAttrs), 10);
//Send the RData (ie. "My IOT device._http._tcp.local") //Send the RData (ie. "My IOT device._http._tcp.local")
_conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1); // lenght of "My IOT device" _conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1); // length of "My IOT device"
_conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device"
_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // length of "_http"
_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // lenght of "_tcp" _conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // length of "_tcp"
_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp" _conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
} }
//TXT Responce //TXT Responce
if(replyMask & 0x4){ if((responseSection == 0 ? answerMask : additionalMask) & 0x4){
//Send the name field (ie. "My IOT device._http._tcp.local") //Send the name field (ie. "My IOT device._http._tcp.local")
_conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1); // lenght of "My IOT device" _conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1); // length of "My IOT device"
_conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device"
_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // length of "_http"
_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // lenght of "_tcp" _conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // length of "_tcp"
_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp" _conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
@ -1014,7 +1102,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
uint8_t txtDataLen = _getServiceTxtLen(service,proto); uint8_t txtDataLen = _getServiceTxtLen(service,proto);
uint8_t txtAttrs[10] = { uint8_t txtAttrs[10] = {
0x00, 0x10, //TXT record query 0x00, 0x10, //TXT record query
0x00, 0x01, //Class IN 0x80, 0x01, //Class IN, with cache flush
0x00, 0x00, 0x11, 0x94, //TTL 4500 0x00, 0x00, 0x11, 0x94, //TTL 4500
0x00, txtDataLen, //RData length 0x00, txtDataLen, //RData length
}; };
@ -1024,7 +1112,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
MDNSTxt * txtPtr = _getServiceTxt(service,proto); MDNSTxt * txtPtr = _getServiceTxt(service,proto);
while(txtPtr !=0){ while(txtPtr !=0){
uint8_t txtLen = txtPtr->_txt.length(); uint8_t txtLen = txtPtr->_txt.length();
_conn->append(reinterpret_cast<const char*>(&txtLen), 1); // lenght of txt _conn->append(reinterpret_cast<const char*>(&txtLen), 1); // length of txt
_conn->append(reinterpret_cast<const char*>(txtPtr->_txt.c_str()), txtLen);// the txt _conn->append(reinterpret_cast<const char*>(txtPtr->_txt.c_str()), txtLen);// the txt
txtPtr = txtPtr->_next; txtPtr = txtPtr->_next;
} }
@ -1032,15 +1120,15 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
//SRV Responce //SRV Responce
if(replyMask & 0x2){ if((responseSection == 0 ? answerMask : additionalMask) & 0x2){
//Send the name field (ie. "My IOT device._http._tcp.local") //Send the name field (ie. "My IOT device._http._tcp.local")
_conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1); // lenght of "My IOT device" _conn->append(reinterpret_cast<const char*>(&instanceNameLen), 1); // length of "My IOT device"
_conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device" _conn->append(reinterpret_cast<const char*>(instanceName.c_str()), instanceNameLen);// "My IOT device"
_conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // lenght of "_http" _conn->append(reinterpret_cast<const char*>(&serviceNameLen), 1); // length of "_http"
_conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http" _conn->append(reinterpret_cast<const char*>(serviceName), serviceNameLen); // "_http"
_conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // lenght of "_tcp" _conn->append(reinterpret_cast<const char*>(&protoNameLen), 1); // length of "_tcp"
_conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp" _conn->append(reinterpret_cast<const char*>(protoName), protoNameLen); // "_tcp"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
@ -1063,20 +1151,20 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
}; };
_conn->append(reinterpret_cast<const char*>(srvRData), 6); _conn->append(reinterpret_cast<const char*>(srvRData), 6);
//Send the RData (ie. "esp8266.local") //Send the RData (ie. "esp8266.local")
_conn->append(reinterpret_cast<const char*>(&hostNameLen), 1); // lenght of "esp8266" _conn->append(reinterpret_cast<const char*>(&hostNameLen), 1); // length of "esp8266"
_conn->append(reinterpret_cast<const char*>(hostName.c_str()), hostNameLen);// "esp8266" _conn->append(reinterpret_cast<const char*>(hostName.c_str()), hostNameLen);// "esp8266"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
} }
// A Response // A Response
if(replyMask & 0x1){ if((responseSection == 0 ? answerMask : additionalMask) & 0x1){
//Send the RData (ie. "esp8266.local") //Send the RData (ie. "esp8266.local")
_conn->append(reinterpret_cast<const char*>(&hostNameLen), 1); // lenght of "esp8266" _conn->append(reinterpret_cast<const char*>(&hostNameLen), 1); // length of "esp8266"
_conn->append(reinterpret_cast<const char*>(hostName.c_str()), hostNameLen);// "esp8266" _conn->append(reinterpret_cast<const char*>(hostName.c_str()), hostNameLen);// "esp8266"
_conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // lenght "local" _conn->append(reinterpret_cast<const char*>(&localNameLen), 1); // length "local"
_conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local" _conn->append(reinterpret_cast<const char*>(localName), localNameLen); // "local"
_conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator _conn->append(reinterpret_cast<const char*>(&terminator), 1); // terminator
@ -1089,6 +1177,7 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
_conn->append(reinterpret_cast<const char*>(aaaAttrs), 10); _conn->append(reinterpret_cast<const char*>(aaaAttrs), 10);
// Send RData // Send RData
uint32_t ip = multicastInterface;
uint8_t aaaRData[4] = { uint8_t aaaRData[4] = {
(uint8_t)(ip & 0xFF), //IP first octet (uint8_t)(ip & 0xFF), //IP first octet
(uint8_t)((ip >> 8) & 0xFF), //IP second octet (uint8_t)((ip >> 8) & 0xFF), //IP second octet
@ -1097,9 +1186,10 @@ void MDNSResponder::_reply(uint8_t replyMask, char * service, char *proto, uint1
}; };
_conn->append(reinterpret_cast<const char*>(aaaRData), 4); _conn->append(reinterpret_cast<const char*>(aaaRData), 4);
} }
}
ip_addr_t ifaddr; ip_addr_t ifaddr;
ifaddr.addr = ip; ifaddr.addr = multicastInterface;
_conn->setMulticastInterface(ifaddr); _conn->setMulticastInterface(ifaddr);
_conn->send(); _conn->send();
} }

View File

@ -125,9 +125,10 @@ private:
uint16_t _getServicePort(char *service, char *proto); uint16_t _getServicePort(char *service, char *proto);
MDNSTxt * _getServiceTxt(char *name, char *proto); MDNSTxt * _getServiceTxt(char *name, char *proto);
uint16_t _getServiceTxtLen(char *name, char *proto); uint16_t _getServiceTxtLen(char *name, char *proto);
IPAddress _getRequestMulticastInterface();
void _parsePacket(); void _parsePacket();
void _reply(uint8_t replyMask, char * service, char *proto, uint16_t port, uint32_t ip); void _replyToTypeEnumRequest(IPAddress multicastInterface);
size_t advertiseServices(); // advertise all hosted services void _replyToInstanceRequest(uint8_t questionMask, uint8_t responseMask, char * service, char *proto, uint16_t port, IPAddress multicastInterface);
MDNSAnswer* _getAnswerFromIdx(int idx); MDNSAnswer* _getAnswerFromIdx(int idx);
int _getNumAnswers(); int _getNumAnswers();
bool _listen(); bool _listen();