|
|
|
|
@ -16,7 +16,9 @@
|
|
|
|
|
#include "route_lib.h" |
|
|
|
|
#include "etcp_api.h" |
|
|
|
|
#include "etcp.h" |
|
|
|
|
#include "etcp_connections.h" |
|
|
|
|
#include "utun_instance.h" |
|
|
|
|
#include "config_parser.h" |
|
|
|
|
#include "../lib/debug_config.h" |
|
|
|
|
|
|
|
|
|
// Размер пакета (без заголовка ETCP)
|
|
|
|
|
@ -263,30 +265,16 @@ static void route_bgp_on_route_change(struct ROUTE_TABLE* table,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Отправить один маршрут через ETCP |
|
|
|
|
* @brief Отправить один маршрут через ETCP (вспомогательная функция для отправки одного пакета) |
|
|
|
|
*/ |
|
|
|
|
static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
|
|
|
|
const struct ROUTE_ENTRY* route) |
|
|
|
|
static int route_bgp_send_route_single(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
|
|
|
|
const struct ROUTE_ENTRY* route, |
|
|
|
|
uint32_t endpoint_ip, uint16_t endpoint_port) |
|
|
|
|
{ |
|
|
|
|
if (!bgp || !conn || !route) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Пропускаем неактивные маршруты
|
|
|
|
|
if (!(route->flags & ROUTE_FLAG_ACTIVE)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Пропускаем локальные маршруты если они не для анонса
|
|
|
|
|
if ((route->flags & ROUTE_FLAG_ADVERTISED) && (route->prefix_length & ROUTE_PREFIX_F_LOCAL)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Создаем ETCP пакет
|
|
|
|
|
struct ll_entry* entry = ll_alloc_lldgram(sizeof(struct ROUTE_BGP_PACKET)); |
|
|
|
|
if (!entry) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to allocate packet"); |
|
|
|
|
return; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ROUTE_BGP_PACKET* pkt = (struct ROUTE_BGP_PACKET*)entry->dgram; |
|
|
|
|
@ -296,7 +284,7 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
|
|
|
|
pkt->prefix_length = route->prefix_length; |
|
|
|
|
|
|
|
|
|
// Устанавливаем флаги
|
|
|
|
|
if (route->endpoint_ip && route->endpoint_port) { |
|
|
|
|
if (endpoint_ip && endpoint_port) { |
|
|
|
|
pkt->prefix_length |= ROUTE_PREFIX_F_DIRECT; |
|
|
|
|
} |
|
|
|
|
// Если это локальный маршрут - отмечаем (не будет пересылаться дальше)
|
|
|
|
|
@ -305,22 +293,91 @@ static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pkt->latency = htons(route->metrics.latency_ms * 10); // ms -> x0.1 ms
|
|
|
|
|
pkt->endpoint_port = htons(route->endpoint_port); |
|
|
|
|
pkt->endpoint_ip = htonl(route->endpoint_ip); |
|
|
|
|
pkt->endpoint_port = endpoint_port; |
|
|
|
|
pkt->endpoint_ip = endpoint_ip; |
|
|
|
|
pkt->network = htonl(route->network); |
|
|
|
|
pkt->bandwidth_kbps = htonl(route->metrics.bandwidth_kbps); |
|
|
|
|
pkt->node_id = bgp->instance->node_id; // Наш node_id
|
|
|
|
|
pkt->route_type = route->type; |
|
|
|
|
|
|
|
|
|
entry->len = sizeof(struct ROUTE_BGP_PACKET); |
|
|
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Sending route: %08x/%d to conn %p", |
|
|
|
|
route->network, route->prefix_length & 0x3F, (void*)conn); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Sending route: %08x/%d to conn %p, endpoint=%u.%u.%u.%u:%d", |
|
|
|
|
route->network, route->prefix_length & 0x3F, (void*)conn, |
|
|
|
|
(endpoint_ip >> 24) & 0xFF, (endpoint_ip >> 16) & 0xFF, |
|
|
|
|
(endpoint_ip >> 8) & 0xFF, endpoint_ip & 0xFF, |
|
|
|
|
ntohs(endpoint_port)); |
|
|
|
|
|
|
|
|
|
// Отправляем через ETCP
|
|
|
|
|
if (etcp_send(conn, entry) != 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to send route via ETCP"); |
|
|
|
|
queue_dgram_free(entry); |
|
|
|
|
queue_entry_free(entry); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Отправить один маршрут через ETCP |
|
|
|
|
*/ |
|
|
|
|
static void route_bgp_send_route(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn,
|
|
|
|
|
const struct ROUTE_ENTRY* route) |
|
|
|
|
{ |
|
|
|
|
if (!bgp || !conn || !route) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Пропускаем неактивные маршруты
|
|
|
|
|
if (!(route->flags & ROUTE_FLAG_ACTIVE)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Пропускаем локальные маршруты если они не для анонса
|
|
|
|
|
if ((route->flags & ROUTE_FLAG_ADVERTISED) && (route->prefix_length & ROUTE_PREFIX_F_LOCAL)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Для LOCAL маршрутов - отправляем с нескольких endpoints если есть PUBLIC или NAT серверы
|
|
|
|
|
if (route->type == ROUTE_TYPE_LOCAL && conn->links) { |
|
|
|
|
// Сначала отправляем PUBLIC (приоритет), затем NAT
|
|
|
|
|
struct ETCP_LINK* link = conn->links; |
|
|
|
|
int sent_any = 0; |
|
|
|
|
|
|
|
|
|
// Первый проход - PUBLIC
|
|
|
|
|
while (link) { |
|
|
|
|
if (link->conn && link->conn->type == CFG_SERVER_TYPE_PUBLIC && link->initialized) { |
|
|
|
|
struct sockaddr_in* sin = (struct sockaddr_in*)&link->conn->local_addr; |
|
|
|
|
uint32_t ip = *(uint32_t*)&sin->sin_addr; |
|
|
|
|
uint16_t port = sin->sin_port; |
|
|
|
|
route_bgp_send_route_single(bgp, conn, route, ip, port); |
|
|
|
|
sent_any = 1; |
|
|
|
|
} |
|
|
|
|
link = link->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Второй проход - NAT
|
|
|
|
|
link = conn->links; |
|
|
|
|
while (link) { |
|
|
|
|
if (link->conn && link->conn->type == CFG_SERVER_TYPE_NAT && link->nat_ip && link->initialized) { |
|
|
|
|
uint32_t ip = link->nat_ip; |
|
|
|
|
uint16_t port = link->nat_port; |
|
|
|
|
route_bgp_send_route_single(bgp, conn, route, ip, port); |
|
|
|
|
sent_any = 1; |
|
|
|
|
} |
|
|
|
|
link = link->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Если нет PUBLIC и NAT - отправляем без endpoint (0.0.0.0:0)
|
|
|
|
|
if (!sent_any) { |
|
|
|
|
route_bgp_send_route_single(bgp, conn, route, 0, 0); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
// Для LEARNED маршрутов - используем endpoint из route
|
|
|
|
|
route_bgp_send_route_single(bgp, conn, route,
|
|
|
|
|
htonl(route->endpoint_ip),
|
|
|
|
|
htons(route->endpoint_port)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|