1 1.1 christos /* dso-transport.h 2 1.1 christos * 3 1.1 christos * Copyright (c) 2018-2021 Apple Inc. All rights reserved. 4 1.1 christos * 5 1.1 christos * Licensed under the Apache License, Version 2.0 (the "License"); 6 1.1 christos * you may not use this file except in compliance with the License. 7 1.1 christos * You may obtain a copy of the License at 8 1.1 christos * 9 1.1 christos * https://www.apache.org/licenses/LICENSE-2.0 10 1.1 christos * 11 1.1 christos * Unless required by applicable law or agreed to in writing, software 12 1.1 christos * distributed under the License is distributed on an "AS IS" BASIS, 13 1.1 christos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 1.1 christos * See the License for the specific language governing permissions and 15 1.1 christos * limitations under the License. 16 1.1 christos * 17 1.1 christos */ 18 1.1 christos 19 1.1 christos #ifndef __DSO_TRANSPORT_H 20 1.1 christos #define __DSO_TRANSPORT_H 21 1.1 christos 22 1.1 christos #include "mdns_addr_tailq.h" // For mdns_addr_tailq_t. 23 1.1 christos 24 1.1 christos #ifdef DSO_USES_NETWORK_FRAMEWORK 25 1.1 christos #include <Network/Network.h> 26 1.1 christos #endif 27 1.1 christos 28 1.1 christos // Maximum number of IP addresses that we'll deal with as a result of looking up a name 29 1.1 christos // to which to connect. 30 1.1 christos #define MAX_DSO_CONNECT_ADDRS 16 31 1.1 christos 32 1.1 christos // Threshold above which we indicate that a DSO connection isn't writable. This is advisory, 33 1.1 christos // but e.g. for a Discovery Relay, if the remote proxy isn't consuming what we are sending, we 34 1.1 christos // should start dropping packets on the floor rather than just queueing more and more packets. 35 1.1 christos // 60k may actually be too much. This is used when we're using NW Framework, because it doesn't 36 1.1 christos // allow us to use TCP_NOTSENT_LOWAT directly. 37 1.1 christos #define MAX_UNSENT_BYTES 60000 38 1.1 christos 39 1.1 christos // Use 0 to represent an invalid ID for the object dso_connect_state_t and dso_transport_t. 40 1.1 christos #define DSO_CONNECT_STATE_INVALID_SERIAL 0 41 1.1 christos #define DSO_TRANSPORT_INVALID_SERIAL 0 42 1.1 christos 43 1.1 christos struct dso_transport { 44 1.1 christos dso_state_t *dso; // DSO state for which this is the transport 45 1.1 christos struct dso_transport *next; // Transport is on list of transports. 46 1.1 christos void *event_context; // I/O event context 47 1.1 christos mDNSAddr remote_addr; // The IP address to which we have connected 48 1.1 christos int remote_port; // The port to which we have connected 49 1.1 christos 50 1.1 christos uint32_t serial; // Serial number for locating possibly freed dso_transport_t structs. 51 1.1 christos #ifdef DSO_USES_NETWORK_FRAMEWORK 52 1.1 christos nw_connection_t connection; 53 1.1 christos dispatch_data_t to_write; 54 1.1 christos size_t bytes_to_write; 55 1.1 christos size_t unsent_bytes; 56 1.1 christos bool write_failed; // This is set if any of the parts of the dso_write process fail 57 1.1 christos #else 58 1.1 christos TCPSocket *connection; // Socket connected to Discovery Proxy 59 1.1 christos size_t bytes_needed; 60 1.1 christos size_t message_length; // Length of message we are currently accumulating, if known 61 1.1 christos uint8_t *inbuf; // Buffer for incoming messages. 62 1.1 christos size_t inbuf_size; 63 1.1 christos uint8_t *inbufp; // Current read pointer (may not be in inbuf) 64 1.1 christos bool need_length; // True if we need a 2-byte length 65 1.1 christos 66 1.1 christos uint8_t lenbuf[2]; // Buffer for storing the length in a DNS TCP message 67 1.1 christos 68 1.1 christos #define MAX_WRITE_HUNKS 4 // When writing a DSO message, we need this many separate hunks. 69 1.1 christos const uint8_t *to_write[MAX_WRITE_HUNKS]; 70 1.1 christos ssize_t write_lengths[MAX_WRITE_HUNKS]; 71 1.1 christos int num_to_write; 72 1.1 christos #endif // DSO_USES_NETWORK_FRAMEWORK 73 1.1 christos 74 1.1 christos uint8_t *outbuf; // Output buffer for building and sending DSO messages 75 1.1 christos size_t outbuf_size; 76 1.1 christos }; 77 1.1 christos 78 1.1 christos typedef struct dso_lookup dso_lookup_t; 79 1.1 christos struct dso_lookup { 80 1.1 christos dso_lookup_t *next; 81 1.1 christos DNSServiceRef sdref; 82 1.1 christos }; 83 1.1 christos 84 1.1 christos typedef struct dso_connect_state dso_connect_state_t; 85 1.1 christos 86 1.1 christos typedef enum { 87 1.1 christos // When the object is created and holds a reference to the context, the callback(see below) is called with 88 1.1 christos // dso_connect_life_cycle_create. 89 1.1 christos dso_connect_life_cycle_create, 90 1.1 christos // When the object is canceled, the callback(see below) is called with dso_connect_life_cycle_cancel to provide a 91 1.1 christos // chance for the context to do the corresponding cleaning work(cancel or release/free). 92 1.1 christos dso_connect_life_cycle_cancel, 93 1.1 christos // When the object is freed, the callback(see below) is called with dso_connect_life_cycle_free to provide a chance 94 1.1 christos // for the context to clean anything remains allocated. 95 1.1 christos dso_connect_life_cycle_free 96 1.1 christos } dso_connect_life_cycle_t; 97 1.1 christos 98 1.1 christos typedef bool (*dso_connect_life_cycle_context_callback_t)(const dso_connect_life_cycle_t life_cycle, 99 1.1 christos void *const context, dso_connect_state_t *const dso_connect); 100 1.1 christos 101 1.1 christos typedef struct dso_transport_address dso_transport_address_t; 102 1.1 christos struct dso_transport_address { 103 1.1 christos dso_transport_address_t *next; 104 1.1 christos mDNSAddr address; 105 1.1 christos mDNSIPPort port; 106 1.1 christos }; 107 1.1 christos 108 1.1 christos struct dso_connect_state { 109 1.1 christos dso_connect_state_t *next; 110 1.1 christos dso_event_callback_t callback; 111 1.1 christos dso_state_t *dso; 112 1.1 christos char *detail; 113 1.1 christos void *context; 114 1.1 christos 115 1.1 christos // The callback gets called when dso_state_t is created, canceled or finalized to do some status maintaining 116 1.1 christos // operation for the context. This is passed into dso_state_create(), when dso_connect_state_t uses the context to 117 1.1 christos // create a new dso_state_t in dso_connection_succeeded(). 118 1.1 christos dso_life_cycle_context_callback_t dso_context_callback; 119 1.1 christos // The callback gets called when dso_connect_t is created, canceled or finalized to do some status maintaining 120 1.1 christos // operation for the context. 121 1.1 christos dso_connect_life_cycle_context_callback_t dso_connect_context_callback; 122 1.1 christos TCPListener *listener; 123 1.1 christos 124 1.1 christos uint32_t serial; // Serial number that identifies a specific dso_connect_state_t. 125 1.1 christos char *hostname; 126 1.1 christos 127 1.1 christos // A list of addresses that we've discovered, and the next address to try. 128 1.1 christos dso_transport_address_t *addrs, *next_addr; 129 1.1 christos DNSServiceRef lookup; 130 1.1 christos mDNSBool canceled; // Indicates if the dso_connect_state_t has been canceled and should be ignored for processing. 131 1.1 christos 132 1.1 christos mDNSBool connecting; 133 1.1 christos 134 1.1 christos #if MDNSRESPONDER_SUPPORTS(APPLE, TERMINUS_ASSISTED_UNICAST_DISCOVERY) 135 1.1 christos // A boolean value to indicate whether the dso session should use the preconfigured TLS server certificates to 136 1.1 christos // perform the trust evaluation. 137 1.1 christos mDNSBool trusts_alternative_server_certificates; 138 1.1 christos #endif 139 1.1 christos 140 1.1 christos mDNSIPPort config_port, connect_port; 141 1.1 christos dso_transport_t *transport; 142 1.1 christos #ifdef DSO_USES_NETWORK_FRAMEWORK 143 1.1 christos nw_connection_t connection; 144 1.1 christos bool tls_enabled; 145 1.1 christos #else 146 1.1 christos size_t inbuf_size; 147 1.1 christos #endif 148 1.1 christos size_t outbuf_size; 149 1.1 christos int max_outstanding_queries; 150 1.1 christos mDNSs32 last_event; 151 1.1 christos mDNSs32 reconnect_time; 152 1.1 christos mDNSu32 if_idx; // The index of the interface where the DSO session is established through. 153 1.1 christos }; 154 1.1 christos 155 1.1 christos typedef struct { 156 1.1 christos TCPListener *listener; 157 1.1 christos dso_event_callback_t callback; 158 1.1 christos void *context; 159 1.1 christos } dso_listen_context_t; 160 1.1 christos 161 1.1 christos typedef struct { 162 1.1 christos const uint8_t *message; 163 1.1 christos size_t length; 164 1.1 christos } dso_message_payload_t; 165 1.1 christos 166 1.1 christos void dso_transport_init(void); 167 1.1 christos mStatus dso_set_connection(dso_state_t *dso, TCPSocket *socket); 168 1.1 christos void dso_schedule_reconnect(mDNS *m, dso_connect_state_t *cs, mDNSs32 when); 169 1.1 christos void dso_set_callback(dso_state_t *dso, void *context, dso_event_callback_t cb); 170 1.1 christos mStatus dso_message_write(dso_state_t *dso, dso_message_t *msg, bool disregard_low_water); 171 1.1 christos dso_connect_state_t *dso_connect_state_create( 172 1.1 christos const char *hostname, mDNSAddr *addr, mDNSIPPort port, 173 1.1 christos int max_outstanding_queries, size_t inbuf_size, size_t outbuf_size, 174 1.1 christos dso_event_callback_t callback, 175 1.1 christos dso_state_t *dso, void *context, 176 1.1 christos const dso_life_cycle_context_callback_t dso_context_callback, 177 1.1 christos const dso_connect_life_cycle_context_callback_t dso_connect_context_callback, 178 1.1 christos const char *detail); 179 1.1 christos #ifdef DSO_USES_NETWORK_FRAMEWORK 180 1.1 christos void dso_connect_state_use_tls(dso_connect_state_t *cs); 181 1.1 christos #endif 182 1.1 christos void dso_connect_state_cancel(dso_connect_state_t *const cs); 183 1.1 christos bool dso_connect(dso_connect_state_t *connect_state); 184 1.1 christos void dso_reconnect(dso_connect_state_t *cs, dso_state_t *dso); 185 1.1 christos mStatus dso_listen(dso_connect_state_t *listen_context); 186 1.1 christos bool dso_write_start(dso_transport_t *transport, size_t length); 187 1.1 christos bool dso_write_finish(dso_transport_t *transport); 188 1.1 christos void dso_write(dso_transport_t *transport, const uint8_t *buf, size_t length); 189 1.1 christos #endif // __DSO_TRANSPORT_H 190 1.1 christos 191 1.1 christos // Local Variables: 192 1.1 christos // mode: C 193 1.1 christos // tab-width: 4 194 1.1 christos // c-file-style: "bsd" 195 1.1 christos // c-basic-offset: 4 196 1.1 christos // fill-column: 108 197 1.1 christos // indent-tabs-mode: nil 198 1.1 christos // End: 199