From cb38337c2b6f28cf56b29ffc2519012b7d342e61 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Fri, 24 Apr 2020 19:09:42 +0200 Subject: [PATCH] lib: stricly-prevent use of a connection used to watch events The protocol cannot handle received events mixed with regular messages. Once the connection is dedicated to a watch, prevent its regular use. --- src/lib/atom.c | 7 ++++++- src/lib/atom.h | 1 + src/lib/connection.c | 3 ++- src/lib/lldpctl.h | 6 ++++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/lib/atom.c b/src/lib/atom.c index f81d3bbc..54e94ae6 100644 --- a/src/lib/atom.c +++ b/src/lib/atom.c @@ -314,6 +314,10 @@ _lldpctl_do_something(lldpctl_conn_t *conn, { ssize_t rc; + if (conn->state == CONN_STATE_WATCHING) + /* The connection cannot be used anymore. */ + return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE); + if (conn->state == CONN_STATE_IDLE) { /* We need to build the message to send, then send * it. */ @@ -371,6 +375,7 @@ lldpctl_watch_callback(lldpctl_conn_t *conn, if (rc == 0) { conn->watch_cb = cb; conn->watch_data = data; + conn->state = CONN_STATE_WATCHING; } return rc; } @@ -382,7 +387,7 @@ lldpctl_watch(lldpctl_conn_t *conn) RESET_ERROR(conn); - if (conn->state != CONN_STATE_IDLE) + if (conn->state != CONN_STATE_WATCHING) return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE); conn->watch_triggered = 0; diff --git a/src/lib/atom.h b/src/lib/atom.h index a818f7ac..d6ae218f 100644 --- a/src/lib/atom.h +++ b/src/lib/atom.h @@ -54,6 +54,7 @@ struct lldpctl_conn_t { #define CONN_STATE_GET_CHASSIS_RECV 14 #define CONN_STATE_GET_DEFAULT_PORT_SEND 15 #define CONN_STATE_GET_DEFAULT_PORT_RECV 16 +#define CONN_STATE_WATCHING 17 int state; /* Current state */ /* Data attached to the state. It is used to check that we are using the * same data as a previous call until the state machine goes to diff --git a/src/lib/connection.c b/src/lib/connection.c index aa88dadf..191d7c6a 100644 --- a/src/lib/connection.c +++ b/src/lib/connection.c @@ -262,7 +262,8 @@ lldpctl_recv(lldpctl_conn_t *conn, const uint8_t *data, size_t length) return conn->input_buffer_len; } -int lldpctl_process_conn_buffer(lldpctl_conn_t *conn) +int +lldpctl_process_conn_buffer(lldpctl_conn_t *conn) { int rc; diff --git a/src/lib/lldpctl.h b/src/lib/lldpctl.h index c9f4d474..2369bf20 100644 --- a/src/lib/lldpctl.h +++ b/src/lib/lldpctl.h @@ -471,7 +471,8 @@ typedef enum { * reference to it, be sure to increment the reference count in the callback. * * @warning The provided connection should not be used at all. Do not use @c - * lldpctl_atom_set_*() functions on @c interface or @c neighbor either. + * lldpctl_atom_set_*() functions on @c interface or @c neighbor either. If you + * do, you will get a @c LLDPCTL_ERR_INVALID_STATE error. * * @see lldpctl_watch_callback */ @@ -494,7 +495,8 @@ typedef void (*lldpctl_change_callback)(lldpctl_conn_t *conn, * LLDPCTL_ERR_WOULDBLOCK. * * @warning Once a callback is registered, the connection shouldn't be used for - * anything else than receiving notifications. + * anything else than receiving notifications. If you do, you will get a @c + * LLDPCTL_ERR_INVALID_STATE error. */ int lldpctl_watch_callback(lldpctl_conn_t *conn, lldpctl_change_callback cb, -- 2.39.2