Browse Source

1

nodeinfo-routing-update
jeka 1 month ago
parent
commit
b27ea97055
  1. 101
      lib/platform_compat.c
  2. 6
      lib/platform_compat.h
  3. 4
      src/config_parser.c
  4. 18
      src/etcp_connections.c
  5. 1
      src/etcp_connections.h
  6. 6
      src/route_bgp.c

101
lib/platform_compat.c

@ -3,16 +3,27 @@
#include "platform_compat.h" #include "platform_compat.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#include <bcrypt.h> #include <bcrypt.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
#ifndef STATUS_SUCCESS #ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif #endif
#else #else
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <net/if.h>
#endif #endif
/* /*
@ -35,3 +46,93 @@ int random_bytes(uint8_t *buffer, size_t len) {
return (ret == (ssize_t)len) ? 0 : -1; return (ret == (ssize_t)len) ? 0 : -1;
#endif #endif
} }
#ifndef _WIN32
static uint32_t get_default_route_ip_linux(void) {
FILE *f = fopen("/proc/net/route", "r");
if (!f) return 0;
char line[256];
char *ifname = NULL;
unsigned int dest, gw;
if (!fgets(line, sizeof(line), f)) {
fclose(f);
return 0;
}
while (fgets(line, sizeof(line), f)) {
int items = sscanf(line, "%ms %x %x", &ifname, &dest, &gw);
if (items != 3) {
free(ifname);
continue;
}
if (dest == 0) {
free(ifname);
break;
}
free(ifname);
ifname = NULL;
}
fclose(f);
if (!ifname) return 0;
struct ifaddrs *ifaddr, *ifa;
if (getifaddrs(&ifaddr) == -1) {
free(ifname);
return 0;
}
uint32_t result = 0;
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) continue;
if (ifa->ifa_name == NULL) continue;
if (strcmp(ifa->ifa_name, ifname) != 0) continue;
if (ifa->ifa_addr->sa_family != AF_INET) continue;
struct sockaddr_in *addr = (struct sockaddr_in *)ifa->ifa_addr;
result = addr->sin_addr.s_addr;
break;
}
freeifaddrs(ifaddr);
free(ifname);
return result;
}
#else
static uint32_t get_default_route_ip_windows(void) {
SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET) return 0;
struct sockaddr_in remote;
remote.sin_family = AF_INET;
remote.sin_port = htons(53);
remote.sin_addr.s_addr = inet_addr("8.8.8.8");
if (connect(s, (struct sockaddr *)&remote, sizeof(remote)) == SOCKET_ERROR) {
closesocket(s);
return 0;
}
struct sockaddr_in local;
int len = sizeof(local);
if (getsockname(s, (struct sockaddr *)&local, &len) == SOCKET_ERROR) {
closesocket(s);
return 0;
}
closesocket(s);
return local.sin_addr.s_addr;
}
#endif
uint32_t get_default_route_ip(void) {
#ifdef _WIN32
return get_default_route_ip_windows();
#else
return get_default_route_ip_linux();
#endif
}

6
lib/platform_compat.h

@ -136,8 +136,14 @@
#include <poll.h> #include <poll.h>
#endif #endif
#include <stdint.h>
// Generate cryptographically secure random bytes // Generate cryptographically secure random bytes
// Returns 0 on success, -1 on error // Returns 0 on success, -1 on error
int random_bytes(uint8_t *buffer, size_t len); int random_bytes(uint8_t *buffer, size_t len);
// Get IPv4 address of interface with default route (0.0.0.0 destination)
// Returns IPv4 address in network byte order, 0 on error
uint32_t get_default_route_ip(void);
#endif // PLATFORM_COMPAT_H #endif // PLATFORM_COMPAT_H

4
src/config_parser.c

@ -99,6 +99,10 @@ static int parse_key_value(const char *line, char *key, size_t key_len, char *va
size_t val_len = strlen(val_start); size_t val_len = strlen(val_start);
if (val_len >= value_len) return -1; if (val_len >= value_len) return -1;
strcpy(value, val_start); strcpy(value, val_start);
char *comment = strchr(value, '#');
if (comment) *comment = '\0';
trim(value); trim(value);
return 0; return 0;

18
src/etcp_connections.c

@ -491,6 +491,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
e_sock->errorcode = 0; e_sock->errorcode = 0;
e_sock->pkt_format_errors = 0; e_sock->pkt_format_errors = 0;
e_sock->type = type; e_sock->type = type;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Add Socket type=%d", type);
// Add to instance's socket list // Add to instance's socket list
e_sock->next = instance->etcp_sockets; e_sock->next = instance->etcp_sockets;
@ -1136,7 +1137,24 @@ int init_connections(struct UTUN_INSTANCE* instance) {
struct CFG_SERVER* server = config->servers; struct CFG_SERVER* server = config->servers;
while (server) { while (server) {
// Create socket for this server // Create socket for this server
// Auto-detect local IP for public servers with 0.0.0.0
uint32_t default_ip = 0;
if (server->type == CFG_SERVER_TYPE_PUBLIC) {
struct sockaddr_in* sin = (struct sockaddr_in*)&server->ip;
if (sin->sin_addr.s_addr == 0) {
default_ip = get_default_route_ip();
if (default_ip == 0) {
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "Failed to detect default route IP for server %s", server->name);
}
}
}
struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, &server->ip, server->netif_index, server->so_mark, server->type); struct ETCP_SOCKET* e_sock = etcp_socket_add(instance, &server->ip, server->netif_index, server->so_mark, server->type);
if (e_sock && default_ip != 0) {
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Server %s type %d ip=%08x", server->name, server->type, default_ip);
e_sock->local_defaultroute_ip = default_ip;
}
if (!e_sock) { if (!e_sock) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create socket for server %s", server->name); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to create socket for server %s", server->name);
server = server->next; server = server->next;

1
src/etcp_connections.h

@ -44,6 +44,7 @@ struct ETCP_SOCKET {
void* socket_id; // Socket ID from uasync_add_socket void* socket_id; // Socket ID from uasync_add_socket
uint8_t type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE uint8_t type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE
uint32_t local_defaultroute_ip; // auto-detected IPv4 for public servers (network byte order)
}; };
// ETCP Link - одно динамическое соединение (один путь) // ETCP Link - одно динамическое соединение (один путь)

6
src/route_bgp.c

@ -383,10 +383,13 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
// Первый проход - PUBLIC // Первый проход - PUBLIC
while (link) { while (link) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending routine: scanning conn type=%d init=%d", link->conn->type, link->initialized);
if (link->conn && link->conn->type == CFG_SERVER_TYPE_PUBLIC && link->initialized) { if (link->conn && link->conn->type == CFG_SERVER_TYPE_PUBLIC && link->initialized) {
struct sockaddr_in* sin = (struct sockaddr_in*)&link->conn->local_addr; struct sockaddr_in* sin = (struct sockaddr_in*)&link->conn->local_addr;
uint32_t ip = *(uint32_t*)&sin->sin_addr; uint32_t ip = *(uint32_t*)&sin->sin_addr;
uint16_t port = sin->sin_port; uint16_t port = sin->sin_port;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending routine [public]");
route_bgp_send_route_single(bgp, conn, route, ip, port); route_bgp_send_route_single(bgp, conn, route, ip, port);
sent_any = 1; sent_any = 1;
} }
@ -399,6 +402,7 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
if (link->conn && link->conn->type == CFG_SERVER_TYPE_NAT && link->nat_ip && link->initialized) { if (link->conn && link->conn->type == CFG_SERVER_TYPE_NAT && link->nat_ip && link->initialized) {
uint32_t ip = link->nat_ip; uint32_t ip = link->nat_ip;
uint16_t port = link->nat_port; uint16_t port = link->nat_port;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending routine [nat]");
route_bgp_send_route_single(bgp, conn, route, ip, port); route_bgp_send_route_single(bgp, conn, route, ip, port);
sent_any = 1; sent_any = 1;
} }
@ -407,10 +411,12 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
// Если нет PUBLIC и NAT - отправляем без endpoint (0.0.0.0:0) // Если нет PUBLIC и NAT - отправляем без endpoint (0.0.0.0:0)
if (!sent_any) { if (!sent_any) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending routine [any]");
route_bgp_send_route_single(bgp, conn, route, 0, 0); route_bgp_send_route_single(bgp, conn, route, 0, 0);
} }
} else { } else {
// Для LEARNED маршрутов - используем endpoint из route // Для LEARNED маршрутов - используем endpoint из route
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending routine [learned]");
route_bgp_send_route_single(bgp, conn, route, route_bgp_send_route_single(bgp, conn, route,
htonl(route->endpoint_ip), htonl(route->endpoint_ip),
htons(route->endpoint_port)); htons(route->endpoint_port));

Loading…
Cancel
Save