Debug: improved debug level 2 with socket-description, also for notification

This commit is contained in:
Olof hagsand 2023-11-01 13:02:32 +01:00
parent 71431dcd82
commit e9c5287c36
10 changed files with 102 additions and 53 deletions

View file

@ -89,44 +89,7 @@ ce_find_byid(struct client_entry *ce_list,
return NULL; return NULL;
} }
/*! Stream callback for netconf stream notification (RFC 5277) /*! Construct a client string description from client_entry information for logging
*
* @param[in] h Clixon handle
* @param[in] op 0:event, 1:rm
* @param[in] event Event as XML
* @param[in] arg Extra argument provided in stream_ss_add
* @see stream_ss_add
*/
int
ce_event_cb(clicon_handle h,
int op,
cxobj *event,
void *arg)
{
struct client_entry *ce = (struct client_entry *)arg;
clixon_debug(CLIXON_DBG_DEFAULT, "%s op:%d", __FUNCTION__, op);
switch (op){
case 1:
/* Risk of recursion here */
if (ce->ce_s)
backend_client_rm(h, ce);
break;
default:
if (send_msg_notify_xml(h, ce->ce_s, ce->ce_source_host, event) < 0){
if (errno == ECONNRESET || errno == EPIPE){
clicon_log(LOG_WARNING, "client %d reset", ce->ce_nr);
}
break;
}
/* note there may be other notifications than RFC5277 streams */
ce->ce_out_notifications++;
netconf_monitoring_counter_inc(h, "out-notifications");
}
return 0;
}
/*! Construct a client string from client_entry information for logging
* *
* @param[in] ce Client entry struct * @param[in] ce Client entry struct
* @param[out] cbp Cligen buffer, deallocate with cbuf_free * @param[out] cbp Cligen buffer, deallocate with cbuf_free
@ -134,7 +97,7 @@ ce_event_cb(clicon_handle h,
* @retval -1 Error * @retval -1 Error
*/ */
static int static int
ce_client_string(struct client_entry *ce, ce_client_descr(struct client_entry *ce,
cbuf **cbp) cbuf **cbp)
{ {
int retval = -1; int retval = -1;
@ -148,12 +111,11 @@ ce_client_string(struct client_entry *ce,
if ((cb = cbuf_new()) == NULL){ if ((cb = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new"); clicon_err(OE_UNIX, errno, "cbuf_new");
goto done; goto done;
} }
if (ce->ce_transport){ if (ce->ce_transport){
if (nodeid_split(ce->ce_transport, NULL, &id) < 0) if (nodeid_split(ce->ce_transport, NULL, &id) < 0)
goto done; goto done;
cprintf(cb, "%s", id); cprintf(cb, "%s:", id);
} }
cprintf(cb, "%u", ce->ce_id); cprintf(cb, "%u", ce->ce_id);
*cbp = cb; *cbp = cb;
@ -164,6 +126,54 @@ ce_client_string(struct client_entry *ce,
return retval; return retval;
} }
/*! Stream callback for netconf stream notification (RFC 5277)
*
* @param[in] h Clixon handle
* @param[in] op 0:event, 1:rm
* @param[in] event Event as XML
* @param[in] arg Extra argument provided in stream_ss_add
* @retval 0 OK
* @retval -1 Error
* @see stream_ss_add
*/
int
ce_event_cb(clicon_handle h,
int op,
cxobj *event,
void *arg)
{
int retval = -1;
struct client_entry *ce = (struct client_entry *)arg;
cbuf *cbce = NULL;
clixon_debug(CLIXON_DBG_DEFAULT, "%s op:%d", __FUNCTION__, op);
switch (op){
case 1:
/* Risk of recursion here */
if (ce->ce_s)
backend_client_rm(h, ce);
break;
default:
if (ce_client_descr(ce, &cbce) < 0)
goto done;
if (send_msg_notify_xml(h, ce->ce_s, cbuf_get(cbce), event) < 0){
if (errno == ECONNRESET || errno == EPIPE){
clicon_log(LOG_WARNING, "client %d reset", ce->ce_nr);
}
break;
}
/* note there may be other notifications than RFC5277 streams */
ce->ce_out_notifications++;
netconf_monitoring_counter_inc(h, "out-notifications");
}
retval = 0;
done:
if (cbce)
cbuf_free(cbce);
return retval;
}
/*! Unlock all db:s of a client and call user unlock calback /*! Unlock all db:s of a client and call user unlock calback
* *
* @see xmldb_unlock_all unlocks, but does not call user callbacks which is a backend thing * @see xmldb_unlock_all unlocks, but does not call user callbacks which is a backend thing
@ -290,6 +300,7 @@ backend_monitoring_state_get(clicon_handle h,
* @param[in] ce Client handle * @param[in] ce Client handle
* @retval 0 Ok * @retval 0 Ok
* @retval -1 Error (fatal) * @retval -1 Error (fatal)
* @see backend_client_add for adding
* @see backend_client_delete for actual deallocation of client entry struct * @see backend_client_delete for actual deallocation of client entry struct
*/ */
int int
@ -1628,7 +1639,18 @@ from_client_msg(clicon_handle h,
* 3. Its a create-subscription message that uses a separate socket(=client) * 3. Its a create-subscription message that uses a separate socket(=client)
*/ */
if (op_id != 0 && ce->ce_id != op_id && strcmp(rpcname, "create-subscription")){ if (op_id != 0 && ce->ce_id != op_id && strcmp(rpcname, "create-subscription")){
client_entry *ce0;
clixon_debug(CLIXON_DBG_DEFAULT, "%s Warning: incoming session-id:%u does not match ce_id:%u on socket: %d", __FUNCTION__, op_id, ce->ce_id, ce->ce_s); clixon_debug(CLIXON_DBG_DEFAULT, "%s Warning: incoming session-id:%u does not match ce_id:%u on socket: %d", __FUNCTION__, op_id, ce->ce_id, ce->ce_s);
/* Copy transport from orig client-entry */
if (ce->ce_transport == NULL &&
(ce0 = ce_find_byid(backend_client_list(h), op_id)) != NULL &&
ce0->ce_transport){
if ((ce->ce_transport = strdup(ce0->ce_transport)) == NULL){
clicon_err(OE_UNIX, errno, "strdup");
goto done;
}
}
} }
/* Note that this validation is also made in xml_yang_validate_rpc, but not for hello /* Note that this validation is also made in xml_yang_validate_rpc, but not for hello
*/ */
@ -1775,7 +1797,7 @@ from_client_msg(clicon_handle h,
// XXX clixon_debug(CLIXON_DBG_MSG, "Reply:%s", cbuf_get(cbret)); // XXX clixon_debug(CLIXON_DBG_MSG, "Reply:%s", cbuf_get(cbret));
/* XXX problem here is that cbret has not been parsed so may contain /* XXX problem here is that cbret has not been parsed so may contain
parse errors */ parse errors */
if (ce_client_string(ce, &cbce) < 0) if (ce_client_descr(ce, &cbce) < 0)
goto done; goto done;
if (send_msg_reply(ce->ce_s, cbuf_get(cbce), cbuf_get(cbret), cbuf_len(cbret)+1) < 0){ if (send_msg_reply(ce->ce_s, cbuf_get(cbce), cbuf_get(cbret), cbuf_len(cbret)+1) < 0){
switch (errno){ switch (errno){
@ -1843,7 +1865,7 @@ from_client(int s,
clicon_err(OE_NETCONF, EINVAL, "Internal error: s != ce->ce_s"); clicon_err(OE_NETCONF, EINVAL, "Internal error: s != ce->ce_s");
goto done; goto done;
} }
if (ce_client_string(ce, &cbce) < 0) if (ce_client_descr(ce, &cbce) < 0)
goto done; goto done;
if (clicon_msg_rcv(ce->ce_s, cbuf_get(cbce), 0, &msg, &eof) < 0) if (clicon_msg_rcv(ce->ce_s, cbuf_get(cbce), 0, &msg, &eof) < 0)
goto done; goto done;

View file

@ -828,7 +828,9 @@ from_client_commit(clicon_handle h,
goto done; goto done;
goto ok; goto ok;
} }
if (ret == 1) if (ret == 0)
clixon_debug(CLIXON_DBG_DEFAULT, "Commit candidate failed");
else
cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE); cprintf(cbret, "<rpc-reply xmlns=\"%s\"><ok/></rpc-reply>", NETCONF_BASE_NAMESPACE);
ok: ok:
retval = 0; retval = 0;
@ -929,7 +931,7 @@ from_client_validate(clicon_handle h,
/*! Restart specific backend plugins without full backend restart /*! Restart specific backend plugins without full backend restart
* *
* Note, depending on plugin callbacks, there may be other dependencies which may make this * @note, depending on plugin callbacks, there may be other dependencies which may make this
* difficult in the general case. * difficult in the general case.
*/ */
int int

View file

@ -53,6 +53,7 @@
* client socket and a separate notification client socket. * client socket and a separate notification client socket.
* But they are the same session. * But they are the same session.
* But the clixon client-entry do not differentiate * But the clixon client-entry do not differentiate
* @see backend_client_add
*/ */
struct client_entry{ struct client_entry{
struct client_entry *ce_next; /* The clients linked list */ struct client_entry *ce_next; /* The clients linked list */

View file

@ -101,7 +101,11 @@ struct backend_handle {
clicon_handle clicon_handle
backend_handle_init(void) backend_handle_init(void)
{ {
return clicon_handle_init0(sizeof(struct backend_handle)); struct backend_handle *bh;
bh = (struct backend_handle *)clicon_handle_init0(sizeof(struct backend_handle));
bh->bh_ce_nr = 1; /* To align with session-id */
return (clicon_handle)bh;
} }
/*! Deallocates a backend handle, including all client structs /*! Deallocates a backend handle, including all client structs

View file

@ -1377,7 +1377,6 @@ restconf_ssl_accept_client(clicon_handle h,
*/ */
if (restconf_auth_type_get(h) == CLIXON_AUTH_CLIENT_CERTIFICATE){ if (restconf_auth_type_get(h) == CLIXON_AUTH_CLIENT_CERTIFICATE){
X509 *peercert; X509 *peercert;
// XXX SSL_get1_peer_certificate(ssl)
#if OPENSSL_VERSION_NUMBER < 0x30000000L #if OPENSSL_VERSION_NUMBER < 0x30000000L
if ((peercert = SSL_get_peer_certificate(rc->rc_ssl)) != NULL){ if ((peercert = SSL_get_peer_certificate(rc->rc_ssl)) != NULL){
X509_free(peercert); X509_free(peercert);

14
example/main/autocli.xml Normal file
View file

@ -0,0 +1,14 @@
<clixon-config xmlns="http://clicon.org/config">
<autocli>
<module-default>false</module-default>
<list-keyword-default>kw-nokey</list-keyword-default>
<treeref-state-default>false</treeref-state-default>
<edit-mode-default>list container</edit-mode-default>
<completion-default>true</completion-default>
<rule>
<name>include clixon-example</name>
<module-name>clixon-example</module-name>
<operation>enable</operation>
</rule>
</autocli>
</clixon-config>

View file

@ -0,0 +1,7 @@
<clixon-config xmlns="http://clicon.org/config">
<restconf>
<enable>true</enable>
<auth-type>none</auth-type>
<socket><namespace>default</namespace><address>0.0.0.0</address><port>80</port><ssl>false</ssl></socket>
</restconf>
</clixon-config>

View file

@ -128,7 +128,7 @@ for op in begin validate complete commit commit_done end; do
done done
# Negative test: restart a plugin that does not exist # Negative test: restart a plugin that does not exist
new "Send restart to nonexistatn plugin expect fail" new "Send restart to nonexisting plugin expect fail"
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><restart-plugin $LIBNS><plugin>xxx</plugin></restart-plugin></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>plugin</bad-element></error-info><error-severity>error</error-severity><error-message>No such plugin</error-message></rpc-error></rpc-reply>" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><restart-plugin $LIBNS><plugin>xxx</plugin></restart-plugin></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>plugin</bad-element></error-info><error-severity>error</error-severity><error-message>No such plugin</error-message></rpc-error></rpc-reply>"
if [ $BE -ne 0 ]; then if [ $BE -ne 0 ]; then

View file

@ -185,7 +185,7 @@ module clixon-lib {
} }
identity restconf { identity restconf {
description description
"RESTCONF either as HTTP/1 or /2, TLS or not, reverese proxy (eg fcgi/nginx) or native"; "RESTCONF either as HTTP/1 or /2, TLS or not, reverse proxy (eg fcgi/nginx) or native";
base ncm:transport; base ncm:transport;
} }
identity cli { identity cli {