* Internal backend socket protocol changed: uint32_t session-id added, see clixon_proto.h

* * Changed session-id handing. Instead of using pid of peer process, a proper session id generated by the server is used, following RFC6241.
This commit is contained in:
Olof hagsand 2019-10-19 19:52:09 +02:00
parent a387c599e2
commit b624e911b8
23 changed files with 230 additions and 155 deletions

View file

@ -51,8 +51,8 @@
*/
/* Struct per database in hash */
typedef struct {
int de_pid;
cxobj *de_xml; /* cache */
uint32_t de_id; /* session id */
cxobj *de_xml; /* cache */
} db_elmnt;
/*
@ -98,4 +98,7 @@ 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);
int clicon_session_id_set(clicon_handle h, uint32_t id);
uint32_t clicon_session_id_get(clicon_handle h);
#endif /* _CLIXON_DATA_H_ */

View file

@ -57,10 +57,10 @@ int xmldb_get0_clear(clicon_handle h, cxobj *x);
int xmldb_get0_free(clicon_handle h, cxobj **xp);
int xmldb_put(clicon_handle h, const char *db, enum operation_type op, cxobj *xt, char *username, cbuf *cbret); /* in clixon_datastore_write.[ch] */
int xmldb_copy(clicon_handle h, const char *from, const char *to);
int xmldb_lock(clicon_handle h, const char *db, int pid);
int xmldb_lock(clicon_handle h, const char *db, uint32_t id);
int xmldb_unlock(clicon_handle h, const char *db);
int xmldb_unlock_all(clicon_handle h, int pid);
int xmldb_islocked(clicon_handle h, const char *db);
int xmldb_unlock_all(clicon_handle h, uint32_t id);
uint32_t xmldb_islocked(clicon_handle h, const char *db);
int xmldb_exists(clicon_handle h, const char *db);
int xmldb_delete(clicon_handle h, const char *db);
int xmldb_create(clicon_handle h, const char *db);

View file

@ -51,8 +51,9 @@ enum format_enum{
/* Protocol message header */
struct clicon_msg {
uint32_t op_len; /* length of message. network byte order. */
char op_body[0]; /* rest of message, actual data */
uint32_t op_len; /* length of message. network byte order. */
uint32_t op_id; /* session-id. network byte order. */
char op_body[0]; /* rest of message, actual data */
};
/*
@ -62,11 +63,11 @@ char *format_int2str(enum format_enum showas);
enum format_enum format_str2int(char *str);
#if defined(__GNUC__) && __GNUC__ >= 3
struct clicon_msg *clicon_msg_encode(char *format, ...) __attribute__ ((format (printf, 1, 2)));
struct clicon_msg *clicon_msg_encode(uint32_t id, char *format, ...) __attribute__ ((format (printf, 2, 3)));
#else
struct clicon_msg *clicon_msg_encode(char *format, ...);
struct clicon_msg *clicon_msg_encode(uint32_t id, char *format, ...);
#endif
int clicon_msg_decode(struct clicon_msg *msg, yang_stmt *yspec, cxobj **xml);
int clicon_msg_decode(struct clicon_msg *msg, yang_stmt *yspec, uint32_t *id, cxobj **xml);
int clicon_connect_unix(char *sockpath);
@ -87,7 +88,7 @@ int clicon_msg_send(int s, struct clicon_msg *msg);
int clicon_msg_rcv(int s, struct clicon_msg **msg, int *eof);
int send_msg_notify_xml(int s, cxobj *xev);
int send_msg_notify_xml(clicon_handle h, int s, cxobj *xev);
int send_msg_reply(int s, char *data, uint32_t datalen);

View file

@ -54,7 +54,7 @@ int clicon_rpc_lock(clicon_handle h, char *db);
int clicon_rpc_unlock(clicon_handle h, char *db);
int clicon_rpc_get(clicon_handle h, char *xpath, cvec *nsc, netconf_content content, int32_t depth, cxobj **xret);
int clicon_rpc_close_session(clicon_handle h);
int clicon_rpc_kill_session(clicon_handle h, int session_id);
int clicon_rpc_kill_session(clicon_handle h, uint32_t session_id);
int clicon_rpc_validate(clicon_handle h, char *db);
int clicon_rpc_commit(clicon_handle h);
int clicon_rpc_discard_changes(clicon_handle h);

View file

@ -495,3 +495,35 @@ clicon_db_elmnt_set(clicon_handle h,
return -1;
return 0;
}
/*! Get session id
* @param[in] h Clicon handle
* @retval id Session identifier
* Two uses: the backend assigns session-id for clients.
*/
uint32_t
clicon_session_id_get(clicon_handle h)
{
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;
}
/*! Set session id
* @param[in] h Clicon handle
* @param[in] id Session id
* @retval 0 OK
* @retval -1 Error
*/
int
clicon_session_id_set(clicon_handle h,
uint32_t id)
{
clicon_hash_t *cdat = clicon_data(h);
clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t));
return 0;
}

