Browse Source

1

congestion
Evgeny 6 months ago
parent
commit
8bad15b7bb
  1. 43
      lib/debug_config.c
  2. 3
      lib/debug_config.h
  3. 15
      lib/socket_compat.c
  4. 3
      lib/socket_compat.h
  5. 14
      src/etcp_connections.c
  6. 16
      src/route_bgp.c
  7. 16
      src/route_bgp.txt

43
lib/debug_config.c

@ -57,6 +57,49 @@ ip_str_t ip_to_str(const void *addr, int family) {
return result; return result;
} }
ip_str_t sockaddr_storage_to_str(const struct sockaddr_storage *addr) {
ip_str_t result;
result.str[0] = '\0';
if (!addr) {
return result;
}
char ip_buf[INET6_ADDRSTRLEN];
ip_buf[0] = '\0';
uint16_t port = 0;
void *src = NULL;
if (addr->ss_family == AF_INET) {
const struct sockaddr_in *ipv4 = (const struct sockaddr_in *)addr;
src = (void *)&ipv4->sin_addr;
port = ntohs(ipv4->sin_port);
}
else if (addr->ss_family == AF_INET6) {
const struct sockaddr_in6 *ipv6 = (const struct sockaddr_in6 *)addr;
src = (void *)&ipv6->sin6_addr;
port = ntohs(ipv6->sin6_port);
}
else {
return result;
}
if (!inet_ntop(addr->ss_family, src, ip_buf, sizeof(ip_buf))) {
return result;
}
if (addr->ss_family == AF_INET6) {
// IPv6 обязательно в []
snprintf(result.str, sizeof(result.str), "[%s]:%u", ip_buf, port);
} else {
snprintf(result.str, sizeof(result.str), "%s:%u", ip_buf, port);
}
return result;
}
static const struct { static const struct {
const char* name; const char* name;

3
lib/debug_config.h

@ -111,10 +111,11 @@ void debug_enable_console(int enable);
// IP address to string (static buffer, single-threaded) // IP address to string (static buffer, single-threaded)
typedef struct { typedef struct {
char str[48]; // INET6_ADDRSTRLEN(45) + \0 char str[54]; // INET6_ADDRSTRLEN(45) + 6chars (:port) + \0
} ip_str_t; } ip_str_t;
ip_str_t ip_to_str(const void *addr, int family);// big endian addr ip_str_t ip_to_str(const void *addr, int family);// big endian addr
ip_str_t sockaddr_storage_to_str(const struct sockaddr_storage *addr);// автоопределение v4 или v6
// hex dump в лог // hex dump в лог
void log_dump(const char* prefix, const uint8_t* data, size_t len); void log_dump(const char* prefix, const uint8_t* data, size_t len);

15
lib/socket_compat.c

@ -230,3 +230,18 @@ ssize_t socket_recvfrom(socket_t sock, void* buf, size_t len,
return recvfrom(sock, buf, len, 0, src, src_len); return recvfrom(sock, buf, len, 0, src, src_len);
#endif #endif
} }
uint16_t ss_get_port(const struct sockaddr_storage *addr) {
if (!addr) return 0;
if (addr->ss_family == AF_INET) {
const struct sockaddr_in *ipv4 = (const struct sockaddr_in *)addr;
return ntohs(ipv4->sin_port);
}
else if (addr->ss_family == AF_INET6) {
const struct sockaddr_in6 *ipv6 = (const struct sockaddr_in6 *)addr;
return ntohs(ipv6->sin6_port);
}
return 0;
}

3
lib/socket_compat.h

@ -69,4 +69,7 @@ ssize_t socket_recvfrom(socket_t sock, void* buf, size_t len,
// Utility // Utility
const char* socket_strerror(int err); const char* socket_strerror(int err);
// взять порт из sockaddr_storage
uint16_t ss_get_port(const struct sockaddr_storage *addr);
#endif // SOCKET_COMPAT_H #endif // SOCKET_COMPAT_H

14
src/etcp_connections.c

@ -926,7 +926,7 @@ static int etcp_send_ping_raw(struct ETCP_DGRAM* dgram, socket_t fd, sc_context_
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "sendto failed for ping, err=%d", socket_get_error()); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "sendto failed for ping, err=%d", socket_get_error());
return -1; return -1;
} }
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "ping sendto succeeded, sent=%zd bytes", sent); DEBUG_TRACE(DEBUG_CATEGORY_BGP, "ping sendto succeeded to %s sent=%zd bytes", sent, sockaddr_storage_to_str(addr).str);
return (int)sent; return (int)sent;
} }
@ -1593,18 +1593,8 @@ int init_sockets(struct UTUN_INSTANCE* instance) {
} }
success_count++; success_count++;
// Convert IP to string for logging
char addr_str[INET6_ADDRSTRLEN + 10];
if (server->ip.ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)&server->ip;
snprintf(addr_str, sizeof(addr_str), "%s:%d", ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
} else {
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&server->ip;
snprintf(addr_str, sizeof(addr_str), "%s:%d", ip_to_str(&sin6->sin6_addr, AF_INET6).str, ntohs(sin6->sin6_port));
}
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Initialized server %s on %s (links: %zu)", DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Initialized server %s on %s (links: %zu)",
server->name, addr_str, e_sock->num_channels); server->name, sockaddr_storage_to_str(&server->ip).str, e_sock->num_channels);
server = server->next; server = server->next;
} }

