diff --git a/CMakeLists.txt b/CMakeLists.txt
index 78a20014107b6486344743aa1f369881256b07d9..eef94a73f28c5ab5ca0dd0554c91e8e69f4a8186 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ project(cellframe-sdk C)
 cmake_minimum_required(VERSION 2.8)
 
 set(CMAKE_C_STANDARD 11)
-set(CELLFRAME_SDK_NATIVE_VERSION "2.5-14")
+set(CELLFRAME_SDK_NATIVE_VERSION "2.5-15")
 add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"")
 
 set(DAPSDK_MODULES "")
diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h
index c1389199a3785207478d4d94f0faf1efa61d2ea8..3b58cda9e5d68d7ae879194037bd8b88d4e60c32 100755
--- a/dap-sdk/core/include/dap_common.h
+++ b/dap-sdk/core/include/dap_common.h
@@ -160,7 +160,13 @@ DAP_STATIC_INLINE void _dap_aligned_free( void *ptr )
     DAP_FREE( base_ptr );
 }
 
-#define DAP_PROTOCOL_VERSION  22
+/*
+ * 23: added support for encryption key type parameter and option to encrypt headers
+*/
+#define DAP_PROTOCOL_VERSION          23
+#define DAP_PROTOCOL_VERSION_DEFAULT  22 // used if version is not explicitly specified
+
+#define DAP_CLIENT_PROTOCOL_VERSION   23
 
 #if __SIZEOF_LONG__==8
 #define DAP_UINT64_FORMAT_X  "lX"
@@ -406,8 +412,7 @@ int timespec_diff(struct timespec *a_start, struct timespec *a_stop, struct time
 
 int get_select_breaker(void);
 int send_select_break(void);
-char * exec_with_ret(const char * a_cmd);
-char * exec_with_ret_multistring(const char * a_cmd);
+int exec_with_ret(char**, const char*);
 char * dap_random_string_create_alloc(size_t a_length);
 void dap_random_string_fill(char *str, size_t length);
 void dap_dump_hex(const void* data, size_t size);
diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c
index 09909bb97f9c431f17ecfcfac03d75569a16b102..800425970092a112cf1d408ccb5a8b2d3a2c36e9 100755
--- a/dap-sdk/core/src/dap_common.c
+++ b/dap-sdk/core/src/dap_common.c
@@ -519,6 +519,27 @@ int send_select_break( )
   return 0;
 }
 
+
+int exec_with_ret(char** repl, const char * a_cmd) {
+    FILE * fp;
+    size_t buf_len = 0;
+    char buf[4096] = {0};
+    fp = popen(a_cmd, "r");
+    if (!fp) {
+        log_it(L_ERROR,"Cmd execution error: '%s'", strerror(errno));
+        return(255);
+    }
+    memset(buf, 0, sizeof(buf));
+    fgets(buf, sizeof(buf) - 1, fp);
+    buf_len = strlen(buf);
+    if(repl) {
+        if(buf[buf_len - 1] == '\n')
+            buf[buf_len - 1] ='\0';
+        *repl = strdup(buf);
+    }
+    return pclose(fp);
+}
+
 #ifdef ANDROID1
 static u_long myNextRandom = 1;
 
