summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fastd.c5
-rw-r--r--src/fastd.h4
-rw-r--r--src/fastd_config.h.in3
-rw-r--r--src/verify.c11
4 files changed, 23 insertions, 0 deletions
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 <fcntl.h>
#include <pthread.h>
#include <poll.h>
+#include <semaphore.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -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);