mod_netconf: reload hello message using ssh channel
create new netconf session to get current hello message
- refs #994
diff --git a/src/mod_netconf.c b/src/mod_netconf.c
index f3a8631..e9217a6 100644
--- a/src/mod_netconf.c
+++ b/src/mod_netconf.c
@@ -69,6 +69,8 @@
#include <libnetconf.h>
#include <libnetconf_ssh.h>
+struct nc_session *nc_session_connect_channel(struct nc_session *session, const struct nc_cpblts* cpblts);
+
#ifdef WITH_NOTIFICATIONS
#include "notification_module.h"
#endif
@@ -206,6 +208,38 @@
if (sid) json_object_object_add(err_reply, "session-id", json_object_new_string(sid));
}
+void prepare_status_message(struct session_with_mutex *s, struct nc_session *session)
+{
+ json_object *json_obj;
+ const char *cpbltstr;
+ struct nc_cpblts* cpblts = NULL;
+ if (s->hello_message != NULL) {
+ json_object_object_del(s->hello_message, NULL);
+ }
+ s->hello_message = json_object_new_object();
+ if (session != NULL) {
+ json_object_object_add(s->hello_message, "sid", json_object_new_string(nc_session_get_id(session)));
+ json_object_object_add(s->hello_message, "version", json_object_new_string((nc_session_get_version(session) == 0)?"1.0":"1.1"));
+ json_object_object_add(s->hello_message, "host", json_object_new_string(nc_session_get_host(session)));
+ json_object_object_add(s->hello_message, "port", json_object_new_string(nc_session_get_port(session)));
+ json_object_object_add(s->hello_message, "user", json_object_new_string(nc_session_get_user(session)));
+ cpblts = nc_session_get_cpblts (session);
+ if (cpblts != NULL) {
+ json_obj = json_object_new_array();
+ nc_cpblts_iter_start (cpblts);
+ while ((cpbltstr = nc_cpblts_iter_next (cpblts)) != NULL) {
+ json_object_array_add(json_obj, json_object_new_string(cpbltstr));
+ }
+ json_object_object_add(s->hello_message, "capabilities", json_obj);
+ }
+ } else {
+ json_object_object_add(s->hello_message, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(s->hello_message, "error-message", json_object_new_string("Invalid session identifier."));
+ }
+
+}
+
+
/**
* \defgroup netconf_operations NETCONF operations
* The list of NETCONF operations that mod_netconf supports.
@@ -247,6 +281,7 @@
}
locked_session->session = session;
locked_session->last_activity = apr_time_now();
+ locked_session->hello_message = NULL;
pthread_mutex_init (&locked_session->lock, NULL);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "Before session_lock");
/* get exclusive access to sessions_list (conns) */
@@ -261,6 +296,10 @@
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "Add connection to the list");
apr_hash_set(conns, apr_pstrdup(pool, session_key), APR_HASH_KEY_STRING, (void *) locked_session);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "Before session_unlock");
+
+ /* store information about session from hello message for future usage */
+ prepare_status_message(locked_session, session);
+
/* end of critical section */
if (pthread_rwlock_unlock (&session_lock) != 0) {
ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
@@ -292,6 +331,9 @@
apr_array_clear(locked_session->notifications);
pthread_mutex_destroy(&locked_session->lock);
ns = locked_session->session;
+ if (locked_session->hello_message != NULL) {
+ json_object_object_del(locked_session->hello_message, NULL);
+ }
free (locked_session);
}
if (ns != NULL) {
@@ -776,17 +818,16 @@
ssize_t buffer_len;
struct pollfd fds;
int status, buffer_size, ret;
- json_object *request, *reply, *json_obj, *capabilities;
+ json_object *request, *reply, *capabilities;
int operation;
int i, chunk_len, len = 0;
char* session_key, *data;
const char *host, *port, *user, *pass;
- const char *msgtext, *cpbltstr;
+ const char *msgtext;
const char *target, *source, *filter, *config, *defop, *erropt, *sid;
const char *identifier, *version, *format;
- struct nc_session *session = NULL;
- struct session_with_mutex * locked_session;
struct nc_cpblts* cpblts = NULL;
+ struct session_with_mutex * locked_session;
NC_DATASTORE ds_type_s, ds_type_t;
NC_EDIT_DEFOP_TYPE defop_type = NC_EDIT_DEFOP_NOTSET;
NC_EDIT_ERROPT_TYPE erropt_type = 0;
@@ -958,6 +999,7 @@
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "hash: %s", session_key);
}
+ /** \todo check if this is neccessary... probably leads to memory leaks */
reply = json_object_new_object();
if (session_key == NULL) {
/* negative reply */
@@ -1244,35 +1286,36 @@
json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
}
break;
- case MSG_INFO:
+ case MSG_RELOADHELLO:
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: get info about session %s", session_key);
locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
- if (locked_session != NULL) {
- session = locked_session->session;
- } else {
- session = NULL;
- }
- if (session != NULL) {
- json_object_object_add(reply, "sid", json_object_new_string(nc_session_get_id(session)));
- json_object_object_add(reply, "version", json_object_new_string((nc_session_get_version(session) == 0)?"1.0":"1.1"));
- json_object_object_add(reply, "host", json_object_new_string(nc_session_get_host(session)));
- json_object_object_add(reply, "port", json_object_new_string(nc_session_get_port(session)));
- json_object_object_add(reply, "user", json_object_new_string(nc_session_get_user(session)));
- cpblts = nc_session_get_cpblts (session);
- if (cpblts != NULL) {
- json_obj = json_object_new_array();
- nc_cpblts_iter_start (cpblts);
- while ((cpbltstr = nc_cpblts_iter_next (cpblts)) != NULL) {
- json_object_array_add(json_obj, json_object_new_string(cpbltstr));
- }
- json_object_object_add(reply, "capabilities", json_obj);
- }
+ if ((locked_session != NULL) && (locked_session->hello_message != NULL)) {
+ struct nc_session *temp_session = nc_session_connect_channel(locked_session->session, NULL);
+ prepare_status_message(locked_session, temp_session);
+ nc_session_close(temp_session, NC_SESSION_TERM_CLOSED);
} else {
json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
json_object_object_add(reply, "error-message", json_object_new_string("Invalid session identifier."));
+ break;
}
+ /* do NOT insert "break" here, we want to give new info back */;
+ case MSG_INFO:
+ if (operation != MSG_INFO) {
+ json_object_object_del(reply, NULL);
+ reply = locked_session->hello_message;
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: get info about session %s", session_key);
+ locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
+ if ((locked_session != NULL) && (locked_session->hello_message != NULL)) {
+ json_object_object_del(reply, NULL);
+ reply = locked_session->hello_message;
+ } else {
+ json_object_object_add(reply, "type", json_object_new_int(REPLY_ERROR));
+ json_object_object_add(reply, "error-message", json_object_new_string("Invalid session identifier."));
+ }
+ }
break;
case MSG_GENERIC:
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: generic request for session %s", session_key);