• Home
  • Raw
  • Download

Lines Matching +full:ipv4 +full:- +full:single +full:- +full:target

8  * RFC 6762 - Multicast DNS<br>
9 * RFC 6763 - DNS-Based Service Discovery
16 * -------------------------
18 * - Sending goodbye messages (zero ttl) - shutdown, DHCP lease about to expire, DHCP turned off...
19 * - Sending negative responses NSEC
20 * - Fragmenting replies if required
21 * - Individual known answer detection for all local IPv6 addresses
22 * - Dynamic size of outgoing packet
54 * Author: Jasper Verschueren <jasper.verschueren@apart-audio.com>
78 #error "If you want to use MDNS with IPv4, you have to define LWIP_IGMP=1 in your lwipopts.h"
92 /* IPv4 multicast group 224.0.0.251 */
120 #define MDNS_RESPONSE_DELAY (LWIP_RAND() %(MDNS_RESPONSE_DELAY_MAX - \
125 #define MDNS_RESPONSE_TC_DELAY_MS (LWIP_RAND() % (MDNS_RESPONSE_TC_DELAY_MAX - \
131 /* first probe timeout SHOULD be random 0-250 ms*/
145 * -> increase by a factor 2 with every response sent.
254 if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { in check_host()
260 if (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY) { in check_host()
266 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { in check_host()
279 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { in check_host()
288 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { in check_host()
292 && (rr->type == DNS_RRTYPE_A || rr->type == DNS_RRTYPE_ANY)) { in check_host()
297 if (rr->type == DNS_RRTYPE_AAAA || rr->type == DNS_RRTYPE_ANY) { in check_host()
319 if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { in check_service()
325 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && in check_service()
326 (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { in check_service()
332 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && in check_service()
333 (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { in check_service()
339 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { in check_service()
341 if (rr->type == DNS_RRTYPE_SRV || rr->type == DNS_RRTYPE_ANY) { in check_service()
344 if (rr->type == DNS_RRTYPE_TXT || rr->type == DNS_RRTYPE_ANY) { in check_service()
366 if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { in check_request()
372 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && in check_request()
373 (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { in check_request()
378 if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { in check_request()
380 if (rr->type == DNS_RRTYPE_SRV || rr->type == DNS_RRTYPE_ANY) { in check_request()
383 if (rr->type == DNS_RRTYPE_TXT || rr->type == DNS_RRTYPE_ANY) { in check_request()
403 pkt->parse_offset = mdns_readname(pkt->pbuf, pkt->parse_offset, &info->domain); in mdns_read_rr_info()
404 if (pkt->parse_offset == MDNS_READNAME_ERROR) { in mdns_read_rr_info()
408 copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); in mdns_read_rr_info()
412 pkt->parse_offset += copied; in mdns_read_rr_info()
413 info->type = lwip_ntohs(field16); in mdns_read_rr_info()
415 copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); in mdns_read_rr_info()
419 pkt->parse_offset += copied; in mdns_read_rr_info()
420 info->klass = lwip_ntohs(field16); in mdns_read_rr_info()
437 if (pkt->pbuf->tot_len < pkt->parse_offset) { in mdns_read_question()
441 if (pkt->questions_left) { in mdns_read_question()
443 pkt->questions_left--; in mdns_read_question()
446 res = mdns_read_rr_info(pkt, &question->info); in mdns_read_question()
452 question->unicast = question->info.klass & 0x8000; in mdns_read_question()
453 question->info.klass &= 0x7FFF; in mdns_read_question()
466 * @param num_left number of answers left -> answers, authoritative or additional
473 if (pkt->questions_left) { in mdns_read_answer()
478 if (pkt->pbuf->tot_len < pkt->parse_offset) { in mdns_read_answer()
486 (*num_left)--; in mdns_read_answer()
489 res = mdns_read_rr_info(pkt, &answer->info); in mdns_read_answer()
495 answer->cache_flush = answer->info.klass & 0x8000; in mdns_read_answer()
496 answer->info.klass &= 0x7FFF; in mdns_read_answer()
498 copied = pbuf_copy_partial(pkt->pbuf, &ttl, sizeof(ttl), pkt->parse_offset); in mdns_read_answer()
502 pkt->parse_offset += copied; in mdns_read_answer()
503 answer->ttl = lwip_ntohl(ttl); in mdns_read_answer()
505 copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); in mdns_read_answer()
509 pkt->parse_offset += copied; in mdns_read_answer()
510 answer->rd_length = lwip_ntohs(field16); in mdns_read_answer()
512 answer->rd_offset = pkt->parse_offset; in mdns_read_answer()
513 pkt->parse_offset += answer->rd_length; in mdns_read_answer()
523 * @param destination The target address to send to (usually multicast address)
549 struct mdns_service *serv = mdns->services[i]; in mdns_announce()
570 * @param result pointer to save result in -> MDNS_LEXICOGRAPHICAL_EQUAL,
585 if (ans_a->info.klass != ans_b->info.klass) { in mdns_lexicographical_comparison()
586 if (ans_a->info.klass > ans_b->info.klass) { in mdns_lexicographical_comparison()
596 if (ans_a->info.type != ans_b->info.type) { in mdns_lexicographical_comparison()
597 if (ans_a->info.type > ans_b->info.type) { in mdns_lexicographical_comparison()
609 * We have 4 different RR types in our authoritative section (if IPv4 and IPv6 is enabled): A, in mdns_lexicographical_comparison()
619 if (ans_a->info.type != DNS_RRTYPE_SRV && ans_b->info.type != DNS_RRTYPE_SRV) { in mdns_lexicographical_comparison()
620 len = LWIP_MIN(ans_a->rd_length, ans_b->rd_length); in mdns_lexicographical_comparison()
622 a_rd = pbuf_get_at(pkt_a->pbuf, (u16_t)(ans_a->rd_offset + i)); in mdns_lexicographical_comparison()
623 b_rd = pbuf_get_at(pkt_b->pbuf, (u16_t)(ans_b->rd_offset + i)); in mdns_lexicographical_comparison()
636 if (ans_a->rd_length != ans_b->rd_length) { in mdns_lexicographical_comparison()
637 if (ans_a->rd_length > ans_b->rd_length) { in mdns_lexicographical_comparison()
651 a_rd = pbuf_get_at(pkt_a->pbuf, (u16_t)(ans_a->rd_offset + i)); in mdns_lexicographical_comparison()
652 b_rd = pbuf_get_at(pkt_b->pbuf, (u16_t)(ans_b->rd_offset + i)); in mdns_lexicographical_comparison()
665 res = mdns_readname(pkt_a->pbuf, ans_a->rd_offset + 6, &domain_a); in mdns_lexicographical_comparison()
669 res = mdns_readname(pkt_b->pbuf, ans_b->rd_offset + 6, &domain_b); in mdns_lexicographical_comparison()
719 a_list->size = 0; in mdns_init_answer_list()
721 a_list->offset[i] = 0; in mdns_init_answer_list()
744 int pos = a_list->size; in mdns_push_answer_to_sorted_list()
747 u16_t num_left = pkt->authoritative; in mdns_push_answer_to_sorted_list()
748 u16_t parse_offset = pkt->parse_offset; in mdns_push_answer_to_sorted_list()
751 if ((a_list->size + 1) >= MDNS_PROBE_TIEBREAK_MAX_ANSWERS) { in mdns_push_answer_to_sorted_list()
755 for (i = 0; i < a_list->size; i++) { in mdns_push_answer_to_sorted_list()
757 pkt->parse_offset = a_list->offset[i]; in mdns_push_answer_to_sorted_list()
772 for (j = (a_list->size + 1); j>i; j--) { in mdns_push_answer_to_sorted_list()
773 a_list->offset[j] = a_list->offset[j-1]; in mdns_push_answer_to_sorted_list()
779 a_list->offset[pos] = new_offset; in mdns_push_answer_to_sorted_list()
780 a_list->size++; in mdns_push_answer_to_sorted_list()
782 pkt->parse_offset = parse_offset; in mdns_push_answer_to_sorted_list()
796 if (q->info.type == DNS_RRTYPE_ANY || q->info.type == a->info.type) { in mdns_is_answer_to_question()
798 if (mdns_domain_eq(&q->info.domain, &a->info.domain)) { in mdns_is_answer_to_question()
814 inpkt->pbuf = outpkt->pbuf; in mdns_convert_out_to_in_pkt()
815 inpkt->parse_offset = SIZEOF_DNS_HDR; in mdns_convert_out_to_in_pkt()
817 inpkt->questions = inpkt->questions_left = outpkt->questions; in mdns_convert_out_to_in_pkt()
818 inpkt->answers = inpkt->answers_left = outpkt->answers; in mdns_convert_out_to_in_pkt()
819 inpkt->authoritative = inpkt->authoritative_left = outpkt->authoritative; in mdns_convert_out_to_in_pkt()
820 inpkt->additional = inpkt->additional_left = outpkt->additional; in mdns_convert_out_to_in_pkt()
833 /* Arbitrarily chose 200 -> don't want to see more then that. It's only in mdns_debug_print_answer()
839 …pos = snprintf(string, sizeof(string), "Type = %2d, class = %1d, rdata = ", a->info.type, a->info.… in mdns_debug_print_answer()
840 for (i = 0; ((i < a->rd_length) && ((pos + 4*i) < 195)) ; i++) { in mdns_debug_print_answer()
841 … snprintf(&string[pos + 4*i], 5, "%3d ", (u8_t)pbuf_get_at(pkt->pbuf, (u16_t)(a->rd_offset + i))); in mdns_debug_print_answer()
893 pkt_parse_offset = pkt->parse_offset; in mdns_handle_probe_tiebreaking()
900 while (pkt->questions_left) { in mdns_handle_probe_tiebreaking()
923 while (pkt->questions_left) { in mdns_handle_probe_tiebreaking()
959 while(pkt->authoritative_left) { in mdns_handle_probe_tiebreaking()
960 save_parse_offset = pkt->parse_offset; in mdns_handle_probe_tiebreaking()
961 res = mdns_read_answer(pkt, &pkt_a, &pkt->authoritative_left); in mdns_handle_probe_tiebreaking()
978 pkt->authoritative_left = pkt->authoritative; in mdns_handle_probe_tiebreaking()
981 * - lexicographically later? -> we win, ignore the packet. in mdns_handle_probe_tiebreaking()
982 * - lexicographically earlier? -> we loose, wait one second and retry. in mdns_handle_probe_tiebreaking()
983 * - lexicographically equal? -> no conflict, check other probes. in mdns_handle_probe_tiebreaking()
995 pkt->parse_offset = pkt_a_list.offset[i]; in mdns_handle_probe_tiebreaking()
996 res = mdns_read_answer(pkt, &pkt_a, &pkt->authoritative_left); in mdns_handle_probe_tiebreaking()
1027 * -> check if one of both have more answers to the question */ in mdns_handle_probe_tiebreaking()
1051 pkt->parse_offset = pkt_parse_offset; in mdns_handle_probe_tiebreaking()
1054 pkt->questions_left = pkt->questions; in mdns_handle_probe_tiebreaking()
1055 pkt->authoritative_left = pkt->authoritative; in mdns_handle_probe_tiebreaking()
1083 while (pkt->questions_left) { in mdns_parse_pkt_questions()
1098 reply->unicast_reply_requested = 1; in mdns_parse_pkt_questions()
1101 reply->host_replies |= check_host(netif, &q.info, &reply->host_reverse_v6_replies); in mdns_parse_pkt_questions()
1104 service = mdns->services[i]; in mdns_parse_pkt_questions()
1108 reply->serv_replies[i] |= check_service(service, &q.info); in mdns_parse_pkt_questions()
1132 while (pkt->answers_left) { in mdns_parse_pkt_known_answers()
1138 res = mdns_read_answer(pkt, &ans, &pkt->answers_left); in mdns_parse_pkt_known_answers()
1155 match = reply->host_replies & check_host(netif, &ans.info, &rev_v6); in mdns_parse_pkt_known_answers()
1165 len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans); in mdns_parse_pkt_known_answers()
1171 reply->host_replies &= ~REPLY_HOST_PTR_V4; in mdns_parse_pkt_known_answers()
1177 reply->host_reverse_v6_replies &= ~rev_v6; in mdns_parse_pkt_known_answers()
1178 if (reply->host_reverse_v6_replies == 0) { in mdns_parse_pkt_known_answers()
1179 reply->host_replies &= ~REPLY_HOST_PTR_V6; in mdns_parse_pkt_known_answers()
1187 pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip4_addr(netif), ans.rd_length) == 0) { in mdns_parse_pkt_known_answers()
1189 reply->host_replies &= ~REPLY_HOST_A; in mdns_parse_pkt_known_answers()
1196 pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip6_addr(netif, 0), ans.rd_length) == 0) { in mdns_parse_pkt_known_answers()
1198 reply->host_replies &= ~REPLY_HOST_AAAA; in mdns_parse_pkt_known_answers()
1205 service = mdns->services[i]; in mdns_parse_pkt_known_answers()
1209 match = reply->serv_replies[i] & check_service(service, &ans.info); in mdns_parse_pkt_known_answers()
1222 len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans); in mdns_parse_pkt_known_answers()
1228 reply->serv_replies[i] &= ~REPLY_SERVICE_TYPE_PTR; in mdns_parse_pkt_known_answers()
1235 reply->serv_replies[i] &= ~REPLY_SERVICE_NAME_PTR; in mdns_parse_pkt_known_answers()
1246 len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); in mdns_parse_pkt_known_answers()
1252 len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); in mdns_parse_pkt_known_answers()
1258 len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); in mdns_parse_pkt_known_answers()
1259 if (len != sizeof(field16) || lwip_ntohs(field16) != service->port) { in mdns_parse_pkt_known_answers()
1264 len = mdns_readname(pkt->pbuf, read_pos, &known_ans); in mdns_parse_pkt_known_answers()
1270 reply->serv_replies[i] &= ~REPLY_SERVICE_SRV; in mdns_parse_pkt_known_answers()
1274 if (service->txtdata.length == ans.rd_length && in mdns_parse_pkt_known_answers()
1275 pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) { in mdns_parse_pkt_known_answers()
1277 reply->serv_replies[i] &= ~REPLY_SERVICE_TXT; in mdns_parse_pkt_known_answers()
1305 while (pkt->authoritative_left) { in mdns_parse_pkt_authoritative_answers()
1310 res = mdns_read_answer(pkt, &ans, &pkt->authoritative_left); in mdns_parse_pkt_authoritative_answers()
1327 match = reply->host_replies & check_host(netif, &ans.info, &rev_v6); in mdns_parse_pkt_authoritative_answers()
1329 reply->probe_query_recv = 1; in mdns_parse_pkt_authoritative_answers()
1334 service = mdns->services[i]; in mdns_parse_pkt_authoritative_answers()
1338 match = reply->serv_replies[i] & check_service(service, &ans.info); in mdns_parse_pkt_authoritative_answers()
1341 reply->probe_query_recv = 1; in mdns_parse_pkt_authoritative_answers()
1361 dest->host_questions |= src->host_questions; in mdns_add_msg_to_delayed()
1362 dest->host_replies |= src->host_replies; in mdns_add_msg_to_delayed()
1363 dest->host_reverse_v6_replies |= src->host_reverse_v6_replies; in mdns_add_msg_to_delayed()
1365 dest->serv_questions[i] |= src->serv_questions[i]; in mdns_add_msg_to_delayed()
1366 dest->serv_replies[i] |= src->serv_replies[i]; in mdns_add_msg_to_delayed()
1369 dest->flags = src->flags; in mdns_add_msg_to_delayed()
1370 dest->cache_flush = src->cache_flush; in mdns_add_msg_to_delayed()
1371 dest->tx_id = src->tx_id; in mdns_add_msg_to_delayed()
1372 dest->legacy_query = src->legacy_query; in mdns_add_msg_to_delayed()
1377 * - Perform probe tiebreaking when in probing state
1378 * - Parse all questions and set bits what answers to send
1379 * - Clear pending answers if known answers are supplied
1380 * - Define which type of answer is requested
1381 * - Send out packet or put it on hold until after random time
1399 if ((mdns->state == MDNS_STATE_PROBING) || in mdns_handle_question()
1400 (mdns->state == MDNS_STATE_ANNOUNCE_WAIT)) { in mdns_handle_question()
1403 if ((pkt->questions > 0) && (pkt->answers == 0) && in mdns_handle_question()
1404 (pkt->authoritative > 0) && (pkt->additional == 0)) { in mdns_handle_question()
1405 /* This should be a probe message -> call probe handler */ in mdns_handle_question()
1410 if ((mdns->state != MDNS_STATE_COMPLETE) && in mdns_handle_question()
1411 (mdns->state != MDNS_STATE_ANNOUNCING)) { in mdns_handle_question()
1424 /* Parse answers -> count as known answers because it's a question */ in mdns_handle_question()
1429 if (pkt->next_answer) { in mdns_handle_question()
1430 /* Also parse known-answers from additional packets */ in mdns_handle_question()
1431 struct mdns_packet *pkta = pkt->next_answer; in mdns_handle_question()
1437 pkta = pkta->next_answer; in mdns_handle_question()
1440 /* Parse authoritative answers -> probing */ in mdns_handle_question()
1446 /* Ignore additional answers -> do not have any need for them at the moment */ in mdns_handle_question()
1447 if(pkt->additional) { in mdns_handle_question()
1449 ("MDNS: Query contains additional answers -> they are discarded\n")); in mdns_handle_question()
1468 * - source port != 5353 in mdns_handle_question()
1469 * - a legacy query can only contain 1 question in mdns_handle_question()
1471 if (pkt->source_port != LWIP_IANA_PORT_MDNS) { in mdns_handle_question()
1472 if (pkt->questions == 1) { in mdns_handle_question()
1475 reply.tx_id = pkt->tx_id; in mdns_handle_question()
1489 * - Answering to a single question with a unique answer (not a probe). in mdns_handle_question()
1490 * - Answering to a probe query via unicast. in mdns_handle_question()
1491 * - Answering to a probe query via multicast if not multicasted within 250ms. in mdns_handle_question()
1493 * unique answer? -> not if it includes service type or name ptr's in mdns_handle_question()
1499 if ( ((pkt->questions == 1) && (!shared_answer) && !reply.probe_query_recv) in mdns_handle_question()
1504 if (IP_IS_V6_VAL(pkt->source_addr) && reply.probe_query_recv in mdns_handle_question()
1505 && !reply.unicast_reply_requested && !mdns->ipv6.multicast_probe_timeout) { in mdns_handle_question()
1510 if (IP_IS_V4_VAL(pkt->source_addr) && reply.probe_query_recv in mdns_handle_question()
1511 && !reply.unicast_reply_requested && !mdns->ipv4.multicast_probe_timeout) { in mdns_handle_question()
1527 if ((IP_IS_V6_VAL(pkt->source_addr) && mdns->ipv6.multicast_timeout_25TTL)) { in mdns_handle_question()
1532 if ((IP_IS_V4_VAL(pkt->source_addr) && mdns->ipv4.multicast_timeout_25TTL)) { in mdns_handle_question()
1537 || pkt->recv_unicast in mdns_handle_question()
1549 * - it's a IPv6 incoming packet in mdns_handle_question()
1550 * - no message is in it yet in mdns_handle_question()
1552 if (IP_IS_V6_VAL(pkt->source_addr) && !mdns->ipv6.unicast_msg_in_use) { in mdns_handle_question()
1554 SMEMCPY(&mdns->ipv6.delayed_msg_unicast.dest_addr, &pkt->source_addr, sizeof(ip_addr_t)); in mdns_handle_question()
1555 mdns->ipv6.delayed_msg_unicast.dest_port = pkt->source_port; in mdns_handle_question()
1557 mdns_add_msg_to_delayed(&mdns->ipv6.delayed_msg_unicast, &reply); in mdns_handle_question()
1560 &mdns->ipv6.unicast_msg_in_use); in mdns_handle_question()
1564 /* Add answers to IPv4 waiting list if: in mdns_handle_question()
1565 * - it's a IPv4 incoming packet in mdns_handle_question()
1566 * - no message is in it yet in mdns_handle_question()
1568 if (IP_IS_V4_VAL(pkt->source_addr) && !mdns->ipv4.unicast_msg_in_use) { in mdns_handle_question()
1569 LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: add answers to unicast IPv4 waiting list\n")); in mdns_handle_question()
1570 SMEMCPY(&mdns->ipv4.delayed_msg_unicast.dest_addr, &pkt->source_addr, sizeof(ip_addr_t)); in mdns_handle_question()
1571 mdns->ipv4.delayed_msg_unicast.dest_port = pkt->source_port; in mdns_handle_question()
1573 mdns_add_msg_to_delayed(&mdns->ipv4.delayed_msg_unicast, &reply); in mdns_handle_question()
1576 &mdns->ipv4.unicast_msg_in_use); in mdns_handle_question()
1583 * - it's a IPv6 incoming packet in mdns_handle_question()
1584 * - the 1 second timeout is passed (RFC6762 section 6) in mdns_handle_question()
1585 * - and it's not a probe packet in mdns_handle_question()
1587 * - it's a IPv6 incoming packet in mdns_handle_question()
1588 * - and it's a probe packet in mdns_handle_question()
1590 if (IP_IS_V6_VAL(pkt->source_addr) && !mdns->ipv6.multicast_timeout in mdns_handle_question()
1594 mdns_add_msg_to_delayed(&mdns->ipv6.delayed_msg_multicast, &reply); in mdns_handle_question()
1597 &mdns->ipv6.multicast_msg_waiting); in mdns_handle_question()
1599 else if (IP_IS_V6_VAL(pkt->source_addr) && reply.probe_query_recv) { in mdns_handle_question()
1602 mdns_add_msg_to_delayed(&mdns->ipv6.delayed_msg_multicast, &reply); in mdns_handle_question()
1604 mdns->ipv6.multicast_msg_waiting = 1; in mdns_handle_question()
1608 /* Add answers to IPv4 waiting list if: in mdns_handle_question()
1609 * - it's a IPv4 incoming packet in mdns_handle_question()
1610 * - the 1 second timeout is passed (RFC6762 section 6) in mdns_handle_question()
1611 * - and it's not a probe packet in mdns_handle_question()
1613 * - it's a IPv4 incoming packet in mdns_handle_question()
1614 * - and it's a probe packet in mdns_handle_question()
1616 if (IP_IS_V4_VAL(pkt->source_addr) && !mdns->ipv4.multicast_timeout in mdns_handle_question()
1618 LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: add answers to multicast IPv4 waiting list\n")); in mdns_handle_question()
1620 mdns_add_msg_to_delayed(&mdns->ipv4.delayed_msg_multicast, &reply); in mdns_handle_question()
1623 &mdns->ipv4.multicast_msg_waiting); in mdns_handle_question()
1625 else if (IP_IS_V4_VAL(pkt->source_addr) && reply.probe_query_recv) { in mdns_handle_question()
1626 LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: add answers to probe multicast IPv4 waiting list\n")); in mdns_handle_question()
1628 mdns_add_msg_to_delayed(&mdns->ipv4.delayed_msg_multicast, &reply); in mdns_handle_question()
1630 mdns->ipv4.multicast_msg_waiting = 1; in mdns_handle_question()
1638 SMEMCPY(&reply.dest_addr, &pkt->source_addr, sizeof(ip_addr_t)); in mdns_handle_question()
1639 reply.dest_port = pkt->source_port; in mdns_handle_question()
1653 if (IP_IS_V6_VAL(pkt->source_addr)) { in mdns_handle_question()
1654 if (mdns->ipv6.multicast_timeout && !reply.probe_query_recv) { in mdns_handle_question()
1662 if (IP_IS_V4_VAL(pkt->source_addr)) { in mdns_handle_question()
1663 if (mdns->ipv4.multicast_timeout && !reply.probe_query_recv) { in mdns_handle_question()
1679 if (IP_IS_V6_VAL(pkt->source_addr)) { in mdns_handle_question()
1684 if (IP_IS_V4_VAL(pkt->source_addr)) { in mdns_handle_question()
1696 * - Called by timer
1697 * - Call mdns_handle_question
1698 * - Do cleanup
1706 struct netif *from = netif_get_by_index(pkt->pbuf->if_idx); in mdns_handle_tc_question()
1711 pending_tc_questions = pkt->next_tc_question; in mdns_handle_tc_question()
1715 while (prev && prev->next_tc_question != pkt) { in mdns_handle_tc_question()
1716 prev = prev->next_tc_question; in mdns_handle_tc_question()
1719 prev->next_tc_question = pkt->next_tc_question; in mdns_handle_tc_question()
1722 while (pkt->next_answer) { in mdns_handle_tc_question()
1723 struct mdns_packet *ans = pkt->next_answer; in mdns_handle_tc_question()
1724 pkt->next_answer = ans->next_answer; in mdns_handle_tc_question()
1725 pbuf_free(ans->pbuf); in mdns_handle_tc_question()
1728 pbuf_free(pkt->pbuf); in mdns_handle_tc_question()
1734 * - Check if we exceeded the maximum of 15 conflicts in 10seconds.
1747 mdns->num_conflicts++; in mdns_conflict_save_time()
1748 mdns->conflict_time[mdns->index] = sys_now(); in mdns_conflict_save_time()
1750 LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: conflict timestamp list, insert index = %d\n", mdns->index)); in mdns_conflict_save_time()
1752 LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: time no. %d = %"U32_F"\n", i, mdns->conflict_time[i])); in mdns_conflict_save_time()
1755 if (mdns->num_conflicts >= MDNS_PROBE_MAX_CONFLICTS_BEFORE_RATE_LIMIT) { in mdns_conflict_save_time()
1757 index2 = (mdns->index + 1) % MDNS_PROBE_MAX_CONFLICTS_BEFORE_RATE_LIMIT; in mdns_conflict_save_time()
1759 diff = mdns->conflict_time[mdns->index] - mdns->conflict_time[index2]; in mdns_conflict_save_time()
1763 mdns->rate_limit_activated = 1; in mdns_conflict_save_time()
1767 mdns->index = (mdns->index + 1) % MDNS_PROBE_MAX_CONFLICTS_BEFORE_RATE_LIMIT; in mdns_conflict_save_time()
1772 * - Check if we exceeded the maximum of 15 conflicts in 10seconds.
1773 * - Let the user know there is a conflict.
1815 * - Handle responses on probe query
1816 * - Perform conflict resolution on every packet (RFC6762 section 9)
1832 * (LWIP_IANA_PORT_MDNS) -> RFC6762 section 6 */ in mdns_handle_response()
1833 if (pkt->source_port != LWIP_IANA_PORT_MDNS) { in mdns_handle_response()
1838 while (pkt->questions_left) { in mdns_handle_response()
1853 total_answers_left = pkt->answers_left + pkt->authoritative_left + pkt->additional_left; in mdns_handle_response()
1874 if (req && req->only_ptr) { in mdns_handle_response()
1876 if (memcmp (req->service.name, ans.info.domain.name, req->service.length) != 0) in mdns_handle_response()
1883 if (req && req->result_fn) { in mdns_handle_response()
1888 if (req->only_ptr) { in mdns_handle_response()
1893 p = pbuf_skip(pkt->pbuf, ans.rd_offset, &offset); in mdns_handle_response()
1906 u16_t len = mdns_readname(pkt->pbuf, ans.rd_offset + off, &data.dom); in mdns_handle_response()
1909 data.dom.length = ans.rd_length - off; in mdns_handle_response()
1910 memcpy(&data.dom, (const char *)p->payload + offset + off, data.dom.length); in mdns_handle_response()
1914 memcpy(&data, (const char *)p->payload + offset, 6); in mdns_handle_response()
1921 req->result_fn(&ans, (const char *)&data + off, len, flags, req->arg); in mdns_handle_response()
1924 req->result_fn(&ans, (const char *)p->payload + offset, ans.rd_length, flags, req->arg); in mdns_handle_response()
1933 if ((mdns->state == MDNS_STATE_PROBING) || in mdns_handle_response()
1934 (mdns->state == MDNS_STATE_ANNOUNCE_WAIT)) { in mdns_handle_response()
1946 struct mdns_service* service = mdns->services[i]; in mdns_handle_response()
1968 else if ((mdns->state == MDNS_STATE_ANNOUNCING) || in mdns_handle_response()
1969 (mdns->state == MDNS_STATE_COMPLETE)) { in mdns_handle_response()
1974 /* Evaluate unique hostname records -> A and AAAA */ in mdns_handle_response()
1981 /* Evaluate rdata -> to see if it's a copy of our own data */ in mdns_handle_response()
1985 pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip4_addr(netif), ans.rd_length) == 0) { in mdns_handle_response()
1986 … LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: response equals our own IPv4 address record -> no conflict\n")); in mdns_handle_response()
1995 … if (pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip6_addr(netif, i), ans.rd_length) == 0) { in mdns_handle_response()
1996 …GF(MDNS_DEBUG, ("mDNS: response equals our own iPv6 address record, num = %d -> no conflict\n",i)); in mdns_handle_response()
2004 /* Evaluate unique service name records -> SRV and TXT */ in mdns_handle_response()
2006 struct mdns_service* service = mdns->services[i]; in mdns_handle_response()
2016 /* Evaluate rdata -> to see if it's a copy of our own data */ in mdns_handle_response()
2024 len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); in mdns_handle_response()
2030 len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); in mdns_handle_response()
2036 len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); in mdns_handle_response()
2037 if (len != sizeof(field16) || lwip_ntohs(field16) != service->port) { in mdns_handle_response()
2042 len = mdns_readname(pkt->pbuf, read_pos, &srv_ans); in mdns_handle_response()
2047 … LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: response equals our own SRV record -> no conflict\n")); in mdns_handle_response()
2052 if (service->txtdata.length == ans.rd_length && in mdns_handle_response()
2053 pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) { in mdns_handle_response()
2054 … LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: response equals our own TXT record -> no conflict\n")); in mdns_handle_response()
2062 LWIP_DEBUGF(MDNS_DEBUG, ("mDNS: Conflict resolution -> reset to probing state\n")); in mdns_handle_response()
2069 pkt->answers_left = 0; in mdns_handle_response()
2070 pkt->authoritative_left = 0; in mdns_handle_response()
2071 pkt->additional_left = 0; in mdns_handle_response()
2076 * Handles both IPv4 and IPv6 UDP pcbs.
2089 …LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Received IPv%d MDNS packet, len %d\n", IP_IS_V6(addr) ? 6 : 4, p->… in mdns_recv()
2103 /* Ignore non-standard queries in multicast packets (RFC 6762, section 18.3) */ in mdns_recv()
2118 /* Source address check (RFC6762 section 11) -> for responses. in mdns_recv()
2119 * Source address check (RFC6762 section 5.5) -> for queries. in mdns_recv()
2161 pkt->next_tc_question = pending_tc_questions; in mdns_recv()
2163 /* question with truncated flags, need to wait 400-500ms before replying */ in mdns_recv()
2169 /* this packet is a known-answer packet for a truncated question previously received */ in mdns_recv()
2172 if ((packet.source_port == q->source_port) && in mdns_recv()
2173 ip_addr_eq(&packet.source_addr, &q->source_addr)) in mdns_recv()
2175 q = q->next_tc_question; in mdns_recv()
2183 /* insert this known-ansert in question */ in mdns_recv()
2184 pkt->next_answer = q->next_answer; in mdns_recv()
2185 q->next_answer = pkt; in mdns_recv()
2210 if (args->status_changed.state != 0) { in mdns_netif_ext_status_callback()
2216 if (args->link_changed.state != 0) { in mdns_netif_ext_status_callback()
2237 outmsg->host_questions = QUESTION_PROBE_HOST_ANY; in mdns_define_probe_rrs_to_send()
2240 struct mdns_service* service = mdns->services[i]; in mdns_define_probe_rrs_to_send()
2244 outmsg->serv_questions[i] = QUESTION_PROBE_SERVICE_NAME_ANY; in mdns_define_probe_rrs_to_send()
2250 outmsg->host_replies = REPLY_HOST_A; in mdns_define_probe_rrs_to_send()
2256 outmsg->host_replies |= REPLY_HOST_AAAA; in mdns_define_probe_rrs_to_send()
2262 struct mdns_service *serv = mdns->services[i]; in mdns_define_probe_rrs_to_send()
2264 outmsg->serv_replies[i] = REPLY_SERVICE_SRV; in mdns_define_probe_rrs_to_send()
2293 switch (mdns->state) { in mdns_probe_and_announce()
2298 /*if ipv4 wait with probing until address is set*/ in mdns_probe_and_announce()
2307 mdns->state = MDNS_STATE_PROBING; in mdns_probe_and_announce()
2308 mdns->sent_num++; in mdns_probe_and_announce()
2312 if (mdns->sent_num >= MDNS_PROBE_COUNT) { in mdns_probe_and_announce()
2313 mdns->state = MDNS_STATE_ANNOUNCE_WAIT; in mdns_probe_and_announce()
2314 mdns->sent_num = 0; in mdns_probe_and_announce()
2317 if (mdns->sent_num && mdns->rate_limit_activated == 1) { in mdns_probe_and_announce()
2327 if (mdns->sent_num == 0) { in mdns_probe_and_announce()
2329 mdns->state = MDNS_STATE_ANNOUNCING; in mdns_probe_and_announce()
2331 mdns->rate_limit_activated = 0; in mdns_probe_and_announce()
2339 mdns->sent_num++; in mdns_probe_and_announce()
2341 if (mdns->sent_num >= MDNS_ANNOUNCE_COUNT) { in mdns_probe_and_announce()
2343 mdns->state = MDNS_STATE_COMPLETE; in mdns_probe_and_announce()
2344 mdns->sent_num = 0; in mdns_probe_and_announce()
2347 announce_delay = MDNS_ANNOUNCE_DELAY_MS * (1 << (mdns->sent_num - 1)); in mdns_probe_and_announce()
2383 MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(hostname))); in mdns_resp_add_netif()
2387 mdns->ipv4.delayed_msg_multicast.dest_port = LWIP_IANA_PORT_MDNS; in mdns_resp_add_netif()
2388 SMEMCPY(&mdns->ipv4.delayed_msg_multicast.dest_addr, &v4group, in mdns_resp_add_netif()
2393 mdns->ipv6.delayed_msg_multicast.dest_port = LWIP_IANA_PORT_MDNS; in mdns_resp_add_netif()
2394 SMEMCPY(&mdns->ipv6.delayed_msg_multicast.dest_addr, &v6group, in mdns_resp_add_netif()
2443 struct mdns_service *service = mdns->services[i]; in mdns_resp_remove_netif()
2484 MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, len)); in mdns_resp_rename_netif()
2485 mdns->name[len] = '\0'; /* null termination in case new name is shorter than previous */ in mdns_resp_rename_netif()
2535 if (mdns->services[slot] == NULL) { in mdns_resp_add_service()
2544 MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(name))); in mdns_resp_add_service()
2545 MEMCPY(&srv->service, service, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(service))); in mdns_resp_add_service()
2546 srv->txt_fn = txt_fn; in mdns_resp_add_service()
2547 srv->txt_userdata = txt_data; in mdns_resp_add_service()
2548 srv->proto = (u16_t)proto; in mdns_resp_add_service()
2549 srv->port = port; in mdns_resp_add_service()
2551 mdns->services[slot] = srv; in mdns_resp_add_service()
2574 …LWIP_ERROR("mdns_resp_del_service: Invalid Service ID", (mdns->services[slot] != NULL), return ERR… in mdns_resp_del_service()
2576 srv = mdns->services[slot]; in mdns_resp_del_service()
2577 mdns->services[slot] = NULL; in mdns_resp_del_service()
2604 …LWIP_ERROR("mdns_resp_rename_service: Invalid Service ID", (mdns->services[slot] != NULL), return … in mdns_resp_rename_service()
2606 srv = mdns->services[slot]; in mdns_resp_rename_service()
2608 MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, len)); in mdns_resp_rename_service()
2609 srv->name[len] = '\0'; /* null termination in case new name is shorter than previous */ in mdns_resp_rename_service()
2632 return mdns_domain_add_label(&service->txtdata, txt, txt_len); in mdns_resp_add_service_txtitem()
2647 if (req && req->result_fn) { in mdns_search_stop()
2648 req->result_fn = NULL; in mdns_search_stop()
2691 req->result_fn = result_fn; in mdns_search_service()
2692 req->arg = arg; in mdns_search_service()
2693 req->proto = (u16_t)proto; in mdns_search_service()
2694 req->qtype = DNS_RRTYPE_PTR; in mdns_search_service()
2695 if (proto == DNSSD_PROTO_UDP && strcmp(service, "_services._dns-sd") == 0) { in mdns_search_service()
2696 req->only_ptr = 1; /* don't check other answers */ in mdns_search_service()
2698 mdns_domain_add_string(&req->service, service); in mdns_search_service()
2700 MEMCPY(&req->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(name))); in mdns_search_service()
2734 if (mdns->state >= MDNS_STATE_ANNOUNCING) { in mdns_resp_announce()
2735 /* Announce on IPv6 and IPv4 */ in mdns_resp_announce()
2778 mdns->sent_num = 0; in mdns_resp_restart_delay()
2779 mdns->state = MDNS_STATE_PROBE_WAIT; in mdns_resp_restart_delay()
2781 /* RFC6762 section 8.1: If fifteen conflicts occur within any ten-second period, in mdns_resp_restart_delay()
2785 if (mdns->rate_limit_activated == 1) { in mdns_resp_restart_delay()
2825 mdns_pcb->ttl = MDNS_IP_TTL; in mdns_resp_init()
2851 s = mdns->services[slot]; in mdns_get_service_txt_userdata()
2852 return s ? s->txt_userdata : NULL; in mdns_get_service_txt_userdata()