From 781538295ff7c056ffb5c19c283cfbacd91b243d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 14 Jun 2014 03:30:17 +0200 Subject: Limit the number of concurrent on-verify runs --- src/fastd.c | 5 +++++ src/fastd.h | 4 ++++ src/fastd_config.h.in | 3 +++ src/verify.c | 11 +++++++++++ 4 files changed, 23 insertions(+) diff --git a/src/fastd.c b/src/fastd.c index 6512bf7..eff605e 100644 --- a/src/fastd.c +++ b/src/fastd.c @@ -534,6 +534,11 @@ static inline void init(int argc, char *argv[]) { VECTOR_ALLOC(ctx.peers, 0); VECTOR_ALLOC(ctx.async_pids, 0); +#ifdef WITH_VERIFY + if (sem_init(&ctx.verify_limit, 0, VERIFY_LIMIT)) + exit_errno("sem_init"); +#endif + if (pthread_attr_init(&ctx.detached_thread)) exit_errno("pthread_attr_init"); if (pthread_attr_setdetachstate(&ctx.detached_thread, PTHREAD_CREATE_DETACHED)) diff --git a/src/fastd.h b/src/fastd.h index 19660db..539dd54 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -242,6 +243,9 @@ struct fastd_context { uint64_t next_peer_id; /**< An monotonously increasing ID peers are identified with in some components */ VECTOR(fastd_peer_t*) peers; /**< The currectly active peers */ +#ifdef WITH_VERIFY + sem_t verify_limit; /**< Keeps track of the number of verifier threads */ +#endif #ifdef USE_EPOLL int epoll_fd; /**< The file descriptor for the epoll facility */ diff --git a/src/fastd_config.h.in b/src/fastd_config.h.in index 429e42e..2057be1 100644 --- a/src/fastd_config.h.in +++ b/src/fastd_config.h.in @@ -120,6 +120,9 @@ /** How long a peer stays valid after a successful on-verify run */ #define VERIFY_VALID_TIME 60 /* 1 minute */ +/** Maximum number of concurrent on-verify runs */ +#define VERIFY_LIMIT 32 + /** The minimum interval between two handshakes with a peer */ #define MIN_HANDSHAKE_INTERVAL 15 diff --git a/src/verify.c b/src/verify.c index d875a34..f0dbe55 100644 --- a/src/verify.c +++ b/src/verify.c @@ -80,6 +80,9 @@ static void * do_verify_thread(void *p) { free(arg); + if (sem_post(&ctx.verify_limit)) + exit_errno("sem_post"); + return NULL; } @@ -105,6 +108,11 @@ fastd_tristate_t fastd_verify_peer(fastd_peer_t *peer, fastd_socket_t *sock, con return ret ? fastd_tristate_true : fastd_tristate_false; } else { + if (sem_trywait(&ctx.verify_limit)) { + pr_debug("maximum number of verification processes reached"); + return fastd_tristate_false; + } + verify_arg_t *arg = calloc(1, sizeof(verify_arg_t) + data_len); arg->env = env; @@ -121,6 +129,9 @@ fastd_tristate_t fastd_verify_peer(fastd_peer_t *peer, fastd_socket_t *sock, con if ((errno = pthread_create(&thread, &ctx.detached_thread, do_verify_thread, arg)) != 0) { pr_error_errno("unable to create verify thread"); + if (sem_post(&ctx.verify_limit)) + exit_errno("sem_post"); + fastd_shell_env_free(env); free(arg); -- cgit v1.2.3