diff --git a/CMakeLists.txt b/CMakeLists.txt
index 404c7ae319bd9f786997da4e19dc4c388dc21dcc..e9838e4e4aa47bce6da51f9445f5ebb8b3ebaaa8 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,6 +3,7 @@ project (dap_chain_net_srv_vpn)
   
 set(DAP_CHAIN_NET_SRV_VPN_SRCS 
 	dap_chain_net_srv_vpn.c
+        dap_chain_net_srv_vpn_cdb.c
         dap_chain_net_srv_vpn_cdb_server_list.c
 	dap_chain_net_vpn_client.c
 	dap_chain_net_vpn_client_tun.c
@@ -10,7 +11,8 @@ set(DAP_CHAIN_NET_SRV_VPN_SRCS
 
 set(DAP_CHAIN_NET_SRV_VPN_HEADERS
 	dap_chain_net_srv_vpn.h
-	dap_chain_net_srv_vpn_cdb_server_list.h
+        dap_chain_net_srv_vpn_cdb.h
+        dap_chain_net_srv_vpn_cdb_server_list.h
 	dap_chain_net_vpn_client.h
 	dap_chain_net_vpn_client_tun.h
 
@@ -28,7 +30,7 @@ endif()
 
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_VPN_SRCS} ${DAP_CHAIN_NET_SRV_VPN_HEADERS})
 
-target_link_libraries(dap_chain_net_srv_vpn dap_core dap_crypto dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv)
+target_link_libraries(dap_chain_net_srv_vpn dap_core dap_crypto dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv dap_server_http_db dap_server_http_db_auth)
 target_include_directories(dap_chain_net_srv_vpn INTERFACE .)
 
 set(${PROJECT_NAME}_DEFINITIONS CACHE INTERNAL "${PROJECT_NAME}: Definitions" FORCE)
diff --git a/dap_chain_net_srv_vpn.c b/dap_chain_net_srv_vpn.c
index ca36c8246c8119a3485f1dec856e34508d322f7a..80c776a5b60f4ad302dbac7233bc903cd6ecd422 100755
--- a/dap_chain_net_srv_vpn.c
+++ b/dap_chain_net_srv_vpn.c
@@ -63,6 +63,7 @@
 
 #include "dap_chain_net.h"
 #include "dap_chain_net_srv_vpn.h"
+#include "dap_chain_net_vpn_client.h"
 #include "dap_chain_ledger.h"
 
 #define LOG_TAG "dap_chain_net_srv_vpn"
@@ -97,28 +98,29 @@ static list_addr_element *list_addr_head = NULL;
 
 static ch_vpn_socket_proxy_t * sf_socks = NULL;
 static ch_vpn_socket_proxy_t * sf_socks_client = NULL;
-static pthread_mutex_t sf_socks_mutex;
-static pthread_cond_t sf_socks_cond;
+static pthread_mutex_t s_sf_socks_mutex;
+static pthread_cond_t s_sf_socks_cond;
 static int sf_socks_epoll_fd;
 static pthread_t srv_sf_socks_pid;
 static pthread_t srv_sf_socks_raw_pid;
+static vpn_local_network_t *s_raw_server;
 
-vpn_local_network_t *raw_server;
+static const char *s_addr;
 
-void *srv_ch_sf_thread(void * arg);
-void *srv_ch_sf_thread_raw(void *arg);
-void srv_ch_sf_tun_create();
-void srv_ch_sf_tun_destroy();
+static void *srv_ch_sf_thread(void * arg);
+static void *srv_ch_sf_thread_raw(void *arg);
+static void s_tun_create(void);
+static void s_tun_destroy(void);
 
-void srv_ch_sf_new(dap_stream_ch_t* ch, void* arg);
-void srv_ch_sf_delete(dap_stream_ch_t* ch, void* arg);
-void srv_ch_sf_packet_in(dap_stream_ch_t* ch, void* arg);
-void srv_ch_sf_packet_out(dap_stream_ch_t* ch, void* arg);
+static void s_new(dap_stream_ch_t* ch, void* arg);
+static void srv_ch_sf_delete(dap_stream_ch_t* ch, void* arg);
+static void srv_ch_sf_packet_in(dap_stream_ch_t* ch, void* arg);
+static void srv_ch_sf_packet_out(dap_stream_ch_t* ch, void* arg);
 
 //static int srv_ch_sf_raw_write(uint8_t op_code, const void * data, size_t data_size);
-//void srv_stream_sf_disconnect(ch_vpn_socket_proxy_t * sf_sock);
+//static void srv_stream_sf_disconnect(ch_vpn_socket_proxy_t * sf_sock);
 
-static const char *s_srv_vpn_addr, *s_srv_vpn_mask;
+static char *s_srv_vpn_addr, *s_srv_vpn_mask;
 
 /**
  * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel
@@ -128,20 +130,20 @@ static const char *s_srv_vpn_addr, *s_srv_vpn_mask;
  */
 int dap_chain_net_srv_vpn_init(dap_config_t * g_config)
 {
-    const char *s_addr = dap_config_get_item_str(g_config, "vpn", "network_address");
-    const char *s_mask = dap_config_get_item_str(g_config, "vpn", "network_mask");
-    if(s_addr && s_mask) {
-        s_srv_vpn_addr = strdup(s_addr);
-        s_srv_vpn_mask = strdup(s_mask);
-
-        raw_server = calloc(1, sizeof(vpn_local_network_t));
-        pthread_mutex_init(&raw_server->clients_mutex, NULL);
-        pthread_mutex_init(&raw_server->pkt_out_mutex, NULL);
-        pthread_mutex_init(&sf_socks_mutex, NULL);
-        pthread_cond_init(&sf_socks_cond, NULL);
+    const char *c_addr = dap_config_get_item_str(g_config, "vpn", "network_address");
+    const char *c_mask = dap_config_get_item_str(g_config, "vpn", "network_mask");
+    if(c_addr && c_mask) {
+        s_srv_vpn_addr = strdup(c_addr);
+        s_srv_vpn_mask = strdup(c_mask);
+
+        s_raw_server = DAP_NEW_Z(vpn_local_network_t);
+        pthread_mutex_init(&s_raw_server->clients_mutex, NULL);
+        pthread_mutex_init(&s_raw_server->pkt_out_mutex, NULL);
+        pthread_mutex_init(&s_sf_socks_mutex, NULL);
+        pthread_cond_init(&s_sf_socks_cond, NULL);
         pthread_create(&srv_sf_socks_raw_pid, NULL, srv_ch_sf_thread_raw, NULL);
         pthread_create(&srv_sf_socks_pid, NULL, srv_ch_sf_thread, NULL);
-        dap_stream_ch_proc_add(SERVICE_CHANNEL_ID, srv_ch_sf_new, srv_ch_sf_delete, srv_ch_sf_packet_in,
+        dap_stream_ch_proc_add(DAP_STREAM_CH_ID_NET_SRV_VPN, s_new, srv_ch_sf_delete, srv_ch_sf_packet_in,
                 srv_ch_sf_packet_out);
         return 0;
     }
@@ -151,43 +153,46 @@ int dap_chain_net_srv_vpn_init(dap_config_t * g_config)
 /**
  * @brief ch_sf_deinit
  */
-void dap_chain_net_srv_vpn_deinit()
+void dap_chain_net_srv_vpn_deinit(void)
 {
-    pthread_mutex_destroy(&sf_socks_mutex);
-    pthread_cond_destroy(&sf_socks_cond);
+    pthread_mutex_destroy(&s_sf_socks_mutex);
+    pthread_cond_destroy(&s_sf_socks_cond);
     free((char*) s_srv_vpn_addr);
     free((char*) s_srv_vpn_mask);
-    if(raw_server)
-        free(raw_server);
+    if(s_raw_server)
+        free(s_raw_server);
 }
 
-void srv_ch_sf_tun_create()
+/**
+ * @brief s_tun_create
+ */
+static void s_tun_create(void)
 {
-    inet_aton(s_srv_vpn_addr, &raw_server->client_addr);
-    inet_aton(s_srv_vpn_mask, &raw_server->client_addr_mask);
-    raw_server->client_addr_host.s_addr = (raw_server->client_addr.s_addr | 0x01000000); // grow up some shit here!
-    raw_server->client_addr_last.s_addr = raw_server->client_addr_host.s_addr;
+    inet_aton(s_srv_vpn_addr, &s_raw_server->client_addr);
+    inet_aton(s_srv_vpn_mask, &s_raw_server->client_addr_mask);
+    s_raw_server->client_addr_host.s_addr = (s_raw_server->client_addr.s_addr | 0x01000000); // grow up some shit here!
+    s_raw_server->client_addr_last.s_addr = s_raw_server->client_addr_host.s_addr;
 
-    if((raw_server->tun_ctl_fd = open("/dev/net/tun", O_RDWR)) < 0) {
+    if((s_raw_server->tun_ctl_fd = open("/dev/net/tun", O_RDWR)) < 0) {
         log_it(L_ERROR, "Opening /dev/net/tun error: '%s'", strerror(errno));
     } else {
         int err;
-        memset(&raw_server->ifr, 0, sizeof(raw_server->ifr));
-        raw_server->ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
-        if((err = ioctl(raw_server->tun_ctl_fd, TUNSETIFF, (void *) &raw_server->ifr)) < 0) {
+        memset(&s_raw_server->ifr, 0, sizeof(s_raw_server->ifr));
+        s_raw_server->ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
+        if((err = ioctl(s_raw_server->tun_ctl_fd, TUNSETIFF, (void *) &s_raw_server->ifr)) < 0) {
             log_it(L_CRITICAL, "ioctl(TUNSETIFF) error: '%s' ", strerror(errno));
-            close(raw_server->tun_ctl_fd);
-            raw_server->tun_ctl_fd = -1;
+            close(s_raw_server->tun_ctl_fd);
+            s_raw_server->tun_ctl_fd = -1;
         } else {
             char buf[256];
-            log_it(L_NOTICE, "Bringed up %s virtual network interface (%s/%s)", raw_server->ifr.ifr_name,
-                    inet_ntoa(raw_server->client_addr_host), s_srv_vpn_mask);
-            raw_server->tun_fd = raw_server->tun_ctl_fd; // Looks yes, its so
-            snprintf(buf, sizeof(buf), "ip link set %s up", raw_server->ifr.ifr_name);
+            log_it(L_NOTICE, "Bringed up %s virtual network interface (%s/%s)", s_raw_server->ifr.ifr_name,
+                    inet_ntoa(s_raw_server->client_addr_host), s_srv_vpn_mask);
+            s_raw_server->tun_fd = s_raw_server->tun_ctl_fd; // Looks yes, its so
+            snprintf(buf, sizeof(buf), "ip link set %s up", s_raw_server->ifr.ifr_name);
             int res = system(buf);
-            snprintf(buf, sizeof(buf), "ip addr add %s/%s dev %s ", inet_ntoa(raw_server->client_addr_host),
+            snprintf(buf, sizeof(buf), "ip addr add %s/%s dev %s ", inet_ntoa(s_raw_server->client_addr_host),
                     s_srv_vpn_mask,
-                    raw_server->ifr.ifr_name);
+                    s_raw_server->ifr.ifr_name);
             res = system(buf);
             res = 0;
         }
@@ -195,13 +200,21 @@ void srv_ch_sf_tun_create()
 
 }
 
-void srv_ch_sf_tun_destroy()
+/**
+ * @brief s_tun_destroy
+ */
+static void s_tun_destroy(void)
 {
-    close(raw_server->tun_fd);
-    raw_server->tun_fd = -1;
+    close(s_raw_server->tun_fd);
+    s_raw_server->tun_fd = -1;
 }
 
-static void callback_trafic(dap_client_remote_t *a_client, dap_stream_ch_t* a_ch)
+/**
+ * @brief s_callback_trafic
+ * @param a_client
+ * @param a_ch
+ */
+static void s_callback_trafic(dap_client_remote_t *a_client, dap_stream_ch_t* a_ch)
 {
     dap_chain_net_srv_vpn_t *l_ch_vpn = CH_VPN(a_ch);
     //dap_stream_ch_vpn_t *l_ch_vpn = (dap_stream_ch_vpn_t*)(a_ch->internal);
@@ -233,32 +246,34 @@ static void callback_trafic(dap_client_remote_t *a_client, dap_stream_ch_t* a_ch
  * @brief ch_sf_socket_delete
  * @param sf
  */
-static void ch_sf_socket_delete(ch_vpn_socket_proxy_t * sf)
+static void ch_sf_socket_delete(ch_vpn_socket_proxy_t * a_vpn_socket_proxy)
 {
-    close(sf->sock);
-    pthread_mutex_destroy(& (sf->mutex) );
-    if (sf)
-        free(sf);
+    close(a_vpn_socket_proxy->sock);
+    pthread_mutex_destroy(& (a_vpn_socket_proxy->mutex) );
+    if (a_vpn_socket_proxy)
+        DAP_DELETE(a_vpn_socket_proxy);
 }
 
 
 /**
- * @brief stream_sf_new Callback to constructor of object of Ch
+ * @brief s_new Callback to constructor of object of Ch
  * @param ch
  * @param arg
  */
-void srv_ch_sf_new(dap_stream_ch_t* ch, void* arg)
+void s_new(dap_stream_ch_t* a_stream_ch, void* a_arg)
 {
-    ch->internal = calloc(1, sizeof(dap_chain_net_srv_vpn_t));
-    dap_chain_net_srv_vpn_t * sf = CH_VPN(ch);
+    (void) a_arg;
+
+    a_stream_ch->internal = DAP_NEW_Z(dap_chain_net_srv_vpn_t);
+    dap_chain_net_srv_vpn_t * sf = CH_VPN(a_stream_ch);
     pthread_mutex_init(&sf->mutex, NULL);
     sf->raw_l3_sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
     //
-    if(ch->stream->session->service_key) {
+    if(a_stream_ch->stream->session->service_key) {
 
         char *l_addr_base58;
         char *l_sign_hash_str;
-        ch->stream->session->service_key =
+        a_stream_ch->stream->session->service_key =
                 "RpiDC8c1SxrT7TUExyGWNErgV6HtwkKhSd1yLEkTA9qHcSiYA4GXjE67KJQay2TzHdG2ouk42d8GgLyABu6rP55JeFYzBkqZ7CqijDEw;12345";
 
         const dap_chain_net_srv_abstract_t *l_cond = NULL;
@@ -266,14 +281,14 @@ void srv_ch_sf_new(dap_stream_ch_t* ch, void* arg)
         const char *l_net_name = "kelvin-testnet";
         dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(l_net_name);
         // get value for service and fill l_cond struct
-        uint64_t l_value = dap_chain_net_srv_client_auth(l_ledger, ch->stream->session->service_key, &l_cond);
+        uint64_t l_value = dap_chain_net_srv_client_auth(l_ledger, a_stream_ch->stream->session->service_key, &l_cond);
 
         // add service
         if(l_cond && l_value > 0)
                 {
             dap_chain_net_srv_t l_srv;
             memset(&l_srv, 0, sizeof(dap_chain_net_srv_t));
-            l_srv.callback_trafic = callback_trafic;
+            l_srv.callback_trafic = s_callback_trafic;
             // debug
             l_srv.srv_common.proposal_params.vpn.limit_bytes = 2000;
             if(l_cond)
@@ -308,11 +323,11 @@ void srv_ch_sf_delete(dap_stream_ch_t* ch, void* arg)
         LL_APPEND(list_addr_head, el);
         //   LL_FOREACH(list_addr_head,el) log_it(L_INFO,"addr = %s", inet_ntoa(el->addr));
 
-        pthread_mutex_lock(&raw_server->clients_mutex);
+        pthread_mutex_lock(&s_raw_server->clients_mutex);
 
-        HASH_FIND_INT(raw_server->clients, &raw_client_addr, raw_client);
+        HASH_FIND_INT(s_raw_server->clients, &raw_client_addr, raw_client);
         if(raw_client) {
-            HASH_DEL(raw_server->clients, raw_client);
+            HASH_DEL(s_raw_server->clients, raw_client);
             log_it(L_DEBUG, "ch_sf_delete() %s removed from hash table",
                     inet_ntoa(ch->stream->session->tun_client_addr));
             free(raw_client);
@@ -320,7 +335,7 @@ void srv_ch_sf_delete(dap_stream_ch_t* ch, void* arg)
             log_it(L_DEBUG, "ch_sf_delete() %s is not present in raw sockets hash table",
                     inet_ntoa(ch->stream->session->tun_client_addr));
 
-        pthread_mutex_unlock(&raw_server->clients_mutex);
+        pthread_mutex_unlock(&s_raw_server->clients_mutex);
     }
     HASH_ITER(hh, CH_VPN(ch)->socks , cur, tmp)
     {
@@ -363,17 +378,17 @@ static void stream_sf_socket_ready_to_write(dap_stream_ch_t * ch, bool is_ready)
 static ch_vpn_pkt_t* srv_ch_sf_raw_read()
 {
     ch_vpn_pkt_t*ret = NULL;
-    pthread_mutex_lock(&raw_server->pkt_out_mutex);
-    if(raw_server->pkt_out_rindex == (sizeof(raw_server->pkt_out) / sizeof(raw_server->pkt_out[0]))) {
-        raw_server->pkt_out_rindex = 0; // ring the buffer!
+    pthread_mutex_lock(&s_raw_server->pkt_out_mutex);
+    if(s_raw_server->pkt_out_rindex == (sizeof(s_raw_server->pkt_out) / sizeof(s_raw_server->pkt_out[0]))) {
+        s_raw_server->pkt_out_rindex = 0; // ring the buffer!
     }
-    if((raw_server->pkt_out_rindex != raw_server->pkt_out_windex) || (raw_server->pkt_out_size == 0)) {
-        ret = raw_server->pkt_out[raw_server->pkt_out_rindex];
-        raw_server->pkt_out_rindex++;
-        raw_server->pkt_out_size--;
+    if((s_raw_server->pkt_out_rindex != s_raw_server->pkt_out_windex) || (s_raw_server->pkt_out_size == 0)) {
+        ret = s_raw_server->pkt_out[s_raw_server->pkt_out_rindex];
+        s_raw_server->pkt_out_rindex++;
+        s_raw_server->pkt_out_size--;
     } //else
       //  log_it(L_WARNING, "Packet drop on raw_read() operation, ring buffer is full");
-    pthread_mutex_unlock(&raw_server->pkt_out_mutex);
+    pthread_mutex_unlock(&s_raw_server->pkt_out_mutex);
     return ret;
 }
 
@@ -386,280 +401,285 @@ void srv_ch_sf_packet_in(dap_stream_ch_t* ch, void* arg)
 {
     dap_stream_ch_pkt_t * pkt = (dap_stream_ch_pkt_t *) arg;
 
-    static bool client_connected = false;
-    ch_vpn_pkt_t * sf_pkt = (ch_vpn_pkt_t *) pkt->data;
+    if ( pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT )
+        dap_chain_net_vpn_client_pkt_in( ch, pkt);
+    else {
+        static bool client_connected = false;
+        ch_vpn_pkt_t * sf_pkt = (ch_vpn_pkt_t *) pkt->data;
 
-    int remote_sock_id = sf_pkt->header.sock_id;
+        int remote_sock_id = sf_pkt->header.sock_id;
 
-    //log_it(L_DEBUG, "Got SF packet with id %d op_code 0x%02x", remote_sock_id, sf_pkt->header.op_code);
-    if(sf_pkt->header.op_code >= 0xb0) { // Raw packets
-        switch (sf_pkt->header.op_code) {
-        case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: { // Client request after L3 connection the new IP address
-            log_it(L_DEBUG, "Got SF packet with id %d op_code 0x%02x", remote_sock_id, sf_pkt->header.op_code);
-            struct in_addr n_addr = { 0 };
+        //log_it(L_DEBUG, "Got SF packet with id %d op_code 0x%02x", remote_sock_id, sf_pkt->header.op_code);
+        if(sf_pkt->header.op_code >= 0xb0) { // Raw packets
+            switch (sf_pkt->header.op_code) {
+            case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: { // Client request after L3 connection the new IP address
+                log_it(L_DEBUG, "Got SF packet with id %d op_code 0x%02x", remote_sock_id, sf_pkt->header.op_code);
+                struct in_addr n_addr = { 0 };
 
-            if(n_addr.s_addr == 0) { // If the addres still in the network
+                if(n_addr.s_addr == 0) { // If the addres still in the network
 
-                pthread_mutex_lock(&raw_server->clients_mutex);
+                    pthread_mutex_lock(&s_raw_server->clients_mutex);
 
-                int count_free_addr = -1;
-                list_addr_element *el;
-                LL_COUNT(list_addr_head, el, count_free_addr);
+                    int count_free_addr = -1;
+                    list_addr_element *el;
+                    LL_COUNT(list_addr_head, el, count_free_addr);
 
-                dap_stream_ch_vpn_remote_single_t * n_client = (dap_stream_ch_vpn_remote_single_t*) calloc(1,
-                        sizeof(dap_stream_ch_vpn_remote_single_t));
-                n_client->ch = ch;
+                    dap_stream_ch_vpn_remote_single_t * n_client = (dap_stream_ch_vpn_remote_single_t*) calloc(1,
+                            sizeof(dap_stream_ch_vpn_remote_single_t));
+                    n_client->ch = ch;
 
-                if(count_free_addr > 0) {
-                    n_addr.s_addr = list_addr_head->addr.s_addr;
-                    LL_DELETE(list_addr_head, list_addr_head);
+                    if(count_free_addr > 0) {
+                        n_addr.s_addr = list_addr_head->addr.s_addr;
+                        LL_DELETE(list_addr_head, list_addr_head);
+                    }
+                    else
+                    {
+                        n_addr.s_addr = ntohl(s_raw_server->client_addr_last.s_addr);
+                        n_addr.s_addr++;
+                        n_addr.s_addr = ntohl(n_addr.s_addr);
+                    }
+
+                    n_client->addr = n_addr.s_addr;
+                    s_raw_server->client_addr_last.s_addr = n_addr.s_addr;
+                    ch->stream->session->tun_client_addr.s_addr = n_addr.s_addr;
+                    HASH_ADD_INT(s_raw_server->clients, addr, n_client);
+
+                    pthread_mutex_unlock(&s_raw_server->clients_mutex);
+
+                    log_it(L_NOTICE, "VPN client address %s leased", inet_ntoa(n_addr));
+                    log_it(L_INFO, "\tgateway %s", inet_ntoa(s_raw_server->client_addr_host));
+                    log_it(L_INFO, "\tmask %s", inet_ntoa(s_raw_server->client_addr_mask));
+                    log_it(L_INFO, "\taddr %s", inet_ntoa(s_raw_server->client_addr));
+                    log_it(L_INFO, "\tlast_addr %s", inet_ntoa(s_raw_server->client_addr_last));
+
+                    ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1,
+                            sizeof(pkt_out->header) + sizeof(n_addr) + sizeof(s_raw_server->client_addr_host));
+                    pkt_out->header.sock_id = s_raw_server->tun_fd;
+                    pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REPLY;
+                    pkt_out->header.op_data.data_size = sizeof(n_addr) + sizeof(s_raw_server->client_addr_host);
+
+                    memcpy(pkt_out->data, &n_addr, sizeof(n_addr));
+                    memcpy(pkt_out->data + sizeof(n_addr), &s_raw_server->client_addr_host,
+                            sizeof(s_raw_server->client_addr_host));
+                    dap_stream_ch_pkt_write(ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
+                            pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
+                    stream_sf_socket_ready_to_write(ch, true);
+
+                    //ch_sf_raw_write(n_addr.s_addr,STREAM_SF_PACKET_OP_CODE_RAW_L3_ADDR_REPLY,&n_addr,sizeof(n_addr));
+                } else { // All the network is filled with clients, can't lease a new address
+                    log_it(L_WARNING, "All the network is filled with clients, can't lease a new address");
+                    ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
+                    pkt_out->header.sock_id = s_raw_server->tun_fd;
+                    pkt_out->header.op_code = VPN_PACKET_OP_CODE_PROBLEM;
+                    pkt_out->header.op_problem.code = VPN_PROBLEM_CODE_NO_FREE_ADDR;
+                    dap_stream_ch_pkt_write(ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
+                            pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
+                    stream_sf_socket_ready_to_write(ch, true);
                 }
-                else
-                {
-                    n_addr.s_addr = ntohl(raw_server->client_addr_last.s_addr);
-                    n_addr.s_addr++;
-                    n_addr.s_addr = ntohl(n_addr.s_addr);
+            }
+                break;
+            case VPN_PACKET_OP_CODE_VPN_SEND: {
+                struct in_addr in_saddr, in_daddr;
+                in_saddr.s_addr = ((struct iphdr*) sf_pkt->data)->saddr;
+                in_daddr.s_addr = ((struct iphdr*) sf_pkt->data)->daddr;
+
+                char str_daddr[42], str_saddr[42];
+                strncpy(str_saddr, inet_ntoa(in_saddr), sizeof(str_saddr));
+                strncpy(str_daddr, inet_ntoa(in_daddr), sizeof(str_daddr));
+                int ret;
+                //if( ch_sf_raw_write(STREAM_SF_PACKET_OP_CODE_RAW_SEND, sf_pkt->data, sf_pkt->op_data.data_size)<0){
+                struct sockaddr_in sin = { 0 };
+                sin.sin_family = AF_INET;
+                sin.sin_port = 0;
+                sin.sin_addr.s_addr = in_daddr.s_addr;
+
+                //if((ret=sendto(CH_SF(ch)->raw_l3_sock , sf_pkt->data,sf_pkt->header.op_data.data_size,0,(struct sockaddr *) &sin, sizeof (sin)))<0){
+                if((ret = write(s_raw_server->tun_fd, sf_pkt->data, sf_pkt->header.op_data.data_size)) < 0) {
+                    log_it(L_ERROR, "write() returned error %d : '%s'", ret, strerror(errno));
+                    //log_it(L_ERROR,"raw socket ring buffer overflowed");
+                    ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
+                    pkt_out->header.op_code = VPN_PACKET_OP_CODE_PROBLEM;
+                    pkt_out->header.op_problem.code = VPN_PROBLEM_CODE_PACKET_LOST;
+                    pkt_out->header.sock_id = s_raw_server->tun_fd;
+                    dap_stream_ch_pkt_write(ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
+                            pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
+                    stream_sf_socket_ready_to_write(ch, true);
+                } else {
+                    //log_it(L_DEBUG, "Raw IP packet daddr:%s saddr:%s  %u from %d bytes sent to tun/tap interface",
+                    //        str_saddr, str_daddr, sf_pkt->header.op_data.data_size, ret);
+                    //log_it(L_DEBUG, "Raw IP sent %u bytes ", ret);
                 }
-
-                n_client->addr = n_addr.s_addr;
-                raw_server->client_addr_last.s_addr = n_addr.s_addr;
-                ch->stream->session->tun_client_addr.s_addr = n_addr.s_addr;
-                HASH_ADD_INT(raw_server->clients, addr, n_client);
-
-                pthread_mutex_unlock(&raw_server->clients_mutex);
-
-                log_it(L_NOTICE, "VPN client address %s leased", inet_ntoa(n_addr));
-                log_it(L_INFO, "\tgateway %s", inet_ntoa(raw_server->client_addr_host));
-                log_it(L_INFO, "\tmask %s", inet_ntoa(raw_server->client_addr_mask));
-                log_it(L_INFO, "\taddr %s", inet_ntoa(raw_server->client_addr));
-                log_it(L_INFO, "\tlast_addr %s", inet_ntoa(raw_server->client_addr_last));
-
-                ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1,
-                        sizeof(pkt_out->header) + sizeof(n_addr) + sizeof(raw_server->client_addr_host));
-                pkt_out->header.sock_id = raw_server->tun_fd;
-                pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REPLY;
-                pkt_out->header.op_data.data_size = sizeof(n_addr) + sizeof(raw_server->client_addr_host);
-                memcpy(pkt_out->data, &n_addr, sizeof(n_addr));
-                memcpy(pkt_out->data + sizeof(n_addr), &raw_server->client_addr_host,
-                        sizeof(raw_server->client_addr_host));
-                dap_stream_ch_pkt_write(ch, DATA_CHANNEL_ID, pkt_out,
-                        pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
-                stream_sf_socket_ready_to_write(ch, true);
-
-                //ch_sf_raw_write(n_addr.s_addr,STREAM_SF_PACKET_OP_CODE_RAW_L3_ADDR_REPLY,&n_addr,sizeof(n_addr));
-            } else { // All the network is filled with clients, can't lease a new address
-                log_it(L_WARNING, "All the network is filled with clients, can't lease a new address");
-                ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
-                pkt_out->header.sock_id = raw_server->tun_fd;
-                pkt_out->header.op_code = VPN_PACKET_OP_CODE_PROBLEM;
-                pkt_out->header.op_problem.code = VPN_PROBLEM_CODE_NO_FREE_ADDR;
-                dap_stream_ch_pkt_write(ch, DATA_CHANNEL_ID, pkt_out,
-                        pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
-                stream_sf_socket_ready_to_write(ch, true);
+                //}
             }
-        }
-            break;
-        case VPN_PACKET_OP_CODE_VPN_SEND: {
-            struct in_addr in_saddr, in_daddr;
-            in_saddr.s_addr = ((struct iphdr*) sf_pkt->data)->saddr;
-            in_daddr.s_addr = ((struct iphdr*) sf_pkt->data)->daddr;
-
-            char str_daddr[42], str_saddr[42];
-            strncpy(str_saddr, inet_ntoa(in_saddr), sizeof(str_saddr));
-            strncpy(str_daddr, inet_ntoa(in_daddr), sizeof(str_daddr));
-            int ret;
-            //if( ch_sf_raw_write(STREAM_SF_PACKET_OP_CODE_RAW_SEND, sf_pkt->data, sf_pkt->op_data.data_size)<0){
-            struct sockaddr_in sin = { 0 };
-            sin.sin_family = AF_INET;
-            sin.sin_port = 0;
-            sin.sin_addr.s_addr = in_daddr.s_addr;
-
-            //if((ret=sendto(CH_SF(ch)->raw_l3_sock , sf_pkt->data,sf_pkt->header.op_data.data_size,0,(struct sockaddr *) &sin, sizeof (sin)))<0){
-            if((ret = write(raw_server->tun_fd, sf_pkt->data, sf_pkt->header.op_data.data_size)) < 0) {
-                log_it(L_ERROR, "write() returned error %d : '%s'", ret, strerror(errno));
-                //log_it(L_ERROR,"raw socket ring buffer overflowed");
-                ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
-                pkt_out->header.op_code = VPN_PACKET_OP_CODE_PROBLEM;
-                pkt_out->header.op_problem.code = VPN_PROBLEM_CODE_PACKET_LOST;
-                pkt_out->header.sock_id = raw_server->tun_fd;
-                dap_stream_ch_pkt_write(ch, DATA_CHANNEL_ID, pkt_out,
-                        pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
-                stream_sf_socket_ready_to_write(ch, true);
-            } else {
-                //log_it(L_DEBUG, "Raw IP packet daddr:%s saddr:%s  %u from %d bytes sent to tun/tap interface",
-                //        str_saddr, str_daddr, sf_pkt->header.op_data.data_size, ret);
-                //log_it(L_DEBUG, "Raw IP sent %u bytes ", ret);
+                break;
+            default:
+                log_it(L_WARNING, "Can't process SF type 0x%02x", sf_pkt->header.op_code);
             }
-            //}
-        }
-            break;
-        default:
-            log_it(L_WARNING, "Can't process SF type 0x%02x", sf_pkt->header.op_code);
-        }
-    } else { // All except CONNECT
-        ch_vpn_socket_proxy_t * sf_sock = NULL;
-        if(sf_pkt->header.op_code != VPN_PACKET_OP_CODE_CONNECT) {
+        } else { // All except CONNECT
+            ch_vpn_socket_proxy_t * sf_sock = NULL;
+            if(sf_pkt->header.op_code != VPN_PACKET_OP_CODE_CONNECT) {
+
+                pthread_mutex_lock(&( CH_VPN(ch)->mutex));
+                //      log_it(L_DEBUG,"Looking in hash table with %d",remote_sock_id);
+                HASH_FIND_INT((CH_VPN(ch)->socks), &remote_sock_id, sf_sock);
+                pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
+
+                if(sf_sock != NULL) {
+                    pthread_mutex_lock(&sf_sock->mutex); // Unlock it in your case as soon as possible to reduce lock time
+                    sf_sock->time_lastused = time(NULL);
+                    switch (sf_pkt->header.op_code) {
+                    case VPN_PACKET_OP_CODE_SEND: {
+                        if(client_connected == false)
+                        {
+                            log_it(L_WARNING, "Drop Packet! User not connected!"); // Client need send
+                            pthread_mutex_unlock(&s_sf_socks_mutex);
+                            break;
+                        }
+                        int ret;
+                        if((ret = send(sf_sock->sock, sf_pkt->data, sf_pkt->header.op_data.data_size, 0)) < 0) {
+                            log_it(L_INFO, "Disconnected from the remote host");
+                            pthread_mutex_unlock(&sf_sock->mutex);
+                            pthread_mutex_lock(&( CH_VPN(ch)->mutex));
+                            HASH_DEL(CH_VPN(ch)->socks, sf_sock);
+                            pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
 
-            pthread_mutex_lock(&( CH_VPN(ch)->mutex));
-            //      log_it(L_DEBUG,"Looking in hash table with %d",remote_sock_id);
-            HASH_FIND_INT((CH_VPN(ch)->socks), &remote_sock_id, sf_sock);
-            pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
+                            pthread_mutex_lock(&s_sf_socks_mutex);
+                            HASH_DELETE(hh2, sf_socks, sf_sock);
+                            HASH_DELETE(hh_sock, sf_socks_client, sf_sock);
 
-            if(sf_sock != NULL) {
-                pthread_mutex_lock(&sf_sock->mutex); // Unlock it in your case as soon as possible to reduce lock time
-                sf_sock->time_lastused = time(NULL);
-                switch (sf_pkt->header.op_code) {
-                case VPN_PACKET_OP_CODE_SEND: {
-                    if(client_connected == false)
-                    {
-                        log_it(L_WARNING, "Drop Packet! User not connected!"); // Client need send
-                        pthread_mutex_unlock(&sf_socks_mutex);
-                        break;
+                            struct epoll_event ev;
+                            ev.data.fd = sf_sock->sock;
+                            ev.events = EPOLLIN;
+                            if(epoll_ctl(sf_socks_epoll_fd, EPOLL_CTL_DEL, sf_sock->sock, &ev) < 0) {
+                                log_it(L_ERROR, "Can't remove sock_id %d from the epoll fd", remote_sock_id);
+                                //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=0x%02x result=-2",sf_pkt->sock_id, sf_pkt->op_code);
+                            } else {
+                                log_it(L_NOTICE, "Removed sock_id %d from the the epoll fd", remote_sock_id);
+                                //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=0x%02x result=0",sf_pkt->sock_id, sf_pkt->op_code);
+                            }
+                            pthread_mutex_unlock(&s_sf_socks_mutex);
+
+                            stream_sf_socket_delete(sf_sock);
+                        } else {
+                            sf_sock->bytes_sent += ret;
+                            pthread_mutex_unlock(&sf_sock->mutex);
+                        }
+                        //log_it(L_INFO, "Send action from %d sock_id (sf_packet size %lu,  ch packet size %lu, have sent %d)"
+                        //        , sf_sock->id, sf_pkt->header.op_data.data_size, pkt->hdr.size, ret);
                     }
-                    int ret;
-                    if((ret = send(sf_sock->sock, sf_pkt->data, sf_pkt->header.op_data.data_size, 0)) < 0) {
-                        log_it(L_INFO, "Disconnected from the remote host");
-                        pthread_mutex_unlock(&sf_sock->mutex);
+                        break;
+                    case VPN_PACKET_OP_CODE_DISCONNECT: {
+                        log_it(L_INFO, "Disconnect action from %d sock_id", sf_sock->id);
+
                         pthread_mutex_lock(&( CH_VPN(ch)->mutex));
                         HASH_DEL(CH_VPN(ch)->socks, sf_sock);
                         pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
 
-                        pthread_mutex_lock(&sf_socks_mutex);
+                        pthread_mutex_lock(&s_sf_socks_mutex);
                         HASH_DELETE(hh2, sf_socks, sf_sock);
                         HASH_DELETE(hh_sock, sf_socks_client, sf_sock);
-
                         struct epoll_event ev;
                         ev.data.fd = sf_sock->sock;
                         ev.events = EPOLLIN;
                         if(epoll_ctl(sf_socks_epoll_fd, EPOLL_CTL_DEL, sf_sock->sock, &ev) < 0) {
-                            log_it(L_ERROR, "Can't remove sock_id %d from the epoll fd", remote_sock_id);
-                            //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=0x%02x result=-2",sf_pkt->sock_id, sf_pkt->op_code);
+                            log_it(L_ERROR, "Can't remove sock_id %d to the epoll fd", remote_sock_id);
+                            //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=%uc result=-2",sf_pkt->sock_id, sf_pkt->op_code);
                         } else {
-                            log_it(L_NOTICE, "Removed sock_id %d from the the epoll fd", remote_sock_id);
-                            //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=0x%02x result=0",sf_pkt->sock_id, sf_pkt->op_code);
+                            log_it(L_NOTICE, "Removed sock_id %d from the epoll fd", remote_sock_id);
+                            //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=%uc result=0",sf_pkt->sock_id, sf_pkt->op_code);
                         }
-                        pthread_mutex_unlock(&sf_socks_mutex);
+                        pthread_mutex_unlock(&s_sf_socks_mutex);
 
+                        pthread_mutex_unlock(&sf_sock->mutex);
                         stream_sf_socket_delete(sf_sock);
-                    } else {
-                        sf_sock->bytes_sent += ret;
+                    }
+                        break;
+                    default: {
+                        log_it(L_WARNING, "Unprocessed op code 0x%02x", sf_pkt->header.op_code);
                         pthread_mutex_unlock(&sf_sock->mutex);
                     }
-                    //log_it(L_INFO, "Send action from %d sock_id (sf_packet size %lu,  ch packet size %lu, have sent %d)"
-                    //        , sf_sock->id, sf_pkt->header.op_data.data_size, pkt->hdr.size, ret);
-                }
-                    break;
-                case VPN_PACKET_OP_CODE_DISCONNECT: {
-                    log_it(L_INFO, "Disconnect action from %d sock_id", sf_sock->id);
-
-                    pthread_mutex_lock(&( CH_VPN(ch)->mutex));
-                    HASH_DEL(CH_VPN(ch)->socks, sf_sock);
-                    pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
-
-                    pthread_mutex_lock(&sf_socks_mutex);
-                    HASH_DELETE(hh2, sf_socks, sf_sock);
-                    HASH_DELETE(hh_sock, sf_socks_client, sf_sock);
-                    struct epoll_event ev;
-                    ev.data.fd = sf_sock->sock;
-                    ev.events = EPOLLIN;
-                    if(epoll_ctl(sf_socks_epoll_fd, EPOLL_CTL_DEL, sf_sock->sock, &ev) < 0) {
-                        log_it(L_ERROR, "Can't remove sock_id %d to the epoll fd", remote_sock_id);
-                        //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=%uc result=-2",sf_pkt->sock_id, sf_pkt->op_code);
-                    } else {
-                        log_it(L_NOTICE, "Removed sock_id %d from the epoll fd", remote_sock_id);
-                        //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=%uc result=0",sf_pkt->sock_id, sf_pkt->op_code);
                     }
-                    pthread_mutex_unlock(&sf_socks_mutex);
-
-                    pthread_mutex_unlock(&sf_sock->mutex);
-                    stream_sf_socket_delete(sf_sock);
-                }
-                    break;
-                default: {
-                    log_it(L_WARNING, "Unprocessed op code 0x%02x", sf_pkt->header.op_code);
-                    pthread_mutex_unlock(&sf_sock->mutex);
-                }
-                }
-            } //else
-              //  log_it(L_WARNING, "Packet input: packet with sock_id %d thats not present in current stream channel",
-              //          remote_sock_id);
-        } else {
-            HASH_FIND_INT(CH_VPN(ch)->socks, &remote_sock_id, sf_sock);
-            if(sf_sock) {
-                log_it(L_WARNING, "Socket id %d is already used, take another number for socket id", remote_sock_id);
-            } else { // Connect action
-                struct sockaddr_in remote_addr;
-                char addr_str[1024];
-                size_t addr_str_size =
-                        (sf_pkt->header.op_connect.addr_size > (sizeof(addr_str) - 1)) ?
-                                (sizeof(addr_str) - 1) :
-                                sf_pkt->header.op_connect.addr_size;
-                memset(&remote_addr, 0, sizeof(remote_addr));
-                remote_addr.sin_family = AF_INET;
-                remote_addr.sin_port = htons(sf_pkt->header.op_connect.port);
-
-                memcpy(addr_str, sf_pkt->data, addr_str_size);
-                addr_str[addr_str_size] = 0;
-
-                log_it(L_DEBUG, "Connect action to %s:%u (addr_size %lu)", addr_str, sf_pkt->header.op_connect.port,
-                        sf_pkt->header.op_connect.addr_size);
-                if(inet_pton(AF_INET, addr_str, &(remote_addr.sin_addr)) < 0) {
-                    log_it(L_ERROR, "Wrong remote address '%s:%u'", addr_str, sf_pkt->header.op_connect.port);
-                } else {
-                    int s;
-                    if((s = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
-                        log_it(L_DEBUG, "Socket is created (%d)", s);
-                        if(connect(s, (struct sockaddr *) &remote_addr, sizeof(remote_addr)) >= 0) {
-                            fcntl(s, F_SETFL, O_NONBLOCK);
-                            log_it(L_INFO, "Remote address connected (%s:%u) with sock_id %d", addr_str,
-                                    sf_pkt->header.op_connect.port, remote_sock_id);
-                            ch_vpn_socket_proxy_t * sf_sock = NULL;
-                            sf_sock = DAP_NEW_Z(ch_vpn_socket_proxy_t);
-                            sf_sock->id = remote_sock_id;
-                            sf_sock->sock = s;
-                            sf_sock->ch = ch;
-                            pthread_mutex_init(&sf_sock->mutex, NULL);
-
-                            pthread_mutex_lock(&sf_socks_mutex);
-                            pthread_mutex_lock(&( CH_VPN(ch)->mutex));
-                            HASH_ADD_INT(CH_VPN(ch)->socks, id, sf_sock);
-                            log_it(L_DEBUG, "Added %d sock_id with sock %d to the hash table", sf_sock->id,
-                                    sf_sock->sock);
-                            HASH_ADD(hh2, sf_socks, id, sizeof(sf_sock->id), sf_sock);
-                            log_it(L_DEBUG, "Added %d sock_id with sock %d to the hash table", sf_sock->id,
-                                    sf_sock->sock);
-                            HASH_ADD(hh_sock, sf_socks_client, sock, sizeof(int), sf_sock);
-                            //log_it(L_DEBUG,"Added %d sock_id with sock %d to the socks hash table",sf->id,sf->sock);
-                            pthread_mutex_unlock(&sf_socks_mutex);
-                            pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
-
-                            struct epoll_event ev;
-                            ev.data.fd = s;
-                            ev.events = EPOLLIN | EPOLLERR;
-
-                            if(epoll_ctl(sf_socks_epoll_fd, EPOLL_CTL_ADD, s, &ev) == -1) {
-                                log_it(L_ERROR, "Can't add sock_id %d to the epoll fd", remote_sock_id);
-                                //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=%uc result=-2",sf_pkt->sock_id, sf_pkt->op_code);
+                } //else
+                  //  log_it(L_WARNING, "Packet input: packet with sock_id %d thats not present in current stream channel",
+                  //          remote_sock_id);
+            } else {
+                HASH_FIND_INT(CH_VPN(ch)->socks, &remote_sock_id, sf_sock);
+                if(sf_sock) {
+                    log_it(L_WARNING, "Socket id %d is already used, take another number for socket id", remote_sock_id);
+                } else { // Connect action
+                    struct sockaddr_in remote_addr;
+                    char addr_str[1024];
+                    size_t addr_str_size =
+                            (sf_pkt->header.op_connect.addr_size > (sizeof(addr_str) - 1)) ?
+                                    (sizeof(addr_str) - 1) :
+                                    sf_pkt->header.op_connect.addr_size;
+                    memset(&remote_addr, 0, sizeof(remote_addr));
+                    remote_addr.sin_family = AF_INET;
+                    remote_addr.sin_port = htons(sf_pkt->header.op_connect.port);
+
+                    memcpy(addr_str, sf_pkt->data, addr_str_size);
+                    addr_str[addr_str_size] = 0;
+
+                    log_it(L_DEBUG, "Connect action to %s:%u (addr_size %lu)", addr_str, sf_pkt->header.op_connect.port,
+                            sf_pkt->header.op_connect.addr_size);
+                    if(inet_pton(AF_INET, addr_str, &(remote_addr.sin_addr)) < 0) {
+                        log_it(L_ERROR, "Wrong remote address '%s:%u'", addr_str, sf_pkt->header.op_connect.port);
+                    } else {
+                        int s;
+                        if((s = socket(AF_INET, SOCK_STREAM, 0)) >= 0) {
+                            log_it(L_DEBUG, "Socket is created (%d)", s);
+                            if(connect(s, (struct sockaddr *) &remote_addr, sizeof(remote_addr)) >= 0) {
+                                fcntl(s, F_SETFL, O_NONBLOCK);
+                                log_it(L_INFO, "Remote address connected (%s:%u) with sock_id %d", addr_str,
+                                        sf_pkt->header.op_connect.port, remote_sock_id);
+                                ch_vpn_socket_proxy_t * sf_sock = NULL;
+                                sf_sock = DAP_NEW_Z(ch_vpn_socket_proxy_t);
+                                sf_sock->id = remote_sock_id;
+                                sf_sock->sock = s;
+                                sf_sock->ch = ch;
+                                pthread_mutex_init(&sf_sock->mutex, NULL);
+
+                                pthread_mutex_lock(&s_sf_socks_mutex);
+                                pthread_mutex_lock(&( CH_VPN(ch)->mutex));
+                                HASH_ADD_INT(CH_VPN(ch)->socks, id, sf_sock);
+                                log_it(L_DEBUG, "Added %d sock_id with sock %d to the hash table", sf_sock->id,
+                                        sf_sock->sock);
+                                HASH_ADD(hh2, sf_socks, id, sizeof(sf_sock->id), sf_sock);
+                                log_it(L_DEBUG, "Added %d sock_id with sock %d to the hash table", sf_sock->id,
+                                        sf_sock->sock);
+                                HASH_ADD(hh_sock, sf_socks_client, sock, sizeof(int), sf_sock);
+                                //log_it(L_DEBUG,"Added %d sock_id with sock %d to the socks hash table",sf->id,sf->sock);
+                                pthread_mutex_unlock(&s_sf_socks_mutex);
+                                pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
+
+                                struct epoll_event ev;
+                                ev.data.fd = s;
+                                ev.events = EPOLLIN | EPOLLERR;
+
+                                if(epoll_ctl(sf_socks_epoll_fd, EPOLL_CTL_ADD, s, &ev) == -1) {
+                                    log_it(L_ERROR, "Can't add sock_id %d to the epoll fd", remote_sock_id);
+                                    //stream_ch_pkt_write_f(ch,'i',"sock_id=%d op_code=%uc result=-2",sf_pkt->sock_id, sf_pkt->op_code);
+                                } else {
+                                    log_it(L_NOTICE, "Added sock_id %d  with sock %d to the epoll fd", remote_sock_id, s);
+                                    log_it(L_NOTICE, "Send Connected packet to User");
+                                    ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
+                                    pkt_out->header.sock_id = remote_sock_id;
+                                    pkt_out->header.op_code = VPN_PACKET_OP_CODE_CONNECTED;
+                                    dap_stream_ch_pkt_write(ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT, pkt_out,
+                                            pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
+                                    free(pkt_out);
+                                    client_connected = true;
+                                }
+                                stream_sf_socket_ready_to_write(ch, true);
                             } else {
-                                log_it(L_NOTICE, "Added sock_id %d  with sock %d to the epoll fd", remote_sock_id, s);
-                                log_it(L_NOTICE, "Send Connected packet to User");
-                                ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
-                                pkt_out->header.sock_id = remote_sock_id;
-                                pkt_out->header.op_code = VPN_PACKET_OP_CODE_CONNECTED;
-                                dap_stream_ch_pkt_write(ch, SERVICE_CHANNEL_ID, pkt_out,
-                                        pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
-                                free(pkt_out);
-                                client_connected = true;
+                                log_it(L_INFO, "Can't connect to the remote server %s", addr_str);
+                                dap_stream_ch_pkt_write_f(ch, 'i', "sock_id=%d op_code=%c result=-1",
+                                        sf_pkt->header.sock_id, sf_pkt->header.op_code);
+                                stream_sf_socket_ready_to_write(ch, true);
                             }
-                            stream_sf_socket_ready_to_write(ch, true);
                         } else {
-                            log_it(L_INFO, "Can't connect to the remote server %s", addr_str);
-                            dap_stream_ch_pkt_write_f(ch, 'i', "sock_id=%d op_code=%c result=-1",
-                                    sf_pkt->header.sock_id, sf_pkt->header.op_code);
-                            stream_sf_socket_ready_to_write(ch, true);
+                            log_it(L_ERROR, "Can't create the socket");
                         }
-                    } else {
-                        log_it(L_ERROR, "Can't create the socket");
                     }
                 }
             }
@@ -723,9 +743,9 @@ void * srv_ch_sf_thread(void * arg)
             int s = events[n].data.fd;
 
             ch_vpn_socket_proxy_t * sf = NULL;
-            pthread_mutex_lock(&sf_socks_mutex);
+            pthread_mutex_lock(&s_sf_socks_mutex);
             HASH_FIND(hh_sock, sf_socks_client, &s, sizeof(s), sf);
-            pthread_mutex_unlock(&sf_socks_mutex);
+            pthread_mutex_unlock(&s_sf_socks_mutex);
             if(sf) {
                 if(events[n].events & EPOLLERR) {
                     log_it(L_NOTICE, "Socket id %d has EPOLLERR flag on", s);
@@ -784,9 +804,9 @@ void * srv_ch_sf_thread(void * arg)
  **/
 void* srv_ch_sf_thread_raw(void *arg)
 {
-    srv_ch_sf_tun_create();
+    s_tun_create();
 
-    if(raw_server->tun_fd <= 0) {
+    if(s_raw_server->tun_fd <= 0) {
         log_it(L_CRITICAL, "Tun/tap file descriptor is not initialized");
         return NULL;
     }
@@ -810,7 +830,7 @@ void* srv_ch_sf_thread_raw(void *arg)
     fd_set fds_read, fds_read_active;
 
     FD_ZERO(&fds_read);
-    FD_SET(raw_server->tun_fd, &fds_read);
+    FD_SET(s_raw_server->tun_fd, &fds_read);
     FD_SET(get_select_breaker(), &fds_read);
     /// Main cycle
     do {
@@ -821,7 +841,7 @@ void* srv_ch_sf_thread_raw(void *arg)
             if(FD_ISSET(get_select_breaker(), &fds_read_active)) { // Smth to send
                 ch_vpn_pkt_t* pkt = srv_ch_sf_raw_read();
                 if(pkt) {
-                    int write_ret = write(raw_server->tun_fd, pkt->data, pkt->header.op_data.data_size);
+                    int write_ret = write(s_raw_server->tun_fd, pkt->data, pkt->header.op_data.data_size);
                     if(write_ret > 0) {
                         //log_it(L_DEBUG, "Wrote out %d bytes to the tun/tap interface", write_ret);
                     } else {
@@ -830,8 +850,8 @@ void* srv_ch_sf_thread_raw(void *arg)
                     }
                 }
             }
-            if(FD_ISSET(raw_server->tun_fd, &fds_read_active)) {
-                int read_ret = read(raw_server->tun_fd, tmp_buf, tun_MTU);
+            if(FD_ISSET(s_raw_server->tun_fd, &fds_read_active)) {
+                int read_ret = read(s_raw_server->tun_fd, tmp_buf, tun_MTU);
                 if(read_ret < 0) {
                     log_it(L_CRITICAL, "Tun/tap read returned '%s' error, code (%d)", strerror(errno), read_ret);
                     break;
@@ -847,21 +867,21 @@ void* srv_ch_sf_thread_raw(void *arg)
                     //log_it(L_DEBUG, "Read IP packet from tun/tap interface daddr=%s saddr=%s total_size = %d "
                     //        , str_daddr, str_saddr, read_ret);
                     dap_stream_ch_vpn_remote_single_t * raw_client = NULL;
-                    pthread_mutex_lock(&raw_server->clients_mutex);
-                    HASH_FIND_INT(raw_server->clients, &in_daddr.s_addr, raw_client);
+                    pthread_mutex_lock(&s_raw_server->clients_mutex);
+                    HASH_FIND_INT(s_raw_server->clients, &in_daddr.s_addr, raw_client);
 //                  HASH_ADD_INT(CH_SF(ch)->socks, id, sf_sock );
 //                  HASH_DEL(CH_SF(ch)->socks,sf_sock);
                     if(raw_client) { // Is present in hash table such destination address
                         ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + read_ret);
                         pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_RECV;
-                        pkt_out->header.sock_id = raw_server->tun_fd;
+                        pkt_out->header.sock_id = s_raw_server->tun_fd;
                         pkt_out->header.op_data.data_size = read_ret;
                         memcpy(pkt_out->data, tmp_buf, read_ret);
-                        dap_stream_ch_pkt_write(raw_client->ch, DATA_CHANNEL_ID, pkt_out,
+                        dap_stream_ch_pkt_write(raw_client->ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
                                 pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
                         stream_sf_socket_ready_to_write(raw_client->ch, true);
                     }
-                    pthread_mutex_unlock(&raw_server->clients_mutex);
+                    pthread_mutex_unlock(&s_raw_server->clients_mutex);
                 }
             }/*else {
              log_it(L_CRITICAL,"select() has no tun handler in the returned set");
@@ -874,7 +894,7 @@ void* srv_ch_sf_thread_raw(void *arg)
         }
     } while(1);
     log_it(L_NOTICE, "Raw sockets listen thread is stopped");
-    srv_ch_sf_tun_destroy();
+    s_tun_destroy();
     return NULL;
 }
 
@@ -898,7 +918,7 @@ void srv_ch_sf_packet_out(dap_stream_ch_t* ch, void* arg)
             for(i = 0; i < cur->pkt_out_size; i++) {
                 ch_vpn_pkt_t * pout = cur->pkt_out[i];
                 if(pout) {
-                    if(dap_stream_ch_pkt_write(ch, DATA_CHANNEL_ID, pout,
+                    if(dap_stream_ch_pkt_write(ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout,
                             pout->header.op_data.data_size + sizeof(pout->header))) {
                         isSmthOut = true;
                         free(pout);
@@ -925,10 +945,10 @@ void srv_ch_sf_packet_out(dap_stream_ch_t* ch, void* arg)
             HASH_DEL(CH_VPN(ch)->socks, cur);
             pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
 
-            pthread_mutex_lock(&(sf_socks_mutex));
+            pthread_mutex_lock(&(s_sf_socks_mutex));
             HASH_DELETE(hh2, sf_socks, cur);
             HASH_DELETE(hh_sock, sf_socks_client, cur);
-            pthread_mutex_unlock(&(sf_socks_mutex));
+            pthread_mutex_unlock(&(s_sf_socks_mutex));
 
             pthread_mutex_unlock(&(cur->mutex));
             stream_sf_socket_delete(cur);
diff --git a/dap_chain_net_srv_vpn.h b/dap_chain_net_srv_vpn.h
index 9cf9bee52740e67c617d66e770bb3d36f321bfba..115faaaec4390e2a22d93591ef4871189c2feac8 100755
--- a/dap_chain_net_srv_vpn.h
+++ b/dap_chain_net_srv_vpn.h
@@ -28,6 +28,12 @@
 #include "dap_config.h"
 #include "dap_chain_net_srv.h"
 
+
+#define DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT    0x01
+#define DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA      0x02
+
+#define DAP_STREAM_CH_ID_NET_SRV_VPN        'S'
+
 #define DAP_CHAIN_NET_SRV_VPN_ID            0x0000000000000001
 
 #define VPN_PACKET_OP_CODE_CONNECTED        0x000000a9
@@ -140,6 +146,6 @@ typedef struct dap_chain_net_srv_vpn
 #define CH_VPN(a) ((dap_chain_net_srv_vpn_t *) ((a)->internal) )
 
 int dap_chain_net_srv_vpn_init(dap_config_t * g_config);
-void dap_chain_net_srv_vpn_deinit();
+void dap_chain_net_srv_vpn_deinit(void);
 
 
diff --git a/dap_chain_net_srv_vpn_cdb.c b/dap_chain_net_srv_vpn_cdb.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e1e4dc68cf8b1274d06c923d3dbc17e8334d459
--- /dev/null
+++ b/dap_chain_net_srv_vpn_cdb.c
@@ -0,0 +1,294 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * CellFrame       https://cellframe.net
+ * Sources         https://gitlab.demlabs.net/cellframe
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of CellFrame SDK the open source project
+
+    CellFrame SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    CellFrame SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "utlist.h"
+#include "dap_common.h"
+#include "dap_config.h"
+#include "dap_enc_http.h"
+#include "dap_http.h"
+
+#include "db_core.h"
+#include "db_auth.h"
+#include "db_http.h"
+#include "db_http_file.h"
+
+#include "dap_chain.h"
+#include "dap_chain_net.h"
+#include "dap_chain_ledger.h"
+#include "dap_chain_wallet.h"
+#include "dap_chain_datum_tx.h"
+#include "dap_chain_datum_tx_in.h"
+#include "dap_chain_datum_tx_in_cond.h"
+#include "dap_chain_datum_tx_out_cond.h"
+#include "dap_chain_datum_tx_out.h"
+#include "dap_chain_datum_tx_pkey.h"
+#include "dap_chain_datum_tx_receipt.h"
+#include "dap_chain_datum_tx_sig.h"
+#include "dap_chain_global_db.h"
+#include "dap_pkey.h"
+
+#include "dap_chain_net_srv_vpn_cdb.h"
+#include "dap_chain_net_srv_vpn_cdb_server_list.h"
+
+
+#define LOG_TAG "dap_chain_net_srv_vpn_cdb"
+
+#define DB_URL "/db"
+#define DB_FILE_URL "/db_file"
+#define SLIST_URL "/nodelist"
+
+typedef struct tx_cond_template{
+    char * wallet_name;
+    dap_chain_wallet_t * wallet;
+
+    long double value_coins;
+    uint128_t value_datoshi;
+
+    char * token_ticker;
+    char * net_name;
+    dap_chain_net_t * net;
+    dap_ledger_t * ledger;
+    time_t min_time; // Minimum time between transactions
+
+    struct tx_cond_template * prev;
+    struct tx_cond_template * next;
+} tx_cond_template_t;
+
+static tx_cond_template_t * s_tx_cond_templates = NULL;
+const char *c_wallets_path = NULL;
+
+static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg);
+
+/**
+ * @brief dap_chain_net_srv_vpn_cdb_init
+ * @return
+ */
+int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http)
+{
+    int rc;
+    int ret=0;
+    c_wallets_path = dap_chain_wallet_get_path(g_config);
+    if (dap_config_get_item_bool_default( g_config,
+                                                                "cdb",
+                                                                "servers_list_enabled",
+                                                                false)) {
+
+        if (dap_chain_net_srv_vpn_cdb_server_list_init() != 0) {
+            log_it(L_CRITICAL,"Can't init vpn servers list");
+            return -10;
+        }
+    }
+
+
+    if((rc=db_core_init(dap_config_get_item_str_default(g_config,
+                                                        "cdb",
+                                                        "db_path",
+                                                        "mongodb://localhost/db")))!=0 ){
+        log_it(L_CRITICAL,"Can't init CDB module, return code %d",rc);
+        return -3;
+    }
+    db_http_add_proc( a_http , DB_URL );
+    db_http_file_proc_add( a_http , DB_FILE_URL );
+
+    // Load all chain networks
+    if (dap_config_get_item_bool_default( g_config,
+                                                        "cdb",
+                                                        "servers_list_enabled",
+                                                        false)) {
+        dap_chain_net_srv_vpn_cdb_server_list_add_proc ( a_http, SLIST_URL);
+    }
+    if( dap_config_get_item_bool_default( g_config,"cdb_auth","enabled",false) ){
+        db_auth_init( dap_config_get_item_str_default(g_config,"cdb_auth","collection_name","cdb") );
+        // Produce transaction for authorized users
+        if (dap_config_get_item_bool_default( g_config,
+                                                            "cdb_auth",
+                                                            "tx_cond_create",
+                                                            false)) {
+
+            // Parse tx cond templates
+            size_t l_tx_cond_tpls_count=0;
+            char ** l_tx_cond_tpls =dap_config_get_array_str( g_config,"cdb_auth", "tx_cond_templates",&l_tx_cond_tpls_count);
+            for ( size_t i = 0 ; i< l_tx_cond_tpls_count; i++){
+                char * l_wallet_name = NULL;
+                long double l_value = 0.0L;
+                char * l_token_ticker = NULL;
+                char * l_net_name = NULL;
+                int l_step = 0;
+                time_t l_min_time = 0;
+                char * l_tpl_parse_old = l_tx_cond_tpls[i];
+                // Parse template entries
+                for(char * l_tpl_parse = index(l_tx_cond_tpls[i],':'); l_tpl_parse ;l_tpl_parse = index(l_tpl_parse,':') ){
+                    size_t l_tpl_entry_size = l_tpl_parse - l_tpl_parse_old;
+                    if (l_tpl_entry_size){ // if not empty entry
+                        char *l_tpl_entry = DAP_NEW_Z_SIZE(char,l_tpl_entry_size);
+                        strncpy(l_tpl_entry,l_tpl_parse_old,l_tpl_entry_size-1);
+                        switch ( l_step) { // Parse entries by order
+                            case 0: l_wallet_name = l_tpl_entry; break;
+                            case 1: l_value = strtold( l_tpl_entry, NULL); DAP_DELETE( l_tpl_entry); break;
+                            case 2: l_min_time =(time_t) atoll(l_tpl_entry); DAP_DELETE( l_tpl_entry); break;
+                            case 3: l_token_ticker = l_tpl_entry; break;
+                            case 4: l_net_name = l_tpl_entry; break;
+                            default: log_it( L_WARNING, "Too many ':' (%d) characters in condition template", l_step);
+                        }
+                        l_step++;
+                        if( l_step > 4)
+                            break;
+                    }
+                    l_tpl_parse_old = l_tpl_parse;
+                }
+                // If all what we need is present
+                if ( l_step >4 ) {
+                    if ( l_wallet_name && l_value > 0.0L && l_token_ticker && l_net_name && l_min_time){
+                        // we create condition template
+                        tx_cond_template_t * l_tx_cond_template = DAP_NEW_Z(tx_cond_template_t);
+
+                        l_tx_cond_template->wallet = dap_chain_wallet_open( l_wallet_name,c_wallets_path );
+                        if( l_tx_cond_template->wallet){
+                            l_tx_cond_template->wallet_name = l_wallet_name;
+
+                            l_tx_cond_template->net = dap_chain_net_by_name( l_net_name );
+                            if ( l_tx_cond_template->net){
+                                l_tx_cond_template->net_name = l_net_name;
+                                l_tx_cond_template->ledger = dap_chain_ledger_by_net_name( l_net_name );
+                                if ( l_tx_cond_template->ledger ){
+                                    l_tx_cond_template->min_time = l_min_time;
+                                    l_tx_cond_template->value_coins = l_value;
+                                    l_tx_cond_template->value_datoshi = dap_chain_coins_to_balance ( l_value );
+                                    l_tx_cond_template->token_ticker = l_token_ticker;
+                                    // and put it in list
+                                    l_tx_cond_template->prev = s_tx_cond_templates;
+                                    if ( s_tx_cond_templates)
+                                        s_tx_cond_templates->next = l_tx_cond_template;
+                                    s_tx_cond_templates = l_tx_cond_template;
+                                }else{
+                                    log_it(L_ERROR, "Can't open ledger in network \"%s\" for condition transaction template \"%s\"", l_net_name, l_tx_cond_tpls[i]);
+                                    DAP_DELETE( l_wallet_name );
+                                    DAP_DELETE( l_net_name);
+                                    DAP_DELETE( l_token_ticker);
+                                    DAP_DELETE( l_tx_cond_template);
+                                    l_tx_cond_template = NULL;
+                                    ret = -4;
+                                }
+                            }else{
+                                log_it(L_ERROR, "Can't open network \"%s\" for condition transaction template \"%s\"", l_net_name, l_tx_cond_tpls[i]);
+                                DAP_DELETE( l_wallet_name );
+                                DAP_DELETE( l_net_name);
+                                DAP_DELETE( l_token_ticker);
+                                DAP_DELETE( l_tx_cond_template);
+                                l_tx_cond_template = NULL;
+                                ret = -2;
+                            }
+                        }else{
+                            log_it(L_ERROR, "Can't open wallet \"%s\" for condition transaction template \"%s\"", l_wallet_name, l_tx_cond_tpls[i]);
+                            DAP_DELETE( l_wallet_name );
+                            DAP_DELETE( l_net_name);
+                            DAP_DELETE( l_token_ticker);
+                            DAP_DELETE( l_tx_cond_template);
+                            l_tx_cond_template = NULL;
+                            ret = -3;
+                        }
+                    }
+                }
+            }
+            if ( l_tx_cond_tpls_count )
+                db_auth_set_callbacks( s_auth_callback );
+            else{
+                log_it( L_ERROR, "No condition tpl, can't setup auth callback");
+                ret=-1;
+            }
+        }
+    }
+
+    return ret;
+}
+
+/**
+ * @brief dap_chain_net_srv_vpn_cdb_deinit
+ */
+void dap_chain_net_srv_vpn_cdb_deinit()
+{
+
+}
+
+
+
+/**
+ * @brief s_auth_callback
+ * @param a_delegate
+ * @param a_arg
+ */
+static void s_auth_callback(enc_http_delegate_t* a_delegate, void * a_arg)
+{
+    db_auth_info_t *l_auth_info = (db_auth_info_t *) a_arg;
+    log_it( L_DEBUG, "Authorized, now need to create conditioned transaction if not present");
+
+    for ( tx_cond_template_t * l_tpl = s_tx_cond_templates; l_tpl; l_tpl=l_tpl->next) {
+        enc_http_reply_f(a_delegate,"\t<tx_cond_tpl>\n");
+        enc_http_reply_f(a_delegate,"\t\t<net>%s</net>\n",l_tpl->net_name);
+        enc_http_reply_f(a_delegate,"\t\t<token>%s</token>\n",l_tpl->token_ticker);
+
+        size_t l_gdb_group_size=0;
+
+        // Try to load from gdb
+        char * l_tx_cond_gdb_group = dap_strdup_printf("%s.%s.tx_cond", l_tpl->net->pub.name, DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX );
+        dap_chain_hash_fast_t  * l_tx_cond_hash =  (dap_hash_type_t*) dap_chain_global_db_gr_get(
+                    l_auth_info->user,&l_gdb_group_size,  l_tx_cond_gdb_group );
+
+        // Check for entry size
+        if (l_gdb_group_size && l_gdb_group_size != sizeof (dap_chain_hash_fast_t) ){
+                log_it(L_ERROR, "Wrong size of tx condition on database (%zd but expected %zd), may be old entry",
+                                 l_gdb_group_size, sizeof (dap_chain_hash_fast_t));
+        }
+
+        time_t l_tx_cond_ts = 0;
+        // If loaded lets check is it spent or not
+        if ( l_tx_cond_hash ){
+            dap_chain_datum_tx_t * l_tx = dap_chain_net_get_tx_by_hash( l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET_UNSPENT );
+            if ( ! l_tx ){ // If not found - all outs are used. Create new one
+                // pass all chains
+                l_tx = dap_chain_net_get_tx_by_hash( l_tpl->net, l_tx_cond_hash, TX_SEARCH_TYPE_NET );
+                DAP_DELETE(l_tx_cond_hash);
+                l_tx_cond_hash = NULL;
+                if ( l_tx ){
+                    l_tx_cond_ts =(time_t) l_tx->header.ts_created;
+                }
+            }
+
+        }
+        // Try to create condition
+        if (! l_tx_cond_hash ) {
+
+        }
+
+        // If we loaded or created hash
+        if( l_tx_cond_hash ){
+            char * l_tx_cond_hash_str = dap_chain_hash_fast_to_str_new(l_tx_cond_hash);
+            enc_http_reply_f(a_delegate,"\t\t<tx_cond>%s</tx_cond>\n",l_tx_cond_hash_str);
+            DAP_DELETE(l_tx_cond_hash);
+            DAP_DELETE(l_tx_cond_hash_str);
+        }
+        enc_http_reply_f(a_delegate,"\t</tx_cond_tpl>\n");
+    }
+
+}
diff --git a/dap_chain_net_srv_vpn_cdb.h b/dap_chain_net_srv_vpn_cdb.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc0c5842a7ef94d59614df0771ba9c09a0201fa8
--- /dev/null
+++ b/dap_chain_net_srv_vpn_cdb.h
@@ -0,0 +1,31 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * CellFrame       https://cellframe.net
+ * Sources         https://gitlab.demlabs.net/cellframe
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of CellFrame SDK the open source project
+
+    CellFrame SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    CellFrame SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+#include "dap_http.h"
+
+#define DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX "local.srv.vpn"
+
+int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http);
+void dap_chain_net_srv_vpn_cdb_deinit();
diff --git a/dap_chain_net_srv_vpn_cdb_server_list.c b/dap_chain_net_srv_vpn_cdb_server_list.c
index a40e0ec6404d94c99fa8cc613c8dd8010e507df8..87b5cc52148758244cb4552fb2d62311bef86046 100644
--- a/dap_chain_net_srv_vpn_cdb_server_list.c
+++ b/dap_chain_net_srv_vpn_cdb_server_list.c
@@ -59,13 +59,14 @@ static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg);
 int dap_chain_net_srv_vpn_cdb_server_list_init()
 {
     char **l_cdb_networks;
-    size_t l_cdb_networks_size = 0;
+    uint16_t l_cdb_networks_count = 0;
     log_it(L_NOTICE,"Initialized Server List Module");
-    l_cdb_networks = dap_config_get_array_str( g_config, "cdb", "networks", &l_cdb_networks_size );
+    l_cdb_networks = dap_config_get_array_str( g_config, "cdb", "servers_list_networks", &l_cdb_networks_count );
 
-    if ( l_cdb_networks_size ){
-        s_cdb_net = DAP_NEW_Z_SIZE(dap_chain_net_t*, sizeof (dap_chain_net_t*)* l_cdb_networks_size );
-        for ( size_t i = 0; i < l_cdb_networks_size ; i++) {
+    if ( l_cdb_networks_count ){
+        s_cdb_net = DAP_NEW_Z_SIZE(dap_chain_net_t*, sizeof (dap_chain_net_t*)* l_cdb_networks_count );
+        s_cdb_net_count = l_cdb_networks_count;
+        for ( size_t i = 0; i < l_cdb_networks_count ; i++) {
             s_cdb_net[i] = dap_chain_net_by_name( l_cdb_networks[i] );
             if ( s_cdb_net[i] )
                 log_it( L_INFO, "Added \"%s\" network for server list fetchs", l_cdb_networks[i]);
@@ -86,7 +87,10 @@ void dap_chain_net_srv_vpn_cdb_server_list_deinit(void)
 static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg)
 {
     http_status_code_t * l_ret_code = (http_status_code_t*)a_arg;
-    dap_http_simple_reply_f( a_http_simple, "[\n");
+    dap_string_t *l_reply_str = dap_string_new("[\n");
+
+
+    log_it(L_DEBUG, "Have %zd chain networks for cdb lists", s_cdb_net_count );
 
     for ( size_t i = 0; i < s_cdb_net_count ; i++ ) {
         dap_chain_net_t * l_net = s_cdb_net[i];
@@ -95,45 +99,47 @@ static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg)
             size_t l_orders_count = 0;
             dap_chain_net_srv_price_unit_uid_t l_unit_uid = {{0}};
             dap_chain_net_srv_uid_t l_srv_uid = { .uint64 =DAP_CHAIN_NET_SRV_VPN_ID };
-            dap_chain_net_srv_order_find_all_by( l_net, SERV_DIR_SELL,  l_srv_uid, SERV_CLASS_PERMANENT ,l_unit_uid ,NULL,0,0, &l_orders, &l_orders_count );
-            log_it(L_DEBUG, "Found %sd orders in \"%s\" network", l_orders_count, l_net->pub.name );
+            dap_chain_net_srv_order_find_all_by( l_net, SERV_DIR_SELL,  l_srv_uid, SERV_CLASS_PERMANENT ,l_unit_uid ,
+                                                 NULL,0,0, &l_orders, &l_orders_count );
+            log_it(L_DEBUG, "Found %zd orders in \"%s\" network", l_orders_count, l_net->pub.name );
 
             for ( size_t j = 0; j < l_orders_count ; j++ ) {
                 dap_chain_node_info_t * l_node_info = dap_chain_node_info_read( l_net, &l_orders[j].node_addr );
                 if ( l_node_info ){
                     char l_node_ext_ipv4_str[INET_ADDRSTRLEN]={0};
                     char l_node_ext_ipv6_str[INET6_ADDRSTRLEN]={0};
-                    inet_ntop(AF_INET,&l_node_info->hdr.ext_addr_v4,l_node_ext_ipv4_str,sizeof(l_node_ext_ipv4_str));
-                    inet_ntop(AF_INET6,&l_node_info->hdr.ext_addr_v6,l_node_ext_ipv6_str,sizeof(l_node_ext_ipv6_str));
-
-                    dap_http_simple_reply_f( a_http_simple,
-                                             "    {\n"
-                                             "        \"Location\":\"NETHERLANDS\",\n"
-                                             "        \"Name\":\"%s.Cell-%s.%sd\",\n"
-                                             "        \"Address\":\"%s\",\n"
-                                             "        \"Address6\":\"%s\",\n"
-                                             "        \"Port\":%hu,\n"
-                                             "        \"Description\":\"%s\",\n"
-                                             "        \"Price\":%lu,\n"
-                                             "        \"PriceUnits\":%u,\n"
-                                             "        \"PriceToken\":\"%s\"\n"
-                                             "    },\n",
-                                             l_net->pub.name, l_node_info->hdr.cell_id.uint64, j,
-                                             l_node_ext_ipv4_str,
-                                             l_node_ext_ipv6_str,
-                                             l_node_info->hdr.ext_port,
-                                             l_orders[j].ext,
-                                             l_orders[j].price,
-                                             l_orders[j].price_unit.uint32,
-                                             l_orders[j].price_ticker
-                                            );
+                    if (l_node_info->hdr.ext_addr_v4.s_addr)
+                        inet_ntop(AF_INET,&l_node_info->hdr.ext_addr_v4,l_node_ext_ipv4_str,sizeof(l_node_ext_ipv4_str));
+                    if (  *((uint128_t *) l_node_info->hdr.ext_addr_v6.__in6_u.__u6_addr8 ) )
+                        inet_ntop(AF_INET6,&l_node_info->hdr.ext_addr_v6,l_node_ext_ipv6_str,sizeof(l_node_ext_ipv6_str));
+                    dap_string_append_printf( l_reply_str, "    {\n");
+
+                    dap_string_append_printf( l_reply_str, "        \"Location\":\"NETHERLANDS\",\n");
+                    dap_string_append_printf( l_reply_str, "        \"ChainNet\":\"%s\",\n",l_net->pub.name );
+                    dap_string_append_printf( l_reply_str, "        \"Name\":\"%s.Cell-%lu.%zd\",\n",l_net->pub.name, l_node_info->hdr.cell_id.uint64, j);
+                    if ( l_node_ext_ipv4_str[0] )
+                        dap_string_append_printf( l_reply_str,"        \"Address\":\"%s\",\n",l_node_ext_ipv4_str);
+                    if ( l_node_ext_ipv6_str[0] )
+                        dap_string_append_printf( l_reply_str, "        \"Address6\":\"%s\",\n",l_node_ext_ipv6_str);
+                    dap_string_append_printf( l_reply_str, "        \"Port\":%hu,\n",l_node_info->hdr.ext_port?l_node_info->hdr.ext_port:80);
+                    dap_string_append_printf( l_reply_str, "        \"Ext\":\"%s\",\n",l_orders[j].ext);
+                    dap_string_append_printf( l_reply_str, "        \"Price\":%lu,\n",l_orders[j].price);
+                    dap_string_append_printf( l_reply_str, "        \"PriceUnits\":%u,\n",l_orders[j].price_unit.uint32);
+                    dap_string_append_printf( l_reply_str, "        \"PriceToken\":\"%s\"\n",l_orders[j].price_ticker);
+                    if ( j != l_orders_count-1)
+                        dap_string_append_printf( l_reply_str, "    },\n");
+                    else
+                        dap_string_append_printf( l_reply_str, "    }\n");
 
                 }else
-                    log_it( L_WARNING, "Order %sd in \"%s\" network issued by node without ext_ipv4 field");
+                    log_it( L_WARNING, "Order %zd in \"%s\" network issued by node without ext_ipv4 field",j,l_net->pub.name);
             }
         }
     }
-    dap_http_simple_reply_f( a_http_simple, "]\n");
+    dap_string_append_printf( l_reply_str, "]\n\n");
+    dap_http_simple_reply( a_http_simple, l_reply_str->str, l_reply_str->len );
+    dap_string_free(l_reply_str, true);
+    //log_it(L_DEBUG,"Reply in buffer: %s", a_http_simple->reply_str );
     *l_ret_code = Http_Status_OK;
 
 }
@@ -145,5 +151,5 @@ static void s_http_simple_proc(dap_http_simple_t *a_http_simple, void *a_arg)
  */
 void dap_chain_net_srv_vpn_cdb_server_list_add_proc(dap_http_t *a_http, const char *a_url)
 {
-    dap_http_simple_proc_add(a_http,a_url,1000000,s_http_simple_proc);
+    dap_http_simple_proc_add(a_http,a_url,100000,s_http_simple_proc);
 }
diff --git a/dap_chain_net_srv_vpn_cdb_server_list.h b/dap_chain_net_srv_vpn_cdb_server_list.h
index ed45ed384ffa94bfc8f9806e8f7f3d110bb27b00..6aaacc975870a5f18986c1754649272a6a9731e0 100644
--- a/dap_chain_net_srv_vpn_cdb_server_list.h
+++ b/dap_chain_net_srv_vpn_cdb_server_list.h
@@ -8,20 +8,20 @@
  * Copyright  (c) 2017-2019
  * All rights reserved.
 
- This file is part of DAP (Deus Applications Prototypes) the open source project
+ This file is part of CellFrame SDK the open source project
 
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    CellFrame SDK is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
-    DAP is distributed in the hope that it will be useful,
+    CellFrame SDK is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
 
     You should have received a copy of the GNU General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+    along with any CellFrame SDK based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #pragma once
diff --git a/dap_chain_net_vpn_client.c b/dap_chain_net_vpn_client.c
index e378db5402cc2abfa7e537244599255e869b12ec..6ffa1cf15aa45c33d5fba3202e315c2edb701a21 100644
--- a/dap_chain_net_vpn_client.c
+++ b/dap_chain_net_vpn_client.c
@@ -68,14 +68,49 @@ static pthread_mutex_t sf_socks_mutex;
 static dap_chain_node_info_t *s_node_info = NULL;
 static dap_chain_node_client_t *s_vpn_client = NULL;
 
-dap_stream_ch_t* dap_chain_net_vpn_client_get_stream(void)
+dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void)
 {
     if(!s_vpn_client)
         return NULL;
-    dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, VPN_CLIENT_ID);
+    dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, DAP_STREAM_CH_ID_NET_SRV_VPN );
     return l_stream;
 }
 
+
+
+/// TODO convert below callback to processor of stage
+/*
+void s_stage_callback()
+{
+    char* l_full_path = NULL;
+    const char * l_path = "stream";
+    const char *l_suburl = "globaldb";
+    int l_full_path_size = snprintf(l_full_path, 0, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl,
+            dap_client_get_stream_id(a_client_pvt->client));
+    l_full_path = DAP_NEW_Z_SIZE(char, l_full_path_size + 1);
+    snprintf(l_full_path, l_full_path_size + 1, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl,
+            dap_client_get_stream_id(a_client_pvt->client));
+
+    //dap_client_request(a_client_pvt->client, l_full_path, "12345", 0, m_stream_response, m_stream_error);
+
+    const char *l_add_str = "";
+    // if connect to vpn server
+    const char l_active_vpn_channels[] = { VPN_CLIENT_ID, 0 };
+    if(!dap_strcmp(a_client_pvt->active_channels, l_active_vpn_channels))
+        l_add_str = "\r\nService-Key: test";
+
+    {
+        char *l_message = dap_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s:%d%s\r\n\r\n",
+                l_full_path, a_client_pvt->uplink_addr, a_client_pvt->uplink_port, l_add_str);
+        size_t l_message_size = dap_strlen(l_message);
+        int count = send(a_client_pvt->stream_socket, l_message, l_message_size, 0);
+        DAP_DELETE(l_message);
+    }
+    DAP_DELETE(l_full_path);
+
+}*/
+
+
 /**
  * Start VPN client
  *
@@ -101,11 +136,14 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
     s_node_info->hdr.ext_port = a_port;
 
     dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING; //DAP_CLIENT_STAGE_STREAM_CTL;//STAGE_STREAM_STREAMING;
-    const char l_active_channels[] = { VPN_CLIENT_ID, 0 };
+    const char l_active_channels[] = { DAP_STREAM_CH_ID_NET_SRV_VPN , 0 };
     if(a_ipv4_str)
         inet_pton(AF_INET, a_ipv4_str, &(s_node_info->hdr.ext_addr_v4));
     if(a_ipv6_str)
         inet_pton(AF_INET6, a_ipv6_str, &(s_node_info->hdr.ext_addr_v6));
+
+
+
     s_vpn_client = dap_chain_client_connect(s_node_info, l_stage_target, l_active_channels);
     if(!s_vpn_client) {
         log_it(L_ERROR, "Can't connect to VPN server=%s:%d", a_ipv4_str, a_port);
@@ -132,8 +170,8 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
     // send first packet to server
 //    if(0)
     {
-        dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream();
-        if(l_stream) { // Is present in hash table such destination address
+        dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch();
+        if(l_ch) { // Is present in hash table such destination address
             size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str);
             ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len);
 
@@ -142,9 +180,9 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
             //pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length();
             //pkt_out->header.op_connect.port = a_port;
             //memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len);
-            dap_stream_ch_pkt_write(l_stream, DATA_CHANNEL_ID, pkt_out,
+            dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
                     pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
-            dap_stream_ch_set_ready_to_write(l_stream, true);
+            dap_stream_ch_set_ready_to_write(l_ch, true);
             DAP_DELETE(pkt_out);
         }
     }
@@ -240,62 +278,16 @@ static void send_pong_pkt(dap_stream_ch_t* a_ch)
 }
 
 /**
- * @brief ch_sf_new Callback to constructor of object of Ch
- * @param ch
- * @param arg
- */
-static void ch_sf_new(dap_stream_ch_t* a_ch, void* arg)
-{
-    log_it(L_INFO, "SF channel created");
-
-    a_ch->internal = DAP_NEW_Z(dap_chain_net_srv_vpn_t);
-    dap_chain_net_srv_vpn_t * l_sf = CH_VPN(a_ch);
-    l_sf->ch = a_ch;
-    pthread_mutex_init(&l_sf->mutex, NULL);
-
-    pthread_mutex_lock(&( CH_VPN(a_ch)->mutex));
-    pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex));
-
-    l_sf->raw_l3_sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW);
-    //a_ch->stream->events_socket->is_pingable = true; //set up connection to be pingable by main loop
-
-}
-
-/**
- * @brief ch_sf_delete
- * @param ch
- * @param arg
- */
-static void ch_sf_delete(dap_stream_ch_t* a_ch, void* arg)
-{
-
-    log_it(L_DEBUG, "ch_sf_delete() for %s", a_ch->stream->events_socket->hostaddr);
-    /*    ch_vpn_socket_proxy_t * cur, *tmp;
-     ch_sf_tun_delete(CH_SF(a_ch));
-     HASH_ITER(hh, CH_SF(a_ch)->socks , cur, tmp) {
-     log_it(L_DEBUG,"delete socket: %i", cur->sock);
-     HASH_DEL(CH_SF(a_ch)->socks,cur);
-     if (cur)
-     free(cur);
-     }*/
-    pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex));
-    if(CH_VPN(a_ch)->raw_l3_sock)
-        close(CH_VPN(a_ch)->raw_l3_sock);
-}
-
-/**
- * @brief ch_sf_packet_in
- * @param ch
- * @param arg
+ * @brief dap_chain_net_vpn_client_pkt_in
+ * @param a_ch
+ * @param a_arg
  */
-static void ch_sf_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
+void dap_chain_net_vpn_client_pkt_in(dap_stream_ch_t* a_ch, dap_stream_ch_pkt_t* a_pkt)
 {
-    dap_stream_ch_pkt_t * l_pkt = (dap_stream_ch_pkt_t *) a_arg;
-
-    ch_vpn_pkt_t * l_sf_pkt = (ch_vpn_pkt_t *) l_pkt->data;
-    size_t l_sf_pkt_data_size = l_pkt->hdr.size - sizeof(l_sf_pkt->header);
+    ch_vpn_pkt_t * l_sf_pkt = (ch_vpn_pkt_t *) a_pkt->data;
+    size_t l_sf_pkt_data_size = a_pkt->hdr.size - sizeof(l_sf_pkt->header);
 
-    if(!l_pkt->hdr.size) {
+    if(!a_pkt->hdr.size) {
         log_it(L_WARNING, "Bad input packet");
         return;
     }
@@ -381,7 +373,7 @@ static void ch_sf_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
                         pthread_mutex_unlock(&sf_sock->mutex);
                     }
                     log_it(L_INFO, "Send action from %d sock_id (sf_packet size %lu,  ch packet size %lu, have sent %d)"
-                            , sf_sock->id, l_sf_pkt->header.op_data.data_size, l_pkt->hdr.size, ret);
+                            , sf_sock->id, l_sf_pkt->header.op_data.data_size, a_pkt->hdr.size, ret);
                 }
                     break;
                 case VPN_PACKET_OP_CODE_DISCONNECT: {
@@ -530,61 +522,60 @@ static void ch_sf_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
 }
 
 /**
- * @brief stream_sf_packet_out Packet Out Ch callback
- * @param ch
- * @param arg
+ * @brief dap_chain_net_vpn_client_pkt_out
+ * @param a_ch
  */
-static void ch_sf_packet_out(dap_stream_ch_t* ch, void* arg)
+void dap_chain_net_vpn_client_pkt_out(dap_stream_ch_t* a_ch)
 {
-    ch_vpn_socket_proxy_t * cur = NULL, *tmp;
-    bool isSmthOut = false;
+    ch_vpn_socket_proxy_t * l_cur = NULL, *l_tmp;
+    bool l_is_smth_out = false;
 //    log_it(L_DEBUG,"Socket forwarding packet out callback: %u sockets in hashtable", HASH_COUNT(CH_VPN(ch)->socks) );
-    HASH_ITER(hh, CH_VPN(ch)->socks , cur, tmp)
+    HASH_ITER(hh, CH_VPN(a_ch)->socks , l_cur, l_tmp)
     {
-        bool signalToBreak = false;
-        pthread_mutex_lock(&(cur->mutex));
+        bool l_signal_to_break = false;
+        pthread_mutex_lock(&(l_cur->mutex));
         int i;
 //        log_it(L_DEBUG,"Socket with id %d has %u packets in output buffer", cur->id, cur->pkt_out_size );
-        if(cur->pkt_out_size) {
-            for(i = 0; i < cur->pkt_out_size; i++) {
-                ch_vpn_pkt_t * pout = cur->pkt_out[i];
+        if(l_cur->pkt_out_size) {
+            for(i = 0; i < l_cur->pkt_out_size; i++) {
+                ch_vpn_pkt_t * pout = l_cur->pkt_out[i];
                 if(pout) {
-                    if(dap_stream_ch_pkt_write(ch, 'd', pout, pout->header.op_data.data_size + sizeof(pout->header))) {
-                        isSmthOut = true;
+                    if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout, pout->header.op_data.data_size + sizeof(pout->header))) {
+                        l_is_smth_out = true;
                         if(pout)
                             free(pout);
-                        cur->pkt_out[i] = NULL;
+                        l_cur->pkt_out[i] = NULL;
                     } else {
                         log_it(L_WARNING,
                                 "Buffer is overflowed, breaking cycle to let the upper level cycle drop data to the output socket");
-                        isSmthOut = true;
-                        signalToBreak = true;
+                        l_is_smth_out = true;
+                        l_signal_to_break = true;
                         break;
                     }
                 }
             }
         }
 
-        if(signalToBreak) {
-            pthread_mutex_unlock(&(cur->mutex));
+        if(l_signal_to_break) {
+            pthread_mutex_unlock(&(l_cur->mutex));
             break;
         }
-        cur->pkt_out_size = 0;
-        if(cur->signal_to_delete) {
-            log_it(L_NOTICE, "Socket id %d got signal to be deleted", cur->id);
-            pthread_mutex_lock(&( CH_VPN(ch)->mutex));
-            HASH_DEL(CH_VPN(ch)->socks, cur);
-            pthread_mutex_unlock(&( CH_VPN(ch)->mutex));
+        l_cur->pkt_out_size = 0;
+        if(l_cur->signal_to_delete) {
+            log_it(L_NOTICE, "Socket id %d got signal to be deleted", l_cur->id);
+            pthread_mutex_lock(&( CH_VPN(a_ch)->mutex));
+            HASH_DEL(CH_VPN(a_ch)->socks, l_cur);
+            pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex));
 
             pthread_mutex_lock(&(sf_socks_mutex));
-            HASH_DELETE(hh2, sf_socks, cur);
-            HASH_DELETE(hh_sock, sf_socks_client, cur);
+            HASH_DELETE(hh2, sf_socks, l_cur);
+            HASH_DELETE(hh_sock, sf_socks_client, l_cur);
             pthread_mutex_unlock(&(sf_socks_mutex));
 
-            pthread_mutex_unlock(&(cur->mutex));
-            vpn_socket_delete(cur);
+            pthread_mutex_unlock(&(l_cur->mutex));
+            vpn_socket_delete(l_cur);
         } else
-            pthread_mutex_unlock(&(cur->mutex));
+            pthread_mutex_unlock(&(l_cur->mutex));
     }
     /*    ch->writable = isSmthOut;
      if(isSmthOut) {
@@ -597,8 +588,6 @@ int dap_chain_net_vpn_client_init(dap_config_t * g_config)
 {
     pthread_mutex_init(&sf_socks_mutex, NULL);
 
-    dap_stream_ch_proc_add(VPN_CLIENT_ID, ch_sf_new, ch_sf_delete, ch_sf_packet_in,
-            ch_sf_packet_out);
     return 0;
 }
 
diff --git a/dap_chain_net_vpn_client.h b/dap_chain_net_vpn_client.h
index e31a0b9cef417bdb581b9e680e6a1b2bb2d48fe2..a75a307f737ace6e859c22fe88ee3bd58e9719b8 100644
--- a/dap_chain_net_vpn_client.h
+++ b/dap_chain_net_vpn_client.h
@@ -25,9 +25,11 @@
 #pragma once
 
 #include "dap_stream_ch.h"
+#include "dap_stream_ch_pkt.h"
 #include "dap_chain_net.h"
+#include "dap_chain_net_srv_vpn.h"
 
-dap_stream_ch_t* dap_chain_net_vpn_client_get_stream(void);
+dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void);
 
 int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_str, const char *a_ipv6_str, int a_port);
 int dap_chain_net_vpn_client_stop(void);
@@ -35,3 +37,7 @@ int dap_chain_net_vpn_client_status(void);
 
 int dap_chain_net_vpn_client_init(dap_config_t * g_config);
 void dap_chain_net_vpn_client_deinit();
+
+
+void dap_chain_net_vpn_client_pkt_out(dap_stream_ch_t* a_ch);
+void dap_chain_net_vpn_client_pkt_in(dap_stream_ch_t* a_ch, dap_stream_ch_pkt_t* a_pkt);
diff --git a/dap_chain_net_vpn_client_tun.c b/dap_chain_net_vpn_client_tun.c
index 68ad35486d3f76597720a88d93014a1bd0b78668..d77b8c35b50867dde707b4e95c1563a9a2a8bbe5 100644
--- a/dap_chain_net_vpn_client_tun.c
+++ b/dap_chain_net_vpn_client_tun.c
@@ -310,7 +310,7 @@ static void* thread_read_tun(void *arg)
                     //                  HASH_ADD_INT(CH_SF(ch)->socks, id, sf_sock );
                     //                  HASH_DEL(CH_SF(ch)->socks,sf_sock);
 //                    if(l_stream) { // Is present in hash table such destination address
-                    dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream();
+                    dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream_ch();
                     if(l_stream) {
                         // form packet to vpn-server
                         ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + read_ret);
@@ -321,7 +321,7 @@ static void* thread_read_tun(void *arg)
 
                         pthread_mutex_lock(&s_clients_mutex);
                         // sent packet to vpn server
-                        dap_stream_ch_pkt_write(l_stream, DATA_CHANNEL_ID, pkt_out,
+                        dap_stream_ch_pkt_write(l_stream, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
                                 pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
                         dap_stream_ch_set_ready_to_write(l_stream, true);
                         pthread_mutex_unlock(&s_clients_mutex);