session FEATURE expected hostname for TLS callhome
diff --git a/src/session_client.c b/src/session_client.c
index e0a58fa..223630d 100644
--- a/src/session_client.c
+++ b/src/session_client.c
@@ -1600,7 +1600,7 @@
 #if defined (NC_ENABLED_SSH) || defined (NC_ENABLED_TLS)
 
 int
-nc_client_ch_add_bind_listen(const char *address, uint16_t port, NC_TRANSPORT_IMPL ti)
+nc_client_ch_add_bind_listen(const char *address, uint16_t port, const char *hostname, NC_TRANSPORT_IMPL ti)
 {
     int sock;
 
@@ -1625,20 +1625,16 @@
         return -1;
     }
 
-    client_opts.ch_bind_ti = nc_realloc(client_opts.ch_bind_ti, client_opts.ch_bind_count * sizeof *client_opts.ch_bind_ti);
-    if (!client_opts.ch_bind_ti) {
+    client_opts.ch_binds_aux = nc_realloc(client_opts.ch_binds_aux, client_opts.ch_bind_count * sizeof *client_opts.ch_binds_aux);
+    if (!client_opts.ch_binds_aux) {
         ERRMEM;
         close(sock);
         return -1;
     }
-    client_opts.ch_bind_ti[client_opts.ch_bind_count - 1] = ti;
+    client_opts.ch_binds_aux[client_opts.ch_bind_count - 1].ti = ti;
+    client_opts.ch_binds_aux[client_opts.ch_bind_count - 1].hostname = hostname ? strdup(hostname) : NULL;
 
     client_opts.ch_binds[client_opts.ch_bind_count - 1].address = strdup(address);
-    if (!client_opts.ch_binds[client_opts.ch_bind_count - 1].address) {
-        ERRMEM;
-        close(sock);
-        return -1;
-    }
     client_opts.ch_binds[client_opts.ch_bind_count - 1].port = port;
     client_opts.ch_binds[client_opts.ch_bind_count - 1].sock = sock;
     client_opts.ch_binds[client_opts.ch_bind_count - 1].pollin = 0;
@@ -1655,28 +1651,40 @@
     if (!address && !port && !ti) {
         for (i = 0; i < client_opts.ch_bind_count; ++i) {
             close(client_opts.ch_binds[i].sock);
-            free((char *)client_opts.ch_binds[i].address);
+            free(client_opts.ch_binds[i].address);
+
+            free(client_opts.ch_binds_aux[i].hostname);
 
             ret = 0;
         }
+        client_opts.ch_bind_count = 0;
+
         free(client_opts.ch_binds);
         client_opts.ch_binds = NULL;
-        client_opts.ch_bind_count = 0;
+
+        free(client_opts.ch_binds_aux);
+        client_opts.ch_binds_aux = NULL;
     } else {
         for (i = 0; i < client_opts.ch_bind_count; ++i) {
             if ((!address || !strcmp(client_opts.ch_binds[i].address, address)) &&
                     (!port || (client_opts.ch_binds[i].port == port)) &&
-                    (!ti || (client_opts.ch_bind_ti[i] == ti))) {
+                    (!ti || (client_opts.ch_binds_aux[i].ti == ti))) {
                 close(client_opts.ch_binds[i].sock);
-                free((char *)client_opts.ch_binds[i].address);
+                free(client_opts.ch_binds[i].address);
 
                 --client_opts.ch_bind_count;
                 if (!client_opts.ch_bind_count) {
                     free(client_opts.ch_binds);
                     client_opts.ch_binds = NULL;
+
+                    free(client_opts.ch_binds_aux);
+                    client_opts.ch_binds_aux = NULL;
                 } else if (i < client_opts.ch_bind_count) {
-                    memcpy(&client_opts.ch_binds[i], &client_opts.ch_binds[client_opts.ch_bind_count], sizeof *client_opts.ch_binds);
-                    client_opts.ch_bind_ti[i] = client_opts.ch_bind_ti[client_opts.ch_bind_count];
+                    memcpy(&client_opts.ch_binds[i], &client_opts.ch_binds[client_opts.ch_bind_count],
+                            sizeof *client_opts.ch_binds);
+
+                    memcpy(&client_opts.ch_binds_aux[i], &client_opts.ch_binds_aux[client_opts.ch_bind_count],
+                            sizeof *client_opts.ch_binds_aux);
                 }
 
                 ret = 0;
@@ -1703,20 +1711,20 @@
     }
 
     sock = nc_sock_accept_binds(client_opts.ch_binds, client_opts.ch_bind_count, timeout, &host, &port, &idx);
-
     if (sock < 1) {
         free(host);
         return sock;
     }
 
 #ifdef NC_ENABLED_SSH
-    if (client_opts.ch_bind_ti[idx] == NC_TI_LIBSSH) {
+    if (client_opts.ch_binds_aux[idx].ti == NC_TI_LIBSSH) {
         *session = nc_accept_callhome_ssh_sock(sock, host, port, ctx, NC_TRANSPORT_TIMEOUT);
     } else
 #endif
 #ifdef NC_ENABLED_TLS
-    if (client_opts.ch_bind_ti[idx] == NC_TI_OPENSSL) {
-        *session = nc_accept_callhome_tls_sock(sock, host, port, ctx, NC_TRANSPORT_TIMEOUT);
+    if (client_opts.ch_binds_aux[idx].ti == NC_TI_OPENSSL) {
+        *session = nc_accept_callhome_tls_sock(sock, host, port, ctx, NC_TRANSPORT_TIMEOUT,
+                client_opts.ch_binds_aux[idx].hostname);
     } else
 #endif
     {
diff --git a/src/session_client.h b/src/session_client.h
index 2d87a76..39c9860 100644
--- a/src/session_client.h
+++ b/src/session_client.h
@@ -462,7 +462,7 @@
  * If the caller needs to use specific TLS session properties, they are supposed to use ::nc_connect_libssl().
  *
  * @param[in] host Hostname or address (both Ipv4 and IPv6 are accepted) of the target server.
- * 'localhost' is used by default if NULL is specified.
+ * 'localhost' is used by default if NULL is specified. It is verified by TLS when connecting to it.
  * @param[in] port Port number of the target server. Default value 6513 is used if 0 is specified.
  * @param[in] ctx Optional custom context to use for the session. Disregarding whether set or not, any YANG modules
  * not present and supported by the server are attempted to be loaded using \<get-schema\> (if supported) and/or by
diff --git a/src/session_client_ch.h b/src/session_client_ch.h
index 0ef9560..7b098b0 100644
--- a/src/session_client_ch.h
+++ b/src/session_client_ch.h
@@ -277,6 +277,16 @@
 int nc_client_tls_ch_add_bind_listen(const char *address, uint16_t port);
 
 /**
+ * @brief Add a new client bind and start listening on it for TLS Call Home connections coming from the specified hostname.
+ *
+ * @param[in] address IP address to bind to.
+ * @param[in] port Port to bind to.
+ * @param[in] hostname Expected server hostname, verified by TLS when connecting to it.
+ * @return 0 on success, -1 on error.
+ */
+int nc_client_tls_ch_add_bind_hostname_listen(const char *address, uint16_t port, const char *hostname);
+
+/**
  * @brief Remove a TLS listening client bind.
  *
  * @param[in] address IP address the socket was bound to. NULL matches all.
diff --git a/src/session_client_ssh.c b/src/session_client_ssh.c
index 54310a8..de0c1df 100644
--- a/src/session_client_ssh.c
+++ b/src/session_client_ssh.c
@@ -1146,7 +1146,7 @@
 API int
 nc_client_ssh_ch_add_bind_listen(const char *address, uint16_t port)
 {
-    return nc_client_ch_add_bind_listen(address, port, NC_TI_LIBSSH);
+    return nc_client_ch_add_bind_listen(address, port, NULL, NC_TI_LIBSSH);
 }
 
 API int
diff --git a/src/session_client_tls.c b/src/session_client_tls.c
index 43cfd09..04572a5 100644
--- a/src/session_client_tls.c
+++ b/src/session_client_tls.c
@@ -485,7 +485,13 @@
 API int
 nc_client_tls_ch_add_bind_listen(const char *address, uint16_t port)
 {
-    return nc_client_ch_add_bind_listen(address, port, NC_TI_OPENSSL);
+    return nc_client_ch_add_bind_listen(address, port, NULL, NC_TI_OPENSSL);
+}
+
+API int
+nc_client_tls_ch_add_bind_hostname_listen(const char *address, uint16_t port, const char *hostname)
+{
+    return nc_client_ch_add_bind_listen(address, port, hostname, NC_TI_OPENSSL);
 }
 
 API int
@@ -801,15 +807,15 @@
 }
 
 struct nc_session *
-nc_accept_callhome_tls_sock(int sock, const char *host, uint16_t port, struct ly_ctx *ctx, int timeout)
+nc_accept_callhome_tls_sock(int sock, const char *host, uint16_t port, struct ly_ctx *ctx, int timeout, const char *peername)
 {
     int ret;
     SSL *tls = NULL;
     struct nc_session *session = NULL;
     struct timespec ts_timeout;
 
-    /* create/update TLS structures without setting the peername */
-    if (nc_client_tls_update_opts(&tls_ch_opts, NULL)) {
+    /* create/update TLS structures with explicit expected peername, if any set, the host is just the IP */
+    if (nc_client_tls_update_opts(&tls_ch_opts, peername)) {
         goto cleanup;
     }
 
diff --git a/src/session_p.h b/src/session_p.h
index d009af1..cade331 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -152,7 +152,10 @@
         int sock;
         int pollin;
     } *ch_binds;
-    NC_TRANSPORT_IMPL *ch_bind_ti;
+    struct {
+        NC_TRANSPORT_IMPL ti;
+        char *hostname;
+    } *ch_binds_aux;
     uint16_t ch_bind_count;
 };
 
@@ -745,10 +748,11 @@
  *
  * @param[in] address Address to bind to.
  * @param[in] port Port to bind to.
+ * @param[in] hostname Expected server hostname, may be NULL.
  * @param[in] ti Transport to use.
  * @return 0 on success, -1 on error.
  */
-int nc_client_ch_add_bind_listen(const char *address, uint16_t port, NC_TRANSPORT_IMPL ti);
+int nc_client_ch_add_bind_listen(const char *address, uint16_t port, const char *hostname, NC_TRANSPORT_IMPL ti);
 
 /**
  * @brief Remove a client Call Home bind, stop listening on it.
@@ -819,7 +823,8 @@
 
 #ifdef NC_ENABLED_TLS
 
-struct nc_session *nc_accept_callhome_tls_sock(int sock, const char *host, uint16_t port, struct ly_ctx *ctx, int timeout);
+struct nc_session *nc_accept_callhome_tls_sock(int sock, const char *host, uint16_t port, struct ly_ctx *ctx,
+        int timeout, const char *peername);
 
 /**
  * @brief Establish TLS transport on a socket.