summaryrefslogtreecommitdiff
path: root/moduli.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-10-24 21:02:26 +1100
committerDamien Miller <djm@mindrot.org>2013-10-24 21:02:26 +1100
commit4bedd4032a09ce87322ae5ea80f193f109e5c607 (patch)
tree9e0fea82871764d318cee710050a79a92cca03a3 /moduli.c
parent5ecb41629860687b145be63b8877fabb6bae5eda (diff)
- dtucker@cvs.openbsd.org 2013/10/24 00:49:49
[moduli.c] Periodically print progress and, if possible, expected time to completion when screening moduli for DH groups. ok deraadt djm
Diffstat (limited to 'moduli.c')
-rw-r--r--moduli.c106
1 files changed, 92 insertions, 14 deletions
diff --git a/moduli.c b/moduli.c
index 294ff8fde..bb4dd7beb 100644
--- a/moduli.c
+++ b/moduli.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: moduli.c,v 1.27 2013/05/17 00:13:13 djm Exp $ */ 1/* $OpenBSD: moduli.c,v 1.28 2013/10/24 00:49:49 dtucker Exp $ */
2/* 2/*
3 * Copyright 1994 Phil Karn <karn@qualcomm.com> 3 * Copyright 1994 Phil Karn <karn@qualcomm.com>
4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> 4 * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
@@ -56,6 +56,7 @@
56#include "xmalloc.h" 56#include "xmalloc.h"
57#include "dh.h" 57#include "dh.h"
58#include "log.h" 58#include "log.h"
59#include "misc.h"
59 60
60#include "openbsd-compat/openssl-compat.h" 61#include "openbsd-compat/openssl-compat.h"
61 62
@@ -488,6 +489,79 @@ read_checkpoint(char *cpfile)
488 return lineno; 489 return lineno;
489} 490}
490 491
492static unsigned long
493count_lines(FILE *f)
494{
495 unsigned long count = 0;
496 char lp[QLINESIZE + 1];
497
498 if (fseek(f, 0, SEEK_SET) != 0) {
499 debug("input file is not seekable");
500 return ULONG_MAX;
501 }
502 while (fgets(lp, QLINESIZE + 1, f) != NULL)
503 count++;
504 rewind(f);
505 debug("input file has %lu lines", count);
506 return count;
507}
508
509static char *
510fmt_time(time_t seconds)
511{
512 int day, hr, min;
513 static char buf[128];
514
515 min = (seconds / 60) % 60;
516 hr = (seconds / 60 / 60) % 24;
517 day = seconds / 60 / 60 / 24;
518 if (day > 0)
519 snprintf(buf, sizeof buf, "%dd %d:%02d", day, hr, min);
520 else
521 snprintf(buf, sizeof buf, "%d:%02d", hr, min);
522 return buf;
523}
524
525static void
526print_progress(unsigned long start_lineno, unsigned long current_lineno,
527 unsigned long end_lineno)
528{
529 static time_t time_start, time_prev;
530 time_t time_now, elapsed;
531 unsigned long num_to_process, processed, remaining, percent, eta;
532 double time_per_line;
533 char *eta_str;
534
535 time_now = monotime();
536 if (time_start == 0) {
537 time_start = time_prev = time_now;
538 return;
539 }
540 /* print progress after 1m then once per 5m */
541 if (time_now - time_prev < 5 * 60)
542 return;
543 time_prev = time_now;
544 elapsed = time_now - time_start;
545 processed = current_lineno - start_lineno;
546 remaining = end_lineno - current_lineno;
547 num_to_process = end_lineno - start_lineno;
548 time_per_line = (double)elapsed / processed;
549 /* if we don't know how many we're processing just report count+time */
550 time(&time_now);
551 if (end_lineno == ULONG_MAX) {
552 logit("%.24s processed %lu in %s", ctime(&time_now),
553 processed, fmt_time(elapsed));
554 return;
555 }
556 percent = 100 * processed / num_to_process;
557 eta = time_per_line * remaining;
558 eta_str = xstrdup(fmt_time(eta));
559 logit("%.24s processed %lu of %lu (%lu%%) in %s, ETA %s",
560 ctime(&time_now), processed, num_to_process, percent,
561 fmt_time(elapsed), eta_str);
562 free(eta_str);
563}
564
491/* 565/*
492 * perform a Miller-Rabin primality test 566 * perform a Miller-Rabin primality test
493 * on the list of candidates 567 * on the list of candidates
@@ -512,6 +586,11 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
512 return (-1); 586 return (-1);
513 } 587 }
514 588
589 if (num_lines == 0)
590 end_lineno = count_lines(in);
591 else
592 end_lineno = start_lineno + num_lines;
593
515 time(&time_start); 594 time(&time_start);
516 595
517 if ((p = BN_new()) == NULL) 596 if ((p = BN_new()) == NULL)
@@ -526,26 +605,25 @@ prime_test(FILE *in, FILE *out, u_int32_t trials, u_int32_t generator_wanted,
526 605
527 if (checkpoint_file != NULL) 606 if (checkpoint_file != NULL)
528 last_processed = read_checkpoint(checkpoint_file); 607 last_processed = read_checkpoint(checkpoint_file);
529 if (start_lineno > last_processed) 608 last_processed = start_lineno = MAX(last_processed, start_lineno);
530 last_processed = start_lineno; 609 if (end_lineno == ULONG_MAX)
531 if (num_lines == 0) 610 debug("process from line %lu from pipe", last_processed);
532 end_lineno = ULONG_MAX;
533 else 611 else
534 end_lineno = last_processed + num_lines; 612 debug("process from line %lu to line %lu", last_processed,
535 debug2("process line %lu to line %lu", last_processed, end_lineno); 613 end_lineno);
536 614
537 res = 0; 615 res = 0;
538 lp = xmalloc(QLINESIZE + 1); 616 lp = xmalloc(QLINESIZE + 1);
539 while (fgets(lp, QLINESIZE + 1, in) != NULL && count_in < end_lineno) { 617 while (fgets(lp, QLINESIZE + 1, in) != NULL && count_in < end_lineno) {
540 count_in++; 618 count_in++;
541 if (checkpoint_file != NULL) { 619 if (count_in <= last_processed) {
542 if (count_in <= last_processed) { 620 debug3("skipping line %u, before checkpoint or "
543 debug3("skipping line %u, before checkpoint", 621 "specified start line", count_in);
544 count_in); 622 continue;
545 continue;
546 }
547 write_checkpoint(checkpoint_file, count_in);
548 } 623 }
624 if (checkpoint_file != NULL)
625 write_checkpoint(checkpoint_file, count_in);
626 print_progress(start_lineno, count_in, end_lineno);
549 if (strlen(lp) < 14 || *lp == '!' || *lp == '#') { 627 if (strlen(lp) < 14 || *lp == '!' || *lp == '#') {
550 debug2("%10u: comment or short line", count_in); 628 debug2("%10u: comment or short line", count_in);
551 continue; 629 continue;