Добавлено поле interface_addr в ETCP_SOCKET и interface_ip/port в BGP_NAT_CHECK_REQ

- platform_compat: get_interface_ip_by_index() для получения IP по ifindex
- ETCP_SOCKET: interface_addr заполняется из конфига/interface/default route
- BGP_NAT_CHECK_REQ: добавлены interface_ip/interface_port (network byte order)
- route_bgp_send_nat_check_req: отправляет interface_addr линка
- route_bgp_handle_nat_check_req: принимает interface данные в sockaddr-заглушку
This commit is contained in:
Evgeny committed 2026-04-22 18:16:49 +03:00
1 parent 2e3eb0976a
commit b466d14fe4
7 files changed
+320 -4

No files matched your search

+36
View File
@@ -550,6 +550,42 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "Listen socket initialized: name=%s fd=%d addr=%s:%d", e_sock->name, e_sock->fd, ip_to_str(&sin6->sin6_addr, AF_INET6).str, ntohs(sin6->sin6_port));
}
}
// Определяем interface_addr: IP интерфейса или из конфига
memset(&e_sock->interface_addr, 0, sizeof(e_sock->interface_addr));
if (netif_index > 0) {
uint32_t if_ip = get_interface_ip_by_index(netif_index);
if (if_ip != 0) {
struct sockaddr_in* sin = (struct sockaddr_in*)&e_sock->interface_addr;
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = if_ip;
}
} else if (ip && ip->ss_family == AF_INET) {
struct sockaddr_in* sin = (struct sockaddr_in*)ip;
if (sin->sin_addr.s_addr == 0) {
uint32_t def_ip = get_default_route_ip();
if (def_ip != 0) {
struct sockaddr_in* isin = (struct sockaddr_in*)&e_sock->interface_addr;
isin->sin_family = AF_INET;
isin->sin_addr.s_addr = def_ip;
}
}
}
if (((struct sockaddr_in*)&e_sock->interface_addr)->sin_addr.s_addr == 0) {
if (ip) memcpy(&e_sock->interface_addr, ip, sizeof(struct sockaddr_storage));
} else {
// скопируем порт из конфига в interface_addr
if (ip && ip->ss_family == AF_INET) {
struct sockaddr_in* sin_cfg = (struct sockaddr_in*)ip;
struct sockaddr_in* sin_if = (struct sockaddr_in*)&e_sock->interface_addr;
sin_if->sin_port = sin_cfg->sin_port;
}
}
{
struct sockaddr_in* isin = (struct sockaddr_in*)&e_sock->interface_addr;
if (isin->sin_addr.s_addr != 0) {
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] interface_addr for %s: %s:%d", e_sock->name, ip_to_str(&isin->sin_addr, AF_INET).str, ntohs(isin->sin_port));
}
}
e_sock->instance = instance;
e_sock->errorcode = 0;
e_sock->pkt_format_errors = 0;
+1
View File
@@ -73,6 +73,7 @@ struct ETCP_SOCKET {
uint32_t local_defaultroute_ip; // auto-detected IPv4 for public servers (network byte order)
uint8_t local_defaultroute_ip6[16]; // auto-detected IPv6 for public servers
uint8_t only_local; // 1 = only local connections, no forwarding
struct sockaddr_storage interface_addr; // адрес интерфейса: если bind на интерфейс - его IP, если 0.0.0.0 без интерфейса - IP интерфейса через который идет default route, иначе - адрес из конфига
};
// NAT check status
+30 -4
View File
@@ -995,6 +995,14 @@ static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CO
const struct BGP_NAT_CHECK_REQ* req = (const struct BGP_NAT_CHECK_REQ*)data;
uint8_t socket_id = req->socket_id;
struct sockaddr_storage dummy;
memset(&dummy, 0, sizeof(dummy));
if (req->interface_ip != 0) {
struct sockaddr_in* sin = (struct sockaddr_in*)&dummy;
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = req->interface_ip;
sin->sin_port = req->interface_port;
}
struct ETCP_LINK* target_link = NULL;
struct ETCP_LINK* l = from_conn->links;
@@ -1007,8 +1015,11 @@ static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CO
}
if (!target_link) {
DEBUG_WARN(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: no link with remote_socket_id=%u",
from_conn->log_name, socket_id);
struct sockaddr_in* sin = (struct sockaddr_in*)&dummy;
DEBUG_WARN(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: no link with remote_socket_id=%u interface=%s:%u",
from_conn->log_name, socket_id,
sin->sin_addr.s_addr ? ip_to_str(&sin->sin_addr, AF_INET).str : "none",
(unsigned)ntohs(sin->sin_port));
} else if (target_link->nat_check_status == NAT_CHECK_IN_PROGRESS) {
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "NAT_CHECK_REQ from %s: check already in progress for socket_id=%u",
from_conn->log_name, socket_id);
@@ -1060,6 +1071,19 @@ void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) {
pkt->subcmd = ROUTE_SUBCMD_NAT_CHECK_REQ;
pkt->socket_id = socket_id;
struct ETCP_LINK* l = conn->links;
while (l) {
if (l->remote_socket_id == socket_id) {
struct sockaddr_in* sin = (struct sockaddr_in*)&l->conn->interface_addr;
if (sin->sin_family == AF_INET) {
pkt->interface_ip = sin->sin_addr.s_addr;
pkt->interface_port = sin->sin_port;
}
break;
}
l = l->next;
}
struct ll_entry* e = queue_entry_new(0);
if (!e) {
u_free(pkt);
@@ -1068,6 +1092,8 @@ void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) {
e->dgram = (uint8_t*)pkt;
e->len = sizeof(struct BGP_NAT_CHECK_REQ);
etcp_send(conn, e);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_check_req to %s: socket_id=%u",
conn->log_name, socket_id);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_send_nat_check_req to %s: socket_id=%u interface=%s:%u",
conn->log_name, socket_id,
ip_to_str(&pkt->interface_ip, AF_INET).str,
(unsigned)ntohs(pkt->interface_port));
}
+2
View File
@@ -73,6 +73,8 @@ struct BGP_NAT_CHECK_REQ {
uint8_t cmd;
uint8_t subcmd; // ROUTE_SUBCMD_NAT_CHECK_REQ
uint8_t socket_id; // ID сокета клиента, который надо проверить
uint32_t interface_ip; // interface_addr IP клиента (network byte order)
uint16_t interface_port; // interface_addr port клиента (network byte order)
} __attribute__((packed));
struct route_ping_pending;