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