view 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 source

/* 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 */