/* Distributed Checksum Clearinghouse * * internal client definitions * * Copyright (c) 2006 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 for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * Parties not eligible to receive a license under this agreement can * obtain a commercial license to use DCC and permission to use * U.S. Patent 6,330,590 by contacting Commtouch at http://www.commtouch.com/ * or by email to nospam@commtouch.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.50-1.101 $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<act_inx < class->num_addrs) #define DCC_NO_SRVR ((SRVR_INX)(-1)) /* 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 #10" 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 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 3600 /* start dccifd once/hour */ # define DCCPROC_MAX_CREDITS 500 /* at least 500 */ # define DCCPROC_COST 10 /* at least 0.1/second */ } DCC_CLNT_INFO; #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_SRVR_CLASS dcc; DCC_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_SRVR_CLASS dcc; DCC_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_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_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_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 do 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_clnt_resolve_mutex_lock(void); extern void dcc_clnt_resolve_mutex_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 have_ctxts_lock(void); extern void have_clnt_resolve_mutex(void); extern void have_cwf_lock(void); #else #define have_ctxts_lock() #define have_clnt_resolve_mutex() #define have_cwf_lock() #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 const char *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(void); 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 u_char dcc_clnt_resolve_lock(DCC_EMSG); extern u_char dcc_clnt_resolve_unlock(DCC_EMSG); extern void dcc_force_measure_rtt(DCC_SRVR_CLASS *, u_char); 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_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_lock_tmp_info(DCC_EMSG, const DCC_SRVR_NM *, const DCC_IP *, u_char); extern u_char dcc_clnt_rdy(DCC_EMSG, DCC_CLNT_CTXT *, u_char); #define DCC_CLNT_FG_NONE 0x00 #define DCC_CLNT_FG_GREY 0x01 #define DCC_CLNT_FG_NO_SRVR_OK 0x02 /* picking server optional */ #define DCC_CLNT_FG_NO_FAIL 0x04 #define DCC_CLNT_FG_RETRY 0x08 /* retrying with different server */ #define DCC_CLNT_FG_SLOW 0x10 /* slow timeouts */ extern DCC_CLNT_CTXT *dcc_tmp_clnt_init(DCC_EMSG, DCC_CLNT_CTXT *, const DCC_SRVR_NM *, const DCC_IP *, u_char, u_char); extern DCC_CLNT_CTXT *dcc_clnt_start(DCC_EMSG, DCC_CLNT_CTXT *, const char *, u_char); 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 *, u_char); 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 *, u_char, const SRVR_INX *, DCC_SRVR_ID *, DCC_SOCKU *, DCC_HDR *, int, DCC_OPS, DCC_HDR *, int); typedef union { DCC_HDR hdr; DCC_OK ok; DCC_ERROR error; DCC_ADMN_RESP resp; } AOP_RESP; extern DCC_OPS dcc_aop(DCC_EMSG, DCC_CLNT_CTXT *, u_char, SRVR_INX, DCC_AOPS, u_int32_t, u_char, u_char, u_char, u_char *, u_int, AOP_RESP *, DCC_SOCKU *); extern void dcc_print_info(const char *, const DCC_CLNT_INFO *, u_char, u_char, u_char, u_char); extern int dcc_xhdr_start(char *, int, const DCC_CLNT_INFO *); extern void dcc_header_init(DCC_HEADER_BUF *, DCC_SRVR_ID); extern void dcc_add_header(DCC_HEADER_BUF *, const char *, ...) PATTRIB(2,3); extern void dcc_add_header_ck(DCC_HEADER_BUF *, DCC_CK_TYPES, DCC_TGTS); extern void dcc_write_header(LOG_WRITE_FNC, void *, const char *, int, u_char); extern void dcc_header_white(DCC_HEADER_BUF *); #endif /* DCC_CLNT_H */