View file

@ -254,30 +254,29 @@ xmldb_copy(clicon_handle h,
/*! Lock database
* @param[in] h Clicon handle
* @param[in] db Database
* @param[in] pid Process id
* @param[in] id Session id
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_lock(clicon_handle h,
const char *db,
int pid)
uint32_t id)
{
db_elmnt *de = NULL;
db_elmnt de0 = {0,};
if ((de = clicon_db_elmnt_get(h, db)) != NULL)
de0 = *de;
de0.de_pid = pid;
de0.de_id = id;
clicon_db_elmnt_set(h, db, &de0);
clicon_debug(1, "%s: locked by %u", db, pid);
clicon_debug(1, "%s: locked by %u", db, id);
return 0;
}
/*! Unlock database
* @param[in] h Clicon handle
* @param[in] db Database
* @param[in] pid Process id
* @retval -1 Error
* @retval 0 OK
* Assume all sanity checks have been made
@ -289,21 +288,21 @@ xmldb_unlock(clicon_handle h,
db_elmnt *de = NULL;
if ((de = clicon_db_elmnt_get(h, db)) != NULL){
de->de_pid = 0;
de->de_id = 0;
clicon_db_elmnt_set(h, db, de);
}
return 0;
}
/*! Unlock all databases locked by pid (eg process dies)
/*! Unlock all databases locked by session-id (eg process dies)
* @param[in] h Clicon handle
* @param[in] pid Process / Session id
* @param[in] id Session id
* @retval -1 Error
* @retval 0 OK
*/
int
xmldb_unlock_all(clicon_handle h,
int pid)
uint32_t id)
{
int retval = -1;
char **keys = NULL;
@ -315,8 +314,8 @@ xmldb_unlock_all(clicon_handle h,
goto done;
for (i = 0; i < klen; i++)
if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL &&
de->de_pid == pid){
de->de_pid = 0;
de->de_id == id){
de->de_id = 0;
clicon_db_elmnt_set(h, keys[i], de);
}
retval = 0;
@ -333,7 +332,7 @@ xmldb_unlock_all(clicon_handle h,
* @retval 0 Not locked
* @retval >0 Id of locker
*/
int
uint32_t
xmldb_islocked(clicon_handle h,
const char *db)
{
@ -341,7 +340,7 @@ xmldb_islocked(clicon_handle h,
if ((de = clicon_db_elmnt_get(h, db)) == NULL)
return 0;
return de->de_pid;
return de->de_id;
}
/*! Check if db exists

View file

@ -122,14 +122,17 @@ format_str2int(char *str)
}
/*! Encode a clicon netconf message using variable argument lists
* @param[in] id Session id of client
* @param[in] format Variable agrument list format an XML netconf string
* @retval msg Clicon message to send to eg clicon_msg_send()
* @retval NULL Error
* @retval msg Clicon message to send to eg clicon_msg_send()
* @note if format includes %, they will be expanded according to printf rules.
* if this is a problem, use ("%s", xml) instaead of (xml)
* Notaly this may an issue of RFC 3896 encoded strings
*/
struct clicon_msg *
clicon_msg_encode(char *format, ...)
clicon_msg_encode(uint32_t id,
char *format, ...)
{
va_list args;
uint32_t xmllen;
@ -149,7 +152,8 @@ clicon_msg_encode(char *format, ...)
memset(msg, 0, len);
/* hdr */
msg->op_len = htonl(len);
msg->op_id = htonl(id);
/* body */
va_start(args, format);
vsnprintf(msg->op_body, xmllen, format, args);
@ -161,16 +165,21 @@ clicon_msg_encode(char *format, ...)
/*! Decode a clicon netconf message
* @param[in] msg CLICON msg
* @param[in] yspec Yang specification, (can be NULL)
* @param[out] id Session id
* @param[out] xml XML parse tree
*/
int
clicon_msg_decode(struct clicon_msg *msg,
yang_stmt *yspec,
uint32_t *id,
cxobj **xml)
{
int retval = -1;
char *xmlstr;
/* hdr */
if (id)
*id = ntohl(msg->op_id);
/* body */
xmlstr = msg->op_body;
clicon_debug(1, "%s %s", __FUNCTION__, xmlstr);
@ -569,13 +578,13 @@ send_msg_reply(int s,
* @see send_msg_notify_xml
*/
static int
send_msg_notify(int s,
char *event)
send_msg_notify(int s,
char *event)
{
int retval = -1;
struct clicon_msg *msg = NULL;
if ((msg=clicon_msg_encode("%s", event)) == NULL)
if ((msg=clicon_msg_encode(0, "%s", event)) == NULL)
goto done;
if (clicon_msg_send(s, msg) < 0)
goto done;
@ -596,8 +605,9 @@ send_msg_notify(int s,
* @see send_msg_notify XXX beauty contest
*/
int
send_msg_notify_xml(int s,
cxobj *xev)
send_msg_notify_xml(clicon_handle h,
int s,
cxobj *xev)
{
int retval = -1;
cbuf *cb = NULL;

View file

@ -174,7 +174,7 @@ clicon_rpc_netconf(clicon_handle h,
int retval = -1;
struct clicon_msg *msg = NULL;
if ((msg = clicon_msg_encode("%s", xmlstr)) < 0)
if ((msg = clicon_msg_encode(clicon_session_id_get(h), "%s", xmlstr)) < 0)
goto done;
if (clicon_rpc_msg(h, msg, xret, sp) < 0)
goto done;
@ -318,7 +318,8 @@ clicon_rpc_get_config(clicon_handle h,
cprintf(cb, "/>");
}
cprintf(cb, "</get-config></rpc>");
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -384,7 +385,8 @@ clicon_rpc_edit_config(clicon_handle h,
if (xmlstr)
cprintf(cb, "%s", xmlstr);
cprintf(cb, "</edit-config></rpc>");
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -428,7 +430,8 @@ clicon_rpc_copy_config(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><copy-config><source><%s/></source><target><%s/></target></copy-config></rpc>",
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><copy-config><source><%s/></source><target><%s/></target></copy-config></rpc>",
username?username:"",
db1, db2)) == NULL)
goto done;
@ -468,7 +471,8 @@ clicon_rpc_delete_config(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>",
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>",
username?username:"", db)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@ -503,7 +507,8 @@ clicon_rpc_lock(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><lock><target><%s/></target></lock></rpc>",
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><lock><target><%s/></target></lock></rpc>",
username?username:"", db)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@ -538,7 +543,8 @@ clicon_rpc_unlock(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -634,7 +640,8 @@ clicon_rpc_get(clicon_handle h,
cprintf(cb, "/>");
}
cprintf(cb, "</get></rpc>");
if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"%s", cbuf_get(cb))) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -676,7 +683,8 @@ clicon_rpc_close_session(clicon_handle h)
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><close-session/></rpc>",
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><close-session/></rpc>",
username?username:"")) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@ -702,7 +710,7 @@ clicon_rpc_close_session(clicon_handle h)
*/
int
clicon_rpc_kill_session(clicon_handle h,
int session_id)
uint32_t session_id)
{
int retval = -1;
struct clicon_msg *msg = NULL;
@ -711,7 +719,8 @@ clicon_rpc_kill_session(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><kill-session><session-id>%d</session-id></kill-session></rpc>",
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><kill-session><session-id>%u</session-id></kill-session></rpc>",
username?username:"", session_id)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
@ -746,7 +755,8 @@ clicon_rpc_validate(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -778,7 +788,8 @@ clicon_rpc_commit(clicon_handle h)
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -810,7 +821,8 @@ clicon_rpc_discard_changes(clicon_handle h)
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;
@ -850,7 +862,8 @@ clicon_rpc_create_subscription(clicon_handle h,
char *username;
username = clicon_username_get(h);
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">"
"<stream>%s</stream>"
"<filter type=\"xpath\" select=\"%s\" />"
"</create-subscription></rpc>",
@ -890,7 +903,8 @@ clicon_rpc_debug(clicon_handle h,
username = clicon_username_get(h);
/* XXX: hardcoded example yang, should be clixon-config!!! */
if ((msg = clicon_msg_encode("<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == NULL)
if ((msg = clicon_msg_encode(clicon_session_id_get(h),
"<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == NULL)
goto done;
if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
goto done;