all CHANGE larger api change to enable server stats collecting
All the information required by ietf-netconf-monitoring
model can now be collected.
diff --git a/src/session_server_ssh.c b/src/session_server_ssh.c
index d59e87a..409a83b 100644
--- a/src/session_server_ssh.c
+++ b/src/session_server_ssh.c
@@ -1005,8 +1005,6 @@
return 0;
}
-/* ret 0 - timeout, 1 channel has data, 2 some other channel has data,
- * 3 status change, 4 new SSH message, 5 new NETCONF SSH channel, -1 error */
int
nc_ssh_pollin(struct nc_session *session, int timeout)
{
@@ -1015,8 +1013,10 @@
ret = nc_timedlock(session->ti_lock, timeout);
- if (ret != 1) {
- return ret;
+ if (ret < 0) {
+ return NC_PSPOLL_ERROR;
+ } else if (!ret) {
+ return NC_PSPOLL_TIMEOUT;
}
ret = ssh_execute_message_callbacks(session->ti.libssh.session);
@@ -1027,7 +1027,7 @@
ssh_get_error(session->ti.libssh.session));
session->status = NC_STATUS_INVALID;
session->term_reason = NC_SESSION_TERM_OTHER;
- return 3;
+ return NC_PSPOLL_SESSION_TERM | NC_PSPOLL_SESSION_ERROR;
}
/* new SSH message */
@@ -1038,38 +1038,38 @@
if ((new->status == NC_STATUS_STARTING) && new->ti.libssh.channel
&& (new->flags & NC_SESSION_SSH_SUBSYS_NETCONF)) {
/* new NETCONF SSH channel */
- return 5;
+ return NC_PSPOLL_SSH_CHANNEL;
}
}
}
/* just some SSH message */
- return 4;
+ return NC_PSPOLL_SSH_MSG;
}
/* no new SSH message, maybe NETCONF data? */
ret = ssh_channel_poll_timeout(session->ti.libssh.channel, 0, 0);
/* not this one */
if (!ret) {
- return 2;
+ return NC_PSPOLL_PENDING;
} else if (ret == SSH_ERROR) {
ERR("Session %u: SSH channel error (%s).", session->id,
ssh_get_error(session->ti.libssh.session));
session->status = NC_STATUS_INVALID;
session->term_reason = NC_SESSION_TERM_OTHER;
- return 3;
+ return NC_PSPOLL_SESSION_TERM | NC_PSPOLL_SESSION_ERROR;
} else if (ret == SSH_EOF) {
ERR("Session %u: communication channel unexpectedly closed (libssh).",
session->id);
session->status = NC_STATUS_INVALID;
session->term_reason = NC_SESSION_TERM_DROPPED;
- return 3;
+ return NC_PSPOLL_SESSION_TERM | NC_PSPOLL_SESSION_ERROR;
}
- return 1;
+ return NC_PSPOLL_RPC;
}
-API int
+API NC_MSG_TYPE
nc_connect_callhome_ssh(const char *host, uint16_t port, struct nc_session **session)
{
return nc_connect_callhome(host, port, NC_TI_LIBSSH, session);
@@ -1170,23 +1170,77 @@
return 1;
}
-API int
+API NC_MSG_TYPE
+nc_session_accept_ssh_channel(struct nc_session *orig_session, struct nc_session **session)
+{
+ NC_MSG_TYPE msgtype;
+ struct nc_session *new_session = NULL;
+
+ if (!orig_session) {
+ ERRARG("orig_session");
+ return NC_MSG_ERROR;
+ } else if (!session) {
+ ERRARG("session");
+ return NC_MSG_ERROR;
+ }
+
+ if ((orig_session->status == NC_STATUS_RUNNING) && (orig_session->ti_type == NC_TI_LIBSSH)
+ && orig_session->ti.libssh.next) {
+ for (new_session = orig_session->ti.libssh.next;
+ new_session != orig_session;
+ new_session = new_session->ti.libssh.next) {
+ if ((new_session->status == NC_STATUS_STARTING) && new_session->ti.libssh.channel
+ && (new_session->flags & NC_SESSION_SSH_SUBSYS_NETCONF)) {
+ /* we found our session */
+ break;
+ }
+ }
+ if (new_session == orig_session) {
+ new_session = NULL;
+ }
+ }
+
+ if (!new_session) {
+ ERR("Session does not have a NETCONF SSH channel ready.");
+ return NC_MSG_ERROR;
+ }
+
+ /* assign new SID atomically */
+ pthread_spin_lock(&server_opts.sid_lock);
+ new_session->id = server_opts.new_session_id++;
+ pthread_spin_unlock(&server_opts.sid_lock);
+
+ /* NETCONF handshake */
+ msgtype = nc_handshake(new_session);
+ if (msgtype != NC_MSG_HELLO) {
+ return msgtype;
+ }
+
+ new_session->session_start = time(NULL);
+ new_session->status = NC_STATUS_RUNNING;
+ *session = new_session;
+
+ return msgtype;
+}
+
+API NC_MSG_TYPE
nc_ps_accept_ssh_channel(struct nc_pollsession *ps, struct nc_session **session)
{
+ NC_MSG_TYPE msgtype;
struct nc_session *new_session = NULL;
uint16_t i;
if (!ps) {
ERRARG("ps");
- return -1;
+ return NC_MSG_ERROR;
} else if (!session) {
ERRARG("session");
- return -1;
+ return NC_MSG_ERROR;
}
/* LOCK */
if (nc_ps_lock(ps)) {
- return -1;
+ return NC_MSG_ERROR;
}
for (i = 0; i < ps->session_count; ++i) {
@@ -1215,7 +1269,7 @@
if (!new_session) {
ERR("No session with a NETCONF SSH channel ready was found.");
- return -1;
+ return NC_MSG_ERROR;
}
/* assign new SID atomically */
@@ -1224,13 +1278,14 @@
pthread_spin_unlock(&server_opts.sid_lock);
/* NETCONF handshake */
- if (nc_handshake(new_session)) {
- return -1;
+ msgtype = nc_handshake(new_session);
+ if (msgtype != NC_MSG_HELLO) {
+ return msgtype;
}
new_session->session_start = time(NULL);
new_session->status = NC_STATUS_RUNNING;
*session = new_session;
- return 0;
+ return msgtype;
}