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)
{
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
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;
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;
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));
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:
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]));
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
include $(MAKEFILEPATH)/pb_makefiles/platform.make
-MVERS = "mDNSResponder-1310.40.42"
+MVERS = "mDNSResponder-1310.60.4"
VER =
ifneq ($(strip $(GCC_VERSION)),)
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(@"<failed to decode - buffer space not enough: i: %lu>", 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(@"<failed to decode - snprintf: result: %ld remain: %lu>", i, remaining));
+ ptr += result;
if ((i + 1) % 2 == 0) {
delimiter = ":";
} else {
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.
{
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;
"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);
}
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.
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.
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
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;
}
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);
}
}
}
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
// 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 {
#if TARGET_OS_OSX
#import <UniformTypeIdentifiers/UniformTypeIdentifiersPriv.h>
#import <IOKit/platform/IOPlatformSupportPrivate.h>
+#import <SoftLinking/WeakLinking.h>
#endif // TARGET_OS_OSX
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;
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;
}
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 13104042
+#define _DNS_SD_H 13106004
#ifdef __cplusplus
extern "C" {