16
src/route_bgp.c

@ -424,7 +424,7 @@ void route_bgp_new_conn(struct ETCP_CONN* conn) {
while (c) { while (c) {
struct ETCP_LINK* l = c->links; struct ETCP_LINK* l = c->links;
while (l) { while (l) {
if (l->initialized && l->conn && l->nat_check_status == NAT_CHECK_NONE) { if (l->initialized && l->conn && l->nat_check_status < NAT_CHECK_IN_PROGRESS) {
route_bgp_start_link_nat_check(bgp, l); route_bgp_start_link_nat_check(bgp, l);
} }
l = l->next; l = l->next;
@ -687,9 +687,10 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI
// Find third node to send ping through // Find third node to send ping through
struct ETCP_CONN* third_conn = route_bgp_find_third_node(bgp, link->etcp); struct ETCP_CONN* third_conn = route_bgp_find_third_node(bgp, link->etcp);
if (!third_conn) { if (!third_conn) {
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: no third node found for link"); DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "no third node found for link");
return; return;
} }
// Get target address - use nat_ip/nat_port if set, otherwise use remote_addr // Get target address - use nat_ip/nat_port if set, otherwise use remote_addr
uint32_t target_ip; uint32_t target_ip;
uint16_t target_port; uint16_t target_port;
@ -701,6 +702,9 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI
target_ip = ntohl(sin->sin_addr.s_addr); target_ip = ntohl(sin->sin_addr.s_addr);
target_port = ntohs(sin->sin_port); target_port = ntohs(sin->sin_port);
} }
if (is_local_subnet(target_ip)) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "local ip: %s, skip nat check", ip_to_str(&target_ip, AF_INET).str); return; }
// Allocate callback arg // Allocate callback arg
struct nat_check_arg* arg = u_calloc(1, sizeof(struct nat_check_arg)); struct nat_check_arg* arg = u_calloc(1, sizeof(struct nat_check_arg));
if (!arg) return; if (!arg) return;
@ -711,7 +715,7 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI
const uint8_t* pubkey = link->etcp->crypto_ctx.peer_key_set ? link->etcp->crypto_ctx.peer_public_key : NULL; const uint8_t* pubkey = link->etcp->crypto_ctx.peer_key_set ? link->etcp->crypto_ctx.peer_public_key : NULL;
if (!pubkey) { if (!pubkey) {
u_free(arg); u_free(arg);
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: no peer pubkey for link=%p", (void*)link); DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "no peer pubkey for link=%p", (void*)link);
return; return;
} }
// Send ping via third node - embed peer pubkey for NAT detection // Send ping via third node - embed peer pubkey for NAT detection
@ -720,11 +724,11 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI
pubkey); pubkey);
if (ret == 0) { if (ret == 0) {
link->nat_check_status = NAT_CHECK_IN_PROGRESS; link->nat_check_status = NAT_CHECK_IN_PROGRESS;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: started for link=%p via=%s", DEBUG_INFO(DEBUG_CATEGORY_BGP, "ping remote request via=%s (%s:%d)",
(void*)link, third_conn->log_name); (void*)link, third_conn->log_name, ip_to_str(&target_ip, AF_INET).str, target_port);
} else { } else {
u_free(arg); u_free(arg);
DEBUG_WARN(DEBUG_CATEGORY_BGP, "route_bgp_start_link_nat_check: failed to start for link=%p", DEBUG_WARN(DEBUG_CATEGORY_BGP, "failed to start for link=%p",
(void*)link); (void*)link);
} }
} }

16
src/route_bgp.txt

@ -24,3 +24,19 @@ bgp_update local nodelist:
bgp_withdraw(struct ROUTE_BGP bgp, uint64_t node_to_del, uint64_t wd_source) - wd_source это узел который захотел withdraw. bgp_withdraw(struct ROUTE_BGP bgp, uint64_t node_to_del, uint64_t wd_source) - wd_source это узел который захотел withdraw.
- находим у себя node to del. удаляем если в hoplist найден wd_node (или мы = wd_node) - находим у себя node to del. удаляем если в hoplist найден wd_node (или мы = wd_node)
если удалили - распространяем по всем линкам с этими же аргументами если удалили - распространяем по всем линкам с этими же аргументами
===============================
определение nat
определяем что оба узла в локальной сети:
-если обе ноды имеют локальные адреса сокетов пробуем пинг по локальным адресам
если узел подключился и его сокетовый ip:port отличается от connection ip:port - устанавливаем флаг nat. и инициируем проверку пингом третьим узлом:
проверка считается успешной если по результату пинга ip источника пинга отличается от ip запросившего пинг узла.
проверка типа nat узла который подключился:
- пингуем узел с целью зафиксировать свой ip (в сокете может быть например 0.0.0.0)
- даём команду третьему узлу пингануть этот узел.
- по результатам двух пингов определяем тип nat

Loading…
Cancel
Save