From 92785ecd61deeb645434d972b5e53673e7d4c3b5 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Mon, 19 Jan 2026 23:47:22 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20init=5Fco?= =?UTF-8?q?nnections=20=D1=81=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B9=20=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83?= =?UTF-8?q?=D1=80=D0=BE=D0=B9=20=D0=B8=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA?= =?UTF-8?q?=D0=BE=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/etcp_connections.c | 252 +++++++++++++++++++++++++++-------------- 1 file changed, 165 insertions(+), 87 deletions(-) diff --git a/src/etcp_connections.c b/src/etcp_connections.c index 212fa0e3..ac42b987 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -5,7 +5,6 @@ #include #include #include -#include "debug_config.h" #include "routing.h" #include "utun_instance.h" #include "config_parser.h" @@ -16,6 +15,24 @@ #include #include +// Simple debug macros to replace missing debug_config.h +#define DEBUG_CATEGORY_CONNECTION 1 +#define DEBUG_CATEGORY_ETCP 2 +#define DEBUG_CATEGORY_MEMORY 3 + +#define DEBUG_ERROR(category, fmt, ...) fprintf(stderr, "ERROR: " fmt "\n", ##__VA_ARGS__) +#define DEBUG_INFO(category, fmt, ...) fprintf(stdout, "INFO: " fmt "\n", ##__VA_ARGS__) + + +// Forward declarations for missing functions +struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance); +void etcp_conn_reset(struct ETCP_CONN* etcp); +void etcp_conn_input(struct ETCP_CONN* etcp, struct ETCP_DGRAM* pkt); +void etcp_destroy(struct ETCP_CONN* etcp); +static int etcp_link_send_init_response(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval); +int etcp_input(struct ETCP_DGRAM* pkt); +void packet_pool_free(struct memory_pool* pool, void* ptr); +int etcp_connections_send(struct ETCP_SOCKET* e_sock, uint8_t* data, size_t len, struct sockaddr* addr, socklen_t addr_len); // CONNECTION MANAGEMENT (!!!это всё должно быть static!!!) static void etcp_link_remove_from_connections(struct ETCP_SOCKET* conn, struct ETCP_LINK* link); @@ -247,18 +264,18 @@ void etcp_link_close(struct ETCP_LINK* link) { int etcp_encrypt_send(struct ETCP_DGRAM* dgram) { - sc_context_t* sc = dgram->link->etcp->crypto_ctx; + sc_context_t* sc = &dgram->link->etcp->crypto_ctx; int len=dgram->data_len-dgram->noencrypt_len; - if (len<=0 || len>1480) { dgram->link->send_errors++; return; } + if (len<=0 || len>1480) { dgram->link->send_errors++; return -1; } uint8_t enc_buf[1600]; size_t enc_buf_len; - sc_encrypt(sc, dgram->data, len, &enc_buf, &enc_buf_len); - if (enc_buf_len + dgram->noencrypt_len > 1480) { dgram->link->send_errors++; return; } + sc_encrypt(sc, dgram->data, len, enc_buf, &enc_buf_len); + if (enc_buf_len + dgram->noencrypt_len > 1480) { dgram->link->send_errors++; return -1; } memcpy(enc_buf+enc_buf_len, dgram->data+enc_buf_len, dgram->noencrypt_len); - struct sockaddr_storage* addr=dgram->link->remote_addr; - socklen_t addr_len = (to_addr->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); - ssize_t sent = sendto(dgram->link->conn->fd, enc_buf, len, 0, addr, addr_len); + struct sockaddr_storage* addr=&dgram->link->remote_addr; + socklen_t addr_len = (addr->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); + ssize_t sent = sendto(dgram->link->conn->fd, enc_buf, len, 0, (struct sockaddr*)addr, addr_len); if (sent < 0) dgram->link->send_errors++; else dgram->link->total_encrypted += sent; return (int)sent; } @@ -308,7 +325,6 @@ static void etcp_connections_read_callback(int fd, void* arg) { struct ETCP_SOCKET* e_sock = (struct ETCP_SOCKET*)arg; if (!e_sock) return; - socklen_t addr_len = sizeof(pkt->metadata.remote_addr); struct sockaddr_storage addr; uint8_t data[PACKET_DATA_SIZE]; socklen_t addr_len=sizeof(addr); @@ -319,12 +335,12 @@ static void etcp_connections_read_callback(int fd, void* arg) { return; } - struct ETCP_DGRAM* pkt = memory_pool_alloc(&e_sock->instance->pkt_pool); + struct ETCP_DGRAM* pkt = memory_pool_alloc(e_sock->instance->pkt_pool); if (!pkt) return; size_t pkt_len=0; int errorcode=0; - struct ETCP_LINK* link=etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, &addr); + struct ETCP_LINK* link=etcp_link_find_by_addr(e_sock, &addr); if (link==NULL) {// пробуем расшифровать, возможно это init struct secure_channel sc; if (recv_len<=SC_PUBKEY_SIZE) { errorcode=1; goto ec_fr; } @@ -343,7 +359,7 @@ static void etcp_connections_read_callback(int fd, void* arg) { uint8_t pubkey[SC_PUBKEY_SIZE]; } *ack_hdr=(void*)&pkt->data[0]; uint64_t peer_id; - memcpy(&peer_id, &pkt->data+1, 4); + memcpy(&peer_id, &pkt->data[1], 4); if (ack_hdr->code!=0x02 && ack_hdr->code!=0x04) { errorcode=4; goto ec_fr; }// не init struct ETCP_CONN* conn=e_sock->instance->connections; @@ -357,10 +373,10 @@ static void etcp_connections_read_callback(int fd, void* arg) { conn->peer_node_id=peer_id; } else {// check keys - if (memcmp(&conn->crypto_ctx->peer_public_key, &sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; goto ec_fr; }// коллизия - peer id совпал а ключи разные. + if (memcmp(&conn->crypto_ctx.peer_public_key, &sc.peer_public_key, SC_PUBKEY_SIZE)) { errorcode=5; goto ec_fr; }// коллизия - peer id совпал а ключи разные. } - struct ETCP_LINK* link = etcp_link_new(etcp, e_sock, addr, 1); - if (ack_hdr->code==0x02) etcp_conn_reset(etcp); + struct ETCP_LINK* link = etcp_link_new(conn, e_sock, &addr, 1); + if (ack_hdr->code==0x02) etcp_conn_reset(conn); // send reply - подключение создано struct { uint8_t main_id[2]; @@ -373,14 +389,14 @@ static void etcp_connections_read_callback(int fd, void* arg) { ack_repl_hdr->main_id[0]=0; ack_repl_hdr->main_id[1]=0; memcpy(&ack_repl_hdr->id[0], &e_sock->instance->node_id, 8); - int mtu=e_sock->instance->config->global->mtu; + int mtu=e_sock->instance->config->global.mtu; ack_repl_hdr->mtu[0]=mtu>>8; ack_repl_hdr->mtu[1]=mtu; - pkt->data_len=sizeof(ack_repl_hdr); + pkt->data_len=sizeof(*ack_repl_hdr); pkt->noencrypt_len=0; etcp_encrypt_send(pkt); - packet_pool_free(&e_sock->instance->pkt_pool, pkt); + packet_pool_free(e_sock->instance->pkt_pool, pkt); return; } @@ -389,58 +405,57 @@ static void etcp_connections_read_callback(int fd, void* arg) { pkt->noencrypt_len=0; pkt->link=link; - etcp_input(pkt, conns); + etcp_input(pkt); return; ec_fr: e_sock->pkt_format_errors++; e_sock->errorcode=errorcode; - packet_pool_free(&e_sock->instance->pkt_pool, pkt); + packet_pool_free(e_sock->instance->pkt_pool, pkt); return; } #define MIN(a,b) ((a) < (b) ? (a) : (b)) int etcp_input(struct ETCP_DGRAM* pkt) { - if (!pkt || !e_sock) return -1; + if (!pkt || !pkt->link) return -1; uint8_t* data = pkt->data; - size_t len = pkt->metadata.data_len; + size_t len = pkt->data_len; if (len < 1) return -1; uint8_t header = data[0]; data++; len--; - struct ETCP_CONN* etcp = e_sock->etcp; + struct ETCP_LINK* link = pkt->link; + struct ETCP_CONN* etcp = link->etcp; + + // Check if we have peer key by checking if peer_node_id is set + int has_peer_key = (etcp->peer_node_id != 0); - if (header != ETCP_INIT_REQUEST && header != ETCP_CHANNEL_INIT && etcp->has_peer_key) { + if (header != ETCP_INIT_REQUEST && header != ETCP_CHANNEL_INIT && has_peer_key) { // Decrypt - sc_context_t* sc = etcp->crypto_ctx; + sc_context_t* sc = &etcp->crypto_ctx; uint8_t decrypted[PACKET_DATA_SIZE]; size_t decrypted_len; if (sc_decrypt(sc, data, len, decrypted, &decrypted_len) != SC_OK) { - e_sock->decrypt_errors++; + link->decrypt_errors++; return -1; } memcpy(data, decrypted, decrypted_len); len = decrypted_len; - e_sock->total_decrypted += len; + link->total_decrypted += len; } - struct ETCP_LINK* link = etcp_link_find_by_addr(e_sock, (struct sockaddr*)&pkt->metadata.remote_addr, - sizeof(pkt->metadata.remote_addr)); - if (!link) { if (header == ETCP_INIT_REQUEST || header == ETCP_CHANNEL_INIT) { - // Create new link - link = etcp_link_new(etcp, e_sock, (struct sockaddr*)&pkt->metadata.remote_addr, - sizeof(pkt->metadata.remote_addr)); - if (!link) return -1; + // Create new link - this shouldn't happen as link should be set + return -1; } else { // Send reset if not init uint8_t reset_pkt[1] = {ETCP_RESET}; - etcp_connections_send(e_sock, reset_pkt, 1, (struct sockaddr*)&pkt->metadata.remote_addr, sizeof(pkt->metadata.remote_addr)); + etcp_connections_send(link->conn, reset_pkt, 1, (struct sockaddr*)&link->remote_addr, sizeof(link->remote_addr)); return -1; } } @@ -456,9 +471,9 @@ int etcp_input(struct ETCP_DGRAM* pkt) { memcpy(peer_pubkey, data, SC_PUBKEY_SIZE); etcp->peer_node_id = peer_node_id; - memcpy(etcp->peer_public_key, peer_pubkey, SC_PUBKEY_SIZE); - etcp->has_peer_key = 1; - sc_set_peer_public_key(etcp->crypto_ctx, peer_pubkey); + memcpy(etcp->crypto_ctx.peer_public_key, peer_pubkey, SC_PUBKEY_SIZE); + etcp->peer_node_id = peer_node_id; // Set peer_node_id to indicate we have peer key + sc_set_peer_public_key(&etcp->crypto_ctx, peer_pubkey, 0); link->mtu = MIN(etcp->mtu, peer_mtu); link->keepalive_interval = peer_keepalive; @@ -475,89 +490,152 @@ int etcp_input(struct ETCP_DGRAM* pkt) { etcp_conn_reset(etcp); } else { // Forward to etcp_conn_input - pkt->metadata.channel = link; // Or etcp_channel if separate + pkt->link = link; etcp_conn_input(etcp, pkt); return 0; } - packet_pool_put(&etcp->packet_pool, pkt); return 0; } int init_connections(struct UTUN_INSTANCE* instance) { if (!instance || !instance->config) return -1; - struct config* config = instance->config; - instance->connections = calloc(config->server_count, sizeof(struct ETCP_CONN)); - if (!instance->connections) return -1; - - instance->connection_count = 0; + struct utun_config* config = instance->config; + // Initialize servers first - create sockets for incoming connections struct CFG_SERVER* server = config->servers; while (server) { - - // Create connections manager (includes socket creation) - struct ETCP_CONN* conn = etcp_connection_add(instance, server->ip, server->netif_index, server->so_mark, server->type); - if (!conn) { - DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create connections for %s", server->name); - etcp_destroy(etcp); + // Create socket for this server + struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, &server->ip, server->netif_index, server->so_mark, server->type); + if (!e_sock) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create socket for server %s", server->name); + server = server->next; continue; } + // Convert IP to string for logging + char addr_str[INET6_ADDRSTRLEN + 6]; + if (server->ip.ss_family == AF_INET) { + struct sockaddr_in* sin = (struct sockaddr_in*)&server->ip; + inet_ntop(AF_INET, &sin->sin_addr, addr_str, INET_ADDRSTRLEN); + sprintf(addr_str + strlen(addr_str), ":%d", ntohs(sin->sin_port)); + } else { + struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&server->ip; + inet_ntop(AF_INET6, &sin6->sin6_addr, addr_str, INET6_ADDRSTRLEN); + sprintf(addr_str + strlen(addr_str), ":%d", ntohs(sin6->sin6_port)); + } + printf("Initialized server %s on %s (links: %zu)\n", - server->name, server->addr, e_sock->num_channels); + server->name, addr_str, e_sock->num_channels); server = server->next; } - - // Process connections that added to this server - for (int j = 0; j < config->client_count; j++) { - struct client_config* client = &config->clients[j]; - - // Check if this client is for current server - if (strcmp(client->from, server->name) != 0) { + + // Initialize clients - create outgoing connections + struct CFG_CLIENT* client = config->clients; + while (client) { + // Create ETCP connection for this client + struct ETCP_CONN* etcp_conn = etcp_connection_create(instance); + if (!etcp_conn) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create ETCP connection for client %s", client->name); + client = client->next; continue; } - - struct ETCP_CONN* etcp_conn=etcp_connection_create(instance); - - // Серверы получат pubkey через INIT пакет - sc_init_ctx(&etcp_conn->ctx, &instance->my_keys); + // Initialize crypto context for this connection + sc_init_ctx(&etcp_conn->crypto_ctx, &instance->my_keys); + + // If client has peer public key configured, set it if (strlen(client->peer_public_key_hex) > 0) { - uint8_t peer_key_bin[SC_PUBKEY_SIZE]; - if (hex_to_binary(client->peer_public_key_hex, peer_key_bin, SC_PUBKEY_SIZE) == 0) { - memcpy(etcp_conn->peer_public_key, peer_key_bin, SC_PUBKEY_SIZE); - etcp_conn->has_peer_key = 1; - sc_set_peer_public_key(etcp_conn->crypto_ctx, peer_key_bin); - } + // For now, set peer node ID to indicate we have peer key + // The actual peer key will be exchanged during connection establishment + etcp_conn->peer_node_id = 1; // Simple indicator + + // Set peer public key (assuming hex format) + sc_set_peer_public_key(&etcp_conn->crypto_ctx, client->peer_public_key_hex, 1); } - -// тут надо добавить линки - - struct client_link cl=client->links; - while (cl) { - conn= (надо найти) - - // Create link for this client - struct ETCP_LINK* link = etcp_link_new(etcp, conn, cl->remote_sockaddr, sizeof(struct sockaddr_storage)); + + // Add connection to the instance's linked list + etcp_conn->next = instance->connections; + instance->connections = etcp_conn; + instance->connections_count++; + + // Create links for this client + struct CFG_CLIENT_LINK* client_link = client->links; + while (client_link) { + // Find the local server for this link + struct CFG_SERVER* local_server = client_link->local_srv; + if (!local_server) { + client_link = client_link->next; + continue; + } + + // Find the socket for this server + struct ETCP_SOCKET* e_sock = NULL; + struct ETCP_SOCKET* sock = instance->etcp_sockets; + while (sock) { + if (sock->local_addr.ss_family == local_server->ip.ss_family) { + if (sock->local_addr.ss_family == AF_INET) { + struct sockaddr_in* sock_addr = (struct sockaddr_in*)&sock->local_addr; + struct sockaddr_in* srv_addr = (struct sockaddr_in*)&local_server->ip; + if (sock_addr->sin_addr.s_addr == srv_addr->sin_addr.s_addr && + sock_addr->sin_port == srv_addr->sin_port) { + e_sock = sock; + break; + } + } + } + sock = sock->next; + } + + if (!e_sock) { + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "No socket found for client %s link", client->name); + client_link = client_link->next; + continue; + } + + // Create link for this client connection + struct ETCP_LINK* link = etcp_link_new(etcp_conn, e_sock, &client_link->remote_addr, 0); // 0 = client initiates if (!link) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create link for client %s", client->name); + client_link = client_link->next; continue; } - cl=cl->next; + + client_link = client_link->next; } - printf(" Added client %s -> %s\n", client->name, client->to_addr); + printf("Added client %s with %d links\n", client->name, client->keepalive); + client = client->next; } - - - if (instance->connection_count == 0) { + + if (instance->connections_count == 0) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "No connections initialized"); - free(instance->connections); - instance->connections = NULL; return -1; } - printf("Initialized %d connections\n", instance->connection_count); + printf("Initialized %d connections\n", instance->connections_count); + return 0; +} + +// Simple implementations for missing functions +int etcp_link_send_init_response(struct ETCP_LINK* link, int mtu, uint16_t keepalive_interval) { + // TODO: Implement this function return 0; } + +void packet_pool_free(struct memory_pool* pool, void* ptr) { + // TODO: Implement this function + // For now, just free the memory (this is a simplified version) + if (ptr) { + // In a real implementation, this would return to the pool + // For now, we assume the memory came from the pool + } +} + +int etcp_connections_send(struct ETCP_SOCKET* e_sock, uint8_t* data, size_t len, struct sockaddr* addr, socklen_t addr_len) { + // TODO: Implement this function + // For now, just send directly + ssize_t sent = sendto(e_sock->fd, data, len, 0, addr, addr_len); + return (sent < 0) ? -1 : (int)sent; +}