* 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:
parent
a387c599e2
commit
b624e911b8
23 changed files with 230 additions and 155 deletions
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue