Mercurial > notdcc
diff include/dcc_proto.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_proto.h Tue Mar 10 13:49:58 2009 +0100 @@ -0,0 +1,612 @@ +/* Distributed Checksum Clearinghouse + * + * client-server and server-server protocols + * + * 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.137 $Revision$ + */ + +#ifndef DCC_PROTO_H +#define DCC_PROTO_H + +#define DCC_PKT_VERSION4 4 +#define DCC_PKT_VERSION5 5 +#define DCC_PKT_VERSION6 6 +#define DCC_PKT_VERSION7 7 +#define DCC_PKT_VERSION8 8 +#define DCC_PKT_VERSION 9 /* current */ +#define DCC_PKT_VERSION_MIN DCC_PKT_VERSION4 /* recognized */ +#define DCC_PKT_VERSION_MAX DCC_PKT_VERSION +#define DCC_PKT_VERSION_MIN_VALID DCC_PKT_VERSION_MIN /* sanity check */ +#define DCC_PKT_VERSION_MAX_VALID 0x7f + + +#define DCC_SRVR_PORT 6277 /* default DCC server port # */ +#define DCC_GREY_PORT 6276 /* grey listing server port */ + + +/* types of checksums */ +typedef enum { + DCC_CK_INVALID =0, /* deleted from database when seen */ + DCC_CK_IP =1, /* MD5 of binary source IPv6 address */ + DCC_CK_ENV_FROM =2, /* " " envelope Mail From value */ + DCC_CK_FROM =3, /* " " header From: line */ + DCC_CK_SUB =4, /* " " substitute header line */ + DCC_CK_MESSAGE_ID =5, /* " " header Message-ID: line */ + DCC_CK_RECEIVED =6, /* " " last header Received: line */ + DCC_CK_BODY =7, /* " " body */ + DCC_CK_FUZ1 =8, /* " " filtered body */ + DCC_CK_FUZ2 =9, /* " " " " */ + DCC_CK_G_MSG_R_TOTAL =10, +# define DCC_CK_GREY_MSG DCC_CK_G_MSG_R_TOTAL +# define DCC_CK_REP_TOTAL DCC_CK_G_MSG_R_TOTAL + DCC_CK_G_TRIPLE_R_BULK =11, +# define DCC_CK_GREY3 DCC_CK_G_TRIPLE_R_BULK +# define DCC_CK_REP_BULK DCC_CK_G_TRIPLE_R_BULK + DCC_CK_SRVR_ID =12, /* hostname for server-ID check */ + DCC_CK_ENV_TO =13 /* MD5 of envelope Rcpt To value */ +# define DCC_CK_FLOD_PATH DCC_CK_ENV_TO /* flooding path in server-IDs */ +} DCC_CK_TYPES; +typedef u_char DCC_CK_TYPE_B; /* big enough */ +#define DCC_CK_TYPE_FIRST DCC_CK_IP +#define DCC_CK_TYPE_LAST DCC_CK_ENV_TO +#define DCC_NUM_CKS DCC_CK_TYPE_LAST /* # of valid types */ + +/* DCC_DIM_CKS dimensions arrays of checksum types including DCC_CK_INVALID + * Beware that DCC_DIM_CKS is used in the database header. */ +#define DCC_DIM_CKS (DCC_CK_TYPE_LAST+1) + +/* record of path taken by a report */ +#define DCC_NUM_FLOD_PATH ((int)(sizeof(DCC_SUM)/sizeof(DCC_SRVR_ID))) +typedef struct { + u_char hi, lo; +} DCC_FLOD_PATH_ID; +/* DCC_MAX_FLOD_PATH assumes that among the maximum 14 possible slots for + * checksums in a flooded report (dimension of cks in a DB_RCD or DCC_DIM_CKS), + * DCC_CK_INVALID is never used + * DCC_CK_SRVR_ID is never used when any real checksums are present, + * is so there is always room for 2 extra DCC_CK_FLOD_PATH entries besides + * the natural DCC_CK_FLOD_PATH entry. */ +#define DCC_MAX_FLOD_PATH_CKSUMS 3 +/* This must not be too large lest reports become larger than DCC_DIM_CKS */ +#define DCC_MAX_FLOD_PATH (DCC_NUM_FLOD_PATH*DCC_MAX_FLOD_PATH_CKSUMS) + + +/* checksums in client-server protocol */ +#define DCC_QUERY_MAX DCC_DIM_CKS /* even to prevent structure padding */ + +/* Ensure that arrays of DCC_CKs contain an even number so that structures + * containing them will have no extra structure packing */ +#define DCC_COMP_DIM_CKS ((((DCC_NUM_CKS+1)+1)/2)*2) /* == DCC_DIM_CKS */ + +/* keep some checksums in the database longer than others */ +#define DCC_CK_LONG_TERM(t) ((t) >= DCC_CK_FUZ1 \ + && (t) <= DCC_CK_G_TRIPLE_R_BULK) + +#define DCC_CK_IS_BODY(t) ((t) >= DCC_CK_BODY && (t) <= DCC_CK_FUZ2) + +/* MD5 of greylist msg+sender+target */ +#define DCC_CK_IS_GREY_MSG(g,t) ((g) && (t) == DCC_CK_G_MSG_R_TOTAL) +/* MD5 of greylisted triple */ +#define DCC_CK_IS_GREY_TRIPLE(g,t) ((g) && (t) == DCC_CK_G_TRIPLE_R_BULK) +#define DCC_CK_IS_GREY(g,t) (DCC_CK_IS_GREY_MSG(g,t) \ + || DCC_CK_IS_GREY_TRIPLE(g,t)) + +/* total messages sent by an IP address */ +#define DCC_CK_IS_REP_TOTAL_CMN(g,t) (!(g) && (t) == DCC_CK_G_MSG_R_TOTAL) +/* bulk messages sent by an IP address */ +#define DCC_CK_IS_REP_BULK_CMN(g,t) (!(g) && (t) == DCC_CK_G_TRIPLE_R_BULK) +#define DCC_CK_IS_REP_CMN(g,t) (DCC_CK_IS_REP_TOTAL_CMN(g,t) \ + || DCC_CK_IS_REP_BULK_CMN(g,t)) +#define DCC_CK_IS_REP_TOTAL_OP(g,t) 0 +#define DCC_CK_IS_REP_BULK_OP(g,t) 0 +#define DCC_CK_IS_REP_OP(g,t) 0 + + + +typedef enum { + DCC_OP_INVALID =0, + DCC_OP_NOP =1, /* see if the server is alive */ + DCC_OP_REPORT =2, /* old client reporting and querying */ + DCC_OP_QUERY =3, /* client querying */ + DCC_OP_ANSWER =4, /* server responding */ + DCC_OP_ADMN =5, /* control the server */ + DCC_OP_OK =6, /* administrative operation ok */ + DCC_OP_ERROR =7, /* server failing or complaining */ + DCC_OP_DELETE =8, /* delete some checksums */ + DCC_OP_GREY_REPORT =9, /* greylist report */ + DCC_OP_GREY_QUERY =10, /* " " query */ + DCC_OP_GREY_SPAM =11, /* forget greylisted spammer */ + DCC_OP_GREY_WHITE =12 /* whitelisted greylist triple */ +} DCC_OPS; + +typedef u_int32_t DCC_CLNT_ID; +#define DCC_ID_INVALID 0 +#define DCC_ID_ANON 1 /* anonymous (non-paying) client */ +#define DCC_ID_WHITE 2 /* whitelisted */ +#define DCC_ID_COMP 3 /* compressed */ +#define DCC_ID_SRVR_SIMPLE 4 /* simple server */ +#define DCC_ID_SRVR_REP_OK 5 /* ok to use reputations */ +#define DCC_ID_SRVR_IGNORE 6 /* ignore its flooded reports */ +#define DCC_ID_SRVR_ROGUE 7 /* crazy server */ +#define DCC_ID_SRVR_TYPE(id) ((id) == DCC_ID_SRVR_SIMPLE \ + || (id) == DCC_ID_SRVR_REP_OK \ + || (id) == DCC_ID_SRVR_IGNORE \ + || (id) == DCC_ID_SRVR_ROGUE) +#define DCC_SRVR_ID_MIN 100 /* below reserved for special uses */ +#define DCC_SRVR_ID_MAX 32767 /* below are servers--must be 2**n-1 */ +#define DCC_CLNT_ID_MIN (DCC_SRVR_ID_MAX+1) +#define DCC_CLNT_ID_MAX 16777215 +typedef u_int16_t DCC_SRVR_ID; +#define DCC_SRVR_ID_AUTH (DCC_SRVR_ID_MAX+1) /* client was authenticated */ + +/* client's identification of its transaction */ +typedef u_int32_t DCC_OP_NUM; +typedef struct { + DCC_OP_NUM h; /* client host ID, e.g. IP address */ + DCC_OP_NUM p; /* process ID, serial #, timestamp */ + DCC_OP_NUM r; /* report ID */ + DCC_OP_NUM t; /* client (re)transmission # */ +} DCC_OP_NUMS; + +/* The inter-DCC server flooding algorithm depends on unique-per-server + * timestamps to detect duplicates. That imposes a requirement on + * timestamps that they have resolution enough to separate reports + * from clients arriving at any single server. + * The timestamps are 48 bits consisting of 17 bits of 8's of microseconds + * and 31 bits of seconds. That's sufficient for the UNIX epoch. + * If the DCC is still around in the 2030's (and in the unlikely case that + * 8 microseconds are still fine enough), we can make the 31 bits be + * an offset in a bigger window. + */ +#define DCC_TS_US_RSHIFT 3 +#define DCC_TS_US_MULT (1<<DCC_TS_US_RSHIFT) +#define DCC_TS_SECS_LSHIFT 17 +#define DCC_TS_US_MASK ((1<<DCC_TS_SECS_LSHIFT) - 1) +typedef struct { + u_char b[6]; +} DCC_TS; + +/* The start of any DCC packet. + * The length and version are early, since they are the only fields + * constrained in future versions. */ +typedef struct { + u_int16_t len; /* total DCC packet length */ + u_char pkt_vers; /* packet protocol version */ + u_char op; /* one of DCC_OPS */ + /* Identify the transaction. + * Each client can have many hosts, each host can be multi-homed, + * and each host can be running many processes talking to the + * server. Each packet needs to be uniquely numbered, so that the + * server can recognize as interchangable all of the (re)transmissions + * of a single report (rid) from a client process (pid) on a single + * host (hid), and the client can know which transmission (tid) + * produced a given server response to maintain the client's RTT + * value for the server. */ + DCC_CLNT_ID sender; /* client-ID or server-ID */ + DCC_OP_NUMS op_nums; /* op_num.t must be last */ +} DCC_HDR; + +typedef u_char DCC_SIGNATURE[16]; + +typedef struct { + DCC_HDR hdr; + DCC_SIGNATURE signature; +} DCC_NOP; + + +/* DCC_OP_ADMN administrative requests from localhost + * Most of these can be changed, because the administrative tools + * should match the daemon. */ +typedef enum { + DCC_AOP_OK =-1, /* never really sent */ + DCC_AOP_STOP = 1, /* stop gracefully */ + DCC_AOP_DB_UNLOAD = 2, /* flush cache */ + DCC_AOP_FLOD = 3, /* start or stop flooding */ + DCC_AOP_DB_CLEAN = 4, /* start cleaning */ + DCC_AOP_DB_NEW = 5, /* finish switch to new database */ + DCC_AOP_STATS = 6, /* return counters--val=buffer size */ + DCC_AOP_STATS_CLEAR = 7, /* return and zero counters */ + DCC_AOP_TRACE_ON = 8, + DCC_AOP_TRACE_OFF = 9, + DCC_AOP_unused1 = 10, /* was dcc1-1-36 clients command */ + DCC_AOP_CLIENTS = 11, /* some client IP addresses */ + DCC_AOP_CLIENTS_ID = 12, /* some client IDs */ + DCC_AOP_ANON_DELAY = 13, /* anonymous delay parameters */ + DCC_AOP_CLOCK_CHECK = 14 +} DCC_AOPS; + +/* for DCC_AOP_FLOD */ +typedef enum { + DCC_AOP_FLOD_CHECK=0, + DCC_AOP_FLOD_SHUTDOWN, + DCC_AOP_FLOD_HALT, + DCC_AOP_FLOD_RESUME, + DCC_AOP_FLOD_REWIND, + DCC_AOP_FLOD_LIST, + DCC_AOP_FLOD_STATS, + DCC_AOP_FLOD_STATS_CLEAR, +# define DCC_AOP_FLOD_STATS_ID " server-ID %u " + DCC_AOP_FLOD_FFWD_IN, + DCC_AOP_FLOD_FFWD_OUT +} DCC_AOP_FLODS; + +typedef struct { /* with operation DCC_OP_ADMN */ + DCC_HDR hdr; + int32_t date; /* seconds since epoch on caller */ + u_int32_t val1; /* request type, buffer size, etc. */ + u_char aop; /* one of DCC_AOPS */ + u_char val2; + u_char val3; + u_char val4; +# define MAX_DCC_ADMN_REQ_VAL5 64 + u_char val5[MAX_DCC_ADMN_REQ_VAL5]; + DCC_SIGNATURE signature; +} DCC_ADMN_REQ; +#define DCC_ADMN_REQ_MIN_SIZE (ISZ(DCC_ADMN_REQ) - MAX_DCC_ADMN_REQ_VAL5) + + +typedef u_char DCC_AOP_CLIENTS_CIDR[17]; /* IPv6 netmask and length */ + +/* val2 for DCC_AOP_CLIENTS or DCC_AOP_CLIENTS_ID */ +#define DCC_AOP_CLIENTS_AVG 0x01 /* want averages */ +#define DCC_AOP_CLIENTS_VERS 0x02 /* want protocol version */ +#define DCC_AOP_CLIENTS_ANON 0x04 /* only anonymous clients */ +#define DCC_AOP_CLIENTS_NON_ANON 0x08 /* non-anonymous only */ + +#define DCC_AOP_CLIENTS_MAX_OFFSET ((1<<24)-1) + +/* scale client's response buffer size in part of val1 by this */ +#define DCC_ADMIN_RESP_CLIENTS_SHIFT 5 +/* limit threshold in part of val1 */ +#define DCC_ADMIN_RESP_CLIENTS_MAX_THOLD ((1<<16)-1) + +/* noisy response to DCC_AOP_CLIENTS or DCC_AOP_CLIENTS_ID */ +#define DCC_ADMN_RESP_CLIENTS_BL 0x01 /* this client blacklisted */ +#define DCC_ADMN_RESP_CLIENTS_IPV6 0x02 /* address is IPv6 */ +#define DCC_ADMN_RESP_CLIENTS_SKIP 0x04 /* last_used=clients skipped */ +#define DCC_ADMN_RESP_CLIENTS_ID1 0x08 /* suppressed ID=DCC_ID_ANON */ +#define DCC_ADMN_RESP_CLIENTS_VERS 0x10 /* protocol version # present */ +#define DCC_ADMN_RESP_CLIENTS_LAST 0x20 +#define DCC_ADMN_RESP_CLIENTS_BAD 0x40 /* naughty client */ + +/* worst case bytes used to describe a client */ +#define DCC_ADMN_RESP_CLIENTS_MAX_SIZE (1+1+4*4+16) + +#define DCC_ADMIN_RESP_MAX_CLIENTS (10*1000) + + +#ifdef DCC_PKT_VERSION6 +typedef struct { + u_char clnt_id[4]; + u_char last_used[4]; + u_char requests[3]; + u_char nops[2]; + u_char flags; + union { + u_char ipv6[16]; + u_char ipv4[4]; + } addr; +} DCC_ADMN_RESP_CLIENTSv6; +#endif /* DCC_PKT_VERSION6 */ + +typedef struct { + u_char inflate[4]; + u_char delay[2]; +# define DCC_ANON_DELAY_MAX DCC_MAX_RTT +# define DCC_ANON_DELAY_FOREVER ((u_int16_t)-1) +# define DCC_NO_ANON_DELAY ((u_int16_t)-2) +} DCC_ADMN_RESP_ANON_DELAY; +typedef union { + char string[80*22]; + u_char clients[1]; +#ifdef DCC_PKT_VERSION6 + DCC_ADMN_RESP_CLIENTSv6 clientsV6[1]; +#endif + DCC_ADMN_RESP_ANON_DELAY anon_delay; +} DCC_ADMN_RESP_VAL; +typedef struct { + DCC_HDR hdr; + DCC_ADMN_RESP_VAL val; + DCC_SIGNATURE signature; +} DCC_ADMN_RESP; + + +#define DCC_TRACE_ADMN_BIT 0x0001 /* administrative requests */ +#define DCC_TRACE_ANON_BIT 0x0002 /* anonymous client errors */ +#define DCC_TRACE_CLNT_BIT 0x0004 /* authenticated client errors */ +#define DCC_TRACE_RLIM_BIT 0x0008 /* rate limited messages */ +#define DCC_TRACE_QUERY_BIT 0x0010 /* all queries and reports */ +#define DCC_TRACE_RIDC_BIT 0x0020 /* RID cache messages */ +#define DCC_TRACE_FLOD_BIT 0x0040 /* general inter-server flooding */ +#define DCC_TRACE_FLOD2_BIT 0x0080 /* individual flooded reports */ +#define DCC_TRACE_IDS_BIT 0x0100 /* monitor client- and server-IDs */ +#define DCC_TRACE_BL_BIT 0x0200 /* blacklisted clients */ +#define DCC_TRACE_DB_BIT 0x0400 /* odd database events */ +#define DCC_TRACE_WLIST_BIT 0x0800 /* whitelisted checksums */ +#define DCC_TRACE_BITS (DCC_TRACE_ADMN_BIT | DCC_TRACE_ANON_BIT \ + | DCC_TRACE_CLNT_BIT | DCC_TRACE_RLIM_BIT \ + | DCC_TRACE_QUERY_BIT | DCC_TRACE_RIDC_BIT \ + | DCC_TRACE_FLOD_BIT | DCC_TRACE_FLOD2_BIT \ + | DCC_TRACE_IDS_BIT | DCC_TRACE_BL_BIT \ + | DCC_TRACE_DB_BIT | DCC_TRACE_WLIST_BIT) +#define DCC_TRACE_ON_DEF_BITS (DCC_TRACE_ANON_BIT | DCC_TRACE_CLNT_BIT) +#define DCC_TRACE_OFF_DEF_BITS (DCC_TRACE_BITS \ + & ~(DCC_TRACE_ANON_BIT | DCC_TRACE_CLNT_BIT)) + + +#define DCC_BRAND_MAXLEN 64 +typedef char DCC_BRAND[DCC_BRAND_MAXLEN]; + +/* administrative or NOP ok */ +typedef struct { + DCC_HDR hdr; + u_char max_pkt_vers; /* server can handle this version */ + u_char unused; + u_int16_t qdelay_ms; + DCC_BRAND brand; /* identity or brandname of sender */ + DCC_SIGNATURE signature; +} DCC_OK; + + +typedef u_int32_t DCC_TGTS; /* database is limited to 24 bits */ +#define DCC_TGTS_TOO_MANY 0x00fffff0 /* >= 16777200 targets */ +#define DCC_TGTS_OK 0x00fffff1 /* certified not spam */ +#define DCC_TGTS_OK2 0x00fffff2 /* half certified not spam */ +#define DCC_TGTS_GREY_WHITE DCC_TGTS_OK2 /* whitelisted for greylisting */ +#define DCC_TGTS_DEL 0x00fffff3 /* a deleted checksum */ +#define DCC_TGTS_REP_ADJ 0x00fffff4 /* scale a reputation */ +#define DCC_TGTS_OK_MX 0x00fffff5 /* partly whitelist MX secondary */ +#define DCC_TGTS_OK_MXDCC 0x00fffff6 /* MX secondary with DCC client */ +#define DCC_TGTS_SUBMIT_CLIENT 0x00fffff7 /* SMTP submission client */ +#define DCC_TGTS_MAX_DB DCC_TGTS_REP_ADJ +#define DCC_TGTS_INVALID 0x01000000 +#define DCC_TGTS_SPAM DCC_TGTS_INVALID +#define DCC_TGTS_REP_SPAM 0x02000000 /* reputation hit */ +#define DCC_TGTS_MASK 0x00ffffff + +#define DCC_TGTS_RPT_MAX 2000 +#define DCC_TGTS_FLOD_RPT_MAX (DCC_TGTS_RPT_MAX*1000) +#define BULK_THRESHOLD 10 +#define REFLOOD_THRESHOLD 300 +#define DCC_TGTS_REP_TOTAL_THOLD (BULK_THRESHOLD*2) +#define DCC_TGTS_REP_TOTAL_EXPIRE BULK_THRESHOLD + +/* checksums kept by most servers */ +#define DCC_CK_IS_GREY_BODY(g,t) ((g) ? ((t)==DCC_CK_BODY) : DCC_CK_IS_BODY(t)) +#define DB_GLOBAL_NOKEEP(g,t) (!DCC_CK_IS_GREY_BODY(g,t) \ + && (t) != DCC_CK_SRVR_ID \ + && ((t) != DCC_CK_G_MSG_R_TOTAL || !(g)) \ + && ((t) != DCC_CK_G_TRIPLE_R_BULK || !(g))) + +/* checksums subject to thresholds */ +#define DCC_CK_THOLD_OK(t) ((t) > DCC_CK_INVALID \ + && (t) <= DCC_CK_G_TRIPLE_R_BULK) + +#define IS_ALL_CKSUM(t) (DCC_CK_THOLD_OK(t) && !DCC_CK_IS_REP_CMN(0, t)) +#define IS_CMN_CKSUM(t) DCC_CK_IS_BODY(t) + + +/* a reported checksum from a client */ +typedef u_char DCC_SUM[16]; /* for now all have 16 bytes */ +typedef struct { + DCC_CK_TYPE_B type; + u_char len; /* total length of this checksum */ + DCC_SUM sum; +} DCC_CK; + +/* most packets from client to server */ +typedef struct { + DCC_HDR hdr; + DCC_TGTS tgts; /* # of addressees */ + DCC_CK cks[DCC_QUERY_MAX]; /* even to prevent structure padding */ + DCC_SIGNATURE signature; +} DCC_REPORT; + +/* most responses */ +typedef struct { + DCC_TGTS c; /* current value, with this report */ + DCC_TGTS p; /* previous value, before this report */ +} DCC_ANSWER_BODY_CKS; +typedef struct { + DCC_HDR hdr; + DCC_ANSWER_BODY_CKS b[DCC_QUERY_MAX]; + DCC_SIGNATURE signature; +} DCC_ANSWER; + +#ifdef DCC_PKT_VERSION5 +typedef struct { + DCC_HDR hdr; + DCC_TGTS b[DCC_QUERY_MAX]; /* current values */ + DCC_SIGNATURE signature; +} DCC_ANSWERv5; +#endif + +typedef struct { + DCC_HDR hdr; + DCC_TGTS msg; + DCC_TGTS triple; + DCC_SIGNATURE signature; +} DCC_GREY_ANSWER; + + +/* DCC_OP_DELETE request to delete checksums */ +typedef struct { + DCC_HDR hdr; + int32_t date; /* seconds since epoch on client */ + DCC_CK ck; + u_char pad[2]; + DCC_SIGNATURE signature; +} DCC_DELETE; + + +/* DCC_OP_GREY_SPAM restore greylist embargo */ +typedef struct { + DCC_HDR hdr; + DCC_CK ip; + DCC_CK msg; + DCC_CK triple; + DCC_SIGNATURE signature; +} DCC_GREY_SPAM; + + +/* error response from server to client */ +typedef struct { + DCC_HDR hdr; +# define DCC_ERROR_MSG_LEN 128 + char msg[DCC_ERROR_MSG_LEN]; + DCC_SIGNATURE signature; +} DCC_ERROR; + + +typedef union { + DCC_HDR hdr; + DCC_ANSWER ans; +#ifdef DCC_PKT_VERSION5 + DCC_ANSWERv5 ans5; +#endif + DCC_GREY_ANSWER gans; + DCC_OK ok; + DCC_ERROR error; + DCC_ADMN_RESP resp; + int w[6]; +} DCC_OP_RESP; + + + + +/* ************** server-to-server flooding protocol ************ */ + +/* This protocol is the sort of botch of a mess that results from assuming + * a considered protocol is not necessary and then extending it. */ + +/* A flooding connection starts with the TCP client or connection originator + * sending an ASCII "magic" string including a version number, the connection + * originator's server-ID, whether SOCKS is involved, and a cryptographic + * hash of the fixed-length message. In the common case, the connection + * orginator will send a flood of DCC reports. If SOCKS is involved, the + * connection is immediately turned around. */ +#define DCC_FLOD_VERSION_STR_BASE "DCC flod version " +#define DCC_FLOD_VERSION7 7 +/* in the next version, add a length to DCC_FLOD_END */ +#define DCC_FLOD_VERSION7_STR DCC_FLOD_VERSION_STR_BASE"7" +#define DCC_FLOD_VERSION_DEF 0 +#define DCC_FLOD_VERSION_CUR DCC_FLOD_VERSION7 +#define DCC_FLOD_VERSION_CUR_STR DCC_FLOD_VERSION7_STR +typedef struct { +# define DCC_FLOD_VERSION_STR_LEN 64 + char str[DCC_FLOD_VERSION_STR_LEN]; + u_char sender_srvr_id[sizeof(DCC_SRVR_ID)]; + u_char turn; /* 1=turn connection around for SOCKS */ + u_char unused[3]; +} DCC_FLOD_VERSION_BODY; +typedef struct { + DCC_FLOD_VERSION_BODY body; + char pad[256-sizeof(DCC_FLOD_VERSION_BODY)-sizeof(DCC_SIGNATURE)]; + DCC_SIGNATURE signature; +} DCC_FLOD_VERSION_HDR; + + +/* flood sender's position or serial number + * Only the sender understands sender positions except for these + * special values. However, the special values imply that the position + * must be big endian. */ +typedef u_char DCC_FLOD_POS[8]; +/* special cases sent by the receiver back to the sender */ +typedef enum { + DCC_FLOD_POS_END =0, /* receiver closing with message */ + DCC_FLOD_POS_END_REQ =1, /* receiver wants to stop */ + DCC_FLOD_POS_NOTE =2, /* receiver has a tracing message */ + DCC_FLOD_POS_COMPLAINT =3, /* receiver has a problem message */ + DCC_FLOD_POS_REWIND =4, /* receiver's database emptied */ + DCC_FLOD_POS_FFWD_IN =5 /* receiver wants fast-forward */ +} DCC_FLOD_POS_OPS; +#define DCC_FLOD_POS_MIN 10 + +#define DCC_FLOD_OK_STR "DCC flod ok: " + +/* final result sent from flood receiver to flood sender + * This structure always ends the TCP stream. The length of the msg is + * obtain from the number of buts to the end of the stream. It should + * have had an explicit length in the structure. */ +typedef struct { + DCC_FLOD_POS pos; /* one of DCC_FLOD_POS_* */ +# define DCC_FLOD_MAX_RESP 200 + char msg[DCC_FLOD_MAX_RESP]; /* no '\0'; uses length to EOF */ +} DCC_FLOD_END; +#define FLOD_END_OVHD ISZ(((DCC_FLOD_END*)0)->pos) + +/* report forwarded among servers */ +typedef struct { + DCC_FLOD_POS pos; + u_char tgts[sizeof(DCC_TGTS)]; + u_char srvr_id_auth[sizeof(DCC_SRVR_ID)]; /* receiving server */ + DCC_TS ts; /* date reported */ + u_char num_cks; + DCC_CK cks[DCC_QUERY_MAX]; +} DCC_FLOD_RPT; +#define DCC_FLOD_RPT_LEN(n) (ISZ(DCC_FLOD_RPT) - ISZ(DCC_CK)*DCC_QUERY_MAX \ + + ISZ(DCC_CK)*(n)) + +/* what can appear in the stream of flooded reports */ +typedef union { + DCC_FLOD_VERSION_HDR v; + DCC_FLOD_END e; + DCC_FLOD_RPT r; +} DCC_FLOD_STREAM; + + +/* a response to flooded reports */ +typedef union { + DCC_FLOD_POS pos; + DCC_FLOD_END end; /* final result */ + struct { + DCC_FLOD_POS op; /* one of DCC_FLOD_POS_* */ + u_char len; /* total length */ + char str[DCC_FLOD_MAX_RESP]; /* includes trailing '\0' */ + } note; +} DCC_FLOD_RESP; +#define FLOD_NOTE_OVHD (ISZ(((DCC_FLOD_RESP*)0)->note) - DCC_FLOD_MAX_RESP) + + +/* parts of error messages sent between flooding peers */ +#define DCC_FLOD_BAD_VER_MSG "unrecognized flod version" +#define DCC_FLOD_BAD_ID_MSG "unauthorized ID" +#define DCC_FLOD_BAD_AUTH_MSG "bad authentication for ID" +#define DCC_FLOD_PASSWD_ID_MSG "unknown passwd-ID" + + +#endif /* DCC_PROTO_H */