Home | History | Annotate | Line # | Download | only in ServiceRegistration
      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