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:
parent
34aeafbf9e
commit
59a5bf18f9
11
nest/cli.c
11
nest/cli.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 *);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user