diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddcc3088..4dd90f3c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@
Patch release based on testing by Dave Cornejo, Netgate
+### Minor changes
+* Session-id CLI functionality delayed: "lazy evaluation"
+ * From a cli perspective this is a revert to 4.1 behaviour, where the cli does not immediately exit on start if the backend is not running, but with the new session-id function
+
### Corrected Bugs
* Compile option `VALIDATE_STATE_XML` introduced in `include/custom.h` to control whether code for state data validation is compiled or not.
* Fixed: Validation of user state data led to wrong validation, if state relied on config data, eg leafref/must/when etc.
diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c
index 59605028..b2ddf5f3 100644
--- a/apps/backend/backend_client.c
+++ b/apps/backend/backend_client.c
@@ -1426,11 +1426,15 @@ from_client_hello(clicon_handle h,
int retval = -1;
uint32_t id;
- id = clicon_session_id_get(h);
+ if (clicon_session_id_get(h, &id) < 0){
+ clicon_err(OE_DAEMON, ENOENT, "session_id not set");
+ goto done;
+ }
id++;
clicon_session_id_set(h, id);
cprintf(cbret, "%u", id);
retval = 0;
+ done:
return retval;
}
diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c
index 9f0510b3..9cd860c0 100644
--- a/apps/cli/cli_main.c
+++ b/apps/cli/cli_main.c
@@ -286,7 +286,6 @@ main(int argc, char **argv)
char *str;
int tabmode;
char *dir;
- uint32_t id = 0;
cvec *nsctx_global = NULL; /* Global namespace context */
/* Defaults */
@@ -605,17 +604,8 @@ main(int argc, char **argv)
}
/* Go into event-loop unless -1 command-line */
- if (!once){
- /* Send hello request to backend to get session-id back
- * This is done once at the beginning of the session and then this is
- * used by the client, even though new TCP sessions are created for
- * each message sent to the backend.
- */
- if (clicon_hello_req(h, &id) < 0)
- goto done;
- clicon_session_id_set(h, id);
+ if (!once)
retval = cli_interactive(h);
- }
else
retval = 0;
done:
diff --git a/configure b/configure
index 96f910f7..67a83c0b 100755
--- a/configure
+++ b/configure
@@ -2173,8 +2173,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
CLIXON_VERSION_MAJOR="4"
CLIXON_VERSION_MINOR="3"
-CLIXON_VERSION_PATCH="1"
-CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\""
+CLIXON_VERSION_PATCH="2"
+CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}.PRE\""
# Check CLIgen
if test "$prefix" = "NONE"; then
diff --git a/configure.ac b/configure.ac
index 42dacdd7..b7d0ef04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -44,8 +44,8 @@ AC_INIT(lib/clixon/clixon.h.in)
CLIXON_VERSION_MAJOR="4"
CLIXON_VERSION_MINOR="3"
-CLIXON_VERSION_PATCH="1"
-CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\""
+CLIXON_VERSION_PATCH="2"
+CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}.PRE\""
# Check CLIgen
if test "$prefix" = "NONE"; then
diff --git a/lib/clixon/clixon_data.h b/lib/clixon/clixon_data.h
index a541beac..43d7b934 100644
--- a/lib/clixon/clixon_data.h
+++ b/lib/clixon/clixon_data.h
@@ -98,7 +98,8 @@ int clicon_xml_changelog_set(clicon_handle h, cxobj *xchlog);
int clicon_argv_get(clicon_handle h, int *argc, char ***argv);
int clicon_argv_set(clicon_handle h, char *argv0, int argc, char **argv);
+/*! Set and get (client/backend) session id */
int clicon_session_id_set(clicon_handle h, uint32_t id);
-uint32_t clicon_session_id_get(clicon_handle h);
+int clicon_session_id_get(clicon_handle h, uint32_t *id);
#endif /* _CLIXON_DATA_H_ */
diff --git a/lib/src/clixon_data.c b/lib/src/clixon_data.c
index 2e11bd2b..6ddc3d5e 100644
--- a/lib/src/clixon_data.c
+++ b/lib/src/clixon_data.c
@@ -579,19 +579,24 @@ clicon_db_elmnt_set(clicon_handle h,
}
/*! Get session id
- * @param[in] h Clicon handle
- * @retval id Session identifier
- * Two uses: the backend assigns session-id for clients.
+ * @param[in] h Clicon handle
+ * @param[out] sid Session identifier
+ * @retval 0 OK
+ * @retval -1 Session id not set
+ * Session-ids survive TCP sessions that are created for each message sent to the backend.
+ * The backend assigns session-id for clients: backend assigns, clients get it from backend.
*/
-uint32_t
-clicon_session_id_get(clicon_handle h)
+int
+clicon_session_id_get(clicon_handle h,
+ uint32_t *id)
{
clicon_hash_t *cdat = clicon_data(h);
void *p;
if ((p = clicon_hash_value(cdat, "session-id", NULL)) == NULL)
- return 0;
- return *(uint32_t*)p;
+ return -1;
+ *id = *(uint32_t*)p;
+ return 0;
}
/*! Set session id
@@ -599,6 +604,7 @@ clicon_session_id_get(clicon_handle h)
* @param[in] id Session id
* @retval 0 OK
* @retval -1 Error
+ * Session-ids survive TCP sessions that are created for each message sent to the backend.
*/
int
clicon_session_id_set(clicon_handle h,
diff --git a/lib/src/clixon_proto_client.c b/lib/src/clixon_proto_client.c
index 85d60d16..bdd87f0f 100644
--- a/lib/src/clixon_proto_client.c
+++ b/lib/src/clixon_proto_client.c
@@ -151,6 +151,34 @@ clicon_rpc_msg(clicon_handle h,
return retval;
}
+/*! Check if there is a valid (cached) session-id. If not, send a hello request to backend
+ * Session-ids survive TCP sessions that are created for each message sent to the backend.
+ * Clients use two approaches, either:
+ * (1) Once at the beginning of the session. Netconf and restconf does this
+ * (2) First usage, ie "lazy" evaluation when first needed
+ * @param[in] h clicon handle
+ * @param[out] session_id Session id
+ * @retval 0 OK and session_id set
+ * @retval -1 Error
+ */
+static int
+session_id_check(clicon_handle h,
+ uint32_t *session_id)
+{
+ int retval = -1;
+ uint32_t id;
+
+ if (clicon_session_id_get(h, &id) < 0){ /* Not set yet */
+ if (clicon_hello_req(h, &id) < 0)
+ goto done;
+ clicon_session_id_set(h, id);
+ }
+ retval = 0;
+ *session_id = id;
+ done:
+ return retval;
+}
+
/*! Generic xml netconf clicon rpc
* Want to go over to use netconf directly between client and server,...
* @param[in] h clicon handle
@@ -172,9 +200,12 @@ clicon_rpc_netconf(clicon_handle h,
int *sp)
{
int retval = -1;
+ uint32_t session_id;
struct clicon_msg *msg = NULL;
- if ((msg = clicon_msg_encode(clicon_session_id_get(h), "%s", xmlstr)) < 0)
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
+ if ((msg = clicon_msg_encode(session_id, "%s", xmlstr)) < 0)
goto done;
if (clicon_rpc_msg(h, msg, xret, sp) < 0)
goto done;
@@ -305,7 +336,10 @@ clicon_rpc_get_config(clicon_handle h,
cxobj *xd;
cg_var *cv = NULL;
char *prefix;
+ uint32_t session_id;
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
if ((cb = cbuf_new()) == NULL)
goto done;
cprintf(cb, "");
}
cprintf(cb, "");
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
- "%s", cbuf_get(cb))) == NULL)
+ if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@@ -383,7 +416,10 @@ clicon_rpc_edit_config(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
if ((cb = cbuf_new()) == NULL)
goto done;
cprintf(cb, "");
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
- "%s", cbuf_get(cb))) == NULL)
+ if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@@ -439,10 +474,13 @@ clicon_rpc_copy_config(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
- "<%s/><%s/>",
+ if ((msg = clicon_msg_encode(session_id,
+ "<%s/><%s/>",
username?username:"",
db1, db2)) == NULL)
goto done;
@@ -480,9 +518,12 @@ clicon_rpc_delete_config(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"<%s/>none",
username?username:"", db)) == NULL)
goto done;
@@ -516,9 +557,12 @@ clicon_rpc_lock(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"<%s/>",
username?username:"", db)) == NULL)
goto done;
@@ -552,9 +596,12 @@ clicon_rpc_unlock(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"<%s/>", username?username:"", db)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@@ -621,7 +668,10 @@ clicon_rpc_get(clicon_handle h,
char *username;
cg_var *cv = NULL;
char *prefix;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
if ((cb = cbuf_new()) == NULL)
goto done;
cprintf(cb, "");
}
cprintf(cb, "");
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@@ -692,9 +742,12 @@ clicon_rpc_close_session(clicon_handle h)
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"",
username?username:"")) == NULL)
goto done;
@@ -728,9 +781,12 @@ clicon_rpc_kill_session(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t my_session_id; /* Not the one to kill */
+
+ if (session_id_check(h, &my_session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(my_session_id,
"%u",
username?username:"", session_id)) == NULL)
goto done;
@@ -764,9 +820,12 @@ clicon_rpc_validate(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"<%s/>", username?username:"", db)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@@ -797,9 +856,12 @@ clicon_rpc_commit(clicon_handle h)
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"", username?username:"")) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@@ -830,9 +892,12 @@ clicon_rpc_discard_changes(clicon_handle h)
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"", username?username:"")) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@@ -871,9 +936,12 @@ clicon_rpc_create_subscription(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
""
"%s"
""
@@ -911,9 +979,12 @@ clicon_rpc_debug(clicon_handle h,
cxobj *xret = NULL;
cxobj *xerr;
char *username;
-
+ uint32_t session_id;
+
+ if (session_id_check(h, &session_id) < 0)
+ goto done;
username = clicon_username_get(h);
- if ((msg = clicon_msg_encode(clicon_session_id_get(h),
+ if ((msg = clicon_msg_encode(session_id,
"%d", username?username:"", level)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
diff --git a/test/test_sock.sh b/test/test_sock.sh
index ca702790..ceeef78c 100755
--- a/test/test_sock.sh
+++ b/test/test_sock.sh
@@ -64,10 +64,10 @@ EOF
expectfn "$clixon_cli -1f $cfg show version" 0 "$version."
new "hello session-id 2"
- expecteof "$clixon_util_socket -a $family -s $sock -D $DBG" 0 "" "2"
+ expecteof "$clixon_util_socket -a $family -s $sock -D $DBG" 0 "" "3"
new "hello session-id 2"
- expecteof "$clixon_util_socket -a $family -s $sock -D $DBG" 0 "" "3"
+ expecteof "$clixon_util_socket -a $family -s $sock -D $DBG" 0 "" "4"
if [ $BE -ne 0 ]; then
new "Kill backend"