aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/if_wg.c20
-rw-r--r--src/support.h8
-rw-r--r--src/wg_cookie.c54
-rw-r--r--src/wg_cookie.h11
4 files changed, 45 insertions, 48 deletions
diff --git a/src/if_wg.c b/src/if_wg.c
index 6ffcce1..4a91f59 100644
--- a/src/if_wg.c
+++ b/src/if_wg.c
@@ -1270,17 +1270,15 @@ wg_handshake(struct wg_softc *sc, struct wg_packet *pkt)
struct noise_remote *remote = NULL;
int res;
bool underload = false;
- static struct timeval wg_last_underload; /* microuptime */
- static const struct timeval underload_interval = { UNDERLOAD_TIMEOUT, 0 };
-
- if (wg_queue_len(&sc->sc_handshake_queue) >= MAX_QUEUED_HANDSHAKES/8) {
- getmicrouptime(&wg_last_underload);
- underload = true;
- } else if (wg_last_underload.tv_sec != 0) {
- if (!ratecheck(&wg_last_underload, &underload_interval))
- underload = true;
- else
- bzero(&wg_last_underload, sizeof(wg_last_underload));
+ static sbintime_t wg_last_underload; /* nanouptime */
+
+ underload = wg_queue_len(&sc->sc_handshake_queue) >= MAX_QUEUED_HANDSHAKES / 8;
+ if (underload) {
+ wg_last_underload = getsbinuptime();
+ } else if (wg_last_underload) {
+ underload = wg_last_underload + UNDERLOAD_TIMEOUT * SBT_1S > getsbinuptime();
+ if (!underload)
+ wg_last_underload = 0;
}
m = pkt->p_mbuf;
diff --git a/src/support.h b/src/support.h
index 99cd518..16231a6 100644
--- a/src/support.h
+++ b/src/support.h
@@ -59,6 +59,14 @@ siphash24(const SIPHASH_KEY *key, const void *src, size_t len)
return (SipHashX(&ctx, 2, 4, (const uint8_t *)key, src, len));
}
+static inline uint64_t
+siphash13(const SIPHASH_KEY *key, const void *src, size_t len)
+{
+ SIPHASH_CTX ctx;
+
+ return (SipHashX(&ctx, 1, 3, (const uint8_t *)key, src, len));
+}
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
diff --git a/src/wg_cookie.c b/src/wg_cookie.c
index 26673c1..8b42804 100644
--- a/src/wg_cookie.c
+++ b/src/wg_cookie.c
@@ -21,7 +21,7 @@ static void cookie_macs_mac1(struct cookie_macs *, const void *, size_t,
const uint8_t[COOKIE_KEY_SIZE]);
static void cookie_macs_mac2(struct cookie_macs *, const void *, size_t,
const uint8_t[COOKIE_COOKIE_SIZE]);
-static int cookie_timer_expired(struct timespec *, time_t, long);
+static int cookie_timer_expired(sbintime_t, uint32_t, uint32_t);
static void cookie_checker_make_cookie(struct cookie_checker *,
uint8_t[COOKIE_COOKIE_SIZE], struct sockaddr *);
static int ratelimit_init(struct ratelimit *, uma_zone_t);
@@ -122,7 +122,7 @@ cookie_maker_consume_payload(struct cookie_maker *cp,
}
memcpy(cp->cp_cookie, cookie, COOKIE_COOKIE_SIZE);
- getnanouptime(&cp->cp_birthdate);
+ cp->cp_birthdate = getsbinuptime();
cp->cp_mac1_valid = false;
error:
@@ -141,7 +141,7 @@ cookie_maker_mac(struct cookie_maker *cp, struct cookie_macs *cm, void *buf,
memcpy(cp->cp_mac1_last, cm->mac1, COOKIE_MAC_SIZE);
cp->cp_mac1_valid = true;
- if (!cookie_timer_expired(&cp->cp_birthdate,
+ if (!cookie_timer_expired(cp->cp_birthdate,
COOKIE_SECRET_MAX_AGE - COOKIE_SECRET_LATENCY, 0))
cookie_macs_mac2(cm, buf, len, cp->cp_cookie);
else
@@ -226,18 +226,11 @@ cookie_macs_mac2(struct cookie_macs *cm, const void *buf, size_t len,
blake2s_final(&state, cm->mac2);
}
-static int
-cookie_timer_expired(struct timespec *birthdate, time_t sec, long nsec)
+static __inline int
+cookie_timer_expired(sbintime_t timer, uint32_t sec, uint32_t nsec)
{
- struct timespec uptime;
- struct timespec expire = { .tv_sec = sec, .tv_nsec = nsec };
-
- if (birthdate->tv_sec == 0 && birthdate->tv_nsec == 0)
- return ETIMEDOUT;
-
- getnanouptime(&uptime);
- timespecadd(birthdate, &expire, &expire);
- return timespeccmp(&uptime, &expire, >) ? ETIMEDOUT : 0;
+ sbintime_t now = getsbinuptime();
+ return (now > (timer + sec * SBT_1S + nstosbt(nsec))) ? ETIMEDOUT : 0;
}
static void
@@ -247,10 +240,10 @@ cookie_checker_make_cookie(struct cookie_checker *cc,
struct blake2s_state state;
rw_enter_write(&cc->cc_secret_lock);
- if (cookie_timer_expired(&cc->cc_secret_birthdate,
+ if (cookie_timer_expired(cc->cc_secret_birthdate,
COOKIE_SECRET_MAX_AGE, 0)) {
arc4random_buf(cc->cc_secret, COOKIE_SECRET_SIZE);
- getnanouptime(&cc->cc_secret_birthdate);
+ cc->cc_secret_birthdate = getsbinuptime();
}
blake2s_init_key(&state, COOKIE_COOKIE_SIZE, cc->cc_secret,
COOKIE_SECRET_SIZE);
@@ -301,7 +294,7 @@ ratelimit_gc(struct ratelimit *rl, int force)
{
size_t i;
struct ratelimit_entry *r, *tr;
- struct timespec expiry;
+ sbintime_t expiry, now;
rw_assert_wrlock(&rl->rl_lock);
@@ -316,15 +309,15 @@ ratelimit_gc(struct ratelimit *rl, int force)
return;
}
- if ((cookie_timer_expired(&rl->rl_last_gc, ELEMENT_TIMEOUT, 0) &&
+ if ((cookie_timer_expired(rl->rl_last_gc, ELEMENT_TIMEOUT, 0) &&
rl->rl_table_num > 0)) {
- getnanouptime(&rl->rl_last_gc);
- getnanouptime(&expiry);
- expiry.tv_sec -= ELEMENT_TIMEOUT;
+ now = getsbinuptime();
+ expiry = now - ELEMENT_TIMEOUT * SBT_1S;
+ rl->rl_last_gc = now;
for (i = 0; i < RATELIMIT_SIZE; i++) {
LIST_FOREACH_SAFE(r, &rl->rl_table[i], r_entry, tr) {
- if (timespeccmp(&r->r_last_time, &expiry, <)) {
+ if (r->r_last_time < expiry) {
rl->rl_table_num--;
LIST_REMOVE(r, r_entry);
uma_zfree(rl->rl_zone, r);
@@ -338,17 +331,16 @@ static int
ratelimit_allow(struct ratelimit *rl, struct sockaddr *sa)
{
uint64_t key, tokens;
- struct timespec diff;
+ sbintime_t diff, now;
struct ratelimit_entry *r;
int ret = ECONNREFUSED;
if (sa->sa_family == AF_INET)
- /* TODO siphash24 is the FreeBSD siphash, OK? */
- key = siphash24(&rl->rl_secret, &satosin(sa)->sin_addr,
+ key = siphash13(&rl->rl_secret, &satosin(sa)->sin_addr,
IPV4_MASK_SIZE);
#ifdef INET6
else if (sa->sa_family == AF_INET6)
- key = siphash24(&rl->rl_secret, &satosin6(sa)->sin6_addr,
+ key = siphash13(&rl->rl_secret, &satosin6(sa)->sin6_addr,
IPV6_MASK_SIZE);
#endif
else
@@ -377,11 +369,11 @@ ratelimit_allow(struct ratelimit *rl, struct sockaddr *sa)
* left (that is tokens <= INITIATION_COST) then we block the
* request, otherwise we subtract the INITITIATION_COST and
* return OK. */
- diff = r->r_last_time;
- getnanouptime(&r->r_last_time);
- timespecsub(&r->r_last_time, &diff, &diff);
+ now = getsbinuptime();
+ diff = now - r->r_last_time;
+ r->r_last_time = now;
- tokens = r->r_tokens + diff.tv_sec * NSEC_PER_SEC + diff.tv_nsec;
+ tokens = r->r_tokens + diff;
if (tokens > TOKEN_MAX)
tokens = TOKEN_MAX;
@@ -418,7 +410,7 @@ ratelimit_allow(struct ratelimit *rl, struct sockaddr *sa)
memcpy(&r->r_in6, &satosin6(sa)->sin6_addr, IPV6_MASK_SIZE);
#endif
- getnanouptime(&r->r_last_time);
+ r->r_last_time = getsbinuptime();
r->r_tokens = TOKEN_MAX - INITIATION_COST;
ok:
ret = 0;
diff --git a/src/wg_cookie.h b/src/wg_cookie.h
index d24223f..c6e4604 100644
--- a/src/wg_cookie.h
+++ b/src/wg_cookie.h
@@ -32,10 +32,9 @@
/* Constants for initiation rate limiting */
#define RATELIMIT_SIZE (1 << 13)
#define RATELIMIT_SIZE_MAX (RATELIMIT_SIZE * 8)
-#define NSEC_PER_SEC 1000000000LL
#define INITIATIONS_PER_SECOND 20
#define INITIATIONS_BURSTABLE 5
-#define INITIATION_COST (NSEC_PER_SEC / INITIATIONS_PER_SECOND)
+#define INITIATION_COST (SBT_1S / INITIATIONS_PER_SECOND)
#define TOKEN_MAX (INITIATION_COST * INITIATIONS_BURSTABLE)
#define ELEMENT_TIMEOUT 1
#define IPV4_MASK_SIZE 4 /* Use all 4 bytes of IPv4 address */
@@ -55,7 +54,7 @@ struct ratelimit_entry {
struct in6_addr r_in6;
#endif
};
- struct timespec r_last_time; /* nanouptime */
+ sbintime_t r_last_time; /* nanouptime */
uint64_t r_tokens;
};
@@ -67,7 +66,7 @@ struct ratelimit {
LIST_HEAD(, ratelimit_entry) *rl_table;
u_long rl_table_mask;
size_t rl_table_num;
- struct timespec rl_last_gc; /* nanouptime */
+ sbintime_t rl_last_gc; /* nanouptime */
};
struct cookie_maker {
@@ -76,7 +75,7 @@ struct cookie_maker {
struct rwlock cp_lock;
uint8_t cp_cookie[COOKIE_COOKIE_SIZE];
- struct timespec cp_birthdate; /* nanouptime */
+ sbintime_t cp_birthdate; /* nanouptime */
bool cp_mac1_valid;
uint8_t cp_mac1_last[COOKIE_MAC_SIZE];
};
@@ -92,7 +91,7 @@ struct cookie_checker {
uint8_t cc_cookie_key[COOKIE_KEY_SIZE];
struct rwlock cc_secret_lock;
- struct timespec cc_secret_birthdate; /* nanouptime */
+ sbintime_t cc_secret_birthdate; /* nanouptime */
uint8_t cc_secret[COOKIE_SECRET_SIZE];
};