comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:c7f6b056b673
1 /* Distributed Checksum Clearinghouse
2 *
3 * client-server and server-server protocols
4 *
5 * Copyright (c) 2008 by Rhyolite Software, LLC
6 *
7 * This agreement is not applicable to any entity which sells anti-spam
8 * solutions to others or provides an anti-spam solution as part of a
9 * security solution sold to other entities, or to a private network
10 * which employs the DCC or uses data provided by operation of the DCC
11 * but does not provide corresponding data to other users.
12 *
13 * Permission to use, copy, modify, and distribute this software without
14 * changes for any purpose with or without fee is hereby granted, provided
15 * that the above copyright notice and this permission notice appear in all
16 * copies and any distributed versions or copies are either unchanged
17 * or not called anything similar to "DCC" or "Distributed Checksum
18 * Clearinghouse".
19 *
20 * Parties not eligible to receive a license under this agreement can
21 * obtain a commercial license to use DCC by contacting Rhyolite Software
22 * at sales@rhyolite.com.
23 *
24 * A commercial license would be for Distributed Checksum and Reputation
25 * Clearinghouse software. That software includes additional features. This
26 * free license for Distributed ChecksumClearinghouse Software does not in any
27 * way grant permision to use Distributed Checksum and Reputation Clearinghouse
28 * software
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
31 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
33 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
34 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
35 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
36 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
37 * SOFTWARE.
38 *
39 * Rhyolite Software DCC 1.3.103-1.137 $Revision$
40 */
41
42 #ifndef DCC_PROTO_H
43 #define DCC_PROTO_H
44
45 #define DCC_PKT_VERSION4 4
46 #define DCC_PKT_VERSION5 5
47 #define DCC_PKT_VERSION6 6
48 #define DCC_PKT_VERSION7 7
49 #define DCC_PKT_VERSION8 8
50 #define DCC_PKT_VERSION 9 /* current */
51 #define DCC_PKT_VERSION_MIN DCC_PKT_VERSION4 /* recognized */
52 #define DCC_PKT_VERSION_MAX DCC_PKT_VERSION
53 #define DCC_PKT_VERSION_MIN_VALID DCC_PKT_VERSION_MIN /* sanity check */
54 #define DCC_PKT_VERSION_MAX_VALID 0x7f
55
56
57 #define DCC_SRVR_PORT 6277 /* default DCC server port # */
58 #define DCC_GREY_PORT 6276 /* grey listing server port */
59
60
61 /* types of checksums */
62 typedef enum {
63 DCC_CK_INVALID =0, /* deleted from database when seen */
64 DCC_CK_IP =1, /* MD5 of binary source IPv6 address */
65 DCC_CK_ENV_FROM =2, /* " " envelope Mail From value */
66 DCC_CK_FROM =3, /* " " header From: line */
67 DCC_CK_SUB =4, /* " " substitute header line */
68 DCC_CK_MESSAGE_ID =5, /* " " header Message-ID: line */
69 DCC_CK_RECEIVED =6, /* " " last header Received: line */
70 DCC_CK_BODY =7, /* " " body */
71 DCC_CK_FUZ1 =8, /* " " filtered body */
72 DCC_CK_FUZ2 =9, /* " " " " */
73 DCC_CK_G_MSG_R_TOTAL =10,
74 # define DCC_CK_GREY_MSG DCC_CK_G_MSG_R_TOTAL
75 # define DCC_CK_REP_TOTAL DCC_CK_G_MSG_R_TOTAL
76 DCC_CK_G_TRIPLE_R_BULK =11,
77 # define DCC_CK_GREY3 DCC_CK_G_TRIPLE_R_BULK
78 # define DCC_CK_REP_BULK DCC_CK_G_TRIPLE_R_BULK
79 DCC_CK_SRVR_ID =12, /* hostname for server-ID check */
80 DCC_CK_ENV_TO =13 /* MD5 of envelope Rcpt To value */
81 # define DCC_CK_FLOD_PATH DCC_CK_ENV_TO /* flooding path in server-IDs */
82 } DCC_CK_TYPES;
83 typedef u_char DCC_CK_TYPE_B; /* big enough */
84 #define DCC_CK_TYPE_FIRST DCC_CK_IP
85 #define DCC_CK_TYPE_LAST DCC_CK_ENV_TO
86 #define DCC_NUM_CKS DCC_CK_TYPE_LAST /* # of valid types */
87
88 /* DCC_DIM_CKS dimensions arrays of checksum types including DCC_CK_INVALID
89 * Beware that DCC_DIM_CKS is used in the database header. */
90 #define DCC_DIM_CKS (DCC_CK_TYPE_LAST+1)
91
92 /* record of path taken by a report */
93 #define DCC_NUM_FLOD_PATH ((int)(sizeof(DCC_SUM)/sizeof(DCC_SRVR_ID)))
94 typedef struct {
95 u_char hi, lo;
96 } DCC_FLOD_PATH_ID;
97 /* DCC_MAX_FLOD_PATH assumes that among the maximum 14 possible slots for
98 * checksums in a flooded report (dimension of cks in a DB_RCD or DCC_DIM_CKS),
99 * DCC_CK_INVALID is never used
100 * DCC_CK_SRVR_ID is never used when any real checksums are present,
101 * is so there is always room for 2 extra DCC_CK_FLOD_PATH entries besides
102 * the natural DCC_CK_FLOD_PATH entry. */
103 #define DCC_MAX_FLOD_PATH_CKSUMS 3
104 /* This must not be too large lest reports become larger than DCC_DIM_CKS */
105 #define DCC_MAX_FLOD_PATH (DCC_NUM_FLOD_PATH*DCC_MAX_FLOD_PATH_CKSUMS)
106
107
108 /* checksums in client-server protocol */
109 #define DCC_QUERY_MAX DCC_DIM_CKS /* even to prevent structure padding */
110
111 /* Ensure that arrays of DCC_CKs contain an even number so that structures
112 * containing them will have no extra structure packing */
113 #define DCC_COMP_DIM_CKS ((((DCC_NUM_CKS+1)+1)/2)*2) /* == DCC_DIM_CKS */
114
115 /* keep some checksums in the database longer than others */
116 #define DCC_CK_LONG_TERM(t) ((t) >= DCC_CK_FUZ1 \
117 && (t) <= DCC_CK_G_TRIPLE_R_BULK)
118
119 #define DCC_CK_IS_BODY(t) ((t) >= DCC_CK_BODY && (t) <= DCC_CK_FUZ2)
120
121 /* MD5 of greylist msg+sender+target */
122 #define DCC_CK_IS_GREY_MSG(g,t) ((g) && (t) == DCC_CK_G_MSG_R_TOTAL)
123 /* MD5 of greylisted triple */
124 #define DCC_CK_IS_GREY_TRIPLE(g,t) ((g) && (t) == DCC_CK_G_TRIPLE_R_BULK)
125 #define DCC_CK_IS_GREY(g,t) (DCC_CK_IS_GREY_MSG(g,t) \
126 || DCC_CK_IS_GREY_TRIPLE(g,t))
127
128 /* total messages sent by an IP address */
129 #define DCC_CK_IS_REP_TOTAL_CMN(g,t) (!(g) && (t) == DCC_CK_G_MSG_R_TOTAL)
130 /* bulk messages sent by an IP address */
131 #define DCC_CK_IS_REP_BULK_CMN(g,t) (!(g) && (t) == DCC_CK_G_TRIPLE_R_BULK)
132 #define DCC_CK_IS_REP_CMN(g,t) (DCC_CK_IS_REP_TOTAL_CMN(g,t) \
133 || DCC_CK_IS_REP_BULK_CMN(g,t))
134 #define DCC_CK_IS_REP_TOTAL_OP(g,t) 0
135 #define DCC_CK_IS_REP_BULK_OP(g,t) 0
136 #define DCC_CK_IS_REP_OP(g,t) 0
137
138
139
140 typedef enum {
141 DCC_OP_INVALID =0,
142 DCC_OP_NOP =1, /* see if the server is alive */
143 DCC_OP_REPORT =2, /* old client reporting and querying */
144 DCC_OP_QUERY =3, /* client querying */
145 DCC_OP_ANSWER =4, /* server responding */
146 DCC_OP_ADMN =5, /* control the server */
147 DCC_OP_OK =6, /* administrative operation ok */
148 DCC_OP_ERROR =7, /* server failing or complaining */
149 DCC_OP_DELETE =8, /* delete some checksums */
150 DCC_OP_GREY_REPORT =9, /* greylist report */
151 DCC_OP_GREY_QUERY =10, /* " " query */
152 DCC_OP_GREY_SPAM =11, /* forget greylisted spammer */
153 DCC_OP_GREY_WHITE =12 /* whitelisted greylist triple */
154 } DCC_OPS;
155
156 typedef u_int32_t DCC_CLNT_ID;
157 #define DCC_ID_INVALID 0
158 #define DCC_ID_ANON 1 /* anonymous (non-paying) client */
159 #define DCC_ID_WHITE 2 /* whitelisted */
160 #define DCC_ID_COMP 3 /* compressed */
161 #define DCC_ID_SRVR_SIMPLE 4 /* simple server */
162 #define DCC_ID_SRVR_REP_OK 5 /* ok to use reputations */
163 #define DCC_ID_SRVR_IGNORE 6 /* ignore its flooded reports */
164 #define DCC_ID_SRVR_ROGUE 7 /* crazy server */
165 #define DCC_ID_SRVR_TYPE(id) ((id) == DCC_ID_SRVR_SIMPLE \
166 || (id) == DCC_ID_SRVR_REP_OK \
167 || (id) == DCC_ID_SRVR_IGNORE \
168 || (id) == DCC_ID_SRVR_ROGUE)
169 #define DCC_SRVR_ID_MIN 100 /* below reserved for special uses */
170 #define DCC_SRVR_ID_MAX 32767 /* below are servers--must be 2**n-1 */
171 #define DCC_CLNT_ID_MIN (DCC_SRVR_ID_MAX+1)
172 #define DCC_CLNT_ID_MAX 16777215
173 typedef u_int16_t DCC_SRVR_ID;
174 #define DCC_SRVR_ID_AUTH (DCC_SRVR_ID_MAX+1) /* client was authenticated */
175
176 /* client's identification of its transaction */
177 typedef u_int32_t DCC_OP_NUM;
178 typedef struct {
179 DCC_OP_NUM h; /* client host ID, e.g. IP address */
180 DCC_OP_NUM p; /* process ID, serial #, timestamp */
181 DCC_OP_NUM r; /* report ID */
182 DCC_OP_NUM t; /* client (re)transmission # */
183 } DCC_OP_NUMS;
184
185 /* The inter-DCC server flooding algorithm depends on unique-per-server
186 * timestamps to detect duplicates. That imposes a requirement on
187 * timestamps that they have resolution enough to separate reports
188 * from clients arriving at any single server.
189 * The timestamps are 48 bits consisting of 17 bits of 8's of microseconds
190 * and 31 bits of seconds. That's sufficient for the UNIX epoch.
191 * If the DCC is still around in the 2030's (and in the unlikely case that
192 * 8 microseconds are still fine enough), we can make the 31 bits be
193 * an offset in a bigger window.
194 */
195 #define DCC_TS_US_RSHIFT 3
196 #define DCC_TS_US_MULT (1<<DCC_TS_US_RSHIFT)
197 #define DCC_TS_SECS_LSHIFT 17
198 #define DCC_TS_US_MASK ((1<<DCC_TS_SECS_LSHIFT) - 1)
199 typedef struct {
200 u_char b[6];
201 } DCC_TS;
202
203 /* The start of any DCC packet.
204 * The length and version are early, since they are the only fields
205 * constrained in future versions. */
206 typedef struct {
207 u_int16_t len; /* total DCC packet length */
208 u_char pkt_vers; /* packet protocol version */
209 u_char op; /* one of DCC_OPS */
210 /* Identify the transaction.
211 * Each client can have many hosts, each host can be multi-homed,
212 * and each host can be running many processes talking to the
213 * server. Each packet needs to be uniquely numbered, so that the
214 * server can recognize as interchangable all of the (re)transmissions
215 * of a single report (rid) from a client process (pid) on a single
216 * host (hid), and the client can know which transmission (tid)
217 * produced a given server response to maintain the client's RTT
218 * value for the server. */
219 DCC_CLNT_ID sender; /* client-ID or server-ID */
220 DCC_OP_NUMS op_nums; /* op_num.t must be last */
221 } DCC_HDR;
222
223 typedef u_char DCC_SIGNATURE[16];
224
225 typedef struct {
226 DCC_HDR hdr;
227 DCC_SIGNATURE signature;
228 } DCC_NOP;
229
230
231 /* DCC_OP_ADMN administrative requests from localhost
232 * Most of these can be changed, because the administrative tools
233 * should match the daemon. */
234 typedef enum {
235 DCC_AOP_OK =-1, /* never really sent */
236 DCC_AOP_STOP = 1, /* stop gracefully */
237 DCC_AOP_DB_UNLOAD = 2, /* flush cache */
238 DCC_AOP_FLOD = 3, /* start or stop flooding */
239 DCC_AOP_DB_CLEAN = 4, /* start cleaning */
240 DCC_AOP_DB_NEW = 5, /* finish switch to new database */
241 DCC_AOP_STATS = 6, /* return counters--val=buffer size */
242 DCC_AOP_STATS_CLEAR = 7, /* return and zero counters */
243 DCC_AOP_TRACE_ON = 8,
244 DCC_AOP_TRACE_OFF = 9,
245 DCC_AOP_unused1 = 10, /* was dcc1-1-36 clients command */
246 DCC_AOP_CLIENTS = 11, /* some client IP addresses */
247 DCC_AOP_CLIENTS_ID = 12, /* some client IDs */
248 DCC_AOP_ANON_DELAY = 13, /* anonymous delay parameters */
249 DCC_AOP_CLOCK_CHECK = 14
250 } DCC_AOPS;
251
252 /* for DCC_AOP_FLOD */
253 typedef enum {
254 DCC_AOP_FLOD_CHECK=0,
255 DCC_AOP_FLOD_SHUTDOWN,
256 DCC_AOP_FLOD_HALT,
257 DCC_AOP_FLOD_RESUME,
258 DCC_AOP_FLOD_REWIND,
259 DCC_AOP_FLOD_LIST,
260 DCC_AOP_FLOD_STATS,
261 DCC_AOP_FLOD_STATS_CLEAR,
262 # define DCC_AOP_FLOD_STATS_ID " server-ID %u "
263 DCC_AOP_FLOD_FFWD_IN,
264 DCC_AOP_FLOD_FFWD_OUT
265 } DCC_AOP_FLODS;
266
267 typedef struct { /* with operation DCC_OP_ADMN */
268 DCC_HDR hdr;
269 int32_t date; /* seconds since epoch on caller */
270 u_int32_t val1; /* request type, buffer size, etc. */
271 u_char aop; /* one of DCC_AOPS */
272 u_char val2;
273 u_char val3;
274 u_char val4;
275 # define MAX_DCC_ADMN_REQ_VAL5 64
276 u_char val5[MAX_DCC_ADMN_REQ_VAL5];
277 DCC_SIGNATURE signature;
278 } DCC_ADMN_REQ;
279 #define DCC_ADMN_REQ_MIN_SIZE (ISZ(DCC_ADMN_REQ) - MAX_DCC_ADMN_REQ_VAL5)
280
281
282 typedef u_char DCC_AOP_CLIENTS_CIDR[17]; /* IPv6 netmask and length */
283
284 /* val2 for DCC_AOP_CLIENTS or DCC_AOP_CLIENTS_ID */
285 #define DCC_AOP_CLIENTS_AVG 0x01 /* want averages */
286 #define DCC_AOP_CLIENTS_VERS 0x02 /* want protocol version */
287 #define DCC_AOP_CLIENTS_ANON 0x04 /* only anonymous clients */
288 #define DCC_AOP_CLIENTS_NON_ANON 0x08 /* non-anonymous only */
289
290 #define DCC_AOP_CLIENTS_MAX_OFFSET ((1<<24)-1)
291
292 /* scale client's response buffer size in part of val1 by this */
293 #define DCC_ADMIN_RESP_CLIENTS_SHIFT 5
294 /* limit threshold in part of val1 */
295 #define DCC_ADMIN_RESP_CLIENTS_MAX_THOLD ((1<<16)-1)
296
297 /* noisy response to DCC_AOP_CLIENTS or DCC_AOP_CLIENTS_ID */
298 #define DCC_ADMN_RESP_CLIENTS_BL 0x01 /* this client blacklisted */
299 #define DCC_ADMN_RESP_CLIENTS_IPV6 0x02 /* address is IPv6 */
300 #define DCC_ADMN_RESP_CLIENTS_SKIP 0x04 /* last_used=clients skipped */
301 #define DCC_ADMN_RESP_CLIENTS_ID1 0x08 /* suppressed ID=DCC_ID_ANON */
302 #define DCC_ADMN_RESP_CLIENTS_VERS 0x10 /* protocol version # present */
303 #define DCC_ADMN_RESP_CLIENTS_LAST 0x20
304 #define DCC_ADMN_RESP_CLIENTS_BAD 0x40 /* naughty client */
305
306 /* worst case bytes used to describe a client */
307 #define DCC_ADMN_RESP_CLIENTS_MAX_SIZE (1+1+4*4+16)
308
309 #define DCC_ADMIN_RESP_MAX_CLIENTS (10*1000)
310
311
312 #ifdef DCC_PKT_VERSION6
313 typedef struct {
314 u_char clnt_id[4];
315 u_char last_used[4];
316 u_char requests[3];
317 u_char nops[2];
318 u_char flags;
319 union {
320 u_char ipv6[16];
321 u_char ipv4[4];
322 } addr;
323 } DCC_ADMN_RESP_CLIENTSv6;
324 #endif /* DCC_PKT_VERSION6 */
325
326 typedef struct {
327 u_char inflate[4];
328 u_char delay[2];
329 # define DCC_ANON_DELAY_MAX DCC_MAX_RTT
330 # define DCC_ANON_DELAY_FOREVER ((u_int16_t)-1)
331 # define DCC_NO_ANON_DELAY ((u_int16_t)-2)
332 } DCC_ADMN_RESP_ANON_DELAY;
333 typedef union {
334 char string[80*22];
335 u_char clients[1];
336 #ifdef DCC_PKT_VERSION6
337 DCC_ADMN_RESP_CLIENTSv6 clientsV6[1];
338 #endif
339 DCC_ADMN_RESP_ANON_DELAY anon_delay;
340 } DCC_ADMN_RESP_VAL;
341 typedef struct {
342 DCC_HDR hdr;
343 DCC_ADMN_RESP_VAL val;
344 DCC_SIGNATURE signature;
345 } DCC_ADMN_RESP;
346
347
348 #define DCC_TRACE_ADMN_BIT 0x0001 /* administrative requests */
349 #define DCC_TRACE_ANON_BIT 0x0002 /* anonymous client errors */
350 #define DCC_TRACE_CLNT_BIT 0x0004 /* authenticated client errors */
351 #define DCC_TRACE_RLIM_BIT 0x0008 /* rate limited messages */
352 #define DCC_TRACE_QUERY_BIT 0x0010 /* all queries and reports */
353 #define DCC_TRACE_RIDC_BIT 0x0020 /* RID cache messages */
354 #define DCC_TRACE_FLOD_BIT 0x0040 /* general inter-server flooding */
355 #define DCC_TRACE_FLOD2_BIT 0x0080 /* individual flooded reports */
356 #define DCC_TRACE_IDS_BIT 0x0100 /* monitor client- and server-IDs */
357 #define DCC_TRACE_BL_BIT 0x0200 /* blacklisted clients */
358 #define DCC_TRACE_DB_BIT 0x0400 /* odd database events */
359 #define DCC_TRACE_WLIST_BIT 0x0800 /* whitelisted checksums */
360 #define DCC_TRACE_BITS (DCC_TRACE_ADMN_BIT | DCC_TRACE_ANON_BIT \
361 | DCC_TRACE_CLNT_BIT | DCC_TRACE_RLIM_BIT \
362 | DCC_TRACE_QUERY_BIT | DCC_TRACE_RIDC_BIT \
363 | DCC_TRACE_FLOD_BIT | DCC_TRACE_FLOD2_BIT \
364 | DCC_TRACE_IDS_BIT | DCC_TRACE_BL_BIT \
365 | DCC_TRACE_DB_BIT | DCC_TRACE_WLIST_BIT)
366 #define DCC_TRACE_ON_DEF_BITS (DCC_TRACE_ANON_BIT | DCC_TRACE_CLNT_BIT)
367 #define DCC_TRACE_OFF_DEF_BITS (DCC_TRACE_BITS \
368 & ~(DCC_TRACE_ANON_BIT | DCC_TRACE_CLNT_BIT))
369
370
371 #define DCC_BRAND_MAXLEN 64
372 typedef char DCC_BRAND[DCC_BRAND_MAXLEN];
373
374 /* administrative or NOP ok */
375 typedef struct {
376 DCC_HDR hdr;
377 u_char max_pkt_vers; /* server can handle this version */
378 u_char unused;
379 u_int16_t qdelay_ms;
380 DCC_BRAND brand; /* identity or brandname of sender */
381 DCC_SIGNATURE signature;
382 } DCC_OK;
383
384
385 typedef u_int32_t DCC_TGTS; /* database is limited to 24 bits */
386 #define DCC_TGTS_TOO_MANY 0x00fffff0 /* >= 16777200 targets */
387 #define DCC_TGTS_OK 0x00fffff1 /* certified not spam */
388 #define DCC_TGTS_OK2 0x00fffff2 /* half certified not spam */
389 #define DCC_TGTS_GREY_WHITE DCC_TGTS_OK2 /* whitelisted for greylisting */
390 #define DCC_TGTS_DEL 0x00fffff3 /* a deleted checksum */
391 #define DCC_TGTS_REP_ADJ 0x00fffff4 /* scale a reputation */
392 #define DCC_TGTS_OK_MX 0x00fffff5 /* partly whitelist MX secondary */
393 #define DCC_TGTS_OK_MXDCC 0x00fffff6 /* MX secondary with DCC client */
394 #define DCC_TGTS_SUBMIT_CLIENT 0x00fffff7 /* SMTP submission client */
395 #define DCC_TGTS_MAX_DB DCC_TGTS_REP_ADJ
396 #define DCC_TGTS_INVALID 0x01000000
397 #define DCC_TGTS_SPAM DCC_TGTS_INVALID
398 #define DCC_TGTS_REP_SPAM 0x02000000 /* reputation hit */
399 #define DCC_TGTS_MASK 0x00ffffff
400
401 #define DCC_TGTS_RPT_MAX 2000
402 #define DCC_TGTS_FLOD_RPT_MAX (DCC_TGTS_RPT_MAX*1000)
403 #define BULK_THRESHOLD 10
404 #define REFLOOD_THRESHOLD 300
405 #define DCC_TGTS_REP_TOTAL_THOLD (BULK_THRESHOLD*2)
406 #define DCC_TGTS_REP_TOTAL_EXPIRE BULK_THRESHOLD
407
408 /* checksums kept by most servers */
409 #define DCC_CK_IS_GREY_BODY(g,t) ((g) ? ((t)==DCC_CK_BODY) : DCC_CK_IS_BODY(t))
410 #define DB_GLOBAL_NOKEEP(g,t) (!DCC_CK_IS_GREY_BODY(g,t) \
411 && (t) != DCC_CK_SRVR_ID \
412 && ((t) != DCC_CK_G_MSG_R_TOTAL || !(g)) \
413 && ((t) != DCC_CK_G_TRIPLE_R_BULK || !(g)))
414
415 /* checksums subject to thresholds */
416 #define DCC_CK_THOLD_OK(t) ((t) > DCC_CK_INVALID \
417 && (t) <= DCC_CK_G_TRIPLE_R_BULK)
418
419 #define IS_ALL_CKSUM(t) (DCC_CK_THOLD_OK(t) && !DCC_CK_IS_REP_CMN(0, t))
420 #define IS_CMN_CKSUM(t) DCC_CK_IS_BODY(t)
421
422
423 /* a reported checksum from a client */
424 typedef u_char DCC_SUM[16]; /* for now all have 16 bytes */
425 typedef struct {
426 DCC_CK_TYPE_B type;
427 u_char len; /* total length of this checksum */
428 DCC_SUM sum;
429 } DCC_CK;
430
431 /* most packets from client to server */
432 typedef struct {
433 DCC_HDR hdr;
434 DCC_TGTS tgts; /* # of addressees */
435 DCC_CK cks[DCC_QUERY_MAX]; /* even to prevent structure padding */
436 DCC_SIGNATURE signature;
437 } DCC_REPORT;
438
439 /* most responses */
440 typedef struct {
441 DCC_TGTS c; /* current value, with this report */
442 DCC_TGTS p; /* previous value, before this report */
443 } DCC_ANSWER_BODY_CKS;
444 typedef struct {
445 DCC_HDR hdr;
446 DCC_ANSWER_BODY_CKS b[DCC_QUERY_MAX];
447 DCC_SIGNATURE signature;
448 } DCC_ANSWER;
449
450 #ifdef DCC_PKT_VERSION5
451 typedef struct {
452 DCC_HDR hdr;
453 DCC_TGTS b[DCC_QUERY_MAX]; /* current values */
454 DCC_SIGNATURE signature;
455 } DCC_ANSWERv5;
456 #endif
457
458 typedef struct {
459 DCC_HDR hdr;
460 DCC_TGTS msg;
461 DCC_TGTS triple;
462 DCC_SIGNATURE signature;
463 } DCC_GREY_ANSWER;
464
465
466 /* DCC_OP_DELETE request to delete checksums */
467 typedef struct {
468 DCC_HDR hdr;
469 int32_t date; /* seconds since epoch on client */
470 DCC_CK ck;
471 u_char pad[2];
472 DCC_SIGNATURE signature;
473 } DCC_DELETE;
474
475
476 /* DCC_OP_GREY_SPAM restore greylist embargo */
477 typedef struct {
478 DCC_HDR hdr;
479 DCC_CK ip;
480 DCC_CK msg;
481 DCC_CK triple;
482 DCC_SIGNATURE signature;
483 } DCC_GREY_SPAM;
484
485
486 /* error response from server to client */
487 typedef struct {
488 DCC_HDR hdr;
489 # define DCC_ERROR_MSG_LEN 128
490 char msg[DCC_ERROR_MSG_LEN];
491 DCC_SIGNATURE signature;
492 } DCC_ERROR;
493
494
495 typedef union {
496 DCC_HDR hdr;
497 DCC_ANSWER ans;
498 #ifdef DCC_PKT_VERSION5
499 DCC_ANSWERv5 ans5;
500 #endif
501 DCC_GREY_ANSWER gans;
502 DCC_OK ok;
503 DCC_ERROR error;
504 DCC_ADMN_RESP resp;
505 int w[6];
506 } DCC_OP_RESP;
507
508
509
510
511 /* ************** server-to-server flooding protocol ************ */
512
513 /* This protocol is the sort of botch of a mess that results from assuming
514 * a considered protocol is not necessary and then extending it. */
515
516 /* A flooding connection starts with the TCP client or connection originator
517 * sending an ASCII "magic" string including a version number, the connection
518 * originator's server-ID, whether SOCKS is involved, and a cryptographic
519 * hash of the fixed-length message. In the common case, the connection
520 * orginator will send a flood of DCC reports. If SOCKS is involved, the
521 * connection is immediately turned around. */
522 #define DCC_FLOD_VERSION_STR_BASE "DCC flod version "
523 #define DCC_FLOD_VERSION7 7
524 /* in the next version, add a length to DCC_FLOD_END */
525 #define DCC_FLOD_VERSION7_STR DCC_FLOD_VERSION_STR_BASE"7"
526 #define DCC_FLOD_VERSION_DEF 0
527 #define DCC_FLOD_VERSION_CUR DCC_FLOD_VERSION7
528 #define DCC_FLOD_VERSION_CUR_STR DCC_FLOD_VERSION7_STR
529 typedef struct {
530 # define DCC_FLOD_VERSION_STR_LEN 64
531 char str[DCC_FLOD_VERSION_STR_LEN];
532 u_char sender_srvr_id[sizeof(DCC_SRVR_ID)];
533 u_char turn; /* 1=turn connection around for SOCKS */
534 u_char unused[3];
535 } DCC_FLOD_VERSION_BODY;
536 typedef struct {
537 DCC_FLOD_VERSION_BODY body;
538 char pad[256-sizeof(DCC_FLOD_VERSION_BODY)-sizeof(DCC_SIGNATURE)];
539 DCC_SIGNATURE signature;
540 } DCC_FLOD_VERSION_HDR;
541
542
543 /* flood sender's position or serial number
544 * Only the sender understands sender positions except for these
545 * special values. However, the special values imply that the position
546 * must be big endian. */
547 typedef u_char DCC_FLOD_POS[8];
548 /* special cases sent by the receiver back to the sender */
549 typedef enum {
550 DCC_FLOD_POS_END =0, /* receiver closing with message */
551 DCC_FLOD_POS_END_REQ =1, /* receiver wants to stop */
552 DCC_FLOD_POS_NOTE =2, /* receiver has a tracing message */
553 DCC_FLOD_POS_COMPLAINT =3, /* receiver has a problem message */
554 DCC_FLOD_POS_REWIND =4, /* receiver's database emptied */
555 DCC_FLOD_POS_FFWD_IN =5 /* receiver wants fast-forward */
556 } DCC_FLOD_POS_OPS;
557 #define DCC_FLOD_POS_MIN 10
558
559 #define DCC_FLOD_OK_STR "DCC flod ok: "
560
561 /* final result sent from flood receiver to flood sender
562 * This structure always ends the TCP stream. The length of the msg is
563 * obtain from the number of buts to the end of the stream. It should
564 * have had an explicit length in the structure. */
565 typedef struct {
566 DCC_FLOD_POS pos; /* one of DCC_FLOD_POS_* */
567 # define DCC_FLOD_MAX_RESP 200
568 char msg[DCC_FLOD_MAX_RESP]; /* no '\0'; uses length to EOF */
569 } DCC_FLOD_END;
570 #define FLOD_END_OVHD ISZ(((DCC_FLOD_END*)0)->pos)
571
572 /* report forwarded among servers */
573 typedef struct {
574 DCC_FLOD_POS pos;
575 u_char tgts[sizeof(DCC_TGTS)];
576 u_char srvr_id_auth[sizeof(DCC_SRVR_ID)]; /* receiving server */
577 DCC_TS ts; /* date reported */
578 u_char num_cks;
579 DCC_CK cks[DCC_QUERY_MAX];
580 } DCC_FLOD_RPT;
581 #define DCC_FLOD_RPT_LEN(n) (ISZ(DCC_FLOD_RPT) - ISZ(DCC_CK)*DCC_QUERY_MAX \
582 + ISZ(DCC_CK)*(n))
583
584 /* what can appear in the stream of flooded reports */
585 typedef union {
586 DCC_FLOD_VERSION_HDR v;
587 DCC_FLOD_END e;
588 DCC_FLOD_RPT r;
589 } DCC_FLOD_STREAM;
590
591
592 /* a response to flooded reports */
593 typedef union {
594 DCC_FLOD_POS pos;
595 DCC_FLOD_END end; /* final result */
596 struct {
597 DCC_FLOD_POS op; /* one of DCC_FLOD_POS_* */
598 u_char len; /* total length */
599 char str[DCC_FLOD_MAX_RESP]; /* includes trailing '\0' */
600 } note;
601 } DCC_FLOD_RESP;
602 #define FLOD_NOTE_OVHD (ISZ(((DCC_FLOD_RESP*)0)->note) - DCC_FLOD_MAX_RESP)
603
604
605 /* parts of error messages sent between flooding peers */
606 #define DCC_FLOD_BAD_VER_MSG "unrecognized flod version"
607 #define DCC_FLOD_BAD_ID_MSG "unauthorized ID"
608 #define DCC_FLOD_BAD_AUTH_MSG "bad authentication for ID"
609 #define DCC_FLOD_PASSWD_ID_MSG "unknown passwd-ID"
610
611
612 #endif /* DCC_PROTO_H */