Skip to content

Commit 8acabea

Browse files
mDNSResponder-2200.60.25.0.4
Imported from mDNSResponder-2200.60.25.0.4.tar.gz
1 parent a9f4049 commit 8acabea

File tree

19 files changed

+2475
-848
lines changed

19 files changed

+2475
-848
lines changed

Clients/dnssdutil/dnssdutil.c

Lines changed: 1230 additions & 155 deletions
Large diffs are not rendered by default.

ServiceRegistration/dnssd-proxy.c

Lines changed: 168 additions & 62 deletions
Large diffs are not rendered by default.

ServiceRegistration/ioloop.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ struct dso_transport {
201201
uint8_t *NULLABLE buf;
202202
dso_state_t *NULLABLE dso;
203203
tls_context_t *NULLABLE tls_context;
204-
addr_t address, multicast;
204+
addr_t address, multicast, local;
205205
size_t message_length_len;
206206
size_t message_length, message_cur;
207207
uint8_t message_length_bytes[2];
@@ -383,6 +383,7 @@ bool ioloop_udp_send_message(comm_t *NONNULL comm, addr_t *NULLABLE source, addr
383383
struct iovec *NONNULL iov, int iov_len);
384384
void ioloop_udp_read_callback(io_t *NONNULL io, void *NULLABLE context);
385385
#endif
386+
int get_num_fds(void);
386387

387388
// Local Variables:
388389
// mode: C

ServiceRegistration/macos-ioloop.c

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,9 @@ datagram_read(comm_t *connection, size_t length, dispatch_data_t content, nw_err
599599
return true;
600600
});
601601
if (ret == true) {
602+
// Set the local address
603+
message->local = connection->local;
604+
602605
// Process the message.
603606
if (connection->listener_state != NULL) {
604607
connection->listener_state->datagram_callback(connection, message, connection->listener_state->context);
@@ -821,6 +824,30 @@ connection_state_changed(comm_t *connection, nw_connection_state_t state, nw_err
821824
}
822825
}
823826

827+
static void
828+
ioloop_connection_get_address_from_endpoint(addr_t *addr, nw_endpoint_t endpoint)
829+
{
830+
nw_endpoint_type_t endpoint_type = nw_endpoint_get_type(endpoint);
831+
if (endpoint_type == nw_endpoint_type_address) {
832+
char *address_string = nw_endpoint_copy_address_string(endpoint);
833+
if (address_string == NULL) {
834+
ERROR("unable to get description of new connection.");
835+
} else {
836+
getipaddr(addr, address_string);
837+
if (addr->sa.sa_family == AF_INET6) {
838+
SEGMENTED_IPv6_ADDR_GEN_SRP(&addr->sin6.sin6_addr, rdata_buf);
839+
INFO("parsed connection local IPv6 address is: " PRI_SEGMENTED_IPv6_ADDR_SRP,
840+
SEGMENTED_IPv6_ADDR_PARAM_SRP(&addr->sin6.sin6_addr, rdata_buf));
841+
} else {
842+
IPv4_ADDR_GEN_SRP(&addr->sin.sin_addr, rdata_buf);
843+
INFO("parsed connection local IPv4 address is: " PRI_IPv4_ADDR_SRP,
844+
IPv4_ADDR_PARAM_SRP(&addr->sin.sin_addr, rdata_buf));
845+
}
846+
}
847+
free(address_string);
848+
}
849+
}
850+
824851
static void
825852
ioloop_connection_set_name_from_endpoint(comm_t *listener, comm_t *connection, nw_endpoint_t endpoint)
826853
{
@@ -835,11 +862,11 @@ ioloop_connection_set_name_from_endpoint(comm_t *listener, comm_t *connection, n
835862
getipaddr(&connection->address, address_string);
836863
if (connection->address.sa.sa_family == AF_INET6) {
837864
SEGMENTED_IPv6_ADDR_GEN_SRP(&connection->address.sin6.sin6_addr, rdata_buf);
838-
INFO("parsed connection IPv6 address is: " PRI_SEGMENTED_IPv6_ADDR_SRP,
865+
INFO("parsed connection remote IPv6 address is: " PRI_SEGMENTED_IPv6_ADDR_SRP,
839866
SEGMENTED_IPv6_ADDR_PARAM_SRP(&connection->address.sin6.sin6_addr, rdata_buf));
840867
} else {
841868
IPv4_ADDR_GEN_SRP(&connection->address.sin.sin_addr, rdata_buf);
842-
INFO("parsed connection IPv4 address is: " PRI_IPv4_ADDR_SRP,
869+
INFO("parsed connection remote IPv4 address is: " PRI_IPv4_ADDR_SRP,
843870
IPv4_ADDR_PARAM_SRP(&connection->address.sin.sin_addr, rdata_buf));
844871
}
845872
}
@@ -905,6 +932,13 @@ connection_callback(comm_t *listener, nw_connection_t new_connection)
905932
connection->name = strdup("unidentified");
906933
}
907934

935+
// Best effort
936+
nw_endpoint_t local_endpoint = nw_connection_copy_connected_local_endpoint(connection->connection);
937+
if (local_endpoint != NULL) {
938+
ioloop_connection_get_address_from_endpoint(&connection->local, endpoint);
939+
nw_release(local_endpoint);
940+
}
941+
908942
connection->datagram_callback = listener->datagram_callback;
909943
connection->tcp_stream = listener->tcp_stream;
910944
connection->server = true;
@@ -975,10 +1009,27 @@ ioloop_listener_cancel(comm_t *connection)
9751009
// connection->listener will be released in ioloop_listener_state_changed_handler: nw_listener_state_cancelled.
9761010
}
9771011
#if UDP_LISTENER_USES_CONNECTION_GROUPS
978-
if (!connection->stream && connection->io.fd != -1) {
979-
ioloop_close(&connection->io);
980-
io->refcnt = 100; // Prevent read_cancel from finalizing the io object
981-
ioloop_read_cancel(&connection->io);
1012+
if (connection->connection_group != NULL) {
1013+
INFO("%p %p", connection, connection->connection_group);
1014+
nw_connection_group_cancel(connection->connection_group);
1015+
}
1016+
#else
1017+
if (!connection->tcp_stream && connection->connection == NULL) {
1018+
int fd = connection->io.fd;
1019+
if (fd != -1) {
1020+
ioloop_close(&connection->io);
1021+
close(fd);
1022+
ioloop_read_cancel(&connection->io);
1023+
if (connection->cancel != NULL) {
1024+
RETAIN_HERE(connection, listener);
1025+
dispatch_async(ioloop_main_queue, ^{
1026+
if (connection->cancel != NULL) {
1027+
connection->cancel(connection->context);
1028+
}
1029+
RELEASE_HERE(connection, listener);
1030+
});
1031+
}
1032+
}
9821033
}
9831034
#endif
9841035
}
@@ -1200,12 +1251,12 @@ ioloop_udp_listener_setup(comm_t *listener, const addr_t *ip_address, uint16_t p
12001251
if (family == AF_INET) {
12011252
IPv4_ADDR_GEN_SRP(&listener->address.sin.sin_addr.s_addr, ipv4_addr_buf);
12021253
ERROR("Can't bind to " PRI_IPv4_ADDR_SRP "#%d: %s",
1203-
IPv4_ADDR_PARAM_SRP(&listener->address.sin.sin_addr.s_addr, ipv4_addr_buf), ntohs(port),
1254+
IPv4_ADDR_PARAM_SRP(&listener->address.sin.sin_addr.s_addr, ipv4_addr_buf), port,
12041255
strerror(errno));
12051256
} else {
12061257
SEGMENTED_IPv6_ADDR_GEN_SRP(&listener->address.sin6.sin6_addr.s6_addr, ipv6_addr_buf);
12071258
ERROR("Can't bind to " PRI_SEGMENTED_IPv6_ADDR_SRP "#%d: %s",
1208-
SEGMENTED_IPv6_ADDR_PARAM_SRP(&listener->address.sin6.sin6_addr.s6_addr, ipv6_addr_buf), ntohs(port),
1259+
SEGMENTED_IPv6_ADDR_PARAM_SRP(&listener->address.sin6.sin6_addr.s6_addr, ipv6_addr_buf), port,
12091260
strerror(errno));
12101261
}
12111262
out:

ServiceRegistration/nat64.c

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ static void
102102
nat64_infra_prefix_monitor_cancel(nat64_infra_prefix_monitor_t *monitor)
103103
{
104104
if (monitor != NULL) {
105-
nat64_prefix_t **ppref, *prefix;
106-
ppref = &monitor->infra_nat64_prefixes;
107-
while (*ppref != NULL) {
108-
prefix = *ppref;
109-
ppref = &prefix->next;
105+
nat64_prefix_t *next;
106+
for (nat64_prefix_t *prefix = monitor->infra_nat64_prefixes; prefix != NULL; prefix = next) {
107+
next = prefix->next;
108+
prefix->next = NULL;
110109
RELEASE_HERE(prefix, nat64_prefix);
111110
}
112111
monitor->infra_nat64_prefixes = NULL;
@@ -142,6 +141,7 @@ nat64_thread_prefix_monitor_cancel(nat64_thread_prefix_monitor_t *monitor)
142141
nat64_prefix_t *next;
143142
for (nat64_prefix_t *prefix = monitor->thread_nat64_prefixes; prefix != NULL; prefix = next) {
144143
next = prefix->next;
144+
prefix->next = NULL;
145145
RELEASE_HERE(prefix, nat64_prefix);
146146
}
147147
monitor->thread_nat64_prefixes = NULL;
@@ -1118,8 +1118,8 @@ nat64_infra_prefix_publisher_publishing_action(nat64_infra_prefix_publisher_t *s
11181118
if (event == NULL) {
11191119
return nat64_infra_prefix_publisher_state_invalid;
11201120
} else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_infra_prefix_changed ||
1121-
event->event_type == nat64_event_nat64_infra_prefix_publisher_shutdown)
1122-
{
1121+
event->event_type == nat64_event_nat64_infra_prefix_publisher_shutdown)
1122+
{
11231123
nat64_prefix_t *infra_prefix;
11241124
for (infra_prefix = event->prefix; infra_prefix; infra_prefix = infra_prefix->next) {
11251125
if (!in6prefix_compare(&infra_prefix->prefix, &state_machine->proposed_prefix->prefix, NAT64_PREFIX_SLASH_96_BYTES)) {
@@ -1148,8 +1148,8 @@ nat64_infra_prefix_publisher_publishing_action(nat64_infra_prefix_publisher_t *s
11481148
return nat64_infra_prefix_publisher_state_wait;
11491149
}
11501150
} else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_went_away ||
1151-
event->event_type == nat64_event_nat64_infra_prefix_publisher_shutdown)
1152-
{
1151+
event->event_type == nat64_event_nat64_infra_prefix_publisher_shutdown)
1152+
{
11531153
// Routable OMR prefix is gone
11541154
SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf);
11551155
INFO("Routable OMR prefix is gone, unpublishing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP,
@@ -1413,8 +1413,8 @@ nat64_br_prefix_publisher_publishing_action(nat64_br_prefix_publisher_t *state_m
14131413
}
14141414
}
14151415
} else if (event->event_type == nat64_event_nat64_br_prefix_publisher_ipv4_default_route_went_away ||
1416-
event->event_type == nat64_event_nat64_br_prefix_publisher_shutdown)
1417-
{
1416+
event->event_type == nat64_event_nat64_br_prefix_publisher_shutdown)
1417+
{
14181418
nat64_unpublish_br_prefix(state_machine);
14191419
return nat64_br_prefix_publisher_state_wait_for_anything;
14201420
} else if (event->event_type == nat64_event_nat64_br_prefix_publisher_infra_prefix_changed) {
@@ -1734,16 +1734,25 @@ nat64_offmesh_route_list_callback(route_state_t *route_state, cti_route_vec_t *r
17341734
void
17351735
nat64_thread_shutdown(route_state_t *route_state)
17361736
{
1737-
nat64_t *nat64 = route_state->nat64;
1738-
if (nat64->nat64_infra_prefix_publisher != NULL) {
1739-
nat64_infra_prefix_publisher_event_t infra_event;
1740-
nat64_infra_prefix_publisher_event_init(&infra_event, nat64_event_nat64_infra_prefix_publisher_shutdown);
1741-
nat64_infra_prefix_publisher_event_deliver(nat64->nat64_infra_prefix_publisher, &infra_event);
1742-
}
1743-
if (nat64->nat64_br_prefix_publisher != NULL) {
1744-
nat64_br_prefix_publisher_event_t br_event;
1745-
nat64_br_prefix_publisher_event_init(&br_event, nat64_event_nat64_br_prefix_publisher_shutdown);
1746-
nat64_br_prefix_publisher_event_deliver(nat64->nat64_br_prefix_publisher, &br_event);
1747-
}
1737+
nat64_t *nat64 = route_state->nat64;
1738+
if (nat64->nat64_infra_prefix_publisher != NULL) {
1739+
nat64_infra_prefix_publisher_event_t infra_event;
1740+
nat64_infra_prefix_publisher_event_init(&infra_event, nat64_event_nat64_infra_prefix_publisher_shutdown);
1741+
nat64_infra_prefix_publisher_event_deliver(nat64->nat64_infra_prefix_publisher, &infra_event);
1742+
}
1743+
if (nat64->nat64_br_prefix_publisher != NULL) {
1744+
nat64_br_prefix_publisher_event_t br_event;
1745+
nat64_br_prefix_publisher_event_init(&br_event, nat64_event_nat64_br_prefix_publisher_shutdown);
1746+
nat64_br_prefix_publisher_event_deliver(nat64->nat64_br_prefix_publisher, &br_event);
1747+
}
17481748
}
17491749
#endif
1750+
1751+
// Local Variables:
1752+
// mode: C
1753+
// tab-width: 4
1754+
// c-file-style: "bsd"
1755+
// c-basic-offset: 4
1756+
// fill-column: 120
1757+
// indent-tabs-mode: nil
1758+
// End:

ServiceRegistration/posix.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ ioloop_dump_object_allocation_stats(void)
7171
INFO(PUB_S_SRP, outbuf);
7272
}
7373
}
74+
int num_fds = get_num_fds();
75+
if (num_fds < 0) {
76+
FAULT("out of file descriptors!!");
77+
abort();
78+
}
79+
INFO("%d file descriptors in use", num_fds);
7480
}
7581

7682
interface_address_state_t *interface_addresses;
@@ -459,22 +465,29 @@ time_t srp_time(void)
459465
return tm.tv_sec;
460466
}
461467

462-
#ifdef DEBUG_FD_LEAKS
463468
int
464469
get_num_fds(void)
465470
{
466-
DIR *dirfd = opendir("/dev/fd");
467471
int num = 0;
472+
DIR *dirfd = opendir("/dev/fd");
468473
if (dirfd == NULL) {
469-
return -1;
474+
if (errno == EMFILE) {
475+
FAULT("per-process open file limit reached.");
476+
return -1;
477+
} else if (errno == ENFILE) {
478+
FAULT("per-system open file limit reached.");
479+
return -1;
480+
} else {
481+
ERROR("errno %d " PUB_S_SRP, errno, strerror(errno));
482+
return 0;
483+
}
470484
}
471485
while (readdir(dirfd) != NULL) {
472486
num++;
473487
}
474488
closedir(dirfd);
475489
return num;
476490
}
477-
#endif // DEBUG_VERBOSE
478491

479492
#ifdef MALLOC_DEBUG_LOGGING
480493
#undef malloc

ServiceRegistration/route.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,7 +3091,7 @@ cti_get_xpanid_callback(void *context, uint64_t new_xpanid, cti_status_t status)
30913091
in6addr_zero(&route_state->xpanid_prefix);
30923092
route_state->xpanid_prefix.s6_addr[0] = 0xfd;
30933093
for (int i = 1; i < 8; i++) {
3094-
route_state->xpanid_prefix.s6_addr[i] = ((route_state->srp_server->xpanid >> ((7 - i) * 8)) & 0xFFU);
3094+
route_state->xpanid_prefix.s6_addr[i] = ((route_state->srp_server->xpanid >> ((8 - i) * 8)) & 0xFFU);
30953095
}
30963096
route_state->have_xpanid_prefix = true;
30973097

@@ -3519,7 +3519,7 @@ partition_start_srp_listener(route_state_t *route_state)
35193519

35203520
INFO("starting listener.");
35213521
route_state->srp_listener = srp_proxy_listen(avoid_ports, num_avoid_ports, partition_proxy_listener_ready,
3522-
partition_srp_listener_canceled, NULL, route_state->srp_server);
3522+
partition_srp_listener_canceled, NULL, NULL, route_state->srp_server);
35233523
if (route_state->srp_listener == NULL) {
35243524
ERROR("partition_start_srp_listener: Unable to start SRP Proxy listener, so can't advertise it");
35253525
return;

ServiceRegistration/service-publisher.c

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,12 @@ service_publisher_is_address_mesh_local(service_publisher_t *publisher, addr_t *
139139
{
140140
if (address->sa.sa_family == AF_INET) {
141141
IPv4_ADDR_GEN_SRP(&address->sin.sin_addr, addr_buf);
142-
INFO(PRI_IPv4_ADDR_SRP "is not mesh-local", IPv4_ADDR_PARAM_SRP(&address->sin.sin_addr, addr_buf));
143-
return false;
142+
if (!IN_LOOPBACK(address->sin.sin_addr.s_addr)) {
143+
INFO(PRI_IPv4_ADDR_SRP "is not mesh-local", IPv4_ADDR_PARAM_SRP(&address->sin.sin_addr, addr_buf));
144+
return false;
145+
}
146+
INFO(PRI_IPv4_ADDR_SRP "is the IPv4 loopback address", IPv4_ADDR_PARAM_SRP(&address->sin.sin_addr, addr_buf));
147+
return true;
144148
}
145149
if (address->sa.sa_family != AF_INET6) {
146150
INFO("address family %d can't be mesh-local", address->sa.sa_family);
@@ -149,24 +153,24 @@ service_publisher_is_address_mesh_local(service_publisher_t *publisher, addr_t *
149153

150154
uint8_t *addr_ptr = (uint8_t *)&address->sin6.sin6_addr;
151155
SEGMENTED_IPv6_ADDR_GEN_SRP(addr_ptr, addr_buf);
152-
if (!publisher->have_ml_eid) {
153-
INFO(PRI_SEGMENTED_IPv6_ADDR_SRP "is not mesh-local",
156+
if (IN6_IS_ADDR_LOOPBACK(&address->sin6.sin6_addr)) {
157+
INFO(PRI_SEGMENTED_IPv6_ADDR_SRP " is the IPv6 loopback address.",
154158
SEGMENTED_IPv6_ADDR_PARAM_SRP(addr_ptr, addr_buf));
155-
return false;
156-
}
157-
158-
int i;
159-
for (i = 0; i < 15; i++) {
160-
if (addr_ptr[i] != 0) {
161-
break;
162-
}
159+
return true;
163160
}
164-
if (i == 15 && addr_ptr[i] == 1) {
165-
INFO(PRI_SEGMENTED_IPv6_ADDR_SRP " is the IPv6 localhost address.",
161+
static const uint8_t ipv4mapped_loopback[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 127, 0, 0, 1 };
162+
if (!memcmp(&address->sin6.sin6_addr, ipv4mapped_loopback, sizeof(ipv4mapped_loopback))) {
163+
INFO(PRI_SEGMENTED_IPv6_ADDR_SRP " is the IPv4-mapped loopback address.",
166164
SEGMENTED_IPv6_ADDR_PARAM_SRP(addr_ptr, addr_buf));
167165
return true;
168166
}
169167

168+
if (!publisher->have_ml_eid) {
169+
INFO(PRI_SEGMENTED_IPv6_ADDR_SRP "is not mesh-local",
170+
SEGMENTED_IPv6_ADDR_PARAM_SRP(addr_ptr, addr_buf));
171+
return false;
172+
}
173+
170174
SEGMENTED_IPv6_ADDR_GEN_SRP(&publisher->thread_mesh_local_address, mle_buf);
171175
if (in6prefix_compare(&address->sin6.sin6_addr, &publisher->thread_mesh_local_address, 8)) {
172176
INFO(PRI_SEGMENTED_IPv6_ADDR_SRP
@@ -816,6 +820,7 @@ service_publisher_listener_cancel(service_publisher_t *publisher)
816820
ioloop_comm_release(publisher->srp_listener);
817821
publisher->srp_listener = NULL;
818822
}
823+
srp_mdns_flush(publisher->server_state);
819824
}
820825

821826
static void
@@ -843,10 +848,12 @@ service_publisher_listener_start(service_publisher_t *publisher)
843848
}
844849
publisher->srp_listener = srp_proxy_listen(NULL, 0, service_publisher_listener_ready,
845850
service_publisher_listener_cancel_callback, NULL,
846-
publisher->server_state);
851+
service_publisher_context_release, publisher->server_state);
847852
if (publisher->srp_listener == NULL) {
848853
ERROR("failed to setup SRP listener");
849854
}
855+
// The listener needs to hold a reference on the service publisher until its context release callback is called.
856+
RETAIN_HERE(publisher, service_publisher);
850857
}
851858

852859
// We go to this state when we have decided to publish, but perhaps do not currently have an SRP listener

ServiceRegistration/srp-gw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct service_instance {
7474
service_t *NONNULL service;
7575
int num_instances;
7676
dns_rr_t *NULLABLE srv, *NULLABLE txt;
77+
bool skip_update;
7778
};
7879

7980
// The update_t structure is used to maintain the ongoing state of a particular DNS Update.

0 commit comments

Comments
 (0)