1 1.1 christos /* 2 1.1 christos * xfrd-tcp.h - XFR (transfer) Daemon TCP system header file. Manages tcp conn. 3 1.1 christos * 4 1.1 christos * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * See LICENSE for the license. 7 1.1 christos * 8 1.1 christos */ 9 1.1 christos 10 1.1 christos #ifndef XFRD_TCP_H 11 1.1 christos #define XFRD_TCP_H 12 1.1 christos 13 1.1 christos #include "xfrd.h" 14 1.1.1.3 christos #ifdef HAVE_TLS_1_3 15 1.1.1.3 christos #include <openssl/ssl.h> 16 1.1.1.3 christos #endif 17 1.1.1.3 christos 18 1.1 christos 19 1.1 christos struct buffer; 20 1.1 christos struct xfrd_zone; 21 1.1 christos struct xfrd_soa; 22 1.1 christos struct xfrd_state; 23 1.1 christos struct region; 24 1.1 christos struct dname; 25 1.1 christos struct acl_options; 26 1.1 christos 27 1.1 christos struct xfrd_tcp_pipeline; 28 1.1.1.2 christos typedef struct xfrd_tcp xfrd_tcp_type; 29 1.1.1.2 christos typedef struct xfrd_tcp_set xfrd_tcp_set_type; 30 1.1 christos /* 31 1.1 christos * A set of xfrd tcp connections. 32 1.1 christos */ 33 1.1 christos struct xfrd_tcp_set { 34 1.1.1.3 christos /* tcp connections, array, each has packet and read/wr state */ 35 1.1.1.3 christos struct xfrd_tcp_pipeline **tcp_state; 36 1.1.1.3 christos /* max number of tcp connections, size of tcp_state array */ 37 1.1.1.3 christos int tcp_max; 38 1.1.1.3 christos /* max number of simultaneous connections on a tcp_pipeline */ 39 1.1.1.3 christos int tcp_pipeline; 40 1.1 christos /* number of TCP connections in use. */ 41 1.1 christos int tcp_count; 42 1.1 christos /* TCP timeout. */ 43 1.1 christos int tcp_timeout; 44 1.1 christos /* rbtree with pipelines sorted by master */ 45 1.1.1.2 christos rbtree_type* pipetree; 46 1.1.1.3 christos #ifdef HAVE_TLS_1_3 47 1.1.1.3 christos /* XoT: SSL context */ 48 1.1.1.3 christos SSL_CTX* ssl_ctx; 49 1.1.1.3 christos #endif 50 1.1 christos /* double linked list of zones waiting for a TCP connection */ 51 1.1 christos struct xfrd_zone *tcp_waiting_first, *tcp_waiting_last; 52 1.1 christos }; 53 1.1 christos 54 1.1 christos /* 55 1.1 christos * Structure to keep track of an open tcp connection 56 1.1 christos * The xfrd tcp connection is used to first make a request 57 1.1 christos * Then to receive the answer packet(s). 58 1.1 christos */ 59 1.1 christos struct xfrd_tcp { 60 1.1 christos /* tcp connection state */ 61 1.1 christos /* state: reading or writing */ 62 1.1 christos uint8_t is_reading; 63 1.1 christos 64 1.1 christos /* how many bytes have been read/written - total, 65 1.1 christos incl. tcp length bytes */ 66 1.1 christos uint32_t total_bytes; 67 1.1 christos 68 1.1 christos /* msg len bytes */ 69 1.1 christos uint16_t msglen; 70 1.1 christos 71 1.1 christos /* fd of connection. -1 means unconnected */ 72 1.1 christos int fd; 73 1.1 christos 74 1.1 christos /* packet buffer of connection */ 75 1.1 christos struct buffer* packet; 76 1.1 christos }; 77 1.1 christos 78 1.1 christos /* use illegal pointer value to denote skipped ID number. 79 1.1 christos * if this does not work, we can allocate with malloc */ 80 1.1 christos #define TCP_NULL_SKIP ((struct xfrd_zone*)-1) 81 1.1 christos 82 1.1 christos /** 83 1.1.1.3 christos * The per-id zone pointers, with TCP_NULL_SKIP or a zone pointer for the 84 1.1.1.3 christos * ID value. 85 1.1 christos */ 86 1.1.1.3 christos struct xfrd_tcp_pipeline_id { 87 1.1.1.3 christos /** rbtree node as first member, this is the key. */ 88 1.1.1.3 christos rbnode_type node; 89 1.1.1.3 christos /** the ID of this member */ 90 1.1.1.3 christos uint16_t id; 91 1.1.1.3 christos /** zone pointer or TCP_NULL_SKIP */ 92 1.1.1.3 christos struct xfrd_zone* zone; 93 1.1.1.3 christos /** next free in free list */ 94 1.1.1.3 christos struct xfrd_tcp_pipeline_id* next_free; 95 1.1.1.3 christos }; 96 1.1.1.3 christos 97 1.1.1.3 christos /** 98 1.1.1.3 christos * The tcp pipeline key structure. By ip_len, ip, num_unused and unique by 99 1.1.1.3 christos * pointer value. 100 1.1.1.3 christos */ 101 1.1.1.3 christos struct xfrd_tcp_pipeline_key { 102 1.1 christos /* the rbtree node, sorted by IP and nr of unused queries */ 103 1.1.1.2 christos rbnode_type node; 104 1.1 christos /* destination IP address */ 105 1.1 christos #ifdef INET6 106 1.1 christos struct sockaddr_storage ip; 107 1.1 christos #else 108 1.1 christos struct sockaddr_in ip; 109 1.1 christos #endif /* INET6 */ 110 1.1 christos socklen_t ip_len; 111 1.1 christos /* number of unused IDs. used IDs are waiting to send their query, 112 1.1 christos * or have been sent but not not all answer packets have been received. 113 1.1 christos * Sorted by num_unused, so a lookup smaller-equal for 65536 finds the 114 1.1 christos * connection to that master that has the most free IDs. */ 115 1.1 christos int num_unused; 116 1.1 christos /* number of skip-set IDs (these are 'in-use') */ 117 1.1 christos int num_skip; 118 1.1.1.3 christos }; 119 1.1.1.3 christos 120 1.1.1.3 christos /** 121 1.1.1.3 christos * Structure to keep track of a pipelined set of queries on 122 1.1.1.3 christos * an open tcp connection. The queries may be answered with 123 1.1.1.3 christos * interleaved answer packets, the ID number disambiguates. 124 1.1.1.3 christos * Sorted by the master IP address so you can use lookup with 125 1.1.1.3 christos * smaller-or-equal to find the tcp connection most suitable. 126 1.1.1.3 christos */ 127 1.1.1.3 christos struct xfrd_tcp_pipeline { 128 1.1.1.3 christos /* the key information for the tcp pipeline, in its own 129 1.1.1.3 christos * struct so it can be referenced on its own for comparison funcs */ 130 1.1.1.3 christos struct xfrd_tcp_pipeline_key key; 131 1.1 christos 132 1.1 christos int handler_added; 133 1.1 christos /* the event handler for this pipe (it'll disambiguate by ID) */ 134 1.1 christos struct event handler; 135 1.1 christos 136 1.1 christos /* the tcp connection to use for reading */ 137 1.1.1.2 christos struct xfrd_tcp* tcp_r; 138 1.1 christos /* the tcp connection to use for writing, if it is done successfully, 139 1.1 christos * then the first zone from the sendlist can be removed. */ 140 1.1.1.2 christos struct xfrd_tcp* tcp_w; 141 1.1 christos /* once a byte has been written, handshake complete */ 142 1.1 christos int connection_established; 143 1.1.1.3 christos #ifdef HAVE_TLS_1_3 144 1.1.1.3 christos /* XoT: SSL object */ 145 1.1.1.3 christos SSL *ssl; 146 1.1.1.3 christos /* XoT: if SSL handshake is not done, handshake_want indicates the 147 1.1.1.3 christos * last error. This may be SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE 148 1.1.1.3 christos * when the handshake is still in progress. 149 1.1.1.3 christos */ 150 1.1.1.3 christos int handshake_want; 151 1.1.1.3 christos /* XoT: 1 if the SSL handshake has succeeded, 0 otherwise */ 152 1.1.1.3 christos int handshake_done; 153 1.1.1.3 christos #endif 154 1.1 christos 155 1.1 christos /* list of queries that want to send, first to get write event, 156 1.1 christos * if NULL, no write event interest */ 157 1.1 christos struct xfrd_zone* tcp_send_first, *tcp_send_last; 158 1.1.1.3 christos 159 1.1.1.3 christos /* size of the id and unused arrays. */ 160 1.1.1.3 christos int pipe_num; 161 1.1.1.3 christos /* list of free xfrd_tcp_pipeline_id nodes, these are not in the 162 1.1.1.3 christos * zone_per_id tree. preallocated at pipe_num amount. */ 163 1.1.1.3 christos struct xfrd_tcp_pipeline_id* pipe_id_free_list; 164 1.1.1.3 christos /* The xfrd_zone pointers, per id number. 165 1.1.1.3 christos * The key is struct xfrd_tcp_pipeline_id. 166 1.1.1.3 christos * per-ID number the queries that have this ID number, every 167 1.1 christos * query owns one ID numbers (until it is done). NULL: unused 168 1.1 christos * When a query is done but not all answer-packets have been 169 1.1 christos * consumed for that ID number, the rest is skipped, this 170 1.1 christos * is denoted with the pointer-value TCP_NULL_SKIP, the ids that 171 1.1 christos * are skipped are not on the unused list. They may be 172 1.1 christos * removed once the last answer packet is skipped. 173 1.1.1.3 christos * pipe_num-num_unused values are in the tree (either 174 1.1 christos * a zone pointer or SKIP) */ 175 1.1.1.3 christos rbtree_type* zone_per_id; 176 1.1.1.3 christos /* Array of uint16_t, with ID values. 177 1.1.1.3 christos * unused ID numbers; the first part of the array contains the IDs */ 178 1.1.1.3 christos uint16_t* unused; 179 1.1 christos }; 180 1.1 christos 181 1.1 christos /* create set of tcp connections */ 182 1.1.1.3 christos struct xfrd_tcp_set* xfrd_tcp_set_create(struct region* region, const char *tls_cert_bundle, int tcp_max, int tcp_pipeline); 183 1.1 christos 184 1.1 christos /* init tcp state */ 185 1.1.1.2 christos struct xfrd_tcp* xfrd_tcp_create(struct region* region, size_t bufsize); 186 1.1 christos /* obtain tcp connection for a zone (or wait) */ 187 1.1.1.2 christos void xfrd_tcp_obtain(struct xfrd_tcp_set* set, struct xfrd_zone* zone); 188 1.1 christos /* release tcp connection for a zone (starts waiting) */ 189 1.1.1.2 christos void xfrd_tcp_release(struct xfrd_tcp_set* set, struct xfrd_zone* zone); 190 1.1 christos /* release tcp pipe entirely (does not stop the zones inside it) */ 191 1.1.1.2 christos void xfrd_tcp_pipe_release(struct xfrd_tcp_set* set, 192 1.1.1.2 christos struct xfrd_tcp_pipeline* tp, int conn); 193 1.1 christos /* use tcp connection to start xfr */ 194 1.1 christos void xfrd_tcp_setup_write_packet(struct xfrd_tcp_pipeline* tp, 195 1.1 christos struct xfrd_zone* zone); 196 1.1 christos /* initialize tcp_state for a zone. Opens the connection. true on success.*/ 197 1.1.1.2 christos int xfrd_tcp_open(struct xfrd_tcp_set* set, struct xfrd_tcp_pipeline* tp, 198 1.1.1.2 christos struct xfrd_zone* zone); 199 1.1 christos /* read data from tcp, maybe partial read */ 200 1.1 christos void xfrd_tcp_read(struct xfrd_tcp_pipeline* tp); 201 1.1 christos /* write data to tcp, maybe a partial write */ 202 1.1 christos void xfrd_tcp_write(struct xfrd_tcp_pipeline* tp, struct xfrd_zone* zone); 203 1.1 christos /* handle tcp pipe events */ 204 1.1 christos void xfrd_handle_tcp_pipe(int fd, short event, void* arg); 205 1.1 christos 206 1.1 christos /* 207 1.1 christos * Read from a stream connection (size16)+packet into buffer. 208 1.1 christos * returns value is 209 1.1 christos * -1 on error. 210 1.1 christos * 0 on short read, call back later. 211 1.1 christos * 1 on completed read. 212 1.1 christos * On first call, make sure total_bytes = 0, msglen=0, buffer_clear(). 213 1.1 christos * and the packet and fd need to be set. 214 1.1 christos */ 215 1.1.1.2 christos int conn_read(struct xfrd_tcp* conn); 216 1.1 christos /* 217 1.1 christos * Write to a stream connection (size16)+packet. 218 1.1 christos * return value is 219 1.1 christos * -1 on error. 0 on short write, call back later. 1 completed write. 220 1.1 christos * On first call, make sure total_bytes=0, msglen=buffer_limit(), 221 1.1 christos * buffer_flipped(). packet and fd need to be set. 222 1.1 christos */ 223 1.1.1.2 christos int conn_write(struct xfrd_tcp* conn); 224 1.1 christos 225 1.1 christos /* setup DNS packet for a query of this type */ 226 1.1 christos void xfrd_setup_packet(struct buffer* packet, 227 1.1.1.4 christos uint16_t type, uint16_t klass, const struct dname* dname, uint16_t qid, 228 1.1.1.4 christos int* apex_compress); 229 1.1 christos /* write soa in network format to the packet buffer */ 230 1.1 christos void xfrd_write_soa_buffer(struct buffer* packet, 231 1.1.1.4 christos const struct dname* apex, struct xfrd_soa* soa, int apex_compress); 232 1.1 christos /* use acl address to setup sockaddr struct, returns length of addr. */ 233 1.1 christos socklen_t xfrd_acl_sockaddr_to(struct acl_options* acl, 234 1.1 christos #ifdef INET6 235 1.1 christos struct sockaddr_storage *to); 236 1.1 christos #else 237 1.1 christos struct sockaddr_in *to); 238 1.1 christos #endif /* INET6 */ 239 1.1 christos 240 1.1 christos socklen_t xfrd_acl_sockaddr_frm(struct acl_options* acl, 241 1.1 christos #ifdef INET6 242 1.1 christos struct sockaddr_storage *frm); 243 1.1 christos #else 244 1.1 christos struct sockaddr_in *frm); 245 1.1 christos #endif /* INET6 */ 246 1.1 christos 247 1.1 christos /* create pipeline tcp structure */ 248 1.1.1.3 christos struct xfrd_tcp_pipeline* xfrd_tcp_pipeline_create(region_type* region, 249 1.1.1.3 christos int tcp_pipeline); 250 1.1.1.3 christos /* pick num uint16_t values, from 0..max-1, store in array */ 251 1.1.1.3 christos void pick_id_values(uint16_t* array, int num, int max); 252 1.1 christos 253 1.1.1.4 christos #ifdef HAVE_SSL 254 1.1.1.4 christos void get_cert_info(SSL* ssl, region_type* region, char** cert_serial, 255 1.1.1.4 christos char** key_id, char** cert_algorithm, char** tls_version); 256 1.1.1.4 christos #endif 257 1.1.1.4 christos 258 1.1 christos #endif /* XFRD_TCP_H */ 259