Mercurial > notdcc
view include/dcc_proto.h @ 5:0a7a5940ee3a
Change description per license
author | Peter Gervai <grin@grin.hu> |
---|---|
date | Tue, 10 Mar 2009 15:03:24 +0100 |
parents | c7f6b056b673 |
children |
line wrap: on
line source
/* 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 */