summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSShared/uds_daemon.h
blob: dc7d9ac26beac939ab461e5c291b97dff2460174 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/* -*- Mode: C; tab-width: 4 -*-
 *
 * Copyright (c) 2002-2013 Apple Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef UDS_DAEMON_H
#define UDS_DAEMON_H

#include "mDNSEmbeddedAPI.h"
#include "dnssd_ipc.h"

/* Client request: */

// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
#pragma mark - Types and Data Structures
#endif

typedef enum
{
	t_uninitialized,
	t_morecoming,
	t_complete,
	t_error,
	t_terminated
} transfer_state;

typedef struct request_state request_state;

typedef void (*req_termination_fn)(request_state *request);

typedef struct registered_record_entry
{
	struct registered_record_entry *next;
	mDNSu32 key;
	client_context_t regrec_client_context;
	request_state *request;
	mDNSBool external_advertise;
	mDNSInterfaceID origInterfaceID;
	AuthRecord *rr;             // Pointer to variable-sized AuthRecord (Why a pointer? Why not just embed it here?)
} registered_record_entry;

// A single registered service: ServiceRecordSet + bookkeeping
// Note that we duplicate some fields from parent service_info object
// to facilitate cleanup, when instances and parent may be deallocated at different times.
typedef struct service_instance
{
	struct service_instance *next;
	request_state *request;
	AuthRecord *subtypes;
	mDNSBool renameonmemfree;       // Set on config change when we deregister original name
	mDNSBool clientnotified;        // Has client been notified of successful registration yet?
	mDNSBool default_local;         // is this the "local." from an empty-string registration?
	mDNSBool external_advertise;    // is this is being advertised externally?
	domainname domain;
	ServiceRecordSet srs;           // note -- variable-sized object -- must be last field in struct
} service_instance;

// for multi-domain default browsing
typedef struct browser_t
{
	struct browser_t *next;
	domainname domain;
	DNSQuestion q;
} browser_t;

#ifdef _WIN32
typedef unsigned int pid_t;
typedef unsigned int socklen_t;
#endif

#if (!defined(MAXCOMLEN))
#define MAXCOMLEN 16
#endif

struct request_state
{
	request_state *next;
	request_state *primary;         // If this operation is on a shared socket, pointer to primary
	// request_state for the original DNSServiceCreateConnection() operation
	dnssd_sock_t sd;
	pid_t process_id;               // Client's PID value
	char  pid_name[MAXCOMLEN];      // Client's process name
	mDNSu8 uuid[UUID_SIZE];
	mDNSBool validUUID;
	dnssd_sock_t errsd;
	mDNSu32 uid;
	void * platform_data;

	// Note: On a shared connection these fields in the primary structure, including hdr, are re-used
	// for each new request. This is because, until we've read the ipc_msg_hdr to find out what the
	// operation is, we don't know if we're going to need to allocate a new request_state or not.
	transfer_state ts;
	mDNSu32 hdr_bytes;              // bytes of header already read
	ipc_msg_hdr hdr;
	mDNSu32 data_bytes;             // bytes of message data already read
	char          *msgbuf;          // pointer to data storage to pass to free()
	const char    *msgptr;          // pointer to data to be read from (may be modified)
	char          *msgend;          // pointer to byte after last byte of message

	// reply, termination, error, and client context info
	int no_reply;                   // don't send asynchronous replies to client
	mDNSs32 time_blocked;           // record time of a blocked client
	int unresponsiveness_reports;
	struct reply_state *replies;    // corresponding (active) reply list
	req_termination_fn terminate;
	DNSServiceFlags flags;
	mDNSu32 interfaceIndex;

	union
	{
		registered_record_entry *reg_recs;  // list of registrations for a connection-oriented request
		struct
		{
			mDNSInterfaceID interface_id;
			mDNSBool default_domain;
			mDNSBool ForceMCast;
			domainname regtype;
			browser_t *browsers;
			const mDNSu8 *AnonData;
		} browser;
		struct
		{
			mDNSInterfaceID InterfaceID;
			mDNSu16 txtlen;
			void *txtdata;
			mDNSIPPort port;
			domainlabel name;
			char type_as_string[MAX_ESCAPED_DOMAIN_NAME];
			domainname type;
			mDNSBool default_domain;
			domainname host;
			mDNSBool autoname;              // Set if this name is tied to the Computer Name
			mDNSBool autorename;            // Set if this client wants us to automatically rename on conflict
			mDNSBool allowremotequery;      // Respond to unicast queries from outside the local link?
			int num_subtypes;
			mDNSBool AnonData;
			service_instance *instances;
		} servicereg;
		struct
		{
			mDNSInterfaceID interface_id;
			mDNSu32 flags;
			mDNSu32 protocol;
			DNSQuestion q4;
			DNSQuestion *q42;
			DNSQuestion q6;
			DNSQuestion *q62;
			mDNSu8 v4ans;
			mDNSu8 v6ans;
		} addrinfo;
		struct
		{
			mDNSIPPort ReqExt;              // External port we originally requested, for logging purposes
			NATTraversalInfo NATinfo;
		} pm;
		struct
		{
			DNSServiceFlags flags;
			DNSQuestion q_all;
			DNSQuestion q_default;
			DNSQuestion q_autoall;
		} enumeration;
		struct
		{
			DNSQuestion q;
			DNSQuestion *q2;
			mDNSu8 ans;
		} queryrecord;
		struct
		{
			DNSQuestion qtxt;
			DNSQuestion qsrv;
			const ResourceRecord *txt;
			const ResourceRecord *srv;
			mDNSs32 ReportTime;
			mDNSBool external_advertise;
		} resolve;
	} u;
};

