]> git.saurik.com Git - apple/mdnsresponder.git/blob - DSO/dso.h
mDNSResponder-1310.40.42.tar.gz
[apple/mdnsresponder.git] / DSO / dso.h
1 /* dso.h
2 *
3 * Copyright (c) 2018-2019 Apple Computer, 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 * http://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
19 #ifndef __DSO_H
20 #define __DSO_H
21
22 #include <stdbool.h>
23 #include <stdint.h>
24
25 // Maximum number of additional TLVs we support in a DSO message.
26 #define MAX_ADDITLS 10
27
28 typedef enum {
29 kDSOType_Keepalive = 1,
30 kDSOType_RetryDelay = 2,
31 kDSOType_EncryptionPadding = 3,
32 kDSOType_DNSPushSubscribe = 0x40,
33 kDSOType_DNSPushUpdate = 0x41,
34 kDSOType_DNSPushUnsubscribe = 0x42,
35 kDSOType_DNSPushReconfirm = 0x43,
36 kDSOType_mDNSLinkRequest = 0xF901,
37 kDSOType_mDNSLinkDiscontinue = 0xF902,
38 kDSOType_mDNSMessage = 0xF903,
39 kDSOType_LinkIdentifier = 0xF904,
40 kDSOType_L2SourceAddress = 0xF905,
41 kDSOType_IPSourceAddress = 0xF906,
42 kDSOType_mDNSReportLinkChanges = 0xF907,
43 kDSOType_mDNSStopLinkChanges = 0xF908,
44 kDSOType_mDNSLinkAvailable = 0xF900,
45 kDSOType_mDNSLinkUnavailable = 0xF90a,
46 kDSOType_LinkPrefix = 0xf90b
47 } dso_message_types_t;
48
49 // When a DSO message arrives, or one that was sent is acknowledged, or the state of the DSO connection
50 // changes, we need to call the user of the DSO connection.
51 typedef enum {
52 kDSOEventType_DNSMessage, // A DNS message that is not a DSO message
53 kDSOEventType_DNSResponse, // A DNS response that is not a DSO response
54 kDSOEventType_DSOMessage, // DSOState.primary and DSOState.additl will contain the message TLVs;
55 // header will contain the DNS header
56 kDSOEventType_Finalize, // The DSO connection to the other DSO endpoint has terminated and we are
57 // in the idle loop.
58 kDSOEventType_DSOResponse, // DSOState.primary and DSOState.additl contain any TLVs in the response;
59 // header contains the DNS header
60 kDSOEventType_Connected, // We succeeded in making a connection
61 kDSOEventType_ConnectFailed, // We failed to get a connection
62 kDSOEventType_Disconnected, // We were connected, but have disconnected or been disconnected
63 kDSOEventType_ShouldReconnect, // We are disconnected, and a scheduled reconnect timer has gone off.
64 // Recipient is responsible for reconnecting, or deciding not to.
65 kDSOEventType_Inactive, // We went inactive and the inactivity timeout expired, so it's time to drop the connection.
66 kDSOEventType_Keepalive, // It's time to send a keepalive message, here are the values to send
67 kDSOEventType_KeepaliveRcvd, // We just received a keepalive from a client, here are the values.
68 kDSOEventType_RetryDelay // We got a RetryDelay from the server. Have to shut down.
69 } dso_event_type_t;
70
71 typedef struct dso_outstanding_query {
72 uint16_t id;
73 void *context;
74 } dso_outstanding_query_t;
75
76 typedef struct dso_outstanding_query_state {
77 int outstanding_query_count;
78 int max_outstanding_queries;
79 dso_outstanding_query_t queries[0];
80 } dso_outstanding_query_state_t;
81
82 typedef struct dso_query_receive_context {
83 void *query_context;
84 uint16_t rcode;
85 } dso_query_receive_context_t;
86
87 typedef struct dso_disconnect_context {
88 uint32_t reconnect_delay;
89 } dso_disconnect_context_t;
90
91 typedef struct dso_keepalive_context {
92 uint32_t inactivity_timeout;
93 uint32_t keepalive_interval;
94 } dso_keepalive_context_t;
95
96 // Structure to represent received DSO TLVs
97 typedef struct dsotlv {
98 uint16_t opcode;
99 uint16_t length;
100 const uint8_t *payload;
101 } dso_tlv_t;
102
103 // DSO message under construction
104 typedef struct dso_message {
105 uint8_t *buf; // The buffer in which we are constructing the message
106 size_t max; // Size of the buffer
107 size_t cur; // Current position in the buffer
108 bool building_tlv; // True if we have started and not finished building a TLV
109 int outstanding_query_number; // Number of the outstanding query state entry for this message, or -1
110 size_t tlv_len; // Current length of the TLV we are building.
111 size_t tlv_len_offset; // Where to store the length of the current TLV when finished.
112 const uint8_t *no_copy_bytes; // One TLV can have data that isn't copied into the buffer
113 size_t no_copy_bytes_len; // Length of that data, if any.
114 size_t no_copy_bytes_offset; // Where in the buffer the data should be interposed.
115 } dso_message_t;
116
117 // Record of ongoing activity
118 typedef struct dso_activity dso_activity_t;
119 struct dso_activity {
120 dso_activity_t *next;
121 void (*finalize)(dso_activity_t *activity);
122 const char *activity_type; // Name of the activity type, must be the same pointer for all activities of a type.
123 void *context; // Activity implementation's context (if any).
124 char *name; // Name of the individual activity
125 };
126
127 typedef struct dso_transport dso_transport_t;
128 typedef struct dso_state dso_state_t;
129 typedef int64_t event_time_t;
130
131 typedef void (*dso_event_callback_t)(void *context, const void *header,
132 dso_state_t *dso, dso_event_type_t eventType);
133 typedef void (*dso_transport_finalize_t)(dso_transport_t *transport);
134
135 // DNS Stateless Operations state
136 struct dso_state {
137 dso_state_t *next;
138 void *context; // The context of the next layer up (e.g., a Discovery Proxy)
139 dso_event_callback_t cb; // Called when an event happens
140
141 // Transport state; handled separately for reusability
142 dso_transport_t *transport; // The transport (e.g., dso-transport.c or other).
143 dso_transport_finalize_t transport_finalize;
144
145 uint32_t serial; // Unique serial number which can be used after the DSO has been dropped.
146 bool is_server; // True if the endpoint represented by this DSO state is a server
147 // (according to the DSO spec)
148 bool has_session; // True if DSO session establishment has happened for this DSO endpoint
149 event_time_t response_awaited; // If we are waiting for a session-establishing response, when it's
150 // expected; otherwise zero.
151 uint32_t keepalive_interval; // Time between keepalives (to be sent, on client, expected, on server)
152 uint32_t inactivity_timeout; // Session can't be inactive more than this amount of time.
153 event_time_t keepalive_due; // When the next keepalive is due (to be received or sent)
154 event_time_t inactivity_due; // When next activity has to happen for connection to remain active
155 dso_activity_t *activities; // Outstanding DSO activities.
156
157 dso_tlv_t primary; // Primary TLV for current message
158 dso_tlv_t additl[MAX_ADDITLS]; // Additional TLVs
159 int num_additls; // Number of additional TLVs in this message
160
161 char *remote_name;
162
163 dso_outstanding_query_state_t *outstanding_queries;
164 };
165
166 // Provided by dso.c
167 dso_state_t *dso_create(bool is_server, int max_outstanding_queries, const char *remote_name,
168 dso_event_callback_t callback, void *context, dso_transport_t *transport);
169 dso_state_t *dso_find_by_serial(uint32_t serial);
170 void dso_drop(dso_state_t *dso);
171 int32_t dso_idle(void *context, int64_t now, int64_t next_timer_event);
172 void dso_release(dso_state_t **dsop);
173 void dso_start_tlv(dso_message_t *state, int opcode);
174 void dso_add_tlv_bytes(dso_message_t *state, const uint8_t *bytes, size_t len);
175 void dso_add_tlv_bytes_no_copy(dso_message_t *state, const uint8_t *bytes, size_t len);
176 void dso_add_tlv_byte(dso_message_t *state, uint8_t byte);
177 void dso_add_tlv_u16(dso_message_t *state, uint16_t u16);
178 void dso_add_tlv_u32(dso_message_t *state, uint32_t u32);
179 void dso_finish_tlv(dso_message_t *state);
180 dso_activity_t *dso_find_activity(dso_state_t *dso, const char *name, const char *activity_type, void *context);
181 dso_activity_t *dso_add_activity(dso_state_t *dso, const char *name, const char *activity_type,
182 void *context, void (*finalize)(dso_activity_t *));
183 void dso_drop_activity(dso_state_t *dso, dso_activity_t *activity);
184 void dso_ignore_response(dso_state_t *dso, void *context);
185 bool dso_make_message(dso_message_t *state, uint8_t *outbuf, size_t outbuf_size,
186 dso_state_t *dso, bool unidirectional, void *callback_state);
187 size_t dso_message_length(dso_message_t *state);
188 void dso_retry_delay(dso_state_t *dso, const DNSMessageHeader *header);
189 void dso_keepalive(dso_state_t *dso, const DNSMessageHeader *header);
190 void dso_message_received(dso_state_t *dso, const uint8_t *message, size_t message_length);
191 void dns_message_received(dso_state_t *dso, const uint8_t *message, size_t message_length);
192
193 // Provided by DSO transport implementation for use by dso.c:
194 int32_t dso_transport_idle(void *context, int64_t now, int64_t next_timer_event);
195 bool dso_send_simple_response(dso_state_t *dso, int rcode, const DNSMessageHeader *header, const char *pres);
196 bool dso_send_not_implemented(dso_state_t *dso, const DNSMessageHeader *header);
197 bool dso_send_refused(dso_state_t *dso, const DNSMessageHeader *header);
198 bool dso_send_formerr(dso_state_t *dso, const DNSMessageHeader *header);
199 bool dso_send_servfail(dso_state_t *dso, const DNSMessageHeader *header);
200 bool dso_send_name_error(dso_state_t *dso, const DNSMessageHeader *header);
201 bool dso_send_no_error(dso_state_t *dso, const DNSMessageHeader *header);
202 #endif // !defined(__DSO_H)
203
204 // Local Variables:
205 // mode: C
206 // tab-width: 4
207 // c-file-style: "bsd"
208 // c-basic-offset: 4
209 // fill-column: 108
210 // indent-tabs-mode: nil
211 // End: