session CHANGE always store ip-address host in the session

Fixes cesnet/netopeer2#382
diff --git a/src/session_client.c b/src/session_client.c
index 5ddb6bc..738fbb1 100644
--- a/src/session_client.c
+++ b/src/session_client.c
@@ -1310,18 +1310,20 @@
    has to be invoked, until it returns a valid socket.
  */
 int
-nc_sock_connect(const char* host, uint16_t port, int timeout, int* sock_pending)
+nc_sock_connect(const char *host, uint16_t port, int timeout, int *sock_pending, char **ip_host)
 {
     int i;
-    int sock = sock_pending?*sock_pending:-1;
+    int sock = sock_pending ? *sock_pending : -1;
     struct addrinfo hints, *res_list, *res;
     char port_s[6]; /* length of string representation of short int */
+    char *buf;
+    void *addr;
 
-    VRB("nc_sock_connect(%s, %u, %d, %d)", host, port, timeout, sock);
+    DBG("nc_sock_connect(%s, %u, %d, %d)", host, port, timeout, sock);
 
     /* no pending socket */
     if (sock == -1) {
-        /* Connect to a server */
+        /* connect to a server */
         snprintf(port_s, 6, "%u", port);
         memset(&hints, 0, sizeof hints);
         hints.ai_family = AF_UNSPEC;
@@ -1340,6 +1342,27 @@
                 continue;
             }
             VRB("Successfully connected to %s:%s over %s.", host, port_s, (res->ai_family == AF_INET6) ? "IPv6" : "IPv4");
+            if (ip_host && ((res->ai_family == AF_INET6) || (res->ai_family == AF_INET))) {
+                buf = malloc(INET6_ADDRSTRLEN);
+                if (!buf) {
+                    ERRMEM;
+                    close(sock);
+                    return -1;
+                }
+                if (res->ai_family == AF_INET) {
+                    addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
+                } else {
+                    addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
+                }
+                if (!inet_ntop(res->ai_family, addr, buf, INET6_ADDRSTRLEN)) {
+                    ERR("Converting host to IP address failed (%s).", strerror(errno));
+                    free(buf);
+                    close(sock);
+                    return -1;
+                }
+
+                *ip_host = buf;
+            }
             break;
         }
         freeaddrinfo(res_list);
diff --git a/src/session_client_ssh.c b/src/session_client_ssh.c
index b0ba9dd..4319517 100644
--- a/src/session_client_ssh.c
+++ b/src/session_client_ssh.c
@@ -1489,7 +1489,7 @@
 static struct nc_session *
 _nc_connect_libssh(ssh_session ssh_session, struct ly_ctx *ctx, struct nc_client_ssh_opts *opts, int timeout)
 {
-    char *host = NULL, *username = NULL;
+    char *host = NULL, *username = NULL, *ip_host;
     unsigned short port = 0;
     int sock;
     struct passwd *pw;
@@ -1528,13 +1528,16 @@
         ssh_options_set(session->ti.libssh.session, SSH_OPTIONS_HOST, host);
 
         /* create and connect socket */
-        sock = nc_sock_connect(host, port, -1, NULL);
+        sock = nc_sock_connect(host, port, -1, NULL, &ip_host);
         if (sock == -1) {
             ERR("Unable to connect to %s:%u (%s).", host, port, strerror(errno));
             goto fail;
         }
         ssh_options_set(session->ti.libssh.session, SSH_OPTIONS_FD, &sock);
         ssh_set_blocking(session->ti.libssh.session, 0);
+
+        free(host);
+        host = ip_host;
     }
 
     /* was username set? */
@@ -1622,7 +1625,7 @@
     const long timeout = NC_SSH_TIMEOUT;
     int sock;
     uint32_t port_uint;
-    char *username;
+    char *username, *ip_host = NULL;
     struct passwd *pw;
     struct nc_session *session = NULL;
 
@@ -1675,7 +1678,7 @@
             "ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss");
 
     /* create and assign communication socket */
-    sock = nc_sock_connect(host, port, -1, NULL);
+    sock = nc_sock_connect(host, port, -1, NULL, &ip_host);
     if (sock == -1) {
         ERR("Unable to connect to %s:%u (%s).", host, port, strerror(errno));
         goto fail;
@@ -1707,13 +1710,14 @@
     }
 
     /* store information into the dictionary */