// struct physically sits between ipc message header and call-specific fields in the message buffer
typedef struct
{
	DNSServiceFlags flags;          // Note: This field is in NETWORK byte order
	mDNSu32 ifi;                    // Note: This field is in NETWORK byte order
	DNSServiceErrorType error;      // Note: This field is in NETWORK byte order
} reply_hdr;

typedef struct reply_state
{
	struct reply_state *next;       // If there are multiple unsent replies
	mDNSu32 totallen;
	mDNSu32 nwriten;
	ipc_msg_hdr mhdr[1];
	reply_hdr rhdr[1];
} reply_state;

/* Client interface: */

#define SRS_PORT(S) mDNSVal16((S)->RR_SRV.resrec.rdata->u.srv.port)

#define LogTimer(MSG,T) LogMsgNoIdent( MSG " %08X %11d  %08X %11d", (T), (T), (T)-now, (T)-now)

extern int udsserver_init(dnssd_sock_t skts[], mDNSu32 count);
extern mDNSs32 udsserver_idle(mDNSs32 nextevent);
extern void udsserver_info(void);  // print out info about current state
extern void udsserver_handle_configchange(mDNS *const m);
extern int udsserver_exit(void);    // should be called prior to app exit
extern void LogMcastStateInfo(mDNSBool mflag, mDNSBool start, mDNSBool mstatelog);
#define LogMcastQ       (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastQuestion
#define LogMcastS       (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMcastService
#define LogMcast        (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsg
#define LogMcastNoIdent (mDNS_McastLoggingEnabled == 0) ? ((void)0) : LogMsgNoIdent

/* Routines that uds_daemon expects to link against: */

typedef void (*udsEventCallback)(int fd, short filter, void *context);
extern mStatus udsSupportAddFDToEventLoop(dnssd_sock_t fd, udsEventCallback callback, void *context, void **platform_data);
extern int     udsSupportReadFD(dnssd_sock_t fd, char* buf, int len, int flags, void *platform_data);
extern mStatus udsSupportRemoveFDFromEventLoop(dnssd_sock_t fd, void *platform_data); // Note: This also CLOSES the file descriptor as well

extern void RecordUpdatedNiceLabel(mDNSs32 delay);

// Globals and functions defined in uds_daemon.c and also shared with the old "daemon.c" on OS X

extern mDNS mDNSStorage;
extern DNameListElem *AutoRegistrationDomains;
extern DNameListElem *AutoBrowseDomains;

extern mDNSs32 ChopSubTypes(char *regtype, char **AnonData);
extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p, char **AnonData);
extern int CountExistingRegistrations(domainname *srv, mDNSIPPort port);
extern mDNSBool callExternalHelpers(mDNSInterfaceID InterfaceID, const domainname *const domain, DNSServiceFlags flags);
extern void FreeExtraRR(mDNS *const m, AuthRecord *const rr, mStatus result);
extern int CountPeerRegistrations(ServiceRecordSet *const srs);

#if APPLE_OSX_mDNSResponder

// D2D interface support
extern void external_start_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
extern void external_stop_browsing_for_service(mDNSInterfaceID InterfaceID, const domainname *const type, DNS_TypeValues qtype, DNSServiceFlags flags);
extern void external_start_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
extern void external_stop_advertising_service(const ResourceRecord *const resourceRecord, DNSServiceFlags flags);
extern void external_start_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
extern void external_stop_resolving_service(mDNSInterfaceID InterfaceID, const domainname *const fqdn, DNSServiceFlags flags);
extern void external_connection_release(const domainname *instance);

#else   // APPLE_OSX_mDNSResponder

#define external_start_browsing_for_service(A,B,C,D) (void)(A)
#define external_stop_browsing_for_service(A,B,C,D)  (void)(A)
#define external_start_advertising_service(A,B)      (void)(A)
#define external_stop_advertising_service(A,B)       do { (void)(A); (void)(B); } while (0)
#define external_start_resolving_service(A,B,C)      (void)(A)
#define external_stop_resolving_service(A,B,C)       (void)(A)
#define external_connection_release(A)               (void)(A)

#endif // APPLE_OSX_mDNSResponder

extern const char mDNSResponderVersionString_SCCS[];
#define mDNSResponderVersionString (mDNSResponderVersionString_SCCS+5)

#if DEBUG
extern void SetDebugBoundPath(void);
extern int IsDebugSocketInUse(void);
#endif

#endif /* UDS_DAEMON_H */