1 /* srp-mdns-proxy.h 2 * 3 * Copyright (c) 2019-2024 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This file contains structure definitions used by the SRP Advertising Proxy. 18 */ 19 20 #ifndef __SRP_MDNS_PROXY_H__ 21 #define __SRP_MDNS_PROXY_H__ 1 22 23 #include <stddef.h> // For ptrdiff_t 24 #include "ioloop-common.h" // for service_connection_t 25 26 typedef struct adv_instance adv_instance_t; 27 typedef struct adv_record_registration adv_record_t; 28 typedef struct adv_host adv_host_t; 29 typedef struct adv_update adv_update_t; 30 typedef struct client_update client_update_t; 31 typedef struct adv_instance_vec adv_instance_vec_t; 32 typedef struct adv_record_vec adv_record_vec_t; 33 typedef struct srpl_connection srpl_connection_t; 34 typedef struct srp_server_state srp_server_t; 35 typedef struct route_state route_state_t; 36 typedef struct srp_wanted_state srp_wanted_state_t; // private 37 typedef struct srp_xpc_client srp_xpc_client_t; // private 38 typedef struct srpl_domain srpl_domain_t; // private 39 typedef struct service_tracker service_tracker_t; 40 typedef struct thread_tracker thread_tracker_t; 41 typedef struct node_type_tracker node_type_tracker_t; 42 typedef struct service_publisher service_publisher_t; 43 typedef struct dns_host_description dns_host_description_t; 44 typedef struct service_instance service_instance_t; 45 typedef struct service service_t; 46 typedef struct delete delete_t; 47 typedef struct _cti_connection_t *cti_connection_t; 48 typedef struct dnssd_proxy_advertisements dnssd_proxy_advertisements_t; 49 #if SRP_FEATURE_DISCOVERY_PROXY_SERVER 50 typedef struct dnssd_dp_proxy_advertisements dnssd_dp_proxy_advertisements_t; 51 #endif 52 typedef struct dnssd_client dnssd_client_t; 53 typedef struct probe_state probe_state_t; 54 typedef struct srpl_instance srpl_instance_t; 55 typedef struct wanted_service wanted_service_t; 56 57 #ifdef SRP_TEST_SERVER 58 typedef struct dns_service_event dns_service_event_t; 59 typedef struct test_state test_state_t; 60 typedef struct srp_server_state srp_server_t; 61 typedef struct srpl_connection srpl_connection_t; 62 #endif 63 64 #define TSR_TIMESTAMP_STRING_LEN 28 65 66 enum { 67 PRIORITY_DEFAULT = 0, 68 #if !defined(__OPEN__SOURCE__) && !defined(POSIX_BUILD) 69 PRIORITY_HOMEPOD_ODEON = 1, 70 PRIORITY_HOMEPOD_NO_ODEON = 25, 71 PRIORITY_APPLETV_WIFI = 50, 72 PRIORITY_APPLETV_ETHERNET = 75, 73 #endif 74 }; 75 76 // Server internal state 77 struct srp_server_state { 78 #if SRP_TEST_SERVER 79 srp_server_t *NULLABLE next; 80 #endif 81 char *NULLABLE name; 82 adv_host_t *NULLABLE hosts; 83 dnssd_txn_t *NULLABLE shared_registration_txn; 84 srpl_domain_t *NULLABLE srpl_domains; 85 srpl_instance_t *NULLABLE unmatched_instances; 86 #ifdef SRP_TEST_SERVER 87 dns_service_event_t *NULLABLE dns_service_events; 88 test_state_t *NULLABLE test_state; 89 comm_t *NULLABLE srpl_listener; 90 srpl_connection_t *NULLABLE connections; // list of connections that other srp servers create to connect to us 91 int server_id; 92 #endif 93 #if STUB_ROUTER 94 route_state_t *NULLABLE route_state; 95 #endif 96 #if THREAD_DEVICE 97 service_tracker_t *NULLABLE service_tracker; 98 service_publisher_t *NULLABLE service_publisher; 99 thread_tracker_t *NULLABLE thread_tracker; 100 node_type_tracker_t *NULLABLE node_type_tracker; 101 char *NULLABLE wed_ext_address; // For Wake-on End Device, the extended MAC address, if we are in p2p mode 102 struct in6_addr wed_ml_eid; // For Wake-on End Device, the ML-EID, if we are in p2p mode 103 #endif 104 dnssd_proxy_advertisements_t *NULLABLE dnssd_proxy_advertisements; 105 #if SRP_FEATURE_DISCOVERY_PROXY_SERVER 106 dnssd_dp_proxy_advertisements_t *NULLABLE dnssd_dp_proxy_advertisements; 107 #endif 108 dnssd_client_t *NULLABLE dnssd_client; 109 io_t *NULLABLE adv_ctl_listener; 110 wakeup_t *NULLABLE srpl_browse_wakeup; 111 wakeup_t *NULLABLE object_allocation_stats_dump_wakeup; 112 struct in6_addr ula_prefix; 113 uint64_t xpanid; 114 int advertise_interface; 115 116 uint32_t max_lease_time; 117 uint32_t min_lease_time; // thirty seconds 118 uint32_t key_max_lease_time; 119 uint32_t key_min_lease_time; // thirty seconds 120 int full_dump_count; 121 122 uint32_t priority; 123 uint16_t rloc16; 124 125 bool have_rloc16; 126 bool have_mesh_local_address; 127 bool srp_replication_enabled; 128 bool break_srpl_time; 129 #if STUB_ROUTER 130 bool stub_router_enabled; 131 #endif 132 bool srp_unicast_service_blocked; 133 bool srp_anycast_service_blocked; 134 }; 135 136 struct adv_instance { 137 int ref_count; 138 dnssd_txn_t *NULLABLE txn; // The dnssd_txn_t that was created from the shared connection. 139 intptr_t shared_txn; // The shared txn on which the txn for this instance's registration was created 140 adv_host_t *NULLABLE host; // Host to which this service instance belongs 141 adv_update_t *NULLABLE update; // Ongoing update that currently owns this instance, if any. 142 wakeup_t *NULLABLE retry_wakeup; // In case we get a spurious name conflict. 143 char *NONNULL instance_name; // Single label instance name (future: service instance FQDN) 144 char *NONNULL service_type; // Two label service type (e.g., _ipps._tcp) 145 int port; // Port on which service can be found. 146 uint8_t *NULLABLE txt_data; // Contents of txt record 147 uint16_t txt_length; // length of txt record contents 148 message_t *NULLABLE message; // Message that produces the current value of this instance 149 ptrdiff_t recent_message; // Most recent message (never dereference--this is for comparison only). 150 int64_t lease_expiry; // Time when lease expires, relative to ioloop_timenow(). 151 unsigned wakeup_interval; // Exponential backoff interval 152 bool removed; // True if this instance is being kept around for replication. 153 bool update_pending; // True if we got a conflict while updating and are waiting to try again 154 bool anycast; // True if service registration is through anycast service. 155 bool skip_update; // True if we shouldn't actually register this instance 156 }; 157 158 // A record registration 159 struct adv_record_registration { 160 int ref_count; 161 DNSRecordRef NULLABLE rref; // The RecordRef we get back from DNSServiceRegisterRecord(). 162 adv_host_t *NULLABLE host; // The host object to which this record refers. 163 intptr_t shared_txn; // The shared transaction on which this record was registered. 164 adv_update_t *NULLABLE update; // The ongoing update, if any 165 uint8_t *NULLABLE rdata; 166 uint16_t rrtype; // For hosts, always A or AAAA, for instances always TXT, PTR or SRV. 167 uint16_t rdlen; // Length of the RR 168 bool update_pending; // True if we are updating this record and haven't gotten a response yet. 169 }; 170 171 struct adv_host { 172 int ref_count; 173 srp_server_t *NULLABLE server_state; // Server state to which this host belongs. 174 wakeup_t *NONNULL re_register_wakeup; // Wakeup for retry when we run into a name conflict 175 wakeup_t *NONNULL retry_wakeup; // Wakeup for retry when we run into a temporary failure 176 wakeup_t *NONNULL lease_wakeup; // Wakeup at least expiry time 177 adv_host_t *NULLABLE next; // Hosts are maintained in a linked list. 178 adv_update_t *NULLABLE update; // Update to this host, if one is being done 179 char *NONNULL name; // Name of host (without domain) 180 char *NULLABLE registered_name; // The name that is registered, which may be different due to mDNS conflict 181 message_t *NULLABLE message; // Most recent successful SRP update for this host 182 srpl_connection_t *NULLABLE srpl_connection; // SRP replication server that is currently updating this host. 183 int name_serial; // The number we are using to disambiguate the name. 184 adv_record_vec_t *NULLABLE addresses; // One or more address records 185 adv_record_t *NULLABLE key_record; // Key record, if we registered that. 186 adv_instance_vec_t *NULLABLE instances; // Zero or more service instances. 187 188 dns_rr_t key; // The key data represented as an RR; key->name is NULL. 189 uint32_t key_id; // A possibly-unique id that is computed across the key for brevity in 190 // debugging 191 unsigned wakeup_interval; // Exponential backoff interval for re-registration 192 int retry_interval; // Interval to wait before attempting to re-register after the daemon has 193 // died. 194 time_t update_time; // Time when the update completed. 195 time_t remove_received_time; // Time when the remove is received 196 uint64_t update_server_id; // Server ID from server that sent the update 197 uint64_t server_stable_id; // Stable ID of server that got update from client (we're using server ULA). 198 uint16_t key_rdlen; // Length of key 199 uint8_t *NULLABLE key_rdata; // Raw KEY rdata, suitable for DNSServiceRegisterRecord(). 200 uint32_t lease_interval; // Interval for address lease 201 uint32_t key_lease; // Interval for key lease 202 int64_t lease_expiry; // Time when lease expires, relative to ioloop_timenow(). 203 bool removed; // True if this host has been removed (and is being kept for replication) 204 205 // True if we have a pending late conflict resolution. If we get a conflict after the update for the 206 // host registration has expired, and there happens to be another update in progress, then we want 207 // to defer the host registration. 208 bool update_pending; 209 bool re_register_pending; 210 211 }; 212 213 struct adv_update { 214 int ref_count; 215 216 adv_host_t *NULLABLE host; // Host being updated 217 218 // Connection state, if applicable, of the client request that produced this update. 219 client_update_t *NULLABLE client; 220 int num_outstanding_updates; // Total count updates that have been issued but not yet confirmed. 221 222 // Addresses to apply to the host. At present only one address is ever advertised, but we remember all the 223 // addresses that were registered. 224 adv_record_vec_t *NULLABLE remove_addresses; 225 adv_record_vec_t *NULLABLE add_addresses; 226 227 // If non-null, this update is changing the advertised address of the host to the referenced address. 228 adv_record_t *NULLABLE key; 229 230 // The set of instances from the update that already exist but have changed. 231 // This array mirrors the array of instances configured on the host; entries to be updated 232 // are non-NULL, entries that don't need updated are NULL. 233 adv_instance_vec_t *NONNULL update_instances; 234 235 // The set of instances that exist and need to be removed. 236 adv_instance_vec_t *NONNULL remove_instances; 237 238 // The set of instances that exist and were renewed 239 adv_instance_vec_t *NONNULL renew_instances; 240 241 // The set of instances that need to be added. 242 adv_instance_vec_t *NONNULL add_instances; 243 244 // Outstanding instance updates 245 int num_instances_started; 246 int num_instances_completed; 247 248 // Outstanding record updates 249 int num_records_started; 250 int num_records_completed; 251 252 // Lease intervals for host entry and key entry. 253 uint32_t host_lease, key_lease; 254 255 // If nonzero, this is an explicit expiry time for the lease, because the update is restoring 256 // a host after a server restart, or else renaming a host after a late name conflict. In this 257 // case, we do not want to extend the lease--just get the host registration right. 258 int64_t lease_expiry; 259 260 // The time when we started doing the update. If we get a retransmission, we can compare the current 261 // to this time to see if we ought to try again. 262 time_t start_time; 263 264 // True if we are registering the key to hold the hostname. 265 bool registering_key; 266 }; 267 268 struct adv_instance_vec { 269 int ref_count; 270 int num; 271 adv_instance_t * NULLABLE *NONNULL vec; 272 }; 273 274 struct adv_record_vec { 275 int ref_count; 276 int num; 277 adv_record_t * NULLABLE *NONNULL vec; 278 }; 279 280 struct client_update { 281 client_update_t *NULLABLE next; 282 comm_t *NULLABLE connection; // Connection on which in-process update was received. 283 srpl_connection_t *NULLABLE srpl_connection; // SRP replication connection on which update was received. 284 dns_message_t *NULLABLE parsed_message; // Message that triggered the update. 285 message_t *NULLABLE message; // Message that triggered the update. 286 287 dns_host_description_t *NULLABLE host; // Host data parsed from message 288 service_instance_t *NULLABLE instances; // Service instances parsed from message 289 service_t *NULLABLE services; // Services parsed from message 290 delete_t *NULLABLE removes; // Removes parsed from message 291 dns_name_t *NULLABLE update_zone; // Zone being updated 292 srp_server_t *NULLABLE server_state; // SRP server state associated with this update, for testing 293 uint32_t host_lease, key_lease; // Lease intervals for host entry and key entry. 294 int index; // Message number for multi-message SRP updates 295 uint8_t rcode; 296 bool skip; // If true, this update is completely overshadowed by later updates and we 297 // should skip it. 298 bool drop; // If true, the signature on this message didn't validate and we mustn't 299 // send a response 300 bool skip_host_updates; // If true, don't actually register any host records. 301 }; 302 303 struct wanted_service { 304 wanted_service_t *NULLABLE next; 305 char *NULLABLE name; 306 char *NULLABLE service_type; 307 }; 308 309 // Exported functions. 310 bool srp_mdns_shared_registration_txn_setup(srp_server_t *NONNULL server_state); 311 void srp_mdns_shared_record_remove(srp_server_t *NONNULL server_state, adv_record_t *NONNULL record); 312 void srp_mdns_update_finished(adv_update_t *NONNULL update); 313 #define adv_instance_retain(instance) adv_instance_retain_(instance, __FILE__, __LINE__) 314 void adv_instance_retain_(adv_instance_t *NONNULL instance, const char *NONNULL file, int line); 315 #define adv_instance_release(instance) adv_instance_release_(instance, __FILE__, __LINE__) 316 void adv_instance_release_(adv_instance_t *NONNULL instance, const char *NONNULL file, int line); 317 #define adv_record_retain(record) adv_record_retain_(record, __FILE__, __LINE__) 318 void adv_record_retain_(adv_record_t *NONNULL record, const char *NONNULL file, int line); 319 #define adv_record_release(record) adv_record_release_(record, __FILE__, __LINE__) 320 void adv_record_release_(adv_record_t *NONNULL record, const char *NONNULL file, int line); 321 void adv_instance_context_release(void *NONNULL context); 322 323 #define srp_adv_host_release(host) srp_adv_host_release_(host, __FILE__, __LINE__) 324 void srp_adv_host_release_(adv_host_t *NONNULL host, const char *NONNULL file, int line); 325 #define srp_adv_host_retain(host) srp_adv_host_retain_(host, __FILE__, __LINE__) 326 void srp_adv_host_retain_(adv_host_t *NONNULL host, const char *NONNULL file, int line); 327 #define srp_adv_host_copy(server_state, name) srp_adv_host_copy_(server_state, name, __FILE__, __LINE__) 328 adv_host_t *NULLABLE srp_adv_host_copy_(srp_server_t *NONNULL server_state, dns_name_t *NONNULL name, 329 const char *NONNULL file, int line); 330 int srp_current_valid_host_count(srp_server_t *NONNULL server_state); 331 int srp_hosts_to_array(srp_server_t *NONNULL server_state, adv_host_t *NONNULL *NULLABLE host_array, int max_hosts); 332 bool srp_adv_host_valid(adv_host_t *NONNULL host); 333 srp_server_t *NULLABLE server_state_create(const char *NONNULL name, int max_lease_time, 334 int min_lease_time, int key_max_lease_time, int key_min_lease_time); 335 DNSServiceAttributeRef NULLABLE srp_adv_instance_tsr_attribute_generate(adv_instance_t *NONNULL instance, 336 char *NONNULL time_buf, size_t time_buf_size); 337 DNSServiceAttributeRef NULLABLE srp_adv_host_tsr_attribute_generate(adv_host_t *NONNULL host, 338 char *NONNULL time_buf, size_t time_buf_size); 339 DNSServiceAttributeRef NULLABLE srp_message_tsr_attribute_generate(message_t *NULLABLE message, uint32_t key_id, 340 char *NONNULL time_buf, size_t time_buf_size); 341 #endif // __SRP_MDNS_PROXY_H__ 342 343 // Local Variables: 344 // mode: C 345 // tab-width: 4 346 // c-file-style: "bsd" 347 // c-basic-offset: 4 348 // fill-column: 120 349 // indent-tabs-mode: nil 350 // End: 351