server session FEATURE check hello and idle timeouts
diff --git a/src/session.c b/src/session.c
index 04f7bf1..87ca628 100644
--- a/src/session.c
+++ b/src/session.c
@@ -754,10 +754,9 @@
     int ver = -1;
     int flag = 0;
 
-    /* TODO */
-    msgtype = nc_read_msg_poll(session, NC_CLIENT_HELLO_TIMEOUT * 1000, &xml);
+    msgtype = nc_read_msg_poll(session, server_opts.hello_timeout * 1000, &xml);
 
-    switch(msgtype) {
+    switch (msgtype) {
     case NC_MSG_HELLO:
         /* get know NETCONF version */
         LY_TREE_FOR(xml->child, node) {
@@ -787,6 +786,10 @@
     case NC_MSG_ERROR:
         /* nothing special, just pass it out */
         break;
+    case NC_MSG_WOULDBLOCK:
+        ERR("Client's <hello> timeout elapsed.");
+        msgtype = NC_MSG_ERROR;
+        break;
     default:
         ERR("Unexpected message received instead of <hello>.");
         msgtype = NC_MSG_ERROR;
diff --git a/src/session_p.h b/src/session_p.h
index c4ea43b..3aa09cc 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -222,6 +222,7 @@
     struct nc_msg_cont *notifs;    /**< queue for notifications received instead of RPC reply */
 
     /* server side only data */
+    time_t last_rpc;
 #ifdef ENABLE_SSH
     /* additional flags */
 #   define NC_SESSION_SSH_AUTHENTICATED 0x02
diff --git a/src/session_server.c b/src/session_server.c
index bc75fe1..03ffaff 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -406,6 +406,7 @@
         goto fail;
     }
     (*session)->status = NC_STATUS_RUNNING;
+    (*session)->last_rpc = time(NULL);
 
     return 0;
 
@@ -584,6 +585,7 @@
 {
     int ret;
     uint16_t i;
+    time_t cur_time;
     NC_MSG_TYPE msgtype;
     struct nc_session *session;
     struct nc_server_rpc *rpc;
@@ -594,12 +596,22 @@
         return -1;
     }
 
+    cur_time = time(NULL);
+
     for (i = 0; i < ps->session_count; ++i) {
         if (ps->sessions[i].session->status != NC_STATUS_RUNNING) {
             ERR("Session %u: session not running.", ps->sessions[i].session->id);
             return -1;
         }
 
+        /* TODO invalidate only sessions without subscription */
+        if (ps->sessions[i].session->last_rpc + server_opts.idle_timeout >= cur_time) {
+            ERR("Session %u: session idle timeout elapsed.", ps->sessions[i].session->id);
+            ps->sessions[i].session->status = NC_STATUS_INVALID;
+            ps->sessions[i].session->term_reason = NC_SESSION_TERM_TIMEOUT;
+            return 3;
+        }
+
         if (ps->sessions[i].revents) {
             break;
         }
@@ -723,6 +735,7 @@
     }
 
     /* process RPC */
+    session->last_rpc = time(NULL);
     msgtype = nc_send_reply(session, rpc);
 
     pthread_mutex_unlock(session->ti_lock);
diff --git a/src/session_server.h b/src/session_server.h
index 08fc6cc..a9f18c3 100644
--- a/src/session_server.h
+++ b/src/session_server.h
@@ -272,7 +272,7 @@
 /**
  * @brief Set SSH authentication attempts of every client. 3 by default.
  *
- * @param[in] auth_attempts Failed authentication attepmts before a client is dropped.
+ * @param[in] auth_attempts Failed authentication attempts before a client is dropped.
  * @return 0 on success, -1 on error.
  */
 int nc_ssh_server_set_auth_attempts(uint16_t auth_attempts);