diff --git a/dap-sdk/crypto/include/dap_enc_key.h b/dap-sdk/crypto/include/dap_enc_key.h
index 7ef187742ec71e45813da67a55d286cddee647b0..42711803e73cfa8bc21d79d8a920723224cbeb79 100755
--- a/dap-sdk/crypto/include/dap_enc_key.h
+++ b/dap-sdk/crypto/include/dap_enc_key.h
@@ -43,7 +43,7 @@ typedef enum dap_enc_data_type{DAP_ENC_DATA_TYPE_RAW,
 
 typedef enum dap_enc_key_type{
 
-
+                           DAP_ENC_KEY_TYPE_INVALID = -1,
                            DAP_ENC_KEY_TYPE_IAES, // Symmetric AES
                            DAP_ENC_KEY_TYPE_OAES,// from https://github.com/monero-project/monero/tree/master/src/crypto
 
@@ -123,7 +123,8 @@ typedef enum dap_enc_key_type{
 
                            DAP_ENC_KEY_TYPE_SIG_RINGCT20,//ring signature for confidentional transaction
 
-                           DAP_ENC_KEY_TYPE_NULL = 0
+                           DAP_ENC_KEY_TYPE_LAST = DAP_ENC_KEY_TYPE_SIG_RINGCT20,
+                           DAP_ENC_KEY_TYPE_NULL = 0 // avoid using it: 0 is a DAP_ENC_KEY_TYPE_NULL and DAP_ENC_KEY_TYPE_IAES at the same time
 
                          }  dap_enc_key_type_t;
 
@@ -244,6 +245,7 @@ int dap_enc_key_init(void);
 void dap_enc_key_deinit(void);
 
 const char *dap_enc_get_type_name(dap_enc_key_type_t a_key_type);
+dap_enc_key_type_t dap_enc_key_type_find_by_name(const char * a_name);
 size_t dap_enc_key_get_enc_size(dap_enc_key_t * a_key, const size_t buf_in_size);
 size_t dap_enc_key_get_dec_size(dap_enc_key_t * a_key, const size_t buf_in_size);
 
diff --git a/dap-sdk/crypto/src/dap_enc_key.c b/dap-sdk/crypto/src/dap_enc_key.c
index 95b9c89200f6f94124a1657e9cc882b54fd6bebf..69aac3100950811fae7b7f007c85abaad88e5b2e 100755
--- a/dap-sdk/crypto/src/dap_enc_key.c
+++ b/dap-sdk/crypto/src/dap_enc_key.c
@@ -837,7 +837,18 @@ const char *dap_enc_get_type_name(dap_enc_key_type_t a_key_type)
     if(s_callbacks[a_key_type].name) {
         return s_callbacks[a_key_type].name;
     }
-    log_it(L_ERROR, "name not realize for current key type");
+    log_it(L_WARNING, "name was not set for key type %d", a_key_type);
     return 0;
 
 }
+
+dap_enc_key_type_t dap_enc_key_type_find_by_name(const char * a_name){
+    for(dap_enc_key_type_t i = 0; i <= DAP_ENC_KEY_TYPE_LAST; i++){
+        const char * l_current_key_name = dap_enc_get_type_name(i);
+        if(l_current_key_name && !strcmp(a_name, l_current_key_name))
+            return i;
+    }
+    log_it(L_WARNING, "no key type with name %s", a_name);
+    return DAP_ENC_KEY_TYPE_INVALID;
+}
+
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index 3ce887e4f93e9532d9c780d13860159172de6691..63db3542a11c4015f350aebc98bd215eec1706a6 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -79,6 +79,8 @@
 
 static void s_stage_status_after(dap_client_pvt_t * a_client_internal);
 
+const static dap_enc_key_type_t s_dap_client_pvt_preferred_encryption_type = DAP_ENC_KEY_TYPE_IAES;
+
 // ENC stage callbacks
 void m_enc_init_response(dap_client_t *, void *, size_t);
 void m_enc_init_error(dap_client_t *, int);
@@ -402,7 +404,7 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt)
     case STAGE_STATUS_IN_PROGRESS: {
         switch (a_client_pvt->stage) {
         case STAGE_ENC_INIT: {
-            log_it(L_INFO, "Go to stage ENC: prepare the request");         
+            log_it(L_INFO, "Go to stage ENC: prepare the request");
             a_client_pvt->session_key_open = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_MSRLN, NULL, 0, NULL, 0, 0);
             if (!a_client_pvt->session_key_open) {
                 log_it(L_ERROR, "Insufficient memory! May be a huge memory leak present");
@@ -443,7 +445,17 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt)
             log_it(L_DEBUG, "STREAM_CTL request size %u", strlen(l_request));
 
             char *l_suburl;
-            l_suburl = dap_strdup_printf("stream_ctl,channels=%s", a_client_pvt->active_channels);
+
+            uint32_t l_least_common_dap_protocol = min(a_client_pvt->remote_protocol_version,
+                                                       a_client_pvt->uplink_protocol_version);
+
+            if(l_least_common_dap_protocol < 23){
+                l_suburl = dap_strdup_printf("stream_ctl,channels=%s",
+                                             a_client_pvt->active_channels);
+            }else{
+                l_suburl = dap_strdup_printf("stream_ctl,channels=%s,enc_type=%d,enc_headers=%d",
+                                             a_client_pvt->active_channels,dap_stream_get_preferred_encryption_type(),0);
+            }
             //
             dap_client_pvt_request_enc(a_client_pvt,
             DAP_UPLINK_PATH_STREAM_CTL,
@@ -462,7 +474,7 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt)
                 a_client_pvt->stage_status = STAGE_STATUS_ERROR;
                 break;
             }
-#ifdef _WIN32 
+#ifdef _WIN32
             {
               int buffsize = 65536;
               int optsize = sizeof( int );
@@ -959,13 +971,22 @@ void m_enc_init_response(dap_client_t * a_client, void * a_response, size_t a_re
                         json_parse_count++;
                     }
                 }
+                if(json_object_get_type(val) == json_type_int) {
+                    int val_int = (uint32_t)json_object_get_int(val);
+                    if(!strcmp(key, "dap_protocol_version")) {
+                        l_client_pvt->remote_protocol_version = val_int;
+                        json_parse_count++;
+                    }
+                }
             }
             // free jobj
             json_object_put(jobj);
+            if(!l_client_pvt->remote_protocol_version)
+                l_client_pvt->remote_protocol_version = DAP_PROTOCOL_VERSION_DEFAULT;
         }
         //char l_session_id_b64[DAP_ENC_BASE64_ENCODE_SIZE(DAP_ENC_KS_KEY_ID_SIZE) + 1] = { 0 };
         //char *l_bob_message_b64 = DAP_NEW_Z_SIZE(char, a_response_size - sizeof(l_session_id_b64) + 1);
