Mercurial > notdcc
diff include/dcc_clnt.h @ 0:c7f6b056b673
First import of vendor version
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 13:49:58 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/dcc_clnt.h Tue Mar 10 13:49:58 2009 +0100 @@ -0,0 +1,545 @@ +/* Distributed Checksum Clearinghouse + * + * internal client definitions + * + * Copyright (c) 2008 by Rhyolite Software, LLC + * + * This agreement is not applicable to any entity which sells anti-spam + * solutions to others or provides an anti-spam solution as part of a + * security solution sold to other entities, or to a private network + * which employs the DCC or uses data provided by operation of the DCC + * but does not provide corresponding data to other users. + * + * Permission to use, copy, modify, and distribute this software without + * changes for any purpose with or without fee is hereby granted, provided + * that the above copyright notice and this permission notice appear in all + * copies and any distributed versions or copies are either unchanged + * or not called anything similar to "DCC" or "Distributed Checksum + * Clearinghouse". + * + * Parties not eligible to receive a license under this agreement can + * obtain a commercial license to use DCC by contacting Rhyolite Software + * at sales@rhyolite.com. + * + * A commercial license would be for Distributed Checksum and Reputation + * Clearinghouse software. That software includes additional features. This + * free license for Distributed ChecksumClearinghouse Software does not in any + * way grant permision to use Distributed Checksum and Reputation Clearinghouse + * software + * + * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC + * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Rhyolite Software DCC 1.3.103-1.120 $Revision$ + */ + +#ifndef DCC_CLNT_H +#define DCC_CLNT_H + +#include "dcc_defs.h" + + +#define DCC_DCCD_DELAY (100*1000) /* typical server delay */ + +/* The minimum assumed RTT should be long enough for the DCC server to do + * some disk operations even if the server and network have usually + * been faster. */ +#define DCC_MIN_RTT (DCC_DCCD_DELAY + 150*1000) + +#define DCC_MAX_XMITS 4 + +/* worst client-->server-->client RTT + * The total delay for N exponentially increasing delays starting with X + * is about X*(2**N). With the delay limited to Y, it is Y*N. + * The RTT measuring done with NOPs uses retransmission delays based on + * DCC_MIN_RTT, and so will not find a server with a worse delay than + * DCC_MAX_RTT */ +#define DCC_MAX_RTT (DCC_MIN_RTT<<DCC_MAX_XMITS) +#define DCC_MAX_RTT_SECS (DCC_MAX_RTT/DCC_US) + +#define DCC_RTT_ADJ_MAX (DCC_MAX_RTT/2) /* limit manual RTT bias */ +#define DCC_RTT_VERS_ADJ DCC_RTT_ADJ_MAX /* penalize strange versions */ +#define DCC_RTT_BAD (DCC_MAX_RTT*2+1) + +/* If DCC_MAX_XMITS and the retransmission delay limited to DCC_MAX_RTT_SECS, + * the the worst case delay is DCC_MAX_XMITS*DCC_MAX_RTT_SECS=16 seconds */ +#define DCC_MAX_DELAY (DCC_MAX_XMITS*DCC_MAX_RTT) +#define DCC_MAX_DELAY_SECS (DCC_MAX_DELAY/DCC_US) + + +/* No client's retransmission can be delayed by more than this starting + * from the initial intransmission and including network delays for the + * last retransmission + * This controls how long a DCC server must remember old requests + * to recognize retransmissions. */ +#define DCC_MAX_RETRANS_DELAY_SECS (DCC_MAX_DELAY_SECS*2) + + +#ifndef DCC_MAP_RESOLVE +#define DCC_MAP_RESOLVE (2*60*60) /* DNS resolve server host names */ +#endif +#ifndef DCC_WHITECLNT_RESOLVE +#define DCC_WHITECLNT_RESOLVE (2*60*60) /* DNS resolve whitelist hosts */ +#endif + +#define DCC_MAX_SRVR_NMS 8 /* server hostnames */ +#define DCC_MAX_SRVR_ADDRS 12 /* server IP addresses */ + +extern u_char dcc_clnt_debug; +extern int dcc_debug_ttl; + +extern char dcc_clnt_hostname[MAXHOSTNAMELEN]; + +/* information kept by a client about a server */ +typedef struct { + int rtt_adj; + DCC_CLNT_ID clnt_id; /* our client-ID sent to the server */ + u_int16_t port; /* network byte order port # */ + u_char defined; /* name resolves into an IP address */ + char hostname[DCC_MAXDOMAINLEN]; /* null terminated */ + u_char pad; + DCC_PASSWD passwd; /* null filled but not terminated */ +} DCC_SRVR_NM; + +/* the port number must be installed in this before use */ +#define DCC_SRVR_NM_DEF_HOST "127.0.0.1" +#define DCC_SRVR_NM_DEF {0, DCC_ID_ANON, 0, 0, {DCC_SRVR_NM_DEF_HOST}, 0, {""}} + +typedef u_int16_t NAM_INX; +typedef struct { /* a single server address */ + DCC_IP ip; + time_t rtt_updated; /* when RTT last updated */ + int rtt; /* round trip time in microseconds */ + int srvr_wait; /* microseconds server penalizes us */ + u_int32_t resp_mem; /* 1 bit per recent xmit */ +# define DCC_TOTAL_XMITS_MAX (sizeof(u_int32_t)*8) + NAM_INX nam_inx; /* DCC_NO_NM or DCC_SRVR_NM.nms index */ +# define NO_NAM ((NAM_INX)(-1)) +# define GOOD_NAM(n) ((n) < DCC_MAX_SRVR_NMS) + DCC_SRVR_ID srvr_id; /* the server's claimed ID */ + u_char total_xmits; + u_char total_resps; + u_char srvr_pkt_vers; + u_char flags; +# define DCC_SRVR_ADDR_MHOME 0x01 /* do not use connect */ + DCC_BRAND brand; /* the server's announced brand name */ +} DCC_SRVR_ADDR; + +typedef u_char SRVR_INX; +typedef struct { + time_t resolve; /* when names need to be resolved */ + time_t measure; /* when RTT measurements need */ + int gen; + int base_rtt; /* RTT to the chosen server */ + int thold_rtt; /* threshold for switching */ + int avg_thold_rtt; /* long term threshold */ + int num_srvrs; /* addresses in .addrs */ + time_t fail_time; /* DCC broken until then */ + u_char fail_exp; /* backoff */ +# define DCC_INIT_FAIL_SECS (DCC_MAX_DELAY_SECS*2) +# define DCC_MAX_FAIL_EXP 6 +# define DCC_MAX_FAIL_SECS (DCC_INIT_FAIL_SECS<<DCC_MAX_FAIL_EXP) + SRVR_INX srvr_inx; /* NO_SRVR or index in .addrs */ +# define NO_SRVR ((SRVR_INX)(-1)) +# define GOOD_SRVR(c,s) ((s) < (c)->num_srvrs) +# define HAVE_SRVR(c) GOOD_SRVR(c,c->srvr_inx) + DCC_SRVR_NM nms[DCC_MAX_SRVR_NMS]; + DCC_SRVR_ADDR addrs[DCC_MAX_SRVR_ADDRS]; +} DCC_SRVR_CLASS; + +/* Information about DCC servers shared among clients on a host + * This is the shape of the mmap()'ed file. */ +typedef struct { +# define DCC_MAP_INFO_VERSION "DCC client mapped data version #11" + char version[36]; + u_int residue; /* random # for picking addresses */ + u_char flags; +# define DCC_INFO_FG_IPV6 0x01 +#ifdef NO_IPV6 +# define DCC_INFO_IPV6() 0 +#else +# define DCC_INFO_IPV6() (dcc_clnt_info \ + && (dcc_clnt_info->flags \ + & DCC_INFO_FG_IPV6) != 0) +#endif +# define DCC_INFO_FG_SOCKS 0x02 +# define DCC_INFO_FG_TMP 0x04 + DCC_HDR proto_hdr; /* prototype DCC request header */ + DCC_SRVR_CLASS dcc; /* normal DCC services */ + DCC_SRVR_CLASS grey; /* grey listing */ + DCC_IP src; /* send from this interface */ + time_t dccproc_last; + time_t dccproc_dccifd_try; + int dccproc_c; +# define DCCPROC_TRY_DCCIFD (60*60) /* start dccifd once/hour */ +# define DCCPROC_MAX_CREDITS 500 /* at least 500 */ +# define DCCPROC_COST 10 /* and at least 0.1/second */ +} DCC_CLNT_INFO; + + +#define DCC_MAP_INFO_VERSION_10 "DCC client mapped data version #10" +#ifdef DCC_MAP_INFO_VERSION_10 +typedef struct { + int rtt_adj; + DCC_CLNT_ID clnt_id; + u_int16_t port; + u_char defined; + char hostname[MAXHOSTNAMELEN]; + u_char pad; + DCC_PASSWD passwd; +} DCC_V10_SRVR_NM; +typedef struct { + time_t resolve; + time_t measure; + int gen; + int base_rtt; + int thold_rtt; + int avg_thold_rtt; + int num_addrs; + time_t fail_time; + u_char fail_exp; + u_char act_inx; + DCC_V10_SRVR_NM nms[DCC_MAX_SRVR_NMS]; + DCC_SRVR_ADDR addrs[DCC_MAX_SRVR_ADDRS]; +} DCC_V10_SRVR_CLASS; +typedef struct { + char version[36]; + u_int residue; + u_char flags; + DCC_HDR proto_hdr; + DCC_V10_SRVR_CLASS dcc; + DCC_V10_SRVR_CLASS grey; + DCC_IP src; + time_t dccproc_last; + time_t dccproc_dccifd_try; + int dccproc_c; +} DCC_V10_CLNT_INFO; +#endif /* DCC_MAP_INFO_VERSION_10 */ + +#define DCC_MAP_INFO_VERSION_9 "DCC client mapped data version #9" +#ifdef DCC_MAP_INFO_VERSION_9 +typedef struct { + char version[36]; + u_int residue; + u_char flags; + DCC_HDR proto_hdr; + DCC_V10_SRVR_CLASS dcc; + DCC_V10_SRVR_CLASS grey; + DCC_IP src; +} DCC_V9_CLNT_INFO; +#endif /* DCC_MAP_INFO_VERSION_9 */ + +#define DCC_MAP_INFO_VERSION_8 "DCC client mapped data version #8" +#ifdef DCC_MAP_INFO_VERSION_8 +typedef struct { + char version[36]; + u_int residue; + u_char flags; + DCC_HDR proto_hdr; + DCC_V10_SRVR_CLASS dcc; + DCC_V10_SRVR_CLASS grey; +} DCC_V8_CLNT_INFO; +#endif /* DCC_MAP_INFO_VERSION_8 */ + +#ifndef DCC_WIN32 +#define DCC_MAP_INFO_VERSION_7 "DCC client mapped data version #7" +#endif +#ifdef DCC_MAP_INFO_VERSION_7 +typedef struct { + DCC_SOCKU su; + time_t rtt_updated; + int rtt; + int srvr_wait; + u_int32_t resp_mem; + u_int16_t nm_inx; + DCC_SRVR_ID srvr_id; + u_char total_xmits; + u_char total_resps; + u_char srvr_pkt_vers; + u_char unused[1]; + DCC_BRAND brand; +} DCC_V7_IPV6_SRVR_ADDR; +typedef struct { + union { + struct sockaddr sa; + struct sockaddr_in ipv4; + struct dcc_sockaddr_in6 ipv6; + } su; + time_t rtt_updated; + int rtt; + int srvr_wait; + u_int32_t resp_mem; + u_int16_t nm_inx; + DCC_SRVR_ID srvr_id; + u_char total_xmits; + u_char total_resps; + u_char srvr_pkt_vers; + u_char unused[1]; + DCC_BRAND brand; +} DCC_V7_NOIPV6_SRVR_ADDR; + +typedef struct { + time_t resolve; + time_t measure; + int gen; + int base_rtt; + int thold_rtt; + int avg_thold_rtt; + int num_addrs; + time_t fail_time; + u_char fail_exp; + u_char act_inx; + DCC_V10_SRVR_NM nms[8]; + DCC_V7_IPV6_SRVR_ADDR addrs[12]; +} DCC_V7_IPV6_SRVR_CLASS; +typedef struct { + time_t resolve; + time_t measure; + int gen; + int base_rtt; + int thold_rtt; + int avg_thold_rtt; + int num_addrs; + time_t fail_time; + u_char fail_exp; + u_char act_inx; + DCC_V10_SRVR_NM nms[8]; + DCC_V7_NOIPV6_SRVR_ADDR addrs[12]; +} DCC_V7_NOIPV6_SRVR_CLASS; + +typedef struct { + char version[36]; + u_int residue; + u_char flags; + DCC_HDR proto_hdr; + DCC_V7_IPV6_SRVR_CLASS dcc; + DCC_V7_IPV6_SRVR_CLASS grey; +} DCC_V7_IPV6_CLNT_INFO; +typedef struct { + char version[36]; + u_int residue; + u_char flags; + DCC_HDR proto_hdr; + DCC_V7_NOIPV6_SRVR_CLASS dcc; + DCC_V7_NOIPV6_SRVR_CLASS grey; +} DCC_V7_NOIPV6_CLNT_INFO; +#endif /* DCC_MAP_INFO_VERSION_7 */ + +#ifndef DCC_WIN32 +#define DCC_MAP_INFO_VERSION_6 "DCC client mapped data version #6" +#endif +#ifdef DCC_MAP_INFO_VERSION_6 +typedef struct { + char version[36]; + time_t resolve; + time_t measure; + time_t srvr_fail_time; + int base_rtt; + int thold_rtt; + int avg_thold_rtt; + u_char unused[8]; + u_char srvr_fail_exp; + u_char act_inx; + u_char total_addrs; + u_char flags; + DCC_HDR proto_hdr; + DCC_V10_SRVR_NM nms[8]; +} DCC_V6_CLNT_INFO; + +typedef struct { + DCC_CLNT_ID clnt_id; + u_int16_t port; + char hostname[MAXHOSTNAMELEN+1]; + DCC_PASSWD passwd; + signed char rtt_adj; +} DCC_V5_SRVR_NM; + +typedef struct { +# define DCC_MAP_INFO_VERSION_5 "DCC client mapped data version #5" + char version[36]; + time_t resolve; + int min_delay; + u_int16_t act_inx; + u_char unused[13]; + u_char total_addrs; + u_char working_addrs; + u_char flags; + DCC_HDR proto_hdr; + DCC_V5_SRVR_NM nms[8]; +} DCC_V5_CLNT_INFO; +#endif /* DCC_MAP_INFO_VERSION_6 */ + +#define DCC_IS_GREY(class) ((class) == &dcc_clnt_info->grey) +#define DCC_IS_GREY_STR(c) (DCC_IS_GREY(c) ? "greylist" : "DCC") +#define DCC_GREY2PORT(mode) htons((mode)? DCC_GREY_PORT : DCC_SRVR_PORT) +#define DCC_CLASS2PORT(c) DCC_GREY2PORT(DCC_IS_GREY(c)) +#define DCC_GREY2CLASS(g) ((g) ? &dcc_clnt_info->grey : &dcc_clnt_info->dcc) + +extern DCC_CLNT_INFO *dcc_clnt_info; /* memory mapped shared data */ +extern u_char dcc_all_srvrs; /* try to contact all servers */ +extern DCC_PATH dcc_info_nm; + + +typedef struct { /* record of 1 transmission */ + DCC_OP_NUMS op_nums; + time_t sent_us; /* microseconds since operation start */ + DCC_OPS op; + DCC_CLNT_ID id; + int addrs_gen; + DCC_SOCKU su; + int addr_inx; + DCC_PASSWD passwd; +} DCC_XLOG_ENTRY; + +typedef struct { + u_char outstanding; /* unheard responses */ + u_char working_addrs; + struct { + u_char xmits; + u_char resps; + } cur[DCC_MAX_SRVR_ADDRS]; + DCC_XLOG_ENTRY *base; /* start of array */ + DCC_XLOG_ENTRY *next; /* next entry to use */ + DCC_XLOG_ENTRY *last; /* last entry in array */ +} DCC_XLOG; + +/* invalid timer */ +#define DCC_OP_NUMS_NULL ((u_int32_t)-1) + + +typedef struct dcc_clnt_ctxt { + struct dcc_clnt_ctxt *fwd; + struct timeval now; /* current time */ + struct timeval start; /* when operation started */ + int now_us; /* usecs since start of operation */ + time_t bind_time; /* when to retry binding socket */ +# define DCC_CTXT_REBIND_SECS 3600 /* check local interface hourly */ + SOCKET soc; + DCC_SOCKU bind_su; /* socket bound to this address */ + DCC_SOCKU conn_su; /* socket connected to this address */ + DCC_XLOG xlog; + DCC_XLOG_ENTRY xlog_entries[DCC_MAX_SRVR_ADDRS*DCC_MAX_XMITS]; + u_char flags; +# define DCC_CTXT_USING_IPV4 0x01 /* socket is opened for IPv4 */ +# define DCC_CTXT_SRCBAD 0x02 /* bind() failed */ +} DCC_CLNT_CTXT; + +#define DCC_INFO_USE_IPV4 "IPv6 off" +#define DCC_INFO_USE_IPV6 "IPv6 on" +#define DCC_INFO_USE_SOCKS "use SOCKS" +#define DCC_INFO_USE_SRC "src=" +#define DCC_INFO_USE_SRCBAD "but unused" + + +/* many POSIX thread implementations have unexpected side effects on + * ordinary system calls, so allow the calling application + * to not use threads by having both threaded and unthreaded + * DCC client interfaces */ + +extern void dcc_ctxts_lock(void); +extern void dcc_ctxts_unlock(void); +extern void dcc_syslog_lock(void); +extern void dcc_syslog_unlock(void); +extern u_char dcc_clnt_wake_resolve(void); +extern void dcc_clnt_stop_resolve(void); +extern void dcc_clnt_unthread_init(void); +extern void dcc_clnt_thread_init(void); +extern void lock_work(void); +extern void unlock_work(void); +extern void lock_wf(void); +extern void unlock_wf(void); +#ifdef DCC_DEBUG_CLNT_LOCK +extern void assert_ctxts_locked(void); +extern void assert_ctxts_unlocked(void); +extern void assert_info_locked(void); +extern void assert_info_unlocked(void); +extern void assert_cwf_locked(void); +#else +#define assert_ctxts_locked() +#define assert_ctxts_unlocked() +#define assert_info_locked() +#define assert_info_unlocked() +#define assert_cwf_locked() +#endif /* DCC_DEBUG_CLNT_LOCK */ +extern u_char helper_lock_init(void); +extern void helper_lock(void); +extern void helper_unlock(void); + + +extern const char *dcc_ap2str(const DCC_SRVR_ADDR *); +extern int dcc_ap2str_opt(char *, int, + const DCC_SRVR_CLASS *, u_char inx, char); + +extern FILE *dcc_open_srvr_nm(DCC_EMSG, const char *); +extern const char *dcc_parse_nm_port(DCC_EMSG, const char *, u_int, + char *, u_int, u_int16_t *, char *, u_int, + const char *, int); +extern int dcc_parse_srvr_nm(DCC_EMSG, DCC_SRVR_NM *, u_char *, + const char *, const char *, int); +extern const char *dcc_srvr_nm(u_char); +extern DCC_CLNT_CTXT *dcc_alloc_ctxt(void); +extern void dcc_rel_ctxt(DCC_CLNT_CTXT *); +extern u_char dcc_info_unlock(DCC_EMSG); +extern u_char dcc_info_lock(DCC_EMSG); +extern void dcc_force_measure_rtt(DCC_SRVR_CLASS *); +extern u_char dcc_create_map(DCC_EMSG, const DCC_PATH, int *, + const DCC_SRVR_NM *, int, + const DCC_SRVR_NM *, int, + const DCC_IP *, u_char); +extern u_char dcc_unmap_close_info(DCC_EMSG); +extern u_char dcc_map_info(DCC_EMSG, const char *, int); +extern u_char dcc_map_lock_info(DCC_EMSG, const char *, int); +extern u_char dcc_map_tmp_info(DCC_EMSG, const DCC_SRVR_NM *, + const DCC_IP *, u_char); +typedef u_char DCC_CLNT_FGS; +#define DCC_CLNT_FG_NONE 0x00 +#define DCC_CLNT_FG_GREY 0x01 +#define DCC_CLNT_FG_BAD_SRVR_OK 0x02 +#define DCC_CLNT_FG_NO_PICK_SRVR 0x04 +#define DCC_CLNT_FG_NO_FAIL 0x08 +#define DCC_CLNT_FG_RETRY 0x10 /* retrying with different server */ +#define DCC_CLNT_FG_SLOW 0x20 /* slow timeouts */ +#define DCC_CLNT_FG_RETRANS 0x40 /* use old op_nums.r */ +extern u_char dcc_clnt_rdy(DCC_EMSG, DCC_CLNT_CTXT *, DCC_CLNT_FGS); +extern DCC_CLNT_CTXT *dcc_tmp_clnt_init(DCC_EMSG, DCC_CLNT_CTXT *, + const DCC_SRVR_NM *, + const DCC_IP *, DCC_CLNT_FGS, u_char); +extern DCC_CLNT_CTXT *dcc_clnt_start(DCC_EMSG, DCC_CLNT_CTXT *, + const char *, DCC_CLNT_FGS); +extern DCC_CLNT_CTXT *dcc_clnt_start_fin(DCC_EMSG, DCC_CLNT_CTXT *); +extern DCC_CLNT_CTXT *dcc_clnt_init(DCC_EMSG, DCC_CLNT_CTXT *, + const char *, DCC_CLNT_FGS); +extern u_char dcc_clnt_connect(DCC_EMSG, DCC_CLNT_CTXT *, const DCC_SOCKU *); +extern void dcc_clnt_soc_close(DCC_CLNT_CTXT *); +extern u_char dcc_clnt_soc_reopen(DCC_EMSG, DCC_CLNT_CTXT *); +extern int dcc_select_poll(DCC_EMSG, SOCKET, u_char, int); +extern u_char dcc_clnt_op(DCC_EMSG, DCC_CLNT_CTXT *, DCC_CLNT_FGS, + const SRVR_INX *, DCC_SRVR_ID *, DCC_SOCKU *, + DCC_HDR *, int, DCC_OPS, DCC_OP_RESP *, int); + +extern DCC_OPS dcc_aop(DCC_EMSG, DCC_CLNT_CTXT *, + DCC_CLNT_FGS, SRVR_INX, time_t, + DCC_AOPS, u_int32_t, u_char, u_char, u_char, + u_char *, u_int, DCC_OP_RESP *, DCC_SOCKU *); +extern u_char dcc_aop_persist(DCC_EMSG, DCC_CLNT_CTXT *, DCC_CLNT_FGS, u_char, + DCC_AOPS, u_int32_t, int, DCC_OP_RESP *); + +extern void dcc_print_info(const char *, const DCC_CLNT_INFO *, + u_char, u_char, u_char, u_char, u_char); + +extern int get_xhdr_fname(char *, int, const DCC_CLNT_INFO *); +extern void xhdr_init(DCC_HEADER_BUF *, DCC_SRVR_ID); +extern void xhdr_add_str(DCC_HEADER_BUF *, const char *, ...) PATTRIB(2,3); +extern void xhdr_add_ck(DCC_HEADER_BUF *, DCC_CK_TYPES, DCC_TGTS); +extern void xhdr_write(LOG_WRITE_FNC, void *, const char *, int, u_char); +extern void xhdr_whitelist(DCC_HEADER_BUF *); +extern u_char is_xhdr(const char *, int); + + +#endif /* DCC_CLNT_H */