3 * Copyright (c) 2018-2019 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 // Maximum number of additional TLVs we support in a DSO message.
26 #define MAX_ADDITLS 10
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
;
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.
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
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.
71 typedef struct dso_outstanding_query
{
74 } dso_outstanding_query_t
;
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
;
82 typedef struct dso_query_receive_context
{
85 } dso_query_receive_context_t
;
87 typedef struct dso_disconnect_context
{
88 uint32_t reconnect_delay
;
89 } dso_disconnect_context_t
;
91 typedef struct dso_keepalive_context
{
92 uint32_t inactivity_timeout
;
93 uint32_t keepalive_interval
;
94 } dso_keepalive_context_t
;
96 // Structure to represent received DSO TLVs
97 typedef struct dsotlv
{
100 const uint8_t *payload
;
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.
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
127 typedef struct dso_transport dso_transport_t
;
128 typedef struct dso_state dso_state_t
;
129 typedef int64_t event_time_t
;
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
);
135 // DNS Stateless Operations state
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
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
;
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.
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
163 dso_outstanding_query_state_t
*outstanding_queries
;
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
);
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)
207 // c-file-style: "bsd"
210 // indent-tabs-mode: nil