/* * xfrd-tcp.h - XFR (transfer) Daemon TCP system header file. Manages tcp conn. * * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. * * See LICENSE for the license. * */ #ifndef XFRD_TCP_H #define XFRD_TCP_H #include #include "xfrd.h" struct buffer; struct xfrd_zone; struct xfrd_soa; struct xfrd_state; struct region; struct dname; struct acl_options; typedef struct xfrd_tcp xfrd_tcp_t; typedef struct xfrd_tcp_set xfrd_tcp_set_t; /* * A set of xfrd tcp connections. */ struct xfrd_tcp_set { /* tcp connections, each has packet and read/wr state */ struct xfrd_tcp *tcp_state[XFRD_MAX_TCP]; /* number of TCP connections in use. */ int tcp_count; /* TCP timeout. */ int tcp_timeout; /* linked list of zones waiting for a TCP connection */ struct xfrd_zone *tcp_waiting_first, *tcp_waiting_last; }; /* * Structure to keep track of an open tcp connection * The xfrd tcp connection is used to first make a request * Then to receive the answer packet(s). */ struct xfrd_tcp { /* tcp connection state */ /* state: reading or writing */ uint8_t is_reading; /* how many bytes have been read/written - total, incl. tcp length bytes */ uint32_t total_bytes; /* msg len bytes */ uint16_t msglen; /* fd of connection. -1 means unconnected */ int fd; /* packet buffer of connection */ struct buffer* packet; }; /* create set of tcp connections */ xfrd_tcp_set_t* xfrd_tcp_set_create(struct region* region); /* init tcp state */ xfrd_tcp_t* xfrd_tcp_create(struct region* region); /* obtain tcp connection for a zone (or wait) */ void xfrd_tcp_obtain(xfrd_tcp_set_t* set, struct xfrd_zone* zone); /* release tcp connection for a zone (starts waiting) */ void xfrd_tcp_release(xfrd_tcp_set_t* set, struct xfrd_zone* zone); /* use tcp connection to start xfr */ void xfrd_tcp_xfr(xfrd_tcp_set_t* set, struct xfrd_zone* zone); /* initialize tcp_state for a zone. Opens the connection. true on success.*/ int xfrd_tcp_open(xfrd_tcp_set_t* set, struct xfrd_zone* zone); /* read data from tcp, maybe partial read */ void xfrd_tcp_read(xfrd_tcp_set_t* set, struct xfrd_zone* zone); /* write data to tcp, maybe a partial write */ void xfrd_tcp_write(xfrd_tcp_set_t* set, struct xfrd_zone* zone); /* see if the tcp connection is in the reading stage (else writin) */ static inline int xfrd_tcp_is_reading(xfrd_tcp_set_t* set, int conn) {return set->tcp_state[conn]->is_reading;} /* * Read from a stream connection (size16)+packet into buffer. * returns value is * -1 on error. * 0 on short read, call back later. * 1 on completed read. * On first call, make sure total_bytes = 0, msglen=0, buffer_clear(). * and the packet and fd need to be set. */ int conn_read(xfrd_tcp_t* conn); /* * Write to a stream connection (size16)+packet. * return value is * -1 on error. 0 on short write, call back later. 1 completed write. * On first call, make sure total_bytes=0, msglen=buffer_limit(), * buffer_flipped(). packet and fd need to be set. */ int conn_write(xfrd_tcp_t* conn); /* setup DNS packet for a query of this type */ void xfrd_setup_packet(struct buffer* packet, uint16_t type, uint16_t klass, const struct dname* dname); /* write soa in network format to the packet buffer */ void xfrd_write_soa_buffer(struct buffer* packet, const struct dname* apex, struct xfrd_soa* soa); /* use acl address to setup sockaddr struct, returns length of addr. */ socklen_t xfrd_acl_sockaddr_to(struct acl_options* acl, #ifdef INET6 struct sockaddr_storage *to); #else struct sockaddr_in *to); #endif /* INET6 */ socklen_t xfrd_acl_sockaddr_frm(struct acl_options* acl, #ifdef INET6 struct sockaddr_storage *frm); #else struct sockaddr_in *frm); #endif /* INET6 */ #endif /* XFRD_TCP_H */