]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Socket: pausing and restoring RX is a little bit more checked
authorMaria Matejka <mq@ucw.cz>
Tue, 24 Sep 2024 10:51:01 +0000 (12:51 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 17:55:57 +0000 (18:55 +0100)
lib/socket.h
proto/bgp/packets.c
sysdep/unix/io-loop.c
sysdep/unix/socket.c

index 52f2acec68b644607ae0f71fb621007c2e2f10b2..85aff84cc28c4b362688f04d8795ae8b7c1592c4 100644 (file)
@@ -58,6 +58,7 @@ typedef struct birdsock {
   uint fast_rx;                                /* RX has higher priority in event loop */
   uint rbsize;
   int (*rx_hook)(struct birdsock *, uint size); /* NULL=receiving turned off, returns 1 to clear rx buffer */
+  int (*rx_paused)(struct birdsock *, uint size); /* stored rx_hook when paused */
 
   byte *tbuf, *tpos;                   /* NULL=allocate automatically */
   byte *ttx;                           /* Internal */
@@ -65,6 +66,7 @@ typedef struct birdsock {
   void (*tx_hook)(struct birdsock *);
 
   void (*err_hook)(struct birdsock *, int); /* errno or zero if EOF */
+  void (*err_paused)(struct birdsock *, int); /* called first when paused */
 
   /* Information about received datagrams (UDP, RAW), valid in rx_hook */
   ip_addr faddr, laddr;                        /* src (From) and dst (Local) address of the datagram */
@@ -98,7 +100,7 @@ int sk_send(sock *, uint len);               /* Send data, <0=err, >0=ok, 0=sleep */
 int sk_send_to(sock *, uint len, ip_addr to, uint port); /* sk_send to given destination */
 void sk_reallocate(sock *);            /* Free and allocate tbuf & rbuf */
 void sk_pause_rx(struct birdloop *loop, sock *s);
-void sk_resume_rx(struct birdloop *loop, sock *s, int (*hook)(sock *, uint));
+void sk_resume_rx(struct birdloop *loop, sock *s);
 void sk_set_rbsize(sock *s, uint val); /* Resize RX buffer */
 void sk_set_tbsize(sock *s, uint val); /* Resize TX buffer, keeping content */
 void sk_set_tbuf(sock *s, void *tbuf); /* Switch TX buffer, NULL-> return to internal */
index 3d8a04a3e0186429ca631c437d0f0c9c0ab58f85..25d0d610fdd69f48313c0744aa50345f0f5bedbb 100644 (file)
@@ -3520,7 +3520,7 @@ bgp_do_uncork(callback *cb)
   {
     struct birdsock *sk = p->conn->sk;
     ASSERT_DIE(sk->rpos > sk->rbuf);
-    sk_resume_rx(p->p.loop, sk, bgp_rx);
+    sk_resume_rx(p->p.loop, sk);
     bgp_rx(sk, sk->rpos - sk->rbuf);
     BGP_TRACE(D_PACKETS, "Uncorked");
   }
index bef177149e181aa1fd9c54bf1223ad568ba40606..3f9c3fd9b8eaf92a8979797a2197891cc15bb3ea 100644 (file)
@@ -460,16 +460,21 @@ void
 sk_pause_rx(struct birdloop *loop, sock *s)
 {
   ASSERT_DIE(birdloop_inside(loop));
+  ASSERT_DIE(!s->rx_paused);
+  ASSERT_DIE(s->rx_hook);
+  s->rx_paused = s->rx_hook;
   s->rx_hook = NULL;
   socket_changed(s);
 }
 
 void
-sk_resume_rx(struct birdloop *loop, sock *s, int (*hook)(sock *, uint))
+sk_resume_rx(struct birdloop *loop, sock *s)
 {
   ASSERT_DIE(birdloop_inside(loop));
-  ASSERT_DIE(hook);
-  s->rx_hook = hook;
+  ASSERT_DIE(s->rx_paused);
+  ASSERT_DIE(!s->rx_hook);
+  s->rx_hook = s->rx_paused;
+  s->rx_paused = NULL;
   socket_changed(s);
 }
 
index b789f8fdd737635f8d8a4482eb0e5e415012fa47..c43260214fe5ee613c42d0ac6cb32e914b009c05 100644 (file)
@@ -940,6 +940,9 @@ sk_setup(sock *s)
 static void
 sk_err_hook(sock *s, int e)
 {
+  if (s->rx_paused)
+    CALL(s->err_paused, s, e);
+
   s->err_hook(s, e);
 }