0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 02:01:55 +00:00

CLI closing fix when its action is run asynchronously.

Some CLI actions, notably "show route", are run by queuing an event
somewhere else. If the user closes the socket, in case such an action is
being executed, the CLI must free the socket immediately from the error
hook but the pool must remain until the asynchronous event finishes and
cleans everything up.
This commit is contained in:
Maria Matejka 2023-01-19 10:53:09 +01:00
parent 34aeafbf9e
commit 59a5bf18f9
4 changed files with 19 additions and 8 deletions

View File

@ -307,14 +307,14 @@ cli_event(void *data)
} }
cli * cli *
cli_new(void *priv) cli_new(struct birdsock *sock)
{ {
pool *p = rp_new(cli_pool, "CLI"); pool *p = rp_new(cli_pool, "CLI");
cli *c = mb_alloc(p, sizeof(cli)); cli *c = mb_alloc(p, sizeof(cli));
bzero(c, sizeof(cli)); bzero(c, sizeof(cli));
c->pool = p; c->pool = p;
c->priv = priv; c->sock = sock;
c->event = ev_new(p); c->event = ev_new(p);
c->event->hook = cli_event; c->event->hook = cli_event;
c->event->data = c; c->event->data = c;
@ -415,7 +415,12 @@ cli_free(cli *c)
if (c == cmd_reconfig_stored_cli) if (c == cmd_reconfig_stored_cli)
cmd_reconfig_stored_cli = NULL; cmd_reconfig_stored_cli = NULL;
if (!defer) if (defer)
{
rfree(c->sock);
c->sock = NULL;
}
else
rfree(c->pool); rfree(c->pool);
} }

View File

@ -28,7 +28,7 @@ struct cli_out {
typedef struct cli { typedef struct cli {
node n; /* Node in list of all log hooks */ node n; /* Node in list of all log hooks */
pool *pool; pool *pool;
void *priv; /* Private to sysdep layer */ struct birdsock *sock; /* Underlying socket */
byte *rx_buf, *rx_pos, *rx_aux; /* sysdep */ byte *rx_buf, *rx_pos, *rx_aux; /* sysdep */
struct cli_out *tx_buf, *tx_pos, *tx_write; struct cli_out *tx_buf, *tx_pos, *tx_write;
event *event; event *event;
@ -63,7 +63,7 @@ static inline void cli_separator(cli *c)
/* Functions provided to sysdep layer */ /* Functions provided to sysdep layer */
cli *cli_new(void *); cli *cli_new(struct birdsock *);
void cli_init(void); void cli_init(void);
void cli_free(cli *); void cli_free(cli *);
void cli_kick(cli *); void cli_kick(cli *);

View File

@ -233,6 +233,7 @@ static int
rt_show_cleanup(struct cli *c) rt_show_cleanup(struct cli *c)
{ {
struct rt_show_data *d = c->rover; struct rt_show_data *d = c->rover;
c->cleanup = NULL;
/* Cancel the feed */ /* Cancel the feed */
if (d->req.hook) if (d->req.hook)

View File

@ -395,7 +395,8 @@ static char *path_control_socket = PATH_CONTROL_SOCKET;
static void static void
cli_write(cli *c) cli_write(cli *c)
{ {
sock *s = c->priv; sock *s = c->sock;
ASSERT_DIE(c->sock);
while (c->tx_pos) while (c->tx_pos)
{ {
@ -419,7 +420,9 @@ cli_write(cli *c)
void void
cli_write_trigger(cli *c) cli_write_trigger(cli *c)
{ {
sock *s = c->priv; sock *s = c->sock;
if (!s)
return;
if (s->tbuf == NULL) if (s->tbuf == NULL)
cli_write(c); cli_write(c);
@ -434,7 +437,8 @@ cli_tx(sock *s)
int int
cli_get_command(cli *c) cli_get_command(cli *c)
{ {
sock *s = c->priv; sock *s = c->sock;
ASSERT_DIE(c->sock);
byte *t = c->rx_aux ? : s->rbuf; byte *t = c->rx_aux ? : s->rbuf;
byte *tend = s->rpos; byte *tend = s->rpos;
byte *d = c->rx_pos; byte *d = c->rx_pos;
@ -477,6 +481,7 @@ cli_err(sock *s, int err)
else else
log(L_INFO "CLI connection closed"); log(L_INFO "CLI connection closed");
} }
cli_free(s->data); cli_free(s->data);
} }