From aed41e04134477b192c038aeb16b17c47b959fc7 Mon Sep 17 00:00:00 2001 From: Apple Date: Fri, 18 Dec 2020 09:38:36 +0000 Subject: [PATCH] mDNSResponder-1310.60.4.tar.gz --- Clients/dns-sd.c | 32 +++++++++---- Makefile | 2 +- ServiceRegistration/log_srp.m | 8 ++-- ServiceRegistration/route.c | 47 +++++++++++++++++-- ServiceRegistration/route.h | 9 ++++ mDNSMacOSX/utilities/system_utilities.m | 61 +++++++++++++++---------- mDNSShared/dns_sd.h | 2 +- 7 files changed, 120 insertions(+), 41 deletions(-) diff --git a/Clients/dns-sd.c b/Clients/dns-sd.c index 947b9dd..446f15e 100644 --- a/Clients/dns-sd.c +++ b/Clients/dns-sd.c @@ -910,6 +910,20 @@ static void DNSSD_API reg_reply(DNSServiceRef sdref, const DNSServiceFlags flags if (!(flags & kDNSServiceFlagsMoreComing)) fflush(stdout); } +static int snprintf_safe(char *str, size_t size, const char *format, ...) +{ + int length = 0; + va_list ptr; + va_start(ptr, format); + int result = vsnprintf(str, size, format, ptr); + va_end(ptr); + if (result > 0 && size > 0) + { + length = MIN((size_t)result, size-1); + } + return length; +} + // Output the wire-format domainname pointed to by rd static int snprintd(char *p, int max, const unsigned char **rd) { @@ -917,7 +931,7 @@ static int snprintd(char *p, int max, const unsigned char **rd) const char *const end = p + max; while (**rd) { - p += snprintf(p, end-p, "%.*s.", **rd, *rd+1); + p += snprintf_safe(p, end-p, "%.*s.", **rd, *rd+1); *rd += 1 + **rd; } *rd += 1; // Advance over the final zero byte @@ -934,18 +948,18 @@ static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, size_t rdb_size, unsi unsigned char *ptr; int i; rdataDS *rrds = (rdataDS *)rd; - p += snprintf(p, rdb + rdb_size - p, "%d %d %d ", + p += snprintf_safe(p, rdb + rdb_size - p, "%d %d %d ", rrds->alg, swap16(rrds->keyTag), rrds->digestType); ptr = (unsigned char *)(rd + DS_FIXED_SIZE); for (i = 0; i < (rdlen - DS_FIXED_SIZE); i++) - p += snprintf(p, rdb + rdb_size - p, "%x", ptr[i]); + p += snprintf_safe(p, rdb + rdb_size - p, "%x", ptr[i]); break; } case kDNSServiceType_DNSKEY: { rdataDNSKey *rrkey = (rdataDNSKey *)rd; - p += snprintf(p, rdb + rdb_size - p, "%d %d %d %u ", swap16(rrkey->flags), rrkey->proto, + p += snprintf_safe(p, rdb + rdb_size - p, "%d %d %d %u ", swap16(rrkey->flags), rrkey->proto, rrkey->alg, (unsigned int)keytag((unsigned char *)rrkey, rdlen)); base64Encode(p, rdb + rdb_size - p, (unsigned char *)(rd + DNSKEY_FIXED_SIZE), rdlen - DNSKEY_FIXED_SIZE); break; @@ -993,7 +1007,7 @@ static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, size_t rdb_size, unsi for (i = 0; i < wlen * 8; i++) { if (bmap[i>>3] & (128 >> (i&7))) - p += snprintf(p, rdb + rdb_size - p, " %s ", DNSTypeName(type + i)); + p += snprintf_safe(p, rdb + rdb_size - p, " %s ", DNSTypeName(type + i)); } bmap += wlen; bitmaplen -= wlen; @@ -1018,7 +1032,7 @@ static void ParseDNSSECRecords(uint16_t rrtype, char *rdb, size_t rdb_size, unsi inceptClock = (unsigned long)swap32(rrsig->sigInceptTime); FormatTime(inceptClock, inceptTimeBuf, sizeof(inceptTimeBuf)); - p += snprintf(p, rdb + rdb_size - p, " %-7s %d %d %d %s %s %7d ", + p += snprintf_safe(p, rdb + rdb_size - p, " %-7s %d %d %d %s %s %7d ", DNSTypeName(swap16(rrsig->typeCovered)), rrsig->alg, rrsig->labels, swap32(rrsig->origTTL), expTimeBuf, inceptTimeBuf, swap16(rrsig->keyTag)); @@ -1086,7 +1100,7 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags, switch (rrtype) { case kDNSServiceType_A: - snprintf(rdb, sizeof(rdb), "%d.%d.%d.%d", rd[0], rd[1], rd[2], rd[3]); + snprintf_safe(rdb, sizeof(rdb), "%d.%d.%d.%d", rd[0], rd[1], rd[2], rd[3]); break; case kDNSServiceType_NS: @@ -1098,7 +1112,7 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags, case kDNSServiceType_SOA: p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // mname - p += snprintf(p, rdb + sizeof(rdb) - p, " "); + p += snprintf_safe(p, rdb + sizeof(rdb) - p, " "); p += snprintd(p, rdb + sizeof(rdb) - p, &rd); // rname snprintf(p, rdb + sizeof(rdb) - p, " Ser %d Ref %d Ret %d Exp %d Min %d", ntohl(((uint32_t*)rd)[0]), ntohl(((uint32_t*)rd)[1]), ntohl(((uint32_t*)rd)[2]), ntohl(((uint32_t*)rd)[3]), ntohl(((uint32_t*)rd)[4])); @@ -1111,7 +1125,7 @@ static void DNSSD_API qr_reply(DNSServiceRef sdref, const DNSServiceFlags flags, break; case kDNSServiceType_SRV: - p += snprintf(p, rdb + sizeof(rdb) - p, "%d %d %d ", // priority, weight, port + p += snprintf_safe(p, rdb + sizeof(rdb) - p, "%d %d %d ", // priority, weight, port ntohs(*(unsigned short*)rd), ntohs(*(unsigned short*)(rd+2)), ntohs(*(unsigned short*)(rd+4))); rd += 6; snprintd(p, rdb + sizeof(rdb) - p, &rd); // target host diff --git a/Makefile b/Makefile index 69c06bd..f1763dc 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ include $(MAKEFILEPATH)/pb_makefiles/platform.make -MVERS = "mDNSResponder-1310.40.42" +MVERS = "mDNSResponder-1310.60.4" VER = ifneq ($(strip $(GCC_VERSION)),) diff --git a/ServiceRegistration/log_srp.m b/ServiceRegistration/log_srp.m index 79a25ed..6e55707 100644 --- a/ServiceRegistration/log_srp.m +++ b/ServiceRegistration/log_srp.m @@ -49,9 +49,11 @@ srp_os_log_copy_formatted_string_ipv6_addr_segment(id value) ptr = buf; ptr_limit = buf + sizeof(buf); for (size_t i = 0; i < data.length; i++) { - require_action((size_t)(ptr_limit - ptr) > strlen(delimiter) + 2, exit, - a_str = AStrWithFormat(@"", i)); - ptr += snprintf(ptr, ptr_limit - ptr, "%s%02x", delimiter, addr_data[i]); + size_t remaining = (size_t)(ptr_limit - ptr); + int result = snprintf(ptr, remaining, "%s%02x", delimiter, addr_data[i]); + require_action(result > 0 && result < remaining, exit, + a_str = AStrWithFormat(@"", i, remaining)); + ptr += result; if ((i + 1) % 2 == 0) { delimiter = ":"; } else { diff --git a/ServiceRegistration/route.c b/ServiceRegistration/route.c index dda17f5..de6c3e2 100644 --- a/ServiceRegistration/route.c +++ b/ServiceRegistration/route.c @@ -829,6 +829,8 @@ router_discovery_stop(interface_t *interface, uint64_t now) interface->router_discovery_complete = true; interface->router_discovery_in_progress = false; interface->vicarious_router_discovery_in_progress = false; + // clear out need_reconfigure_prefix when router_discovery_complete is set back to true. + interface->need_reconfigure_prefix = false; flush_stale_routers(interface, now); // See if we need a new prefix on the interface. @@ -840,11 +842,25 @@ adjust_router_received_time(interface_t *const interface, const uint64_t now, co { icmp_message_t *router; + if (interface->routers == NULL) { + if (interface->advertise_ipv6_prefix) { + SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __ipv6_prefix); + INFO("adjust_router_received_time: No router information available for the interface - " + "ifname: " PUB_S_SRP ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, + interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __ipv6_prefix)); + } else { + INFO("adjust_router_received_time: No router information available for the interface - " + "ifname: " PUB_S_SRP, interface->name); + } + + goto exit; + } + for (router = interface->routers; router != NULL; router = router->next) { SEGMENTED_IPv6_ADDR_GEN_SRP(router->source.s6_addr, __router_src_addr_buf); // Only adjust the received time once. if (router->received_time_already_adjusted) { - DEBUG("adjust_router_received_time: received time already adjusted - remaining time: %llu, " + INFO("adjust_router_received_time: received time already adjusted - remaining time: %llu, " "router src: " PRI_SEGMENTED_IPv6_ADDR_SRP, (now - router->received_time) / MSEC_PER_SEC, SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_addr_buf)); continue; @@ -856,7 +872,7 @@ adjust_router_received_time(interface_t *const interface, const uint64_t now, co "now: %" PRIu64 ", time_adjusted: %" PRId64, now, time_adjusted)); router->received_time = now + time_adjusted; router->received_time_already_adjusted = true; // Only adjust the icmp message received time once. - DEBUG("adjust_router_received_time: router received time is adjusted - router src: " PRI_SEGMENTED_IPv6_ADDR_SRP + INFO("adjust_router_received_time: router received time is adjusted - router src: " PRI_SEGMENTED_IPv6_ADDR_SRP ", adjusted value: %" PRId64, SEGMENTED_IPv6_ADDR_PARAM_SRP(router->source.s6_addr, __router_src_addr_buf), time_adjusted); } @@ -1002,7 +1018,8 @@ routing_policy_evaluate(interface_t *interface, bool assume_changed) interface->preferred_lifetime == 0)) { SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf); - INFO("routing_policy_evaluate: advertising prefix again - ifname: " PUB_S_SRP ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, interface->name, + INFO("routing_policy_evaluate: advertising prefix again - ifname: " PUB_S_SRP + ", prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, interface->name, SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf)); // If we were deprecating, stop. @@ -1029,6 +1046,19 @@ routing_policy_evaluate(interface_t *interface, bool assume_changed) something_changed = true; } } + // If there is no on-link prefix present, and srp-mdns-proxy itself is advertising the prefix, and it has configured + // an on-link prefix, and the interface is not thread interface, and it just got an interface address removal event, + // it is possible that the IPv6 routing has been flushed due to loss of address in configd, so here we explicitly + // reconfigure the IPv6 prefix and the routing. + else if (interface->need_reconfigure_prefix && !on_link_prefix_present && interface->advertise_ipv6_prefix && + interface->on_link_prefix_configured && !interface->is_thread) { + SEGMENTED_IPv6_ADDR_GEN_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf); + INFO("routing_policy_evaluate: reconfigure ipv6 prefix due to possible network changes -" + " prefix: " PRI_SEGMENTED_IPv6_ADDR_SRP, + SEGMENTED_IPv6_ADDR_PARAM_SRP(interface->ipv6_prefix.s6_addr, __prefix_buf)); + interface_prefix_configure(interface->ipv6_prefix, interface); + interface->need_reconfigure_prefix = false; + } // If we've been looking to see if there's an on-link prefix, and we got one from the new router advertisement, // stop looking for new one. @@ -2121,6 +2151,8 @@ post_solicit_policy_evaluate(void *context) interface_prefix_evaluate(interface); routing_policy_evaluate(interface, true); + // Always clear out need_reconfigure_prefix when router_discovery_complete is set to true. + interface->need_reconfigure_prefix = false; } static void @@ -2790,6 +2822,7 @@ interface_shutdown(interface_t *interface) interface->router_discovery_complete = false; interface->router_discovery_in_progress = false; interface->vicarious_router_discovery_in_progress = false; + interface->need_reconfigure_prefix = false; interface->link = NULL; } @@ -3076,6 +3109,13 @@ ifaddr_callback(void *__unused context, const char *name, const addr_t *address, INFO("ifaddr_callback: making all routers stale and start router discovery due to removed address"); adjust_router_received_time(interface, ioloop_timenow(), -(MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_STALE + MSEC_PER_SEC)); + // Explicitly set router_discovery_complete to false so we can ensure that srp-mdns-proxy will start + // the router discovery immediately. + interface->router_discovery_complete = false; + // Set need_reconfigure_prefix to true to let routing_policy_evaluate know that the router discovery + // is caused by interface removal event, so when the router discovery finished and nothing changes, + // it can reconfigure the IPv6 routing in case configured does not handle it correctly. + interface->need_reconfigure_prefix = true; routing_policy_evaluate(interface, false); } } @@ -5029,6 +5069,7 @@ partition_maybe_advertise_service(void) } if (i == 16) { INFO("partition_maybe_advertise_service: no listener."); + return; } // The add service function requires a remove prior to the add, so if we are doing an add, we need to wait diff --git a/ServiceRegistration/route.h b/ServiceRegistration/route.h index 84d2931..740028e 100644 --- a/ServiceRegistration/route.h +++ b/ServiceRegistration/route.h @@ -135,6 +135,15 @@ struct interface { // and are waiting 20 seconds to snoop for replies to that RD message that are // multicast. If we hear no replies during that time, we trigger router discovery. bool vicarious_router_discovery_in_progress; + + // Indicates that we have received an interface removal event, it is useful when srp-mdns-proxy is changed to a new + // network where the network signature are the same and they both have no IPv6 service (so no IPv6 prefix will be + // removed), in such case there will be no change from srp-mdns-proxy's point of view. However, configd may still + // flush the IPv6 routing since changing network would cause interface up/down. When the flushing happens, + // srp-mdns-proxy should be able to reconfigure the IPv6 routing by reconfiguring IPv6 prefix. By setting + // need_reconfigure_prefix only when interface address removal happens and check it during the routing evaluation + // srp-mdns-proxy can reconfigure it after the routing evaluation finishes, like router discovery. + bool need_reconfigure_prefix; }; typedef enum icmp_option_type { diff --git a/mDNSMacOSX/utilities/system_utilities.m b/mDNSMacOSX/utilities/system_utilities.m index 35a907c..5f7b86a 100644 --- a/mDNSMacOSX/utilities/system_utilities.m +++ b/mDNSMacOSX/utilities/system_utilities.m @@ -21,6 +21,7 @@ #if TARGET_OS_OSX #import #import +#import #endif // TARGET_OS_OSX bool IsAppleInternalBuild(void) @@ -29,37 +30,49 @@ bool IsAppleInternalBuild(void) } #if TARGET_OS_OSX -util_enclosure_color_t -util_get_enclosure_color_str(char * const out_str, uint8_t len, uint8_t *out_size) +WEAK_LINK_FORCE_IMPORT(_UTHardwareColorGetCurrentEnclosureColor); + +static util_enclosure_color_t +_uti_get_enclosure_color_str(char * const out_str, uint8_t len, uint8_t *out_size) { util_enclosure_color_t color_type = util_enclosure_color_none; if (@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)) { - UTHardwareColor enclosureColor; - if (_UTHardwareColorGetCurrentEnclosureColor(&enclosureColor)) { - switch (enclosureColor.type) { - case UTHardwareColorTypeRGB: { - int size = snprintf(out_str, len, "%u,%u,%u", - enclosureColor.rgb.r, enclosureColor.rgb.g, enclosureColor.rgb.b); - if (size < len) { - color_type = util_enclosure_color_rgb; - *out_size = size; + if(_UTHardwareColorGetCurrentEnclosureColor) { + UTHardwareColor enclosureColor; + if (_UTHardwareColorGetCurrentEnclosureColor(&enclosureColor)) { + switch (enclosureColor.type) { + case UTHardwareColorTypeRGB: { + int size = snprintf(out_str, len, "%u,%u,%u", + enclosureColor.rgb.r, enclosureColor.rgb.g, enclosureColor.rgb.b); + if (size > 0 && size < len) { + color_type = util_enclosure_color_rgb; + *out_size = size; + } + break; } - break; - } - case UTHardwareColorTypeIndexed: { - int size = snprintf(out_str, len, "%i", enclosureColor.index); - if (size < len) { - color_type = util_enclosure_color_index; - *out_size = size; + case UTHardwareColorTypeIndexed: { + int size = snprintf(out_str, len, "%i", enclosureColor.index); + if (size > 0 && size < len) { + color_type = util_enclosure_color_index; + *out_size = size; + } + break; } - break; + default: + *out_size = 0; + break; } - default: - *out_size = 0; - break; } } - } else { + } + return color_type; +} + +util_enclosure_color_t +util_get_enclosure_color_str(char * const out_str, uint8_t len, uint8_t *out_size) +{ + util_enclosure_color_t color_type = _uti_get_enclosure_color_str(out_str, len, out_size); + if (color_type == util_enclosure_color_none) { uint8_t red = 0; uint8_t green = 0; uint8_t blue = 0; @@ -69,7 +82,7 @@ util_get_enclosure_color_str(char * const out_str, uint8_t len, uint8_t *out_siz if (kIOReturnSuccess == rGetDeviceColor) { int size = snprintf(out_str, len, "%u,%u,%u", red, green, blue); - if (size < len) { + if (size > 0 && size < len) { color_type = util_enclosure_color_rgb; *out_size = size; } diff --git a/mDNSShared/dns_sd.h b/mDNSShared/dns_sd.h index d6d1bc8..0b1145e 100644 --- a/mDNSShared/dns_sd.h +++ b/mDNSShared/dns_sd.h @@ -66,7 +66,7 @@ */ #ifndef _DNS_SD_H -#define _DNS_SD_H 13104042 +#define _DNS_SD_H 13106004 #ifdef __cplusplus extern "C" { -- 2.45.2