diff options
-rw-r--r-- | src/if_wg.c | 20 | ||||
-rw-r--r-- | src/support.h | 8 | ||||
-rw-r--r-- | src/wg_cookie.c | 54 | ||||
-rw-r--r-- | src/wg_cookie.h | 11 |
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]; }; |