From 87cd84ba18db05172ea8de336d1f4213a86ac077 Mon Sep 17 00:00:00 2001 From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net> Date: Mon, 4 May 2020 01:49:05 +0700 Subject: [PATCH] [+] Added CELLFRAME_MODULES global variable to set list of modules to build with [*] Removed cyclic depdendece because of dap_dns_server --- CMakeLists.txt | 93 ++- dap-sdk/CMakeLists.txt | 33 +- dap-sdk/net/server-udp/CMakeLists.txt | 4 +- dap-sdk/net/stream/ch/CMakeLists.txt | 2 +- modules/CMakeLists.txt | 110 ++- modules/net/CMakeLists.txt | 2 +- .../net}/dap_dns_server.c | 672 +++++++++--------- .../net}/include/dap_dns_server.h | 244 +++---- 8 files changed, 644 insertions(+), 516 deletions(-) rename {dap-sdk/net/server-udp => modules/net}/dap_dns_server.c (97%) rename {dap-sdk/net/server-udp => modules/net}/include/dap_dns_server.h (97%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ab168b10d..52e30a7ca7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,20 @@ project(cellframe-sdk C) cmake_minimum_required(VERSION 2.8) set(CMAKE_C_STANDARD 11) -set(CELLFRAME_SDK_NATIVE_VERSION "2.0-2") +set(CELLFRAME_SDK_NATIVE_VERSION "2.0-3") include(cmake/OS_Detection.cmake) add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"") +set(DAPSDK_MODULES "") + +if (CELLFRAME_MODULES MATCHES "core") + SET(DAPSDK_MODULES "${DAPSDK_MODULES} core crypto") +endif() + +if (CELLFRAME_MODULES MATCHES "network") + set(DAPSDK_MODULES "${DAPSDK_MODULES} network-core network-client network-server") +endif() + add_subdirectory(dap-sdk) add_subdirectory(3rdparty/monero_crypto) add_subdirectory(3rdparty/cuttdb) @@ -13,14 +23,79 @@ add_subdirectory(modules/) add_library(${PROJECT_NAME} STATIC cellframe-sdk.c) -set(CELLFRAME_LIBS dap_core dap_crypto dap_crypto dap_server_core dap_enc_server dap_udp_server dap_session - dap_enc_server dap_stream dap_stream_ch_chain dap_stream_ch_chain_net - dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_client - dap_chain_cs_dag dap_chain_cs_dag_poa dap_chain_cs_dag_pos - dap_chain_net dap_chain_net_srv - dap_chain_net_srv_vpn dap_chain_net_srv_app dap_chain_net_srv_app_db - dap_chain_net_srv_datum dap_chain_net_srv_datum_pool - dap_chain_wallet dap_chain_global_db dap_chain_mempool dap_chain_cs_none m magic pthread) +# init libs +set(CELLFRAME_LIBS "") + +# Core libs from dap-sdk +if (CELLFRAME_MODULES MATCHES "core") + message("[+] Module 'core'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_core dap_crypto m pthread) +endif() + +# General chain libs +if (CELLFRAME_MODULES MATCHES "chains") + message("[+] Module 'chains'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_common dap_chain dap_chain_global_db dap_chain_wallet dap_chain_crypto) +endif() + +# Networking +if (CELLFRAME_MODULES MATCHES "network") + message("[+] Module 'network'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_server_core dap_enc_server dap_http_server dap_udp_server dap_session + dap_stream dap_stream_ch dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain_net dap_chain_mempool magic) +endif() + +# Chain net services +if (CELLFRAME_MODULES MATCHES "srv-" ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv dap_stream_ch_chain_net_srv) +endif() + +# DAG based consensus(es) +if (CELLFRAME_MODULES MATCHES "cs-dag-" ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_dag) +endif() + +# PoA consensus for DAG +if (CELLFRAME_MODULES MATCHES "cs-dag-poa") + message("[+] Module 'cs-dag-poa'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_dag_poa) +endif() + +# PoS consensus for DAG +if (CELLFRAME_MODULES MATCHES "cs-dag-pos") + message("[+] Module 'cs-dag-pos'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_dag_pos) +endif() + +# No-consensus +if (CELLFRAME_MODULES MATCHES "cs-none") + message("[+] Module 'cs-none'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_none) +endif() + +# Enable service Application +if (CELLFRAME_MODULES MATCHES "srv-app") + message("[+] Module 'srv-app'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_app ) +endif() + +# Enable service Application DB +if (CELLFRAME_MODULES MATCHES "srv-app-db") + message("[+] Module 'srv-app-db'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_app_db ) +endif() + +# Enable service datum process +if (CELLFRAME_MODULES MATCHES "srv-datum") + message("[+] Module 'srv-datum'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_datum ) +endif() + +# Enable service VPN +if (CELLFRAME_MODULES MATCHES "srv-vpn") + message("[+] Module 'srv-vpn'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_vpn ) +endif() if (WIN32) set(CELLFRAME_LIBS ${CELLFRAME_LIBS} KERNEL32 USER32 SHELL32 WINMM GDI32 ADVAPI32 diff --git a/dap-sdk/CMakeLists.txt b/dap-sdk/CMakeLists.txt index c8f8276289..89f2652ec8 100644 --- a/dap-sdk/CMakeLists.txt +++ b/dap-sdk/CMakeLists.txt @@ -1,12 +1,25 @@ -# Core -add_subdirectory(core) +# Core +if (DAPSDK_MODULES MATCHES "core") + # Core + add_subdirectory(core) +endif() +if (DAPSDK_MODULES MATCHES "crypto") + # Cryptography + add_subdirectory(crypto) +endif() -# Cryptography -add_subdirectory(crypto) +# Networking core +if (DAPSDK_MODULES MATCHES "network-core") + add_subdirectory(net/core) + add_subdirectory(net/stream) +endif() +# Networking client +if (DAPSDK_MODULES MATCHES "network-client") + add_subdirectory(net/client) +endif() -# Networking -add_subdirectory(net/core) -add_subdirectory(net/client) -add_subdirectory(net/server) -add_subdirectory(net/server-udp) -add_subdirectory(net/stream) +# Networking server +if (DAPSDK_MODULES MATCHES "network-server") + add_subdirectory(net/server) + add_subdirectory(net/server-udp) +endif() diff --git a/dap-sdk/net/server-udp/CMakeLists.txt b/dap-sdk/net/server-udp/CMakeLists.txt index 94dda44efb..f99bd6023d 100644 --- a/dap-sdk/net/server-udp/CMakeLists.txt +++ b/dap-sdk/net/server-udp/CMakeLists.txt @@ -11,9 +11,9 @@ if(WIN32) #include_directories(../3rdparty/curl/include/) endif() -add_library(${PROJECT_NAME} STATIC ${DAP_UDP_SERVER_SRCS}) +add_library(${PROJECT_NAME} STATIC ${DAP_UDP_SERVER_SRCS} ${DAP_UDP_SERVER_HEADERS}) -target_link_libraries(${PROJECT_NAME} dap_core dap_server_core dap_chain_net) +target_link_libraries(${PROJECT_NAME} dap_core dap_server_core) target_include_directories(${PROJECT_NAME} INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/dap-sdk/net/stream/ch/CMakeLists.txt b/dap-sdk/net/stream/ch/CMakeLists.txt index 8a2c0d822b..657546fb9d 100644 --- a/dap-sdk/net/stream/ch/CMakeLists.txt +++ b/dap-sdk/net/stream/ch/CMakeLists.txt @@ -11,7 +11,7 @@ endif() add_library(${PROJECT_NAME} STATIC ${DAP_STREAM_CH_SRCS} ${DAP_STREAM_CH_HDRS}) -target_link_libraries(dap_stream_ch dap_core dap_crypto dap_stream) +target_link_libraries(dap_stream_ch dap_core dap_crypto dap_udp_server dap_stream ) target_include_directories(dap_stream_ch INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index d9dbd649e8..7b810fc785 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -1,37 +1,77 @@ -add_subdirectory(app-cli) -add_subdirectory(chain) -add_subdirectory(common) -add_subdirectory(mining) -add_subdirectory(wallet) -add_subdirectory(mempool) -add_subdirectory(net) -add_subdirectory(net/srv) -add_subdirectory(global-db) - -# Consensus types -add_subdirectory(type/dag) -#add_subdirectory(type/block) - -# Consensuses -add_subdirectory(consensus/none) -#add_subdirectory(consensus/block-pow) -#add_subdirectory(consensus/block-poa) -add_subdirectory(consensus/dag-pos) -add_subdirectory(consensus/dag-poa) - -# Stream channels -add_subdirectory(channel/chain) -add_subdirectory(channel/chain-net) -add_subdirectory(channel/chain-net-srv) - -# Services -if(NOT (WIN32)) - add_subdirectory(service/vpn) -endif() - -add_subdirectory(service/app) -add_subdirectory(service/app-db) -add_subdirectory(service/datum) -add_subdirectory(service/mining-pool) +# Core +if (CELLFRAME_MODULES MATCHES "core") + add_subdirectory(common) + add_subdirectory(app-cli) +endif() + +# Chains +if (CELLFRAME_MODULES MATCHES "chains") + add_subdirectory(chain) + add_subdirectory(wallet) + add_subdirectory(global-db) +endif() +# Network +if (CELLFRAME_MODULES MATCHES "network") + add_subdirectory(mempool) + add_subdirectory(net) + # Stream channels + add_subdirectory(channel/chain) + add_subdirectory(channel/chain-net) + add_subdirectory(channel/chain-net-srv) +endif() +# Mining +if (CELLFRAME_MODULES MATCHES "mining") + add_subdirectory(mining) +endif() + +# Network services +if (CELLFRAME_MODULES MATCHES "srv") + add_subdirectory(net/srv) +endif() + +# Consensus type dag +if (CELLFRAME_MODULES MATCHES "cs-dag") + add_subdirectory(type/dag) +endif() + +# Consensus type dag +if (CELLFRAME_MODULES MATCHES "cs-block") + add_subdirectory(type/block) +endif() + +# No consensus +if (CELLFRAME_MODULES MATCHES "cs-none") + add_subdirectory(consensus/none) +endif() + +# DAG PoA +if (CELLFRAME_MODULES MATCHES "cs-dag-poa") + add_subdirectory(consensus/dag-poa) +endif() + +# DAG PoS +if (CELLFRAME_MODULES MATCHES "cs-dag-pos") + add_subdirectory(consensus/dag-pos) +endif() + +# Service App +if (CELLFRAME_MODULES MATCHES "srv-app") + add_subdirectory(service/app) +endif() + +# Service App DB +if (CELLFRAME_MODULES MATCHES "srv-app-db") + add_subdirectory(service/app-db) +endif() + +# Service Datum +if (CELLFRAME_MODULES MATCHES "srv-datum") + add_subdirectory(service/datum) +endif() + +# Service VPN +if (CELLFRAME_MODULES MATCHES "srv-vpn") + add_subdirectory(service/vpn) +endif() diff --git a/modules/net/CMakeLists.txt b/modules/net/CMakeLists.txt index 2f19f6a87b..52441d852e 100644 --- a/modules/net/CMakeLists.txt +++ b/modules/net/CMakeLists.txt @@ -4,7 +4,7 @@ project (dap_chain_net) file(GLOB DAP_CHAIN_NET_SRCS *.c) -file(GLOB DAP_CHAIN_NET_HEADERS *.h) +file(GLOB DAP_CHAIN_NET_HEADERS include/*.h) #if (ANDROID) # set(DAP_CHAIN_NET_HEADERS ${DAP_CHAIN_NET_HEADERS} diff --git a/dap-sdk/net/server-udp/dap_dns_server.c b/modules/net/dap_dns_server.c similarity index 97% rename from dap-sdk/net/server-udp/dap_dns_server.c rename to modules/net/dap_dns_server.c index a93c8f55cd..64322e2a78 100644 --- a/dap-sdk/net/server-udp/dap_dns_server.c +++ b/modules/net/dap_dns_server.c @@ -1,336 +1,336 @@ -/* - * Authors: - * Roman Khlopkov <roman.khlopkov@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net - * Copyright (c) 2017-2020 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) 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, - 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/>. -*/ - -#include "dap_dns_server.h" -#include "dap_udp_server.h" -#include "dap_udp_client.h" -#include "dap_client_remote.h" -#include "dap_common.h" -#include "dap_chain_net.h" -#include "dap_chain_node.h" -#include "dap_string.h" -#include "dap_chain_global_db.h" -#include "dap_chain_global_db_remote.h" - -#define UNUSED(x) (void)(x) -#define LOG_TAG "dap_dns_server" - -static dap_dns_server_t *s_dns_server; -static char s_root_alias[] = "dnsroot"; - -/** - * @brief dap_dns_buf_init Initialize DNS parser buffer - * @param buf DNS buffer structure - * @param msg DNS message - * @return none - */ -void dap_dns_buf_init(dap_dns_buf_t *buf, char *msg) { - buf->data = msg; - buf->ptr = 0; -} - -/** - * @brief dap_dns_buf_get_uint16 Get uint16 from network order - * @param buf DNS buffer structure - * @return uint16 in host order - */ -uint16_t dap_dns_buf_get_uint16(dap_dns_buf_t *buf) { - char c; - c = buf->data[buf->ptr++]; - return c << 8 | buf->data[buf->ptr++]; -} - -/** - * @brief dap_dns_buf_put_uint16 Put uint16 to network order - * @param buf DNS buffer structure - * @param val uint16 in host order - * @return none - */ -void dap_dns_buf_put_uint16(dap_dns_buf_t *buf, uint16_t val) { - buf->data[buf->ptr++] = val >> 8; - buf->data[buf->ptr++] = val; -} - -/** - * @brief dap_dns_buf_put_uint32 Put uint32 to network order - * @param buf DNS buffer structure - * @param val uint32 in host order - * @return none - */ -void dap_dns_buf_put_uint32(dap_dns_buf_t *buf, uint32_t val) { - dap_dns_buf_put_uint16(buf, val >> 16); - dap_dns_buf_put_uint16(buf, val); -} - -uint32_t dap_dns_resolve_hostname(char *str) { - log_it(L_DEBUG, "DNS parser retrieve hostname %s", str); - dap_chain_net_t *l_net = dap_chain_net_by_name("kelvin-testnet"); - // get nodes list from global_db - dap_global_db_obj_t *l_objs = NULL; - size_t l_nodes_count = 0; - // read all node - l_objs = dap_chain_global_db_gr_load(l_net->pub.gdb_nodes, &l_nodes_count); - if(!l_nodes_count || !l_objs) - return 0; - size_t l_node_num = rand() % l_nodes_count; - dap_chain_node_info_t *l_node_info = (dap_chain_node_info_t *) l_objs[l_node_num].value; - uint32_t addr = l_node_info->hdr.ext_addr_v4.s_addr; - dap_chain_global_db_objs_delete(l_objs, l_nodes_count); - log_it(L_DEBUG, "DNS resolver find ip %d.%d.%d.%d", addr & 0xFF, (addr >> 8) & 0xFF, (addr >> 16) & 0xFF, (addr >> 24) & 0xFF); - return addr; -} - -/** - * @brief dap_dns_zone_register Register DNS zone and set callback to handle it - * @param zone Name of zone to register - * @param callback Callback to handle DNS zone - * @return 0 if success, else return error code - */ -int dap_dns_zone_register(char *zone, dap_dns_zone_callback_t callback) { - dap_dns_zone_hash_t *new_zone; - HASH_FIND_STR(s_dns_server->hash_table, zone, new_zone); - if (new_zone == NULL) { // zone is not present - new_zone = DAP_NEW(dap_dns_zone_hash_t); - new_zone->zone = dap_strdup(zone); - HASH_ADD_KEYPTR(hh, s_dns_server->hash_table, new_zone->zone, strlen(new_zone->zone), new_zone); - } // if zone present, just reassign callback - new_zone->callback = callback; - return DNS_ERROR_NONE; -} - -/** - * @brief dap_dns_zone_unregister Unregister DNS zone - * @param zone Name of zone to unregister - * @return 0 if success, else return error code - */ -int dap_dns_zone_unregister(char *zone) { - dap_dns_zone_hash_t *asked_zone; - HASH_FIND_STR(s_dns_server->hash_table, zone, asked_zone); - if (asked_zone == NULL) { - return DNS_ERROR_NAME; - } - HASH_DEL(s_dns_server->hash_table, asked_zone); - DAP_DELETE(asked_zone->zone); - DAP_DELETE(asked_zone); - return DNS_ERROR_NONE; -} - -/** - * @brief dap_dns_zone_find Find callback to registered DNS zone - * @param hostname Name of host for which the zone callback being searched - * @return Callback for registered DNS zone, else return NULL - */ -dap_dns_zone_callback_t dap_dns_zone_find(char *hostname) { - dap_dns_zone_hash_t *asked_zone; - HASH_FIND_STR(s_dns_server->hash_table, hostname, asked_zone); - if (asked_zone == NULL) { - if (!strcmp(hostname, &s_root_alias[0])) { - return NULL; - } - char *zone_up = strchr(hostname, '.'); - if (zone_up++ == NULL) { - zone_up = &s_root_alias[0]; - } - return dap_dns_zone_find(zone_up); - } else { - return asked_zone->callback; - } - return NULL; -} - -/** - * @brief dap_dns_client_read Read and parse incoming DNS message, send reply to it - * @param client DAP client remote structure - * @param arg Unused - * @return none - */ -void dap_dns_client_read(dap_client_remote_t *client, void * arg) { - UNUSED(arg); - if (client->buf_in_size < DNS_HEADER_SIZE) { // Bad request - return; - } - dap_dns_buf_t *dns_message = DAP_NEW(dap_dns_buf_t); - dap_dns_buf_t *dns_reply = DAP_NEW(dap_dns_buf_t); - dns_message->data = DAP_NEW_SIZE(char, client->buf_in_size + 1); - dns_message->data[client->buf_in_size] = 0; - dap_client_remote_read(client, dns_message->data, client->buf_in_size); - dns_message->ptr = 0; - - // Parse incoming DNS message - int block_len = DNS_HEADER_SIZE; - dns_reply->data = DAP_NEW_SIZE(char, block_len); - dns_reply->ptr = 0; - uint16_t val = dap_dns_buf_get_uint16(dns_message); // ID - dap_dns_buf_put_uint16(dns_reply, val); - val = dap_dns_buf_get_uint16(dns_message); // Flags - dns_reply->ptr += sizeof(uint16_t); // Put flags later - dap_dns_message_flags_t msg_flags; - msg_flags.val = val; - dap_dns_message_flags_bits_t *flags = &msg_flags.flags; - if (flags->qr) { // It's not request - goto cleanup; - } - flags->rcode = DNS_ERROR_NONE; - flags->qr = 1; // Response bit set - if (flags->tc) { // Truncated messages not supported yet - flags->rcode = DNS_ERROR_NOT_SUPPORTED; - } - flags->ra = 0; // Recursion not supported yet - flags->aa = 1; // Authoritative answer - uint16_t qdcount = dap_dns_buf_get_uint16(dns_message); - dap_dns_buf_put_uint16(dns_reply, qdcount); - val = dap_dns_buf_get_uint16(dns_message); // AN count - if (val) { // No other sections should present - goto cleanup; - } - dap_dns_buf_put_uint16(dns_reply, 1); // 1 answer section - val = dap_dns_buf_get_uint16(dns_message); // NS count - if (val) { // No other sections should present - goto cleanup; - } - dap_dns_buf_put_uint16(dns_reply, val); - val = dap_dns_buf_get_uint16(dns_message); // AR count - if (val) { // No other sections should present - goto cleanup; - } - dap_dns_buf_put_uint16(dns_reply, val); - int dot_count = 0; - dap_string_t *dns_hostname = dap_string_new(""); - for (int i = 0; i < qdcount; i++) { - block_len = strlen(&dns_message->data[dns_message->ptr]) + 1 + 2 * sizeof(uint16_t); - dns_reply->data = DAP_REALLOC(dns_reply->data, dns_reply->ptr + block_len); - memcpy(&dns_reply->data[dns_reply->ptr], &dns_message->data[dns_message->ptr], block_len); - dns_reply->ptr += block_len; - if (flags->rcode) - break; - while (dns_message->ptr < dns_reply->ptr - 2 * sizeof(uint16_t)) { - uint8_t len = dns_message->data[dns_message->ptr++]; - if (len > DNS_MAX_DOMAIN_NAME_LEN) { - flags->rcode = DNS_ERROR_NAME; - break; - } - if (!len) { - break; - } - if (dot_count) { - if (dot_count > 3) { // Max three dots allowed - flags->rcode = DNS_ERROR_NAME; - break; - } - dap_string_append(dns_hostname, "."); - } - dap_string_append_len(dns_hostname, &dns_message->data[dns_message->ptr], len); - dns_message->ptr += len; - dot_count++; - if (dns_hostname->len >= DNS_MAX_HOSTNAME_LEN) { - flags->rcode = DNS_ERROR_NAME; - break; - } - } - val = dap_dns_buf_get_uint16(dns_message); // DNS record type - if (val != DNS_RECORD_TYPE_A) { // Only host address ipv4 - flags->rcode = DNS_ERROR_NOT_SUPPORTED; - break; - } - val = dap_dns_buf_get_uint16(dns_message); // DNS class type - if (val != DNS_CLASS_TYPE_IN) { // Internet only - flags->rcode = DNS_ERROR_NOT_SUPPORTED; - break; - } - if (dns_message->ptr != dns_reply->ptr) { - log_it(L_ERROR, "DNS parser pointer unequal, mptr = %u, rptr = %u", dns_message->ptr, dns_reply->ptr); - } - } - // Find ip addr - uint32_t ip_addr = 0; - if (flags->rcode == DNS_ERROR_NONE) { - dap_dns_zone_callback_t callback = dap_dns_zone_find(dns_hostname->str); - if (callback) { - ip_addr = callback(dns_hostname->str); - } - } - if (ip_addr) { - // Compose DNS answer - block_len = DNS_ANSWER_SIZE; - dns_reply->data = DAP_REALLOC(dns_reply->data, dns_reply->ptr + block_len); - val = 0xc000 | DNS_HEADER_SIZE; // Link to host name - dap_dns_buf_put_uint16(dns_reply, val); - val = DNS_RECORD_TYPE_A; - dap_dns_buf_put_uint16(dns_reply, val); - val = DNS_CLASS_TYPE_IN; - dap_dns_buf_put_uint16(dns_reply, val); - uint32_t ttl = DNS_TIME_TO_LIVE; - dap_dns_buf_put_uint32(dns_reply, ttl); - val = 4; // RD len for ipv4 - dap_dns_buf_put_uint16(dns_reply, val); - dap_dns_buf_put_uint32(dns_reply, ip_addr); - } else if (flags->rcode == DNS_ERROR_NONE) { - flags->rcode = DNS_ERROR_NAME; - } - if (flags->rcode) { - dns_reply->data[7] = 0; // No answer section - } - // Set reply flags - dns_reply->data[2] = msg_flags.val >> 8; - dns_reply->data[3] = msg_flags.val; - // Send DNS reply - dap_udp_client_write(client, dns_reply->data, dns_reply->ptr); - dap_udp_client_ready_to_write(client, true); - dap_string_free(dns_hostname, true); -cleanup: - DAP_DELETE(dns_reply->data); - DAP_DELETE(dns_message->data); - DAP_DELETE(dns_reply); - DAP_DELETE(dns_message); - return; -} - -void dap_dns_server_start() { - s_dns_server = DAP_NEW(dap_dns_server_t); - s_dns_server->hash_table = NULL; - s_dns_server->instance = dap_udp_server_listen(DNS_LISTEN_PORT); - if (!s_dns_server->instance) { - log_it(L_ERROR, "Can't star DNS server"); - return; - } - s_dns_server->instance->client_read_callback = dap_dns_client_read; - s_dns_server->instance->client_read_callback = *dap_dns_client_read; - s_dns_server->instance->client_write_callback = NULL; - s_dns_server->instance->client_new_callback = NULL; - s_dns_server->instance->client_delete_callback = NULL; - dap_dns_zone_register(&s_root_alias[0], dap_dns_resolve_hostname); // root resolver - pthread_create(&s_dns_server->udp_thread, NULL, (void *)dap_udp_server_loop, s_dns_server->instance); -} - -void dap_dns_server_stop() { - dap_dns_zone_hash_t *current_zone, *tmp; - HASH_ITER(hh, s_dns_server->hash_table, current_zone, tmp) { - HASH_DEL(s_dns_server->hash_table, current_zone); - DAP_DELETE(current_zone->zone); - DAP_DELETE(current_zone); - } - // TODO add code to stop udp_thread - dap_udp_server_delete(s_dns_server->instance); - DAP_DELETE(s_dns_server); -} +/* + * Authors: + * Roman Khlopkov <roman.khlopkov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://gitlab.demlabs.net + * Copyright (c) 2017-2020 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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, + 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/>. +*/ + +#include "dap_dns_server.h" +#include "dap_udp_server.h" +#include "dap_udp_client.h" +#include "dap_client_remote.h" +#include "dap_common.h" +#include "dap_chain_net.h" +#include "dap_chain_node.h" +#include "dap_string.h" +#include "dap_chain_global_db.h" +#include "dap_chain_global_db_remote.h" + +#define UNUSED(x) (void)(x) +#define LOG_TAG "dap_dns_server" + +static dap_dns_server_t *s_dns_server; +static char s_root_alias[] = "dnsroot"; + +/** + * @brief dap_dns_buf_init Initialize DNS parser buffer + * @param buf DNS buffer structure + * @param msg DNS message + * @return none + */ +void dap_dns_buf_init(dap_dns_buf_t *buf, char *msg) { + buf->data = msg; + buf->ptr = 0; +} + +/** + * @brief dap_dns_buf_get_uint16 Get uint16 from network order + * @param buf DNS buffer structure + * @return uint16 in host order + */ +uint16_t dap_dns_buf_get_uint16(dap_dns_buf_t *buf) { + char c; + c = buf->data[buf->ptr++]; + return c << 8 | buf->data[buf->ptr++]; +} + +/** + * @brief dap_dns_buf_put_uint16 Put uint16 to network order + * @param buf DNS buffer structure + * @param val uint16 in host order + * @return none + */ +void dap_dns_buf_put_uint16(dap_dns_buf_t *buf, uint16_t val) { + buf->data[buf->ptr++] = val >> 8; + buf->data[buf->ptr++] = val; +} + +/** + * @brief dap_dns_buf_put_uint32 Put uint32 to network order + * @param buf DNS buffer structure + * @param val uint32 in host order + * @return none + */ +void dap_dns_buf_put_uint32(dap_dns_buf_t *buf, uint32_t val) { + dap_dns_buf_put_uint16(buf, val >> 16); + dap_dns_buf_put_uint16(buf, val); +} + +uint32_t dap_dns_resolve_hostname(char *str) { + log_it(L_DEBUG, "DNS parser retrieve hostname %s", str); + dap_chain_net_t *l_net = dap_chain_net_by_name("kelvin-testnet"); + // get nodes list from global_db + dap_global_db_obj_t *l_objs = NULL; + size_t l_nodes_count = 0; + // read all node + l_objs = dap_chain_global_db_gr_load(l_net->pub.gdb_nodes, &l_nodes_count); + if(!l_nodes_count || !l_objs) + return 0; + size_t l_node_num = rand() % l_nodes_count; + dap_chain_node_info_t *l_node_info = (dap_chain_node_info_t *) l_objs[l_node_num].value; + uint32_t addr = l_node_info->hdr.ext_addr_v4.s_addr; + dap_chain_global_db_objs_delete(l_objs, l_nodes_count); + log_it(L_DEBUG, "DNS resolver find ip %d.%d.%d.%d", addr & 0xFF, (addr >> 8) & 0xFF, (addr >> 16) & 0xFF, (addr >> 24) & 0xFF); + return addr; +} + +/** + * @brief dap_dns_zone_register Register DNS zone and set callback to handle it + * @param zone Name of zone to register + * @param callback Callback to handle DNS zone + * @return 0 if success, else return error code + */ +int dap_dns_zone_register(char *zone, dap_dns_zone_callback_t callback) { + dap_dns_zone_hash_t *new_zone; + HASH_FIND_STR(s_dns_server->hash_table, zone, new_zone); + if (new_zone == NULL) { // zone is not present + new_zone = DAP_NEW(dap_dns_zone_hash_t); + new_zone->zone = dap_strdup(zone); + HASH_ADD_KEYPTR(hh, s_dns_server->hash_table, new_zone->zone, strlen(new_zone->zone), new_zone); + } // if zone present, just reassign callback + new_zone->callback = callback; + return DNS_ERROR_NONE; +} + +/** + * @brief dap_dns_zone_unregister Unregister DNS zone + * @param zone Name of zone to unregister + * @return 0 if success, else return error code + */ +int dap_dns_zone_unregister(char *zone) { + dap_dns_zone_hash_t *asked_zone; + HASH_FIND_STR(s_dns_server->hash_table, zone, asked_zone); + if (asked_zone == NULL) { + return DNS_ERROR_NAME; + } + HASH_DEL(s_dns_server->hash_table, asked_zone); + DAP_DELETE(asked_zone->zone); + DAP_DELETE(asked_zone); + return DNS_ERROR_NONE; +} + +/** + * @brief dap_dns_zone_find Find callback to registered DNS zone + * @param hostname Name of host for which the zone callback being searched + * @return Callback for registered DNS zone, else return NULL + */ +dap_dns_zone_callback_t dap_dns_zone_find(char *hostname) { + dap_dns_zone_hash_t *asked_zone; + HASH_FIND_STR(s_dns_server->hash_table, hostname, asked_zone); + if (asked_zone == NULL) { + if (!strcmp(hostname, &s_root_alias[0])) { + return NULL; + } + char *zone_up = strchr(hostname, '.'); + if (zone_up++ == NULL) { + zone_up = &s_root_alias[0]; + } + return dap_dns_zone_find(zone_up); + } else { + return asked_zone->callback; + } + return NULL; +} + +/** + * @brief dap_dns_client_read Read and parse incoming DNS message, send reply to it + * @param client DAP client remote structure + * @param arg Unused + * @return none + */ +void dap_dns_client_read(dap_client_remote_t *client, void * arg) { + UNUSED(arg); + if (client->buf_in_size < DNS_HEADER_SIZE) { // Bad request + return; + } + dap_dns_buf_t *dns_message = DAP_NEW(dap_dns_buf_t); + dap_dns_buf_t *dns_reply = DAP_NEW(dap_dns_buf_t); + dns_message->data = DAP_NEW_SIZE(char, client->buf_in_size + 1); + dns_message->data[client->buf_in_size] = 0; + dap_client_remote_read(client, dns_message->data, client->buf_in_size); + dns_message->ptr = 0; + + // Parse incoming DNS message + int block_len = DNS_HEADER_SIZE; + dns_reply->data = DAP_NEW_SIZE(char, block_len); + dns_reply->ptr = 0; + uint16_t val = dap_dns_buf_get_uint16(dns_message); // ID + dap_dns_buf_put_uint16(dns_reply, val); + val = dap_dns_buf_get_uint16(dns_message); // Flags + dns_reply->ptr += sizeof(uint16_t); // Put flags later + dap_dns_message_flags_t msg_flags; + msg_flags.val = val; + dap_dns_message_flags_bits_t *flags = &msg_flags.flags; + if (flags->qr) { // It's not request + goto cleanup; + } + flags->rcode = DNS_ERROR_NONE; + flags->qr = 1; // Response bit set + if (flags->tc) { // Truncated messages not supported yet + flags->rcode = DNS_ERROR_NOT_SUPPORTED; + } + flags->ra = 0; // Recursion not supported yet + flags->aa = 1; // Authoritative answer + uint16_t qdcount = dap_dns_buf_get_uint16(dns_message); + dap_dns_buf_put_uint16(dns_reply, qdcount); + val = dap_dns_buf_get_uint16(dns_message); // AN count + if (val) { // No other sections should present + goto cleanup; + } + dap_dns_buf_put_uint16(dns_reply, 1); // 1 answer section + val = dap_dns_buf_get_uint16(dns_message); // NS count + if (val) { // No other sections should present + goto cleanup; + } + dap_dns_buf_put_uint16(dns_reply, val); + val = dap_dns_buf_get_uint16(dns_message); // AR count + if (val) { // No other sections should present + goto cleanup; + } + dap_dns_buf_put_uint16(dns_reply, val); + int dot_count = 0; + dap_string_t *dns_hostname = dap_string_new(""); + for (int i = 0; i < qdcount; i++) { + block_len = strlen(&dns_message->data[dns_message->ptr]) + 1 + 2 * sizeof(uint16_t); + dns_reply->data = DAP_REALLOC(dns_reply->data, dns_reply->ptr + block_len); + memcpy(&dns_reply->data[dns_reply->ptr], &dns_message->data[dns_message->ptr], block_len); + dns_reply->ptr += block_len; + if (flags->rcode) + break; + while (dns_message->ptr < dns_reply->ptr - 2 * sizeof(uint16_t)) { + uint8_t len = dns_message->data[dns_message->ptr++]; + if (len > DNS_MAX_DOMAIN_NAME_LEN) { + flags->rcode = DNS_ERROR_NAME; + break; + } + if (!len) { + break; + } + if (dot_count) { + if (dot_count > 3) { // Max three dots allowed + flags->rcode = DNS_ERROR_NAME; + break; + } + dap_string_append(dns_hostname, "."); + } + dap_string_append_len(dns_hostname, &dns_message->data[dns_message->ptr], len); + dns_message->ptr += len; + dot_count++; + if (dns_hostname->len >= DNS_MAX_HOSTNAME_LEN) { + flags->rcode = DNS_ERROR_NAME; + break; + } + } + val = dap_dns_buf_get_uint16(dns_message); // DNS record type + if (val != DNS_RECORD_TYPE_A) { // Only host address ipv4 + flags->rcode = DNS_ERROR_NOT_SUPPORTED; + break; + } + val = dap_dns_buf_get_uint16(dns_message); // DNS class type + if (val != DNS_CLASS_TYPE_IN) { // Internet only + flags->rcode = DNS_ERROR_NOT_SUPPORTED; + break; + } + if (dns_message->ptr != dns_reply->ptr) { + log_it(L_ERROR, "DNS parser pointer unequal, mptr = %u, rptr = %u", dns_message->ptr, dns_reply->ptr); + } + } + // Find ip addr + uint32_t ip_addr = 0; + if (flags->rcode == DNS_ERROR_NONE) { + dap_dns_zone_callback_t callback = dap_dns_zone_find(dns_hostname->str); + if (callback) { + ip_addr = callback(dns_hostname->str); + } + } + if (ip_addr) { + // Compose DNS answer + block_len = DNS_ANSWER_SIZE; + dns_reply->data = DAP_REALLOC(dns_reply->data, dns_reply->ptr + block_len); + val = 0xc000 | DNS_HEADER_SIZE; // Link to host name + dap_dns_buf_put_uint16(dns_reply, val); + val = DNS_RECORD_TYPE_A; + dap_dns_buf_put_uint16(dns_reply, val); + val = DNS_CLASS_TYPE_IN; + dap_dns_buf_put_uint16(dns_reply, val); + uint32_t ttl = DNS_TIME_TO_LIVE; + dap_dns_buf_put_uint32(dns_reply, ttl); + val = 4; // RD len for ipv4 + dap_dns_buf_put_uint16(dns_reply, val); + dap_dns_buf_put_uint32(dns_reply, ip_addr); + } else if (flags->rcode == DNS_ERROR_NONE) { + flags->rcode = DNS_ERROR_NAME; + } + if (flags->rcode) { + dns_reply->data[7] = 0; // No answer section + } + // Set reply flags + dns_reply->data[2] = msg_flags.val >> 8; + dns_reply->data[3] = msg_flags.val; + // Send DNS reply + dap_udp_client_write(client, dns_reply->data, dns_reply->ptr); + dap_udp_client_ready_to_write(client, true); + dap_string_free(dns_hostname, true); +cleanup: + DAP_DELETE(dns_reply->data); + DAP_DELETE(dns_message->data); + DAP_DELETE(dns_reply); + DAP_DELETE(dns_message); + return; +} + +void dap_dns_server_start() { + s_dns_server = DAP_NEW(dap_dns_server_t); + s_dns_server->hash_table = NULL; + s_dns_server->instance = dap_udp_server_listen(DNS_LISTEN_PORT); + if (!s_dns_server->instance) { + log_it(L_ERROR, "Can't star DNS server"); + return; + } + s_dns_server->instance->client_read_callback = dap_dns_client_read; + s_dns_server->instance->client_read_callback = *dap_dns_client_read; + s_dns_server->instance->client_write_callback = NULL; + s_dns_server->instance->client_new_callback = NULL; + s_dns_server->instance->client_delete_callback = NULL; + dap_dns_zone_register(&s_root_alias[0], dap_dns_resolve_hostname); // root resolver + pthread_create(&s_dns_server->udp_thread, NULL, (void *)dap_udp_server_loop, s_dns_server->instance); +} + +void dap_dns_server_stop() { + dap_dns_zone_hash_t *current_zone, *tmp; + HASH_ITER(hh, s_dns_server->hash_table, current_zone, tmp) { + HASH_DEL(s_dns_server->hash_table, current_zone); + DAP_DELETE(current_zone->zone); + DAP_DELETE(current_zone); + } + // TODO add code to stop udp_thread + dap_udp_server_delete(s_dns_server->instance); + DAP_DELETE(s_dns_server); +} diff --git a/dap-sdk/net/server-udp/include/dap_dns_server.h b/modules/net/include/dap_dns_server.h similarity index 97% rename from dap-sdk/net/server-udp/include/dap_dns_server.h rename to modules/net/include/dap_dns_server.h index 6743732de0..ee107a16bf 100644 --- a/dap-sdk/net/server-udp/include/dap_dns_server.h +++ b/modules/net/include/dap_dns_server.h @@ -1,125 +1,125 @@ -/* - * Authors: - * Roman Khlopkov <roman.khlopkov@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net - * Copyright (c) 2017-2020 - * All rights reserved. - - This file is part of DAP (Deus Applications Prototypes) the open source project - - DAP (Deus Applicaions Prototypes) 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, - 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/>. -*/ - -#pragma once - -#ifdef _WIN32 -#include <pthread.h> -#endif -#include "dap_server.h" -#include "uthash.h" - -#define DNS_LISTEN_PORT 53 // UDP -#define DNS_TIME_TO_LIVE 600 // Seconds -#define DNS_HEADER_SIZE 12 +/* + * Authors: + * Roman Khlopkov <roman.khlopkov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://gitlab.demlabs.net + * Copyright (c) 2017-2020 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) 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, + 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/>. +*/ + +#pragma once + +#ifdef _WIN32 +#include <pthread.h> +#endif +#include "dap_server.h" +#include "uthash.h" + +#define DNS_LISTEN_PORT 53 // UDP +#define DNS_TIME_TO_LIVE 600 // Seconds +#define DNS_HEADER_SIZE 12 #define DNS_ANSWER_SIZE 16 #define DNS_MAX_HOSTNAME_LEN 255 -#define DNS_MAX_DOMAIN_NAME_LEN 63 - -typedef enum _dap_dns_query_type_t { - DNS_QUERY_TYPE_STANDARD, - DNS_QUERY_TYPE_INVERSE, - DNS_QUERY_TYPE_STATUS -} dap_dns_query_type_t; - -typedef enum _dap_dns_error_t { - DNS_ERROR_NONE, // No error - DNS_ERROR_FORMAT, // DNS message parsing error - DNS_ERROR_FAILURE, // Internal server error - DNS_ERROR_NAME, // Only for authoritative servers. Name does not exist - DNS_ERROR_NOT_SUPPORTED,// This kind of query not implemented - DNS_ERROR_REFUSED // Operation refused -} dap_dns_error_t; - -typedef enum _dap_dns_record_type_t { - DNS_RECORD_TYPE_A = 1, // Host address - DNS_RECORD_TYPE_NS, // Authoritative name server - DNS_RECORD_TYPE_MD, // Mail destination (obsolete, use MX) - DNS_RECORD_TYPE_MF, // Mail forwarder (obsolete, use MX) - DNS_RECORD_TYPE_CNAME, // Canonical name of alias - DNS_RECORD_TYPE_SOA, // Marks a start of a zone of authority - DNS_RECORD_TYPE_MB, // Mailbox domain name (experimental) - DNS_RECORD_TYPE_MG, // Mail group member (experimental) - DNS_RECORD_TYPE_MR, // Mail rename domain name (experimental) - DNS_RECORD_TYPE_NULL, // NULL resource record (experimental) - DNS_RECORD_TYPE_WKS, // Well known server description - DNS_RECORD_TYPE_PTR, // Domain name pointer - DNS_RECORD_TYPE_HINFO, // Host information - DNS_RECORD_TYPE_MINFO, // Mail box or list information - DNS_RECORD_TYPE_MX, // Mail exchange - DNS_RECORD_TYPE_TXT, // Text strings - DNS_RECORD_TYPE_RP, // Responsible person - DNS_RECORD_TYPE_AXFR = 252, // A request for a transfer of an entire zone - QTYPE only - DNS_RECORD_TYPE_MAILB, // A request for mailbox-related records (MB, MG or MR) - QTYPE only - DNS_RECORD_TYPE_MAILA, // A request for mail agent RRs (obsolete - see MX) - QTYPE only - DNS_RECORD_TYPE_ANY // A request for all records - QTYPE only -} dap_dns_record_type_t; - -typedef enum _dap_dns_class_type_t { - DNS_CLASS_TYPE_IN = 1, // Internet - DNS_CLASS_TYPE_CS, // CSNET (obsolete) - DNS_CLASS_TYPE_CH, // CHAOS - DNS_CLASS_TYPE_HS, // Hesiod [Dyer 87] - DNS_CLASS_TYPE_ANY = 255 // Any class -} dap_dns_class_type_t; - -typedef struct _dap_dns_message_flags_bits_t { - int rcode : 4; // response code, answer only: 0 - no error, 1 - format error, 2 - server failure, 3 - name error, 4 - not supported, 5 - refused - int z : 3; // reserved, must be zero - int ra : 1; // 1 - recursion available (answer only) - int rd : 1; // 1 - recursion desired (query set, copied to answer) - int tc : 1; // 1 - message truncated - int aa : 1; // 1 - authoritative answer (answer only) +#define DNS_MAX_DOMAIN_NAME_LEN 63 + +typedef enum _dap_dns_query_type_t { + DNS_QUERY_TYPE_STANDARD, + DNS_QUERY_TYPE_INVERSE, + DNS_QUERY_TYPE_STATUS +} dap_dns_query_type_t; + +typedef enum _dap_dns_error_t { + DNS_ERROR_NONE, // No error + DNS_ERROR_FORMAT, // DNS message parsing error + DNS_ERROR_FAILURE, // Internal server error + DNS_ERROR_NAME, // Only for authoritative servers. Name does not exist + DNS_ERROR_NOT_SUPPORTED,// This kind of query not implemented + DNS_ERROR_REFUSED // Operation refused +} dap_dns_error_t; + +typedef enum _dap_dns_record_type_t { + DNS_RECORD_TYPE_A = 1, // Host address + DNS_RECORD_TYPE_NS, // Authoritative name server + DNS_RECORD_TYPE_MD, // Mail destination (obsolete, use MX) + DNS_RECORD_TYPE_MF, // Mail forwarder (obsolete, use MX) + DNS_RECORD_TYPE_CNAME, // Canonical name of alias + DNS_RECORD_TYPE_SOA, // Marks a start of a zone of authority + DNS_RECORD_TYPE_MB, // Mailbox domain name (experimental) + DNS_RECORD_TYPE_MG, // Mail group member (experimental) + DNS_RECORD_TYPE_MR, // Mail rename domain name (experimental) + DNS_RECORD_TYPE_NULL, // NULL resource record (experimental) + DNS_RECORD_TYPE_WKS, // Well known server description + DNS_RECORD_TYPE_PTR, // Domain name pointer + DNS_RECORD_TYPE_HINFO, // Host information + DNS_RECORD_TYPE_MINFO, // Mail box or list information + DNS_RECORD_TYPE_MX, // Mail exchange + DNS_RECORD_TYPE_TXT, // Text strings + DNS_RECORD_TYPE_RP, // Responsible person + DNS_RECORD_TYPE_AXFR = 252, // A request for a transfer of an entire zone - QTYPE only + DNS_RECORD_TYPE_MAILB, // A request for mailbox-related records (MB, MG or MR) - QTYPE only + DNS_RECORD_TYPE_MAILA, // A request for mail agent RRs (obsolete - see MX) - QTYPE only + DNS_RECORD_TYPE_ANY // A request for all records - QTYPE only +} dap_dns_record_type_t; + +typedef enum _dap_dns_class_type_t { + DNS_CLASS_TYPE_IN = 1, // Internet + DNS_CLASS_TYPE_CS, // CSNET (obsolete) + DNS_CLASS_TYPE_CH, // CHAOS + DNS_CLASS_TYPE_HS, // Hesiod [Dyer 87] + DNS_CLASS_TYPE_ANY = 255 // Any class +} dap_dns_class_type_t; + +typedef struct _dap_dns_message_flags_bits_t { + int rcode : 4; // response code, answer only: 0 - no error, 1 - format error, 2 - server failure, 3 - name error, 4 - not supported, 5 - refused + int z : 3; // reserved, must be zero + int ra : 1; // 1 - recursion available (answer only) + int rd : 1; // 1 - recursion desired (query set, copied to answer) + int tc : 1; // 1 - message truncated + int aa : 1; // 1 - authoritative answer (answer only) int opcode : 4; // type of query, copied to answer: 0 - standard, 1 - inverse, 2 - status, 3-15 - reserved - int qr : 1; // 0 - query, 1 - response -} dap_dns_message_flags_bits_t; - -typedef uint32_t (*dap_dns_zone_callback_t) (char *hostname); // Callback for DNS zone operations - -typedef union _dap_dns_message_flags_t { - dap_dns_message_flags_bits_t flags; - int val; -} dap_dns_message_flags_t; - -typedef struct _dap_dns_buf_t { - char *data; - uint32_t ptr; -} dap_dns_buf_t; - -typedef struct _dap_dns_zone_hash_t { - char *zone; - dap_dns_zone_callback_t callback; - UT_hash_handle hh; -} dap_dns_zone_hash_t; - -typedef struct _dap_dns_server_t { - dap_server_t *instance; - pthread_t udp_thread; - dap_dns_zone_hash_t *hash_table; -} dap_dns_server_t; - -void dap_dns_server_start(); -void dap_dns_server_stop(); -int dap_dns_zone_register(char *zone, dap_dns_zone_callback_t callback); -int dap_dns_zone_unregister(char *zone); + int qr : 1; // 0 - query, 1 - response +} dap_dns_message_flags_bits_t; + +typedef uint32_t (*dap_dns_zone_callback_t) (char *hostname); // Callback for DNS zone operations + +typedef union _dap_dns_message_flags_t { + dap_dns_message_flags_bits_t flags; + int val; +} dap_dns_message_flags_t; + +typedef struct _dap_dns_buf_t { + char *data; + uint32_t ptr; +} dap_dns_buf_t; + +typedef struct _dap_dns_zone_hash_t { + char *zone; + dap_dns_zone_callback_t callback; + UT_hash_handle hh; +} dap_dns_zone_hash_t; + +typedef struct _dap_dns_server_t { + dap_server_t *instance; + pthread_t udp_thread; + dap_dns_zone_hash_t *hash_table; +} dap_dns_server_t; + +void dap_dns_server_start(); +void dap_dns_server_stop(); +int dap_dns_zone_register(char *zone, dap_dns_zone_callback_t callback); +int dap_dns_zone_unregister(char *zone); -- GitLab