stats.c (11869B)
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others. 2 3 Mixmaster may be redistributed and modified under certain conditions. 4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 5 ANY KIND, either express or implied. See the file COPYRIGHT for 6 details. 7 8 Remailer statistics 9 $Id: stats.c 934 2006-06-24 13:40:39Z rabbi $ */ 10 11 12 #include "mix3.h" 13 #include <stdio.h> 14 #include <string.h> 15 #include <time.h> 16 17 /* log that a message of type t has been received. Statistics for type 2 18 messages are taken from the IDLOG instead of calling this function */ 19 int stats_log(int t) 20 { 21 FILE *f; 22 23 f = mix_openfile(STATS, "a"); 24 if (f == NULL) { 25 errlog(ERRORMSG, "Can't open %s!\n", STATS); 26 return (-1); 27 } 28 lock(f); 29 fprintf(f, "%d 1 %ld\n", t, (long) time(NULL)); 30 unlock(f); 31 fclose(f); 32 return (0); 33 } 34 35 /* log the current pool size after sending messages */ 36 int stats_out(int pool) 37 { 38 FILE *f; 39 40 if (REMAIL == 0) 41 return (0); /* don't keep statistics for the client */ 42 43 f = mix_openfile(STATS, "a"); 44 if (f == NULL) { 45 errlog(ERRORMSG, "Can't open %s!\n", STATS); 46 return (-1); 47 } 48 lock(f); 49 fprintf(f, "p 1 %d %ld\n", pool, (long) time(NULL)); 50 unlock(f); 51 fclose(f); 52 return (0); 53 } 54 55 int stats(BUFFER *b) 56 { 57 FILE *s, *f; 58 char line[LINELEN]; 59 long now, today, then; 60 time_t t; 61 long updated = 0, havestats = 0; 62 int msgd[7][24], msg[7][80]; 63 /* 0 .. Unencrypted 64 * 1 .. Type I PGP 65 * 2 .. Mix 66 * 67 * 3 .. intermediate 68 * 4 .. final hop mail 69 * 5 .. final hop news 70 * 6 .. randhopped (will get counted in intermediate again) 71 */ 72 int poold[2][24], pool[2][80]; 73 int i, num, type, assigned, daysum; 74 char c; 75 idlog_t idbuf; 76 77 now = (time(NULL) / (60 * 60) + 1) * 60 * 60; 78 today = (now / SECONDSPERDAY) * SECONDSPERDAY; 79 80 for (i = 0; i < 24; i++) 81 msgd[0][i] = msgd[1][i] = msgd[2][i] = msgd[3][i] = msgd[4][i] = msgd[5][i] = msgd[6][i]= poold[0][i] = poold[1][i] = 0; 82 for (i = 0; i < 80; i++) 83 msg[0][i] = msg[1][i] = msg[2][i] = msg[3][i] = msg[4][i] = msg[5][i] = msg[6][i] = pool[0][i] = pool[1][i] = 0; 84 85 s = mix_openfile(STATS, "r"); 86 if (s != NULL) { 87 lock(s); 88 fscanf(s, "%ld", &updated); 89 while (fgets(line, sizeof(line), s) != NULL) { 90 switch (line[0]) { 91 case '0': 92 case '1': 93 case '2': 94 case '3': 95 case '4': 96 case '5': 97 case '6': 98 c = '\0'; 99 assigned = sscanf(line, "%d %d %ld %c", &type, &num, &then, &c); 100 daysum = (assigned == 4 && c == 'd'); 101 102 if (now - then < 0 || (daysum && today - then < 0)) 103 break; /* keep memory consistent even if the time 104 suddenly goes backwards :) */ 105 if (now - then < SECONDSPERDAY && !daysum) 106 msgd[type][(now - then) / (60 * 60)] += num; 107 else if (today - then < 80 * SECONDSPERDAY) 108 msg[type][(today - then) / SECONDSPERDAY] += num; 109 if (havestats == 0 || then < havestats) 110 havestats = then; 111 break; 112 case 'p': 113 c = '\0'; 114 assigned = sscanf(line, "p %d %d %ld %c", &num, &i, &then, &c); 115 daysum = (assigned == 4 && c == 'd'); 116 117 if (now - then < 0 || (daysum && today - then < 0)) 118 break; 119 if (now - then < SECONDSPERDAY && !daysum) { 120 poold[0][(now - then) / (60 * 60)] += num; 121 poold[1][(now - then) / (60 * 60)] += i; 122 } else if (today - then < 80 * SECONDSPERDAY) { 123 pool[0][(today - then) / (24 * 60 * 60)] += num; 124 pool[1][(today - then) / (24 * 60 * 60)] += i; 125 } 126 if (havestats == 0 || then < havestats) 127 havestats = then; 128 break; 129 } 130 } 131 unlock(s); 132 fclose(s); 133 } 134 f = mix_openfile(IDLOG, "rb"); 135 if (f != NULL) { 136 while (fread(&idbuf, 1, sizeof(idlog_t), f) == sizeof(idlog_t)) { 137 then = idbuf.time; 138 if (then < updated || now - then < 0) 139 continue; 140 if (now - then < SECONDSPERDAY) 141 msgd[2][(now - then) / (60 * 60)]++; 142 else if (today - then < 80 * SECONDSPERDAY) 143 msg[2][(today - then) / SECONDSPERDAY]++; 144 if (havestats == 0 || then < havestats) 145 havestats = then; 146 } 147 fclose(f); 148 } 149 if (havestats == 0) { 150 if (b != NULL) 151 errlog(NOTICE, "No statistics available.\n"); 152 return (-1); 153 } 154 s = mix_openfile(STATS, "w"); 155 if (s == NULL) { 156 errlog(ERRORMSG, "Can't create %s!\n", STATS); 157 return (-1); 158 } 159 lock(s); 160 fprintf(s, "%ld\n", (long) time(NULL)); /* time of stats.log update */ 161 for (i = 0; i < 24; i++) { 162 for (type = 0; type < 7; type++) 163 if (msgd[type][i] > 0) 164 fprintf(s, "%d %d %ld\n", type, msgd[type][i], now - i * 60 * 60); 165 if (poold[0][i] > 0) 166 fprintf(s, "p %d %d %ld\n", poold[0][i], poold[1][i], now - i * 60 * 60); 167 } 168 for (i = 0; i < 80; i++) { 169 for (type = 0; type < 7; type++) 170 if (msg[type][i] > 0) 171 fprintf(s, "%d %d %ld d\n", type, msg[type][i], 172 today - i * 24 * 60 * 60); 173 if (pool[0][i] > 0) 174 fprintf(s, "p %d %d %ld d\n", pool[0][i], pool[1][i], 175 today - i * 24 * 60 * 60); 176 } 177 unlock(s); 178 fclose(s); 179 if (b != NULL) { 180 struct tm *gt; 181 182 buf_sets(b, "Subject: Statistics for the "); 183 buf_appends(b, SHORTNAME); 184 buf_appends(b, " remailer\n\n"); 185 186 buf_appends(b, "Number of messages in the past 24 hours:\n"); 187 t = now; 188 gt = gmtime(&t); 189 for (i = 23; i >= 0; i--) { 190 buf_appendf(b, " %2dh: ", (24 + gt->tm_hour - i) % 24); 191 if (MIX) { 192 if (PGP || UNENCRYPTED) 193 buf_appends(b, " Mix:"); 194 buf_appendf(b, "%4d", msgd[2][i]); 195 } 196 if (PGP) 197 buf_appendf(b, " PGP: %4d", msgd[1][i]); 198 if (UNENCRYPTED) 199 buf_appendf(b, " Unencrypted:%4d", msgd[0][i]); 200 if (poold[0][i] > 0) 201 buf_appendf(b, " [Pool size:%4d]", poold[1][i] / poold[0][i]); 202 #if 0 203 else 204 buf_appends(b, " [ no remailing ]"); 205 #endif /* 0 */ 206 buf_nl(b); 207 } 208 if ((today - havestats) / SECONDSPERDAY >= 1) 209 buf_appends(b, "\nNumber of messages per day:\n"); 210 for ((i = (today - havestats) / SECONDSPERDAY) > 79 ? 79 : i; 211 i >= 1; i--) { 212 t = now - i * SECONDSPERDAY; 213 gt = gmtime(&t); 214 strftime(line, LINELEN, "%d %b: ", gt); 215 buf_appends(b, line); 216 217 if (MIX) { 218 if (PGP || UNENCRYPTED) 219 buf_appends(b, " Mix:"); 220 buf_appendf(b, "%4d", msg[2][i]); 221 } 222 if (PGP) 223 buf_appendf(b, " PGP: %4d", msg[1][i]); 224 if (UNENCRYPTED) 225 buf_appendf(b, " Unencrypted:%4d", msg[0][i]); 226 if (STATSDETAILS) { 227 buf_appendf(b, " Intermediate:%4d", msg[3][i]); 228 buf_appendf(b, " Mail:%4d", msg[4][i]); 229 buf_appendf(b, " Postings:%4d", msg[5][i]); 230 if (MIDDLEMAN) 231 buf_appendf(b, " Randhopped:%4d", msg[6][i]); 232 } 233 if (pool[0][i] > 0) 234 buf_appendf(b, " [Pool size:%4d]", pool[1][i] / pool[0][i]); 235 #if 0 236 else 237 buf_appends(b, " [ no remailing ]"); 238 #endif /* 0 */ 239 buf_nl(b); 240 } 241 } 242 return (0); 243 } 244 245 int conf(BUFFER *out) 246 { 247 FILE *f; 248 BUFFER *b, *line; 249 int flag = 0; 250 REMAILER remailer[MAXREM]; 251 int pgpkeyid[MAXREM]; 252 int i, num; 253 char tmpline[LINELEN]; 254 255 b = buf_new(); 256 line = buf_new(); 257 258 buf_sets(out, "Subject: Capabilities of the "); 259 buf_appends(out, SHORTNAME); 260 buf_appends(out, " remailer\n\n"); 261 buf_appends(out, remailer_type); 262 buf_appends(out, VERSION); 263 buf_nl(out); 264 265 if (MIX + PGP + UNENCRYPTED == 1) 266 buf_appends(out, "Supported format:"); 267 else 268 buf_appends(out, "Supported formats:\n"); 269 if (MIX) 270 buf_appends(out, " Mixmaster\n"); 271 if (PGP) 272 buf_appends(out, " Cypherpunk with PGP encryption\n"); 273 if (UNENCRYPTED) 274 buf_appends(out, " Cypherpunk (unencrypted)\n"); 275 276 buf_appendf(out, "Pool size: %d\n", POOLSIZE); 277 if (SIZELIMIT) 278 buf_appendf(out, "Maximum message size: %d kB\n", SIZELIMIT); 279 280 /* display destinations to which delivery is explicitly permitted 281 when in middleman mode (contents of DESTALLOW file.) */ 282 283 if (MIDDLEMAN) { 284 f = mix_openfile(DESTALLOW, "r"); 285 if (f != NULL) { 286 buf_read(b, f); 287 fclose(f); 288 while(buf_getline(b, line) != -1) { 289 if (line->length > 0 && line->data[0] != '#') { 290 if (flag == 0) { 291 buf_appends(out, "In addition to other remailers, this remailer also sends mail to these\n addresses directly:\n"); 292 flag = 1; 293 } 294 buf_appendf(out, " %b\n", line); 295 } 296 } 297 } 298 } 299 300 flag = 0; 301 f = mix_openfile(HDRFILTER, "r"); 302 if (f != NULL) { 303 buf_read(b, f); 304 fclose(f); 305 while(buf_getline(b, line) != -1) 306 if (line->length > 0 && line->data[0] != '#') { 307 if (flag == 0) { 308 buf_appends(out, "The following header lines will be filtered:\n"); 309 flag = 1; 310 } 311 buf_appends(out, " "); 312 if (line->length > 3 && streq(line->data + line->length - 2, "/q")) { 313 buf_append(out, line->data, line->length - 1); 314 buf_appends(out, " => delete message"); 315 } 316 else 317 buf_cat(out, line); 318 buf_nl(out); 319 } 320 buf_free(b); 321 } 322 flag = 0; 323 b = readdestblk( ); 324 if ( b != NULL ) { 325 while(buf_getline(b, line) != -1) 326 if (line->length > 0 && !bufleft(line, "#") && !buffind(line, "@")) { 327 /* mail addresses are not listed */ 328 if (flag == 0) { 329 if (NEWS[0]) 330 buf_appends(out, 331 "The following newsgroups/domains are blocked:\n"); 332 else 333 buf_appends(out, "The following domains are blocked:\n"); 334 flag = 1; 335 } 336 buf_appendf(out, " %b\n", line); 337 } 338 if (flag == 0 && NEWS[0]) 339 buf_appends(out, "Note that other newsgroups may be unavailable at the remailer's news server.\n"); 340 } 341 342 buf_nl(out); 343 conf_premail(out); 344 345 if (LISTSUPPORTED) { 346 /* SUPPORTED CPUNK (TYPE I) REMAILERS 347 * 0xDC7532F9 "Heex Remailer <remailer@xmailer.ods.org>" 348 * 0x759ED311 "znar <ka5tkn@cox-internet.com>" 349 * 350 * SUPPORTED MIXMASTER (TYPE II) REMAILERS 351 * aarg remailer@aarg.net 475f3f9fe8da22896c10082695a92c2d 2.9b33 C 352 * anon mixmaster@anon.978.org 7384ba1eec585bfd7d2b0e9b307f0b1d 2.9b36 MCNm 353 */ 354 355 buf_nl(out); 356 #ifdef USE_PGP 357 if (PGP) { 358 buf_appends(out, "SUPPORTED CPUNK (TYPE I) REMAILERS\n"); 359 num = t1_rlist(remailer, NULL); 360 pgp_rkeylist(remailer, pgpkeyid, num); 361 for (i=1; i<=num; i++) { 362 if (remailer[i].flags.pgp) { 363 snprintf(tmpline, LINELEN, "0x%08X \"%s <%s>\"\n", pgpkeyid[i], remailer[i].name, remailer[i].addr); 364 tmpline[LINELEN-1] = '\0'; 365 buf_appends(out, tmpline); 366 } 367 } 368 buf_nl(out); 369 } 370 #endif /* USE_PGP */ 371 if (MIX) { 372 buf_appends(out, "SUPPORTED MIXMASTER (TYPE II) REMAILERS\n"); 373 prepare_type2list(out); 374 buf_nl(out); 375 } 376 } 377 378 379 if ( b ) buf_free(b); 380 buf_free(line); 381 return (0); 382 } 383 384 void conf_premail(BUFFER *out) 385 { 386 buf_appends(out, "$remailer{\""); 387 buf_appends(out, SHORTNAME); 388 buf_appends(out, "\"} = \"<"); 389 buf_appends(out, REMAILERADDR); 390 buf_appendc(out, '>'); 391 if (PGP || UNENCRYPTED) 392 buf_appends(out, " cpunk max"); 393 if (MIX) 394 buf_appends(out, " mix"); 395 if (MIDDLEMAN) 396 buf_appends(out, " middle"); 397 if (PGP) 398 buf_appends(out, " pgp"); 399 if (PGP && !UNENCRYPTED) 400 buf_appends(out, " pgponly"); 401 if (PGP && REPGP) { 402 if (REMIX == 1) 403 buf_appends(out, " repgp"); 404 else 405 buf_appends(out, " repgp2"); 406 } 407 if (REMIX == 1) 408 buf_appends(out, " remix"); 409 else if (REMIX) 410 buf_appends(out, " remix2"); 411 if (PGP || UNENCRYPTED) 412 buf_appends(out, " latent hash cut test"); 413 if (PGP) { 414 #ifdef USE_IDEA 415 buf_appends(out, " ek"); 416 #endif /* USE_IDEA */ 417 buf_appends(out, " ekx"); 418 } 419 #ifdef USE_IDEA 420 buf_appends(out, " esub"); 421 #endif /* USE_IDEA */ 422 #if 0 /* obsolete */ 423 #ifdef USE_NSUB 424 buf_appends(out, " nsub"); 425 #else /* end of USE_NSUB */ 426 buf_appends(out, " ksub"); 427 #endif /* else if not USE_NSUB */ 428 #endif /* 0 */ 429 if (INFLATEMAX) 430 buf_appendf(out, " inflt%d", INFLATEMAX); 431 if (MAXRANDHOPS) 432 buf_appendf(out, " rhop%d", MAXRANDHOPS); 433 if (POOLSIZE >= 5) 434 buf_appends(out, " reord"); 435 if (NEWS[0]) 436 buf_appends(out, " post"); 437 if (SIZELIMIT) 438 buf_appendf(out, " klen%d", SIZELIMIT); 439 if (EXTFLAGS[0]) 440 buf_appendf(out, " %s", EXTFLAGS); 441 buf_appends(out, "\";\n"); 442 }