Home | History | Annotate | Line # | Download | only in dist
      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