-        if(json_parse_count == 2) { //if (sscanf (a_response,"%s %s",l_session_id_b64, l_bob_message_b64) == 2 ){
+        if(json_parse_count >= 2 && json_parse_count <=3) { //if (sscanf (a_response,"%s %s",l_session_id_b64, l_bob_message_b64) == 2 ){
             l_client_pvt->session_key_id = DAP_NEW_Z_SIZE(char, strlen(l_session_id_b64) + 1);
             dap_enc_base64_decode(l_session_id_b64, strlen(l_session_id_b64),
                     l_client_pvt->session_key_id, DAP_ENC_DATA_TYPE_B64);
@@ -1064,14 +1085,14 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
         s_stage_status_after(l_client_internal);
     } else {
         int l_arg_count;
-        char l_stream_id[25] = { 0 };
+        char l_stream_id[26] = { 0 };
         char *l_stream_key = DAP_NEW_Z_SIZE(char, 4096 * 3);
-        void * l_stream_key_raw = DAP_NEW_Z_SIZE(char, 4096);
-        size_t l_stream_key_raw_size = 0;
         uint32_t l_remote_protocol_version;
+        dap_enc_key_type_t l_enc_type = DAP_ENC_KEY_TYPE_OAES;
+        int l_enc_headers = 0;
 
-        l_arg_count = sscanf(l_response_str, "%25s %4096s %u"
-                , l_stream_id, l_stream_key, &l_remote_protocol_version);
+        l_arg_count = sscanf(l_response_str, "%25s %4096s %u %d %d"
+                , l_stream_id, l_stream_key, &l_remote_protocol_version, &l_enc_type, &l_enc_headers);
         if(l_arg_count < 2) {
             log_it(L_WARNING, "STREAM_CTL Need at least 2 arguments in reply (got %d)", l_arg_count);
             l_client_internal->last_error = ERROR_STREAM_CTL_ERROR_RESPONSE_FORMAT;
@@ -1083,8 +1104,8 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
                 l_client_internal->uplink_protocol_version = l_remote_protocol_version;
                 log_it(L_DEBUG, "Uplink protocol version %u", l_remote_protocol_version);
             } else
-                log_it(L_WARNING, "No uplink protocol version, use the default version %d"
-                        , l_client_internal->uplink_protocol_version = DAP_PROTOCOL_VERSION);
+                log_it(L_WARNING, "No uplink protocol version, use legacy version %d"
+                        , l_client_internal->uplink_protocol_version = 22);
 
             if(strlen(l_stream_id) < 13) {
                 //log_it(L_DEBUG, "Stream server id %s, stream key length(base64 encoded) %u"
@@ -1092,17 +1113,17 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
                 log_it(L_DEBUG, "Stream server id %s, stream key '%s'"
                         , l_stream_id, l_stream_key);
 
-                //l_stream_key_raw_size = dap_enc_base64_decode(l_stream_key,strlen(l_stream_key),
-                //                                             l_stream_key_raw,DAP_ENC_DATA_TYPE_B64);
                 // Delete old key if present
                 if(l_client_internal->stream_key)
                     dap_enc_key_delete(l_client_internal->stream_key);
 
                 strncpy(l_client_internal->stream_id, l_stream_id, sizeof(l_client_internal->stream_id) - 1);
                 l_client_internal->stream_key =
-                        dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_OAES, l_stream_key, strlen(l_stream_key), NULL, 0,
+                        dap_enc_key_new_generate(l_enc_type, l_stream_key, strlen(l_stream_key), NULL, 0,
                                 32);
 
+                l_client_internal->encrypted_headers = l_enc_headers;
+
                 if(l_client_internal->stage == STAGE_STREAM_CTL) { // We are on the right stage
                     l_client_internal->stage_status = STAGE_STATUS_DONE;
                     s_stage_status_after(l_client_internal);
@@ -1120,7 +1141,6 @@ void m_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t a_data
 
         }
         DAP_DELETE(l_stream_key);
-        DAP_DELETE(l_stream_key_raw);
     }
 }
 
@@ -1334,4 +1354,3 @@ void m_es_stream_error(dap_events_socket_t * a_es, int a_arg)
     }
     log_it(L_INFO, "m_es_stream_error: code %d", a_arg);
 }
-
diff --git a/dap-sdk/net/client/include/dap_client.h b/dap-sdk/net/client/include/dap_client.h
index ff2ec55fda9f9da9f5c6bb2226d49bf4b915af18..316a31547c6d5b6376f8cb431f626ddc54fd8661 100644
--- a/dap-sdk/net/client/include/dap_client.h
+++ b/dap-sdk/net/client/include/dap_client.h
@@ -66,8 +66,6 @@ typedef enum dap_client_error {
     ERROR_NETWORK_CONNECTION_TIMEOUT
 } dap_client_error_t;
 
-#define DAP_CLIENT_PROTOCOL_VERSION 22
-
 /**
  * @brief The dap_client struct
  */
diff --git a/dap-sdk/net/client/include/dap_client_pvt.h b/dap-sdk/net/client/include/dap_client_pvt.h
index 6966a2cf5f3bef2125ef8189d035df71dccbf556..c3c97473ebd5328b4a586cd05929e844383db086 100644
--- a/dap-sdk/net/client/include/dap_client_pvt.h
+++ b/dap-sdk/net/client/include/dap_client_pvt.h
@@ -60,7 +60,7 @@ typedef struct dap_client_internal
     char * active_channels;
     uint16_t uplink_port;
     uint32_t uplink_protocol_version;
-
+    uint32_t remote_protocol_version;
 
     dap_client_stage_t stage_target;
     dap_client_callback_t stage_target_done_callback;
@@ -77,6 +77,7 @@ typedef struct dap_client_internal
     int connect_attempt;
 
     bool is_encrypted;
+    bool encrypted_headers;
     bool is_reconnect;
     bool is_close_session;// the last request in session, in the header will be added "SessionCloseAfterRequest: true"
     dap_client_callback_data_size_t request_response_callback;
diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/net/core/dap_events_socket.c
index 8dcb64f5f376911a002fe7238edcdd82ff97aed6..5da958b3f0e48621f3f13c9e44b0a6e27e46c83a 100644
--- a/dap-sdk/net/core/dap_events_socket.c
+++ b/dap-sdk/net/core/dap_events_socket.c
@@ -187,6 +187,7 @@ dap_events_socket_t * s_create_type_pipe(dap_worker_t * a_w, dap_events_socket_c
     int l_pipe[2];
     int l_errno;
     char l_errbuf[128];
+    l_errbuf[0]=0;
     if( pipe(l_pipe) < 0 ){
         l_errno = errno;
         strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
@@ -253,6 +254,7 @@ dap_events_socket_t * s_create_type_queue_ptr(dap_worker_t * a_w, dap_events_soc
     int l_pipe[2];
     int l_errno;
     char l_errbuf[128];
+    l_errbuf[0]=0;
     if( pipe2(l_pipe,O_DIRECT | O_NONBLOCK ) < 0 ){
         l_errno = errno;
         strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
@@ -290,7 +292,8 @@ dap_events_socket_t * s_create_type_queue_ptr(dap_worker_t * a_w, dap_events_soc
     l_es->mqd = mq_open(l_mq_name,O_CREAT|O_RDWR,S_IRWXU, &l_mq_attr);
     if (l_es->mqd == -1 ){
         int l_errno = errno;
-        char l_errbuf[128]={0};
+        char l_errbuf[128];
+        l_errbuf[0]=0;
         strerror_r(l_errno,l_errbuf,sizeof (l_errbuf) );
         DAP_DELETE(l_es);
         l_es = NULL;
@@ -357,7 +360,8 @@ int dap_events_socket_queue_proc_input_unsafe(dap_events_socket_t * a_esocket)
             ssize_t l_ret = mq_timedreceive(a_esocket->mqd,(char*) &l_queue_ptr, sizeof (l_queue_ptr),NULL,&s_timeout );
             if (l_ret == -1){
                 int l_errno = errno;
-                char l_errbuf[128]={0};
+                char l_errbuf[128];
+                l_errbuf[0]=0;
                 strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
                 log_it(L_ERROR, "Error in esocket queue_ptr:\"%s\" code %d", l_errbuf, l_errno);
                 return -1;
@@ -398,6 +402,7 @@ dap_events_socket_t * s_create_type_event(dap_worker_t * a_w, dap_events_socket_
     if((l_es->fd = eventfd(0,0) ) < 0 ){
         int l_errno = errno;
         char l_errbuf[128];
+        l_errbuf[0]=0;
         strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
         switch (l_errno) {
             case EINVAL: log_it(L_CRITICAL, "An unsupported value was specified in flags: \"%s\" (%d)", l_errbuf, l_errno); break;
@@ -459,6 +464,7 @@ void dap_events_socket_event_proc_input_unsafe(dap_events_socket_t *a_esocket)
         }else if ( (errno != EAGAIN) && (errno != EWOULDBLOCK) ){  // we use blocked socket for now but who knows...
             int l_errno = errno;
             char l_errbuf[128];
+            l_errbuf[0]=0;
             strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
             log_it(L_WARNING, "Can't read packet from event fd: \"%s\"(%d)", l_errbuf, l_errno);
         }else
@@ -484,8 +490,7 @@ int dap_events_socket_queue_ptr_send( dap_events_socket_t * a_es, void* a_arg)
         return  0;
     else{
         char l_errbuf[128];
-        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-        log_it(L_ERROR, "Can't send ptr to queue:\"%s\" code %d", l_errbuf, l_errno);
+        log_it(L_ERROR, "Can't send ptr to queue:\"%s\" code %d", strerror_r(l_errno, l_errbuf, sizeof (l_errbuf)), l_errno);
         return l_errno;
     }
 #elif defined (DAP_EVENTS_CAPS_QUEUE_POSIX)
@@ -623,6 +628,7 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *sc, bool is_rea
     if ( epoll_ctl(sc->worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 ){
         int l_errno = errno;
         char l_errbuf[128];
+        l_errbuf[0]=0;
         strerror_r( l_errno, l_errbuf, sizeof (l_errbuf));
         log_it( L_ERROR,"Can't update read client socket state in the epoll_fd: \"%s\" (%d)", l_errbuf, l_errno );
     }
@@ -659,6 +665,7 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *sc, bool a_is_r
         if ( epoll_ctl(sc->worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) ){
             int l_errno = errno;
             char l_errbuf[128];
+            l_errbuf[0]=0;
             strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
             log_it(L_ERROR,"Can't update write client socket state in the epoll_fd %d: \"%s\" (%d)",
                    sc->worker->epoll_fd, l_errbuf, l_errno);
@@ -885,6 +892,10 @@ size_t dap_events_socket_write_f_mt(dap_worker_t * a_w,dap_events_socket_t *a_es
  */
 size_t dap_events_socket_write_unsafe(dap_events_socket_t *sc, const void * data, size_t data_size)
 {
+    if(sc->buf_out_size>sizeof(sc->buf_out)){
+        log_it(L_DEBUG,"write buffer already overflow size=%u/max=%u", sc->buf_out_size, sizeof(sc->buf_out));
+        return 0;
+    }
     //log_it(L_DEBUG,"dap_events_socket_write %u sock data %X size %u", sc->socket, data, data_size );
      data_size = ((sc->buf_out_size+data_size)<(sizeof(sc->buf_out)))?data_size:(sizeof(sc->buf_out)-sc->buf_out_size );
      memcpy(sc->buf_out+sc->buf_out_size,data,data_size);
diff --git a/dap-sdk/net/core/dap_worker.c b/dap-sdk/net/core/dap_worker.c
index c4f1e540a0f3305374c2866f6f1fe399f687ab9e..6a2081799ab911a6521789ccc5478ea2be0922ec 100644
--- a/dap-sdk/net/core/dap_worker.c
+++ b/dap-sdk/net/core/dap_worker.c
@@ -134,6 +134,9 @@ void *dap_worker_thread(void *arg)
                         //if(!(events[n].events & EPOLLIN))
                         //cur->no_close = false;
                         if (l_sock_err) {
+                            dap_events_socket_set_readable_unsafe(l_cur, false);
+                            dap_events_socket_set_writable_unsafe(l_cur, false);
+                            l_cur->buf_out_size = 0;
                             l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
                             log_it(L_INFO, "Socket shutdown (EPOLLHUP): %s", strerror(l_sock_err));
                         }
@@ -150,6 +153,9 @@ void *dap_worker_thread(void *arg)
                         log_it(L_ERROR, "Socket error: %s", strerror(l_sock_err));
                     default: ;
                 }
+                dap_events_socket_set_readable_unsafe(l_cur, false);
+                dap_events_socket_set_writable_unsafe(l_cur, false);
+                l_cur->buf_out_size = 0;
                 l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
                 l_cur->callbacks.error_callback(l_cur, 0); // Call callback to process error event
             }
@@ -157,7 +163,10 @@ void *dap_worker_thread(void *arg)
             if (l_epoll_events[n].events & EPOLLRDHUP) {
                 log_it(L_INFO, "Client socket disconnected");
                 dap_events_socket_set_readable_unsafe(l_cur, false);
+                dap_events_socket_set_writable_unsafe(l_cur, false);
+                l_cur->buf_out_size = 0;
                 l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+
             }
 
             if(l_epoll_events[n].events & EPOLLIN) {
@@ -244,6 +253,7 @@ void *dap_worker_thread(void *arg)
                             log_it(L_ERROR, "Some error occured in recv() function: %s", strerror(errno));
                             dap_events_socket_set_readable_unsafe(l_cur, false);
                             l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+                            l_cur->buf_out_size = 0;
                         }
                     }
                     else if (!(l_epoll_events[n].events & EPOLLRDHUP) || !(l_epoll_events[n].events & EPOLLERR)) {
@@ -285,7 +295,7 @@ void *dap_worker_thread(void *arg)
                         l_cur->buf_out_zero_count = 0;
                 }
                 //for(total_sent = 0; total_sent < cur->buf_out_size;) { // If after callback there is smth to send - we do it
-                size_t l_bytes_sent =0;
+                ssize_t l_bytes_sent =0;
                 int l_errno;
                 switch (l_cur->type){
                     case DESCRIPTOR_TYPE_SOCKET:
@@ -308,6 +318,8 @@ void *dap_worker_thread(void *arg)
                     if (l_errno != EAGAIN && l_errno != EWOULDBLOCK ){ // If we have non-blocking socket
                         log_it(L_ERROR, "Some error occured in send(): %s", strerror(errno));
                         l_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+                        l_cur->buf_out_size = 0;
+
                     }
                 }else{
 
@@ -349,7 +361,7 @@ void *dap_worker_thread(void *arg)
         }
 
     } // while
-
+    log_it(L_NOTICE,"Exiting thread #%u", l_worker->id);
     return NULL;
 }
 
diff --git a/dap-sdk/net/server/enc_server/dap_enc_http.c b/dap-sdk/net/server/enc_server/dap_enc_http.c
index eabc22b6f6c1fa57f3781f051c181a719824cc5f..d8db585694eb6436166931bfcef48028aef3273f 100644
--- a/dap-sdk/net/server/enc_server/dap_enc_http.c
+++ b/dap-sdk/net/server/enc_server/dap_enc_http.c
@@ -75,6 +75,7 @@ static void _enc_http_write_reply(struct dap_http_simple *cl_st,
     struct json_object *jobj = json_object_new_object();
     json_object_object_add(jobj, "encrypt_id", json_object_new_string(encrypt_id));
     json_object_object_add(jobj, "encrypt_msg", json_object_new_string(encrypt_msg));
+    json_object_object_add(jobj, "dap_protocol_version", json_object_new_int(DAP_PROTOCOL_VERSION));
     const char* json_str = json_object_to_json_string(jobj);
     dap_http_simple_reply(cl_st, (void*) json_str,
                           (size_t) strlen(json_str));
diff --git a/dap-sdk/net/stream/stream/dap_stream.c b/dap-sdk/net/stream/stream/dap_stream.c
index 35b1dc91dc4cc1c10d8a467f1eef7a603cb5719a..e9598cdf910e84952313b2e19feb0793448a701b 100644
--- a/dap-sdk/net/stream/stream/dap_stream.c
+++ b/dap-sdk/net/stream/stream/dap_stream.c
@@ -90,11 +90,28 @@ bool dap_stream_get_dump_packet_headers(){ return  s_dump_packet_headers; }
 static struct timespec keepalive_loop_sleep = { 0, STREAM_KEEPALIVE_TIMEOUT * 1000 * 1000  };
 static bool s_detect_loose_packet(dap_stream_t * a_stream);
 
+dap_enc_key_type_t s_stream_get_preferred_encryption_type = DAP_ENC_KEY_TYPE_IAES;
+
+void s_dap_stream_load_preferred_encryption_type(dap_config_t * a_config){
+    const char * l_preferred_encryption_name = dap_config_get_item_str(a_config, "stream", "preferred_encryption");
+    if(l_preferred_encryption_name){
+        dap_enc_key_type_t l_found_key_type = dap_enc_key_type_find_by_name(l_preferred_encryption_name);
+        if(l_found_key_type != DAP_ENC_KEY_TYPE_INVALID)
+            s_stream_get_preferred_encryption_type = l_found_key_type;
+    }
+
+    log_it(L_NOTICE,"ecryption type is set to %s", dap_enc_get_type_name(s_stream_get_preferred_encryption_type));
+}
+
+dap_enc_key_type_t dap_stream_get_preferred_encryption_type(){
+    return s_stream_get_preferred_encryption_type;
+}
+
 /**
  * @brief stream_init Init stream module
  * @return  0 if ok others if not
  */
-int dap_stream_init( bool a_dump_packet_headers)
+int dap_stream_init(dap_config_t * a_config)
 {
     if( dap_stream_ch_init() != 0 ){
         log_it(L_CRITICAL, "Can't init channel types submodule");
@@ -105,7 +122,8 @@ int dap_stream_init( bool a_dump_packet_headers)
         return -2;
     }
 
-    s_dump_packet_headers = a_dump_packet_headers;
+    s_dap_stream_load_preferred_encryption_type(a_config);
+    s_dump_packet_headers = dap_config_get_item_bool_default(g_config,"general","debug_dump_stream_headers",false);
     s_keep_alive_loop_quit_signal = false;
     pthread_mutex_init( &s_mutex_keepalive_list, NULL );
     //pthread_create( &keepalive_thread, NULL, stream_loop, NULL );
diff --git a/dap-sdk/net/stream/stream/dap_stream_ctl.c b/dap-sdk/net/stream/stream/dap_stream_ctl.c
index ef5d72345ae8dbb122417fbf8f92a739da045fd1..a19f14e97b5667f3e3195f35c934858c13201fd5 100644
--- a/dap-sdk/net/stream/stream/dap_stream_ctl.c
+++ b/dap-sdk/net/stream/stream/dap_stream_ctl.c
@@ -69,17 +69,15 @@ static struct {
     dap_enc_key_type_t type;
 } s_socket_forward_key;
 
-
 /**
  * @brief stream_ctl_init Initialize stream control module
  * @return Zero if ok others if not
  */
-int dap_stream_ctl_init(dap_enc_key_type_t socket_forward_key_type,
-                        size_t socket_forward_key_size)
+int dap_stream_ctl_init(size_t socket_forward_key_size)
 {
-    s_socket_forward_key.type = socket_forward_key_type;
     s_socket_forward_key.size = socket_forward_key_size;
-    log_it(L_NOTICE,"Initialized stream control module");
+    s_socket_forward_key.type = dap_stream_get_preferred_encryption_type();
+
     return 0;
 }
 
@@ -121,17 +119,22 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg)
     if(l_dg){
         size_t l_channels_str_size = sizeof(ss->active_channels);
         char l_channels_str[sizeof(ss->active_channels)];
-        if(l_dg->url_path && strlen(l_dg->url_path) < 30 &&
-                sscanf(l_dg->url_path, "stream_ctl,channels=%s", l_channels_str) == 1) {
+        dap_enc_key_type_t l_enc_type = s_socket_forward_key.type;
+        int l_enc_headers = 0;
+        bool l_is_legacy=false;
+        int l_url_sscanf_res = sscanf(l_dg->url_path, "stream_ctl,channels=%16s,enc_type=%d,enc_headers=%d", l_channels_str, &l_enc_type, &l_enc_headers);
+        if(l_url_sscanf_res > 0){
+            if(l_url_sscanf_res < 3){
+                log_it(L_INFO, "legacy encryption mode used (OAES)");
+                l_enc_type = DAP_ENC_KEY_TYPE_OAES;
+                l_is_legacy = true;
+            }
             l_new_session = true;
         }
         else if(strcmp(l_dg->url_path, "socket_forward" ) == 0) {
             l_channels_str[0]  = '\0';
             l_new_session = true;
         }
-        /* }else if (strcmp(dg->url_path,"stream_ctl")==0) {
-            l_new_session = true;
-        }*/
         else{
             log_it(L_ERROR,"ctl command unknown: %s",l_dg->url_path);
             enc_http_delegate_delete(l_dg);
@@ -144,7 +147,7 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg)
             strncpy(ss->active_channels, l_channels_str, l_channels_str_size);
             char *key_str = calloc(1, KEX_KEY_STR_SIZE+1);
             dap_random_string_fill(key_str, KEX_KEY_STR_SIZE);
-            ss->key = dap_enc_key_new_generate( s_socket_forward_key.type, key_str, KEX_KEY_STR_SIZE,
+            ss->key = dap_enc_key_new_generate( l_enc_type, key_str, KEX_KEY_STR_SIZE,
                                                NULL, 0, s_socket_forward_key.size);
             dap_http_header_t *l_hdr_key_id = dap_http_header_find(a_http_simple->http_client->in_headers, "KeyID");
             if (l_hdr_key_id) {
@@ -156,7 +159,10 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg)
                 }
                 ss->acl = l_ks_key->acl_list;
             }
-            enc_http_reply_f(l_dg,"%u %s",ss->id,key_str);
+            if (l_is_legacy)
+                enc_http_reply_f(l_dg,"%u %s",ss->id, key_str);
+            else
+                enc_http_reply_f(l_dg,"%u %s %u %d %d",ss->id, key_str, DAP_PROTOCOL_VERSION, l_enc_type, l_enc_headers);
             *return_code = Http_Status_OK;
 
             log_it(L_INFO," New stream session %u initialized",ss->id);
diff --git a/dap-sdk/net/stream/stream/include/dap_stream.h b/dap-sdk/net/stream/stream/include/dap_stream.h
index 888be346b5ae1b3b43b0d3aea5bc9004bfc999e1..0c0325bc3064b3903506d466f48e435025e78162 100644
--- a/dap-sdk/net/stream/stream/include/dap_stream.h
+++ b/dap-sdk/net/stream/stream/include/dap_stream.h
@@ -26,6 +26,8 @@
 #include <pthread.h>
 #include <stdbool.h>
 #include <pthread.h>
+
+#include "dap_config.h"
 #include "dap_stream_session.h"
 #include "dap_stream_ch.h"
 
@@ -91,7 +93,7 @@ typedef struct dap_stream {
 
 #define DAP_STREAM(a) ((dap_stream_t *) (a)->_inheritor )
 
-int dap_stream_init(bool a_dump_packet_headers);
+int dap_stream_init(dap_config_t * g_config);
 
 bool dap_stream_get_dump_packet_headers();
 
@@ -110,4 +112,6 @@ void dap_stream_proc_pkt_in(dap_stream_t * sid);
 void dap_stream_es_rw_states_update(struct dap_stream *a_stream);
 void dap_stream_set_ready_to_write(dap_stream_t * a_stream,bool a_is_ready);
 
+dap_enc_key_type_t dap_stream_get_preferred_encryption_type();
+
 
diff --git a/dap-sdk/net/stream/stream/include/dap_stream_ctl.h b/dap-sdk/net/stream/stream/include/dap_stream_ctl.h
index 56fe6e995554b46dbe186ffb0906712194979452..a040b2eb0086c106ad8f681229c552a2a406a9d8 100644
--- a/dap-sdk/net/stream/stream/include/dap_stream_ctl.h
+++ b/dap-sdk/net/stream/stream/include/dap_stream_ctl.h
@@ -21,11 +21,11 @@
 #pragma once
 
 #include "dap_enc.h"
+#include "dap_config.h"
 typedef struct dap_http dap_http_t;
 #define KEX_KEY_STR_SIZE 128
 
 
-int dap_stream_ctl_init(dap_enc_key_type_t socket_forward_key_type,
-                        size_t socket_forward_key_size);
+int dap_stream_ctl_init(size_t socket_forward_key_size);
 void dap_stream_ctl_deinit();
 void dap_stream_ctl_add_proc(struct dap_http * sh, const char * url);
diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c
index f3a06becbe67b868448ae8ba67762d5ad5d6b7c4..e0cf28cbf82400ac48ceb062dd45b6956c66352f 100644
--- a/modules/chain/dap_chain_ledger.c
+++ b/modules/chain/dap_chain_ledger.c
@@ -775,7 +775,7 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t
                 s_find_datum_tx_by_hash(a_ledger, &l_tx_prev_hash, &l_item_out); // dap_chain_datum_tx_t *l_tx_prev = (dap_chain_datum_tx_t*) dap_chain_node_datum_tx_cache_find(&tx_prev_hash);
         bound_item->item_out = l_item_out;
         if(!l_tx_prev) { // First transaction
-            log_it(L_WARNING,"No previous transaction was found for hash %s",l_tx_prev_hash_str);
+            log_it(L_DEBUG,"No previous transaction was found for hash %s",l_tx_prev_hash_str);
             l_err_num = -5;
             break;
         }
@@ -1047,7 +1047,7 @@ int dap_chain_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *
     int l_ret_check;
     if( (l_ret_check = dap_chain_ledger_tx_cache_check(
              a_ledger, a_tx, &l_list_bound_items, &l_list_tx_out)) < 0){
-        log_it (L_WARNING, "dap_chain_ledger_tx_add_check() tx not passed the check: code %d ",l_ret_check);
+        log_it (L_DEBUG, "dap_chain_ledger_tx_add_check() tx not passed the check: code %d ",l_ret_check);
         return -1;
     }
     dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
@@ -1074,7 +1074,7 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx)
     int l_ret_check;
     if( (l_ret_check = dap_chain_ledger_tx_cache_check(
              a_ledger, a_tx, &l_list_bound_items, &l_list_tx_out)) < 0){
-        log_it (L_WARNING, "dap_chain_ledger_tx_add() tx not passed the check: code %d ",l_ret_check);
+        log_it (L_DEBUG, "dap_chain_ledger_tx_add() tx not passed the check: code %d ",l_ret_check);
         return -1;
     }
     dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c
index 3bc1d829ddea5eb4a4a7e0883de688ec00334cc3..f06679a9a91c0de75cf2280673c780f240fefde6 100644
--- a/modules/channel/chain-net/dap_stream_ch_chain_net.c
+++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c
@@ -170,9 +170,11 @@ void s_stream_ch_delete(dap_stream_ch_t* a_ch, void* a_arg)
     (void) a_arg;
     //printf("* del session=%d\n", a_ch->stream->session->id);
     dap_stream_ch_chain_net_t * l_ch_chain_net = DAP_STREAM_CH_CHAIN_NET(a_ch);
-    pthread_mutex_lock(&l_ch_chain_net->mutex);
-    session_data_del(a_ch->stream->session->id);
-    pthread_mutex_unlock(&l_ch_chain_net->mutex);
+    if(l_ch_chain_net) {
+        pthread_mutex_lock(&l_ch_chain_net->mutex);
+        session_data_del(a_ch->stream->session->id);
+        pthread_mutex_unlock(&l_ch_chain_net->mutex);
+    }
 }
 
 /**
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index fb3731e98df40e5610f20bdd12398dc30b09f9d5..b7e3639f0e27d2bb2574e2cc0d9e86828cecc113 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -398,7 +398,12 @@ static int s_net_states_proc(dap_chain_net_t * l_net)
                     for (int i = 0; i < MIN(s_max_links_count, l_pvt_net->seed_aliases_count); i++) {
                         dap_chain_node_addr_t *l_link_addr = dap_chain_node_alias_find(l_net, l_pvt_net->seed_aliases[i]);
                         dap_chain_node_info_t *l_link_node_info = dap_chain_node_info_read(l_net, l_link_addr);
-                        l_pvt_net->links_info = dap_list_append(l_pvt_net->links_info, l_link_node_info);
+                        if(l_link_node_info) {
+                            l_pvt_net->links_info = dap_list_append(l_pvt_net->links_info, l_link_addr);
+                        }
+                        else{
+                            log_it(L_WARNING, "Not found link "NODE_ADDR_FP_STR" in the node list", NODE_ADDR_FPS_ARGS(l_link_addr));
+                        }
                     }
                 } break;
                 case NODE_ROLE_FULL:
@@ -410,14 +415,16 @@ static int s_net_states_proc(dap_chain_net_t * l_net)
                         int i = rand() % l_pvt_net->seed_aliases_count;
                         dap_chain_node_addr_t *l_remote_addr = dap_chain_node_alias_find(l_net, l_pvt_net->seed_aliases[i]);
                         dap_chain_node_info_t *l_remote_node_info = dap_chain_node_info_read(l_net, l_remote_addr);
-                        dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t);
-                        int res = 0;//dap_dns_client_get_addr(l_remote_node_info->hdr.ext_addr_v4.s_addr, l_net->pub.name, l_link_node_info);
-                        memcpy(l_link_node_info, l_remote_node_info, sizeof(dap_chain_node_info_t));
-                        DAP_DELETE(l_remote_node_info);
-                        if (res) {
-                            DAP_DELETE(l_link_node_info);
-                        } else {
+                        if(l_remote_node_info) {
+                            dap_chain_node_info_t *l_link_node_info = DAP_NEW_Z(dap_chain_node_info_t);
+                            int res = 0; //dap_dns_client_get_addr(l_remote_node_info->hdr.ext_addr_v4.s_addr, l_net->pub.name, l_link_node_info);
+                            memcpy(l_link_node_info, l_remote_node_info, sizeof(dap_chain_node_info_t));
                             l_pvt_net->links_info = dap_list_append(l_pvt_net->links_info, l_link_node_info);
+                            //DAP_DELETE(l_link_node_info);
+                            DAP_DELETE(l_remote_node_info);
+                        }
+                        else{
+                            log_it(L_WARNING, "Not found link "NODE_ADDR_FP_STR" in the node list", NODE_ADDR_FPS_ARGS(l_remote_addr));
                         }
                         if (l_pvt_net->state_target == NET_STATE_OFFLINE) {
                             l_pvt_net->state = NET_STATE_OFFLINE;
diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c
index 9261eec8bfae7ed9fefe0289f998fa54065a725c..aaf563d863221a664b0a72364784bf60975043ec 100644
--- a/modules/service/vpn/dap_chain_net_srv_vpn.c
+++ b/modules/service/vpn/dap_chain_net_srv_vpn.c
@@ -936,7 +936,6 @@ void s_ch_vpn_new(dap_stream_ch_t* a_ch, void* a_arg)
  */
 void s_ch_vpn_delete(dap_stream_ch_t* ch, void* arg)
 {
-    log_it(L_DEBUG, "ch_sf_delete() for %s", ch->stream->esocket->hostaddr);
     dap_chain_net_srv_ch_vpn_t * l_ch_vpn = CH_VPN(ch);
     dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_ch_vpn->net_srv->_inhertor;
 
@@ -1377,16 +1376,17 @@ static size_t s_stream_session_esocket_send(dap_chain_net_srv_stream_session_t *
     }
 
     if(l_data_left_to_send){
-        if ( dap_events_socket_write_unsafe( l_es, a_data +l_direct_wrote,l_data_left_to_send
-                                             ) < l_data_left_to_send ){
-            log_it(L_WARNING,"Loosing data, probably buffers are overfilling, lost %zd bytes", l_data_left_to_send);
+        //if ( dap_events_socket_write_unsafe( l_es, a_data +l_direct_wrote,l_data_left_to_send
+        //                                     ) < l_data_left_to_send ){
+            //log_it(L_WARNING,"Loosing data, probably buffers are overfilling, lost %zd bytes", l_data_left_to_send);
+            log_it(L_WARNING,"Loosing data, lost %zd bytes", l_data_left_to_send);
             l_srv_session->stats.bytes_sent_lost += l_data_left_to_send;
             l_srv_session->stats.packets_sent_lost++;
-        }else{
+        /*}else{
             l_ret += l_data_left_to_send;
             l_srv_session->stats.packets_sent++;
             l_srv_session->stats.bytes_sent+= l_direct_wrote;
-        }
+        }*/
     }
     return l_ret;
 }