/* Distributed Checksum Clearinghouse * * internal client definitions * * --C-LICENSE-- * $Revision: 1.148 $ */ #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<num_srvrs) # define HAVE_CLASS_SRVR(c) VALID_SRVR((c),(c)->srvr_inx) u_char pad[2]; /* preserve size%4 */ 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 u_char DCC_INFO_FGS; typedef struct { DCC_IP ip; DCC_PTIME failed; /* bind() failed */ } DCC_CLNT_SRC; # define DCC_CTXT_REBIND_SECS 3600 /* check local interface hourly */ typedef struct { # define DCC_MAP_INFO_VERSION "DCC client mapped data version #15" char version[40]; DCC_PTIME dccproc_last; DCC_PTIME dccproc_dccifd_try; int32_t 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 */ u_int32_t residue; /* random # for picking addresses */ DCC_HDR proto_hdr; /* prototype DCC request header */ DCC_SRVR_CLASS dcc; /* normal DCC services */ DCC_SRVR_CLASS grey; /* grey listing */ DCC_CLNT_SRC src4, src6; /* send from this local address */ DCC_INFO_FGS fgs; # define DCC_INFO_FG_IPV4_OFF 0x01 # define DCC_INFO_FG_IPV6_OFF 0x02 # define DCC_INFO_FG_SOCKS 0x04 # define DCC_INFO_FG_TMP 0x08 /* unnamed temporary file */ u_char pad[3]; /* preserve size%4 */ } DCC_CLNT_INFO; typedef struct { union { struct in_addr ipv4; struct in6_addr ipv6; } u; DCC_SCOPE_ID scope_id; in_port_t port; sa_family_t family; } DCC_V14_IP; typedef struct { DCC_PTIME rtt_updated; DCC_V14_IP ip; int32_t rtt; int32_t srvr_wait; RESP_MEM resp_mem; NAM_INX nam_inx; DCC_SRVR_ID srvr_id; u_char total_xmits; u_char total_resps; u_char srvr_pkt_vers; u_char flags; DCC_BRAND brand; } DCC_V14_SRVR_ADDR; typedef struct { DCC_PTIME resolve; DCC_PTIME measure; DCC_PTIME fail_time; int32_t gen; int32_t base_rtt; int32_t thold_rtt; int32_t avg_thold_rtt; int32_t num_srvrs; u_char fail_exp; SRVR_INX srvr_inx; DCC_SRVR_NM nms[DCC_MAX_SRVR_NMS]; DCC_V14_SRVR_ADDR addrs[DCC_MAX_SRVR_ADDRS]; } DCC_V14_SRVR_CLASS; typedef struct { DCC_V14_IP ip; time_t failed; } DCC_V14_CLNT_SRC; typedef struct { # define DCC_MAP_INFO_VERSION_14 "DCC client mapped data version #14" char version[40]; DCC_PTIME dccproc_last; DCC_PTIME dccproc_dccifd_try; int32_t dccproc_c; u_int32_t residue; DCC_INFO_FGS fgs; DCC_HDR proto_hdr; DCC_V14_SRVR_CLASS dcc; DCC_V14_SRVR_CLASS grey; DCC_V14_CLNT_SRC src4, src6; } DCC_V14_CLNT_INFO; typedef struct { # define DCC_MAP_INFO_VERSION_13 "DCC client mapped data version #13" char version[40]; DCC_PTIME dccproc_last; DCC_PTIME dccproc_dccifd_try; int32_t dccproc_c; u_int32_t residue; DCC_INFO_FGS fgs; DCC_HDR proto_hdr; DCC_V14_SRVR_CLASS dcc; DCC_V14_SRVR_CLASS grey; DCC_V14_IP src; } DCC_V13_CLNT_INFO; #define DCC_MAP_INFO_VERSION_12 "DCC client mapped data version #12" #ifdef DCC_MAP_INFO_VERSION_12 typedef struct { int rtt_adj; DCC_CLNT_ID clnt_id; in_port_t port; u_char defined; char hostname[DCC_MAXDOMAINLEN]; u_char pad; DCC_PASSWD passwd; } DCC_V12_SRVR_NM; typedef struct { DCC_V14_IP ip; time_t rtt_updated; int rtt; int srvr_wait; RESP_MEM resp_mem; NAM_INX nam_inx; DCC_SRVR_ID srvr_id; u_char total_xmits; u_char total_resps; u_char srvr_pkt_vers; u_char flags; DCC_BRAND brand; } DCC_V12_SRVR_ADDR; typedef struct { time_t resolve; time_t measure; int gen; int base_rtt; int thold_rtt; int avg_thold_rtt; int num_srvrs; time_t fail_time; u_char fail_exp; SRVR_INX srvr_inx; DCC_V12_SRVR_NM nms[DCC_MAX_SRVR_NMS]; DCC_V12_SRVR_ADDR addrs[DCC_MAX_SRVR_ADDRS]; } DCC_V12_SRVR_CLASS; typedef struct { char version[36]; u_int residue; DCC_INFO_FGS fgs; DCC_HDR proto_hdr; DCC_V12_SRVR_CLASS dcc; DCC_V12_SRVR_CLASS grey; DCC_V14_IP src; time_t dccproc_last; time_t dccproc_dccifd_try; int dccproc_c; } DCC_V12_CLNT_INFO; #endif /* DCC_MAP_INFO_VERSION_12 */ #define DCC_MAP_INFO_VERSION_11 "DCC client mapped data version #11" #ifdef DCC_MAP_INFO_VERSION_11 typedef struct { union { struct in_addr v4; struct in6_addr v6; } u; in_port_t port; u_char family; } DCC_V11_IP; typedef struct { DCC_V11_IP ip; time_t rtt_updated; int rtt; int srvr_wait; u_int32_t resp_mem; NAM_INX nam_inx; DCC_SRVR_ID srvr_id; u_char total_xmits; u_char total_resps; u_char srvr_pkt_vers; u_char flags; DCC_BRAND brand; } DCC_V11_SRVR_ADDR; typedef struct { time_t resolve; time_t measure; int gen; int base_rtt; int thold_rtt; int avg_thold_rtt; int num_srvrs; time_t fail_time; u_char fail_exp; SRVR_INX srvr_inx; DCC_V12_SRVR_NM nms[DCC_MAX_SRVR_NMS]; DCC_V11_SRVR_ADDR addrs[DCC_MAX_SRVR_ADDRS]; } DCC_V11_SRVR_CLASS; typedef struct { char version[36]; u_int residue; u_char flags; # define DCC_V11_INFO_FG_IPV6 0x01 # define DCC_V11_INFO_FG_SOCKS 0x02 # define DCC_V11_INFO_FG_TMP 0x04 DCC_HDR proto_hdr; DCC_V11_SRVR_CLASS dcc; DCC_V11_SRVR_CLASS grey; DCC_V11_IP src; time_t dccproc_last; time_t dccproc_dccifd_try; int dccproc_c; } DCC_V11_CLNT_INFO; #endif /* DCC_MAP_INFO_VERSION_11 */ #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; in_port_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_V11_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_V11_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_V11_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 */ #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) ((mode) ? DCC_GREY_PORT_HO : DCC_SRVR_PORT_HO) #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; extern struct stat dcc_info_sb; /* transmission logs */ typedef struct { /* record of 1 transmission */ DCC_OP_NUMS op_nums; time_t sent_us; /* microseconds since operation start */ time_t delay_us; DCC_CLNT_ID id; int addrs_gen; DCC_SOCKU su; SRVR_INX srvr_inx; u_char flags; # define DCC_XLFG_ANS 0x01 /* transmission has been answered */ # define DCC_XLFG_FAKE 0x04 DCC_PASSWD passwd; } DCC_XLENT; typedef struct { u_char outstanding; /* unheard responses */ u_char working_addrs; struct { u_char xmits; u_char resps; u_char failures; } cur[DCC_MAX_SRVR_ADDRS]; DCC_XLENT *next; /* next entry to use */ DCC_XLENT entries[DCC_MAX_SRVR_ADDRS*DCC_MAX_XMITS]; } DCC_XLOG; typedef struct { DCC_SOCKET s; DCC_CLNT_SRC *src; DCC_SOCKU loc; /* socket bound to this address */ DCC_SOCKU rem; /* socket connected to this address */ } DCC_CLNT_CTXT_SOC; 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 */ DCC_CLNT_CTXT_SOC soc[2]; DCC_XLOG xl; } DCC_CLNT_CTXT; #define DCC_INFO_TXT_VERSION "version=" #define DCC_INFO_TXT_VERSION_CUR 3 /* differs from contents version # */ #define DCC_INFO_TXT_IPV6 "IPv6 " #define DCC_INFO_TXT_IPV6_OFF DCC_INFO_TXT_IPV6"off" #define DCC_INFO_TXT_IPV6_ON DCC_INFO_TXT_IPV6"on" #define DCC_INFO_TXT_IPV6_ONLY DCC_INFO_TXT_IPV6"only" #define DCC_INFO_TXT_USE_SOCKS "use SOCKS" #define DCC_INFO_TXT_USE_SRC "src=" #define DCC_INFO_TXT_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 u_char clnt_threaded; extern void dcc_ctxts_lock(void); extern void dcc_ctxts_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_LOCKS 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_LOCKS */ extern u_char helper_lock_init(void); extern void helper_lock(void); extern void helper_unlock(void); #ifdef DCC_DEBUG_LOCKS extern void assert_helper_locked(void); extern void assert_helper_unlocked(void); #else #define assert_helper_locked() #define assert_helper_unlocked() #endif /* DCC_DEBUG_LOCKS */ 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 const char *dcc_parse_nm_port(DCC_EMSG *, const char *, u_int, char *, u_int, in_port_t *, char *, u_int, 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(u_char); extern u_char dcc_create_map(DCC_EMSG *, const char *, int *, const DCC_SRVR_NM *, int, const DCC_SRVR_NM *, int, const DCC_IP *, const DCC_IP *, DCC_INFO_FGS); 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 *, const DCC_IP *, DCC_INFO_FGS); 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_MEASURE_RTTS 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 *, const DCC_IP *, DCC_CLNT_FGS, DCC_INFO_FGS); 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_soc_flush(DCC_CLNT_CTXT_SOC *); extern int clear_soc_error(DCC_EMSG *, DCC_CLNT_CTXT_SOC *, const char *); extern u_char dcc_clnt_connect(DCC_EMSG *, DCC_CLNT_CTXT *, DCC_CLNT_CTXT_SOC *, const DCC_SOCKU *, sa_family_t); extern void dcc_clnt_socs_close(DCC_CLNT_CTXT *); extern DCC_CLNT_SRC *get_clnt_src(const DCC_CLNT_CTXT *ctxt,sa_family_t family); extern u_char dcc_clnt_soc_reopen(DCC_EMSG *, DCC_CLNT_CTXT *, DCC_CLNT_CTXT_SOC *, sa_family_t); 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, void *, 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 print_info_src(const DCC_CLNT_INFO *, const char *); extern void print_info(const char *, const DCC_CLNT_INFO *, 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 *, ...) DCC_PF(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 */