summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2017-10-04 19:11:14 +0200
committerJ08nY2017-10-04 19:11:14 +0200
commit531c26c732ca8d01cd95c88c70bed6038bc8cba8 (patch)
tree82cdab0616f0b3faa1436dc0b08f9d3cefdf36f4
parent53bdab0a3d0411bbdc092dc9c3ae5a0f8afa6c6d (diff)
parent5fce9d7a2b6d012fbbbf1d5fd0c4759418c3d189 (diff)
downloadecgen-531c26c732ca8d01cd95c88c70bed6038bc8cba8.tar.gz
ecgen-531c26c732ca8d01cd95c88c70bed6038bc8cba8.tar.zst
ecgen-531c26c732ca8d01cd95c88c70bed6038bc8cba8.zip
-rw-r--r--README.md1
-rw-r--r--src/ecgen.c4
-rw-r--r--src/exhaustive/exhaustive.c11
-rw-r--r--src/io/cli.c21
-rw-r--r--src/misc/config.h1
-rw-r--r--src/util/timeout.c29
-rw-r--r--src/util/timeout.h56
7 files changed, 121 insertions, 2 deletions
diff --git a/README.md b/README.md
index 047c610..cfff5ed 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ Tool for generating Elliptic curve domain parameters.
- `-m / --memory=SIZE` Use PARI stack of `SIZE` (can have suffix k/m/g).
- `--threads=NUM` Use `NUM` threads.
- `--thread-stack=SIZE` Use PARI stack of `SIZE` (per thread, can have suffix k/m/g).
+ - `--timeout=TIME` Timeout computation of a curve parameter after `TIME` (can have suffix s/m/h/d).
#### Examples
diff --git a/src/ecgen.c b/src/ecgen.c
index c7c5871..822b0af 100644
--- a/src/ecgen.c
+++ b/src/ecgen.c
@@ -29,6 +29,7 @@
#include "invalid/invalid.h"
#include "io/input.h"
#include "io/output.h"
+#include "util/timeout.h"
const char *argp_program_version =
"ecgen 0.6.0\n"
@@ -50,6 +51,9 @@ bool init(void) {
// init PARI PRNG
if (!random_init()) return false;
+ // init the signal handlers, etc. for timeout handling
+ if (!timeout_init(&cfg)) return false;
+
// set datadir if specified
if (cfg.datadir) {
default0("datadir", cfg.datadir);
diff --git a/src/exhaustive/exhaustive.c b/src/exhaustive/exhaustive.c
index 5011490..b55bcca 100644
--- a/src/exhaustive/exhaustive.c
+++ b/src/exhaustive/exhaustive.c
@@ -15,6 +15,7 @@
#include "gen/seed.h"
#include "io/output.h"
#include "util/memory.h"
+#include "util/timeout.h"
exhaustive_t *exhaustive_new(void) { return try_calloc(sizeof(exhaustive_t)); }
@@ -230,7 +231,15 @@ int exhaustive_gen_retry(curve_t *curve, const config_t *cfg,
arg_t *arg = argss ? argss[state] : NULL;
- int diff = generators[state](curve, cfg, arg, (offset_e)state);
+ int diff;
+ timeout_start(cfg->timeout) {
+ // This is not the best, but currently the best idea I have.
+ diff = start_offset - state;
+ }
+ else {
+ diff = generators[state](curve, cfg, arg, (offset_e)state);
+ }
+ timeout_stop();
int new_state = state + diff;
if (new_state < start_offset) new_state = start_offset;
diff --git a/src/io/cli.c b/src/io/cli.c
index 77f279f..74e6cc7 100644
--- a/src/io/cli.c
+++ b/src/io/cli.c
@@ -4,7 +4,6 @@
*/
#include "cli.h"
#include <string.h>
-#include <unistd.h>
#include "exhaustive/ansi.h"
char cli_doc[] =
@@ -34,6 +33,7 @@ enum opt_keys {
OPT_POINTS,
OPT_THREADS,
OPT_TSTACK,
+ OPT_TIMEOUT,
OPT_ANOMALOUS
};
@@ -68,6 +68,7 @@ struct argp_option cli_options[] = {
{"memory", OPT_MEMORY, "SIZE", 0, "Use PARI stack of SIZE (can have suffix k/m/g).", 4},
{"threads", OPT_THREADS, "NUM", 0, "Use NUM threads.", 4},
{"thread-stack", OPT_TSTACK, "SIZE", 0, "Use PARI stack of SIZE (per thread, can have suffix k/m/g).", 4},
+ {"timeout", OPT_TIMEOUT, "TIME", 0, "Timeout computation of a curve parameter after TIME (can have suffix s/m/h/d).", 4},
{0}
};
// clang-format on
@@ -87,6 +88,21 @@ static unsigned long cli_parse_memory(const char *str) {
return read;
}
+static unsigned long cli_parse_time(const char *str) {
+ char *suffix = NULL;
+ unsigned long read = strtoul(str, &suffix, 10);
+ if (suffix) {
+ if (*suffix == 'm' || *suffix == 'M') {
+ read *= 60;
+ } else if (*suffix == 'h' || *suffix == 'H') {
+ read *= 3600;
+ } else if (*suffix == 'd' || *suffix == 'D') {
+ read *= 86400;
+ }
+ }
+ return read;
+}
+
error_t cli_parse(int key, char *arg, struct argp_state *state) {
config_t *cfg = state->input;
@@ -100,6 +116,9 @@ error_t cli_parse(int key, char *arg, struct argp_state *state) {
case OPT_TSTACK:
cfg->thread_memory = cli_parse_memory(arg);
break;
+ case OPT_TIMEOUT:
+ cfg->timeout = cli_parse_time(arg);
+ break;
case OPT_THREADS:
if (!strcmp(arg, "auto") || !strcmp(arg, "AUTO")) {
long nprocs = sysconf(_SC_NPROCESSORS_ONLN);
diff --git a/src/misc/config.h b/src/misc/config.h
index 5069881..fe792d5 100644
--- a/src/misc/config.h
+++ b/src/misc/config.h
@@ -58,6 +58,7 @@ typedef struct {
unsigned long memory;
unsigned long threads;
unsigned long thread_memory;
+ unsigned long timeout;
enum format_e format;
char *output;
diff --git a/src/util/timeout.c b/src/util/timeout.c
new file mode 100644
index 0000000..c9608a9
--- /dev/null
+++ b/src/util/timeout.c
@@ -0,0 +1,29 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#include "timeout.h"
+
+__thread jmp_buf timeout_ptr;
+__thread bool timeout_in = false;
+__thread timer_t timeout_timer;
+
+void timeout_handle(int signum, siginfo_t *siginfo, void *other) {
+ sigset_t mask;
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGALRM);
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+
+ if (timeout_in) siglongjmp(timeout_ptr, 1);
+}
+
+bool timeout_init(const config_t *cfg) {
+ struct sigaction new_action;
+
+ new_action.sa_sigaction = timeout_handle;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = SA_SIGINFO;
+
+ sigaction(SIGALRM, &new_action, NULL);
+ return true;
+} \ No newline at end of file
diff --git a/src/util/timeout.h b/src/util/timeout.h
new file mode 100644
index 0000000..2b615bb
--- /dev/null
+++ b/src/util/timeout.h
@@ -0,0 +1,56 @@
+/*
+ * ecgen, tool for generating Elliptic curve domain parameters
+ * Copyright (C) 2017 J08nY
+ */
+#ifndef ECGEN_TIMEOUT_H
+#define ECGEN_TIMEOUT_H
+
+#include <setjmp.h>
+#include <sys/syscall.h>
+#include <time.h>
+#include <unistd.h>
+#include "io/output.h"
+#include "misc/config.h"
+
+extern __thread sigjmp_buf timeout_ptr;
+extern __thread bool timeout_in;
+extern __thread timer_t timeout_timer;
+
+/**
+ * @brief
+ */
+#define timeout_start(seconds) \
+ if ((seconds) != 0) { \
+ struct sigevent sevp; \
+ sevp.sigev_notify = SIGEV_THREAD_ID; \
+ sevp.sigev_signo = SIGALRM; \
+ sevp._sigev_un._tid = (__pid_t)syscall(SYS_gettid); \
+ \
+ timer_create(CLOCK_MONOTONIC, &sevp, &timeout_timer); \
+ struct itimerspec timer_time = { \
+ .it_interval = {.tv_sec = 0, .tv_nsec = 0}, \
+ .it_value = {.tv_sec = (seconds), .tv_nsec = 0}}; \
+ timer_settime(timeout_timer, 0, &timer_time, NULL); \
+ timeout_in = true; \
+ }; \
+ if ((seconds) != 0 && sigsetjmp(timeout_ptr, 1) == 1)
+
+/**
+ * @brief
+ */
+#define timeout_stop() \
+ { \
+ if (timeout_in) { \
+ timeout_in = false; \
+ timer_delete(timeout_timer); \
+ } \
+ }
+
+/**
+ * @brief
+ * @param cfg
+ * @return
+ */
+bool timeout_init(const config_t *cfg);
+
+#endif // ECGEN_TIMEOUT_H