From 5214d7e59fe4d5d89e14e8e7b654ded25f918afb Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 1 Aug 2024 14:55:05 +0200 Subject: [PATCH 1/2] IO: Ensure that socket rcvbuf is large enough The socket structure has the field rbsize (receive buffer size), which controls the size of the userspace receive buffer. There is also kernel receive buffer, which in some cases may be smaller (e.g. on FreeBSD it is by default ~8k). The patch ensures that the kernel receive buffer is as large as the userspace receive buffer. --- sysdep/unix/io.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 987c7a6b..59b33ef1 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -517,6 +517,40 @@ sk_set_high_port(sock *s UNUSED) return 0; } +static inline int +sk_set_min_rcvbuf_(sock *s, int bufsize) +{ + int oldsize = 0, oldsize_s = sizeof(oldsize); + + if (getsockopt(s->fd, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldsize_s) < 0) + ERR("SO_RCVBUF"); + + if (oldsize >= bufsize) + return 0; + + bufsize = BIRD_ALIGN(bufsize, 64); + if (setsockopt(s->fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) < 0) + ERR("SO_RCVBUF"); + + /* + int newsize = 0, newsize_s = sizeof(newsize); + if (getsockopt(s->fd, SOL_SOCKET, SO_RCVBUF, &newsize, &newsize_s) < 0) + ERR("SO_RCVBUF"); + + log(L_INFO "Setting rcvbuf on %s from %d to %d", + s->iface ? s->iface->name : "*", oldsize, newsize); + */ + + return 0; +} + +static void +sk_set_min_rcvbuf(sock *s, int bufsize) +{ + if (sk_set_min_rcvbuf_(s, bufsize) < 0) + log(L_WARN "Socket error: %s%#m", s->err); +} + static inline byte * sk_skip_ip_header(byte *pkt, int *len) { @@ -862,6 +896,9 @@ sk_set_rbsize(sock *s, uint val) xfree(s->rbuf_alloc); s->rbuf_alloc = xmalloc(val); s->rpos = s->rbuf = s->rbuf_alloc; + + if ((s->type == SK_UDP) || (s->type == SK_IP)) + sk_set_min_rcvbuf(s, s->rbsize); } void @@ -1058,6 +1095,9 @@ sk_setup(sock *s) if (sk_set_priority(s, s->priority) < 0) return -1; + if ((s->type == SK_UDP) || (s->type == SK_IP)) + sk_set_min_rcvbuf(s, s->rbsize); + return 0; } From acbdc29d57373a42a512b505c7d4169fd9ca2bee Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 27 Aug 2024 14:28:41 +0200 Subject: [PATCH 2/2] Lib: Expand timer recurrence to 64b The period of recurent timers was stored in 32b field, despite it was btime-compatible value in us. Therefore, it was limited to ~72 min, which mas okay for most purposes, except configurable MRT dump periods. Thanks to Felix Friedlander for the bugreport. --- lib/timer.c | 4 ++-- lib/timer.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/timer.c b/lib/timer.c index c47e0bbc..92da5061 100644 --- a/lib/timer.c +++ b/lib/timer.c @@ -110,9 +110,9 @@ tm_dump(resource *r) if (t->randomize) debug("rand %d, ", t->randomize); if (t->recurrent) - debug("recur %d, ", t->recurrent); + debug("recur %ld, ", t->recurrent); if (t->expires) - debug("expires in %d ms)\n", (t->expires - current_time()) TO_MS); + debug("expires in %ld ms)\n", (t->expires - current_time()) TO_MS); else debug("inactive)\n"); } diff --git a/lib/timer.h b/lib/timer.h index 0f87852b..83ce34aa 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -22,8 +22,8 @@ typedef struct timer void *data; btime expires; /* 0=inactive */ + btime recurrent; /* Timer recurrence */ uint randomize; /* Amount of randomization */ - uint recurrent; /* Timer recurrence */ int index; } timer; @@ -72,7 +72,7 @@ tm_remains(timer *t) } static inline timer * -tm_new_init(pool *p, void (*hook)(struct timer *), void *data, uint rec, uint rand) +tm_new_init(pool *p, void (*hook)(struct timer *), void *data, btime rec, uint rand) { timer *t = tm_new(p); t->hook = hook;