-    session->host = lydict_insert(ctx, host, 0);
+    session->host = lydict_insert_zc(ctx, ip_host);
     session->port = port;
     session->username = lydict_insert(ctx, username, 0);
 
     return session;
 
 fail:
+    free(ip_host);
     nc_session_free(session, NULL);
     return NULL;
 }
diff --git a/src/session_client_tls.c b/src/session_client_tls.c
index 5611aba..71bb134 100644
--- a/src/session_client_tls.c
+++ b/src/session_client_tls.c
@@ -581,6 +581,7 @@
     struct nc_session *session = NULL;
     int sock, verify, ret;
     struct timespec ts_timeout, ts_cur;
+    char *ip_host = NULL;
 
     if (!tls_opts.cert_path || (!tls_opts.ca_file && !tls_opts.ca_dir)) {
         ERRINIT;
@@ -617,7 +618,7 @@
     }
 
     /* create and assign socket */
-    sock = nc_sock_connect(host, port, -1, NULL);
+    sock = nc_sock_connect(host, port, -1, NULL, &ip_host);
     if (sock == -1) {
         ERR("Unable to connect to %s:%u (%s).", host, port, strerror(errno));
         goto fail;
@@ -680,13 +681,14 @@
     }
 
     /* store information into session and the dictionary */
-    session->host = lydict_insert(ctx, host, 0);
+    session->host = lydict_insert_zc(ctx, ip_host);
     session->port = port;
     session->username = lydict_insert(ctx, "certificate-based", 0);
 
     return session;
 
 fail:
+    free(ip_host);
     nc_session_free(session, NULL);
     return NULL;
 }
diff --git a/src/session_p.h b/src/session_p.h
index 3397d78..367cd29 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -546,10 +546,11 @@
  * @param[in] host Hostname to connect to.
  * @param[in] port Port to connect on.
  * @param[in] timeout for blocking the connect+select call (-1 for infinite).
- * @param[in] sock_pending for exchanging the pending socket, if the blocking timeout was != -1
+ * @param[in,out] sock_pending for exchanging the pending socket, if the blocking timeout was != -1
+ * @param[out] ip_host Optional parameter with string IP address of the connected host.
  * @return Connected socket or -1 on error.
  */
-int nc_sock_connect(const char *host, uint16_t port, int timeout, int* sock_pending);
+int nc_sock_connect(const char *host, uint16_t port, int timeout, int* sock_pending, char **ip_host);
 
 /**
  * @brief Accept a new socket connection.
diff --git a/src/session_server.c b/src/session_server.c
index f49b491..8caaf13 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -901,7 +901,7 @@
             if ((ETIMEDOUT == ret) && (ps->queue[ps->queue_begin] == *id)) {
                 break;
             }
-            
+
             ERR("%s: failed to wait for a pollsession condition (%s).", func, strerror(ret));
             /* remove ourselves from the queue */
             nc_ps_queue_remove_id(ps, *id);
@@ -2844,8 +2844,9 @@
     NC_MSG_TYPE msgtype;
     int sock, ret;
     struct timespec ts_cur;
+    char *ip_host;
 
-    sock = nc_sock_connect(endpt->address, endpt->port, 5, &endpt->sock_pending);
+    sock = nc_sock_connect(endpt->address, endpt->port, 5, &endpt->sock_pending, &ip_host);
     if (sock < 0) {
         return NC_MSG_ERROR;
     }
@@ -2856,12 +2857,13 @@
     if (!(*session)) {
         ERRMEM;
         close(sock);
+        free(ip_host);
         return NC_MSG_ERROR;
     }
     (*session)->status = NC_STATUS_STARTING;
     (*session)->ctx = server_opts.ctx;
     (*session)->flags = NC_SESSION_SHAREDCTX;
-    (*session)->host = lydict_insert(server_opts.ctx, endpt->address, 0);
+    (*session)->host = lydict_insert_zc(server_opts.ctx, ip_host);
     (*session)->port = endpt->port;
 
     /* sock gets assigned to session or closed */