1 /* -*- Mode: C; tab-width: 4 -*- 2 * 3 * Copyright (c) 2002-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 18 #ifndef UDS_DAEMON_H 19 #define UDS_DAEMON_H 20 21 #include "mDNSEmbeddedAPI.h" 22 #include "dnssd_ipc.h" 23 #include "ClientRequests.h" 24 #include "general.h" 25 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN) 26 #include <mdns/audit_token.h> 27 #endif 28 #if MDNSRESPONDER_SUPPORTS(APPLE, TRUST_ENFORCEMENT) 29 #include "mdns_trust.h" 30 #endif 31 #if MDNSRESPONDER_SUPPORTS(APPLE, SIGNED_RESULTS) 32 #include "signed_result.h" 33 #endif 34 35 /* Client request: */ 36 37 // *************************************************************************** 38 // MARK: - Types and Data Structures 39 40 MDNS_CLOSED_ENUM(transfer_state, mDNSu8, 41 t_uninitialized, 42 t_morecoming, 43 t_complete, 44 t_error, 45 t_terminated 46 ); 47 48 typedef struct request_state request_state; 49 50 typedef void (*req_termination_fn)(request_state *request); 51 52 typedef struct registered_record_entry 53 { 54 #if MDNSRESPONDER_SUPPORTS(APPLE, POWERLOG_MDNS_REQUESTS) 55 uint64_t powerlog_start_time; 56 #endif 57 struct registered_record_entry *next; 58 mDNSu32 key; 59 client_context_t regrec_client_context; 60 request_state *request; 61 mDNSBool external_advertise; 62 mDNSInterfaceID origInterfaceID; 63 AuthRecord *rr; // Pointer to variable-sized AuthRecord (Why a pointer? Why not just embed it here?) 64 } registered_record_entry; 65 66 // A single registered service: ServiceRecordSet + bookkeeping 67 // Note that we duplicate some fields from parent service_info object 68 // to facilitate cleanup, when instances and parent may be deallocated at different times. 69 typedef struct service_instance 70 { 71 struct service_instance *next; 72 request_state *request; 73 AuthRecord *subtypes; 74 mDNSBool renameonmemfree; // Set on config change when we deregister original name 75 mDNSBool clientnotified; // Has client been notified of successful registration yet? 76 mDNSBool default_local; // is this the "local." from an empty-string registration? 77 mDNSBool external_advertise; // is this is being advertised externally? 78 domainname domain; 79 ServiceRecordSet srs; // note -- variable-sized object -- must be last field in struct 80 } service_instance; 81 82 // for multi-domain default browsing 83 typedef struct browser_t 84 { 85 struct browser_t *next; 86 domainname domain; 87 DNSQuestion q; 88 } browser_t; 89 90 #ifdef _WIN32 91 # ifdef __MINGW32__ 92 typedef int pid_t; 93 typedef int socklen_t; 94 # else 95 typedef unsigned int pid_t; 96 typedef int socklen_t; 97 # endif // __MINGW32__ 98 #endif //_WIN32 99 100 #if (!defined(MAXCOMLEN)) 101 #define MAXCOMLEN 16 102 #endif 103 104 typedef struct 105 { 106 DNSServiceFlags flags; 107 DNSQuestion q_all; 108 DNSQuestion q_default; 109 DNSQuestion q_autoall; 110 } request_enumeration; 111 mdns_compile_time_max_size_check(request_enumeration, 2144); 112 113 typedef struct 114 { 115 mDNSInterfaceID InterfaceID; 116 mDNSu16 txtlen; 117 void *txtdata; 118 mDNSIPPort port; 119 domainlabel name; 120 char type_as_string[MAX_ESCAPED_DOMAIN_NAME]; 121 domainname type; 122 mDNSBool default_domain; 123 domainname host; 124 mDNSBool autoname; // Set if this name is tied to the Computer Name 125 mDNSBool autorename; // Set if this client wants us to automatically rename on conflict 126 mDNSBool allowremotequery; // Respond to unicast queries from outside the local link? 127 mDNSu32 num_subtypes; 128 service_instance *instances; 129 } request_servicereg; 130 mdns_compile_time_max_size_check(request_servicereg, 1632); 131 132 typedef struct 133 { 134 DNSQuestion qtxt; 135 DNSQuestion qsrv; 136 137 domainname *srv_target_name; // Dynamically allocated SRV rdata(target name) 138 mDNSu8 *txt_rdata; // Dynamically allocated TXT rdata. 139 mDNSIPPort srv_port; // The port number specified in the SRV rdata. 140 mDNSu16 txt_rdlength; // The length of the TXT record rdata. 141 142 mDNSs32 ReportTime; 143 mDNSBool external_advertise; 144 mDNSBool srv_negative; // Whether we have received a negative SRV record. If true, srv_target_name is 145 // always NULL and srv_port's value has no meaning. When srv_target_name is 146 // non-NULL, srv_negative is always false; 147 mDNSBool txt_negative; // Whether we have received a negative TXT record. If true, txt_rdata is always NULL 148 // and txt_rdlength is 0. When txt_rdata is non-NULL, txt_negative is always false. 149 } request_resolve; 150 mdns_compile_time_max_size_check(request_resolve, 1456); 151 152 typedef struct 153 { 154 mDNSInterfaceID interface_id; 155 mDNSBool default_domain; 156 mDNSBool ForceMCast; 157 domainname regtype; 158 browser_t *browsers; 159 } request_browse; 160 mdns_compile_time_max_size_check(request_browse, 280); 161 162 typedef struct 163 { 164 mDNSIPPort ReqExt; // External port we originally requested, for logging purposes 165 NATTraversalInfo NATinfo; 166 } request_port_mapping; 167 mdns_compile_time_max_size_check(request_port_mapping, 208); 168 169 #if MDNSRESPONDER_SUPPORTS(APPLE, PADDING_CHECKS) 170 // The member variables of struct request_state are in descending order of alignment requirement to eliminate 171 // padding between member variables. That is, member variables with an 8-byte alignment requirement come first, followed 172 // by member variables with a 4-byte alignment requirement, and so forth. 173 MDNS_CLANG_TREAT_WARNING_AS_ERROR_BEGIN(-Wpadded) 174 #endif 175 struct request_state 176 { 177 #if MDNSRESPONDER_SUPPORTS(APPLE, QUERIER) 178 mdns_dns_service_id_t custom_service_id; 179 #endif 180 #if MDNSRESPONDER_SUPPORTS(APPLE, POWERLOG_MDNS_REQUESTS) 181 uint64_t powerlog_start_time; 182 #endif 183 request_state *next; // For a shared connection, the next element in the list of subordinate 184 // requests on that connection. Otherwise null. 185 request_state *primary; // For a subordinate request, the request that represents the shared 186 // connection to which this request is subordinate (must have been created 187 // by DNSServiceCreateConnection(). 188 #if MDNSRESPONDER_SUPPORTS(APPLE, AUDIT_TOKEN) 189 mdns_audit_token_t peer_token; // The immediate client's audit token. 190 #endif 191 void * platform_data; 192 #if MDNSRESPONDER_SUPPORTS(APPLE, TRUST_ENFORCEMENT) 193 CFMutableArrayRef trusts; 194 #endif 195 #if MDNSRESPONDER_SUPPORTS(APPLE, SIGNED_RESULTS) 196 mdns_signed_result_t signed_obj; 197 #endif 198 size_t data_bytes; // bytes of message data already read [1] 199 uint8_t *msgbuf; // pointer to data storage to pass to free() [1] 200 const uint8_t *msgptr; // pointer to data to be read from (may be modified) [1] 201 const uint8_t *msgend; // pointer to byte after last byte of message [1] 202 struct reply_state *replies; // corresponding (active) reply list 203 req_termination_fn terminate; 204 request_enumeration *enumeration; 205 request_servicereg *servicereg; 206 request_resolve *resolve; 207 QueryRecordClientRequest *queryrecord; 208 request_browse *browse; 209 request_port_mapping *pm; 210 GetAddrInfoClientRequest *addrinfo; 211 registered_record_entry *reg_recs; // list of registrations for a connection-oriented request 212 dnssd_sock_t sd; 213 pid_t process_id; // The effective client's PID value. 214 dnssd_sock_t errsd; 215 mDNSu32 uid; 216 mDNSu32 request_id; 217 mDNSs32 request_start_time_secs; // The time when the request is started in continuous time seconds. 218 mDNSs32 last_full_log_time_secs; // The time when we print full log information in continuous time seconds. 219 mDNSu32 hdr_bytes; // bytes of header already read [1] 220 ipc_msg_hdr hdr; // [1] 221 mDNSs32 time_blocked; // record time of a blocked client 222 DNSServiceFlags flags; 223 mDNSu32 interfaceIndex; 224 char pid_name[MAXCOMLEN]; // The effective client's process name. 225 mDNSu8 uuid[UUID_SIZE]; 226 mDNSBool validUUID; 227 #if MDNSRESPONDER_SUPPORTS(APPLE, TRACKER_DEBUGGING) 228 mDNSBool addTrackerInfo; 229 #endif 230 #if MDNSRESPONDER_SUPPORTS(APPLE, SIGNED_RESULTS) 231 mDNSBool sign_result; 232 #endif 233 transfer_state ts; // [1] 234 mDNSBool no_reply; // don't send asynchronous replies to client 235 mDNSu8 unresponsiveness_reports; 236 #if MDNSRESPONDER_SUPPORTS(APPLE, PADDING_CHECKS) 237 MDNS_STRUCT_PAD_64_32(2, 6); 238 #endif 239 }; 240 #if MDNSRESPONDER_SUPPORTS(APPLE, PADDING_CHECKS) 241 MDNS_CLANG_TREAT_WARNING_AS_ERROR_END() 242 MDNS_GENERAL_STRUCT_PAD_CHECK(struct request_state); 243 #endif 244 mdns_compile_time_max_size_check(struct request_state, 288); 245 246 // Notes: 247 // 1. On a shared connection these fields in the primary structure, including hdr, are re-used 248 // for each new request. This is because, until we've read the ipc_msg_hdr to find out what the 249 // operation is, we don't know if we're going to need to allocate a new request_state or not. 250 251 // struct physically sits between ipc message header and call-specific fields in the message buffer 252 typedef struct 253 { 254 DNSServiceFlags flags; // Note: This field is in NETWORK byte order 255 mDNSu32 ifi; // Note: This field is in NETWORK byte order 256 DNSServiceErrorType error; // Note: This field is in NETWORK byte order 257 } reply_hdr; 258 259 typedef struct reply_state 260 { 261 struct reply_state *next; // If there are multiple unsent replies 262 mDNSu32 totallen; 263 mDNSu32 nwritten; 264 ipc_msg_hdr mhdr[1]; 265 reply_hdr rhdr[1]; 266 } reply_state; 267 268 /* Client interface: */ 269 270 #define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port) 271 272 #define LogTimerToFD(FILE_DESCRIPTOR, MSG, T) LogToFD((FILE_DESCRIPTOR), MSG " %08X %11d %08X %11d", (T), (T), (T)-now, (T)-now) 273 274 extern int udsserver_init(dnssd_sock_t skts[], size_t count); 275 extern mDNSs32 udsserver_idle(mDNSs32 nextevent); 276 extern void udsserver_info_dump_to_fd(int fd); 277 extern void udsserver_handle_configchange(mDNS *const m); 278 extern int udsserver_exit(void); // should be called prior to app exit 279 extern void LogMcastStateInfo(mDNSBool mflag, mDNSBool start, mDNSBool mstatelog); 280 #define LogMcastQ (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastQuestion 281 #define LogMcastS (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastService 282 #define LogMcast (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsg 283 #define LogMcastNoIdent (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsgNoIdent 284 285 /* Routines that uds_daemon expects to link against: */ 286 287 typedef void (*udsEventCallback)(int fd, void *context); 288 extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context, void **platform_data); 289 extern ssize_t udsSupportReadFD(dnssd_sock_t fd, char* buf, mDNSu32 len, int flags, void *platform_data); 290 extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd, void *platform_data); // Note: This also CLOSES the file descriptor as well 291 292 extern void RecordUpdatedNiceLabel(mDNSs32 delay); 293 294 // Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X 295 296 extern mDNS mDNSStorage; 297 extern DNameListElem *AutoRegistrationDomains; 298 extern DNameListElem *AutoBrowseDomains; 299 300 extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port); 301 extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result); 302 extern int CountPeerRegistrations(ServiceRecordSet *const srs); 303 304 extern const char mDNSResponderVersionString_SCCS[]; 305 #define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5) 306 307 #if defined(DEBUG) && DEBUG 308 extern void SetDebugBoundPath(void); 309 extern int IsDebugSocketInUse(void); 310 #endif 311 312 #endif /* UDS_DAEMON_H */ 313