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