You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
11 KiB
219 lines
11 KiB
Диаграмма вызовов функций при определении типа NAT (NAT detection) |
|
===================================================================== |
|
|
|
=== ИНИЦИАЛИЗАЦИЯ BGP === |
|
|
|
route_bgp_init(instance) |
|
└── etcp_set_new_conn_cbk(instance, route_bgp_etcp_conn_cbk, NULL) |
|
└── При создании нового ETCP_CONN: |
|
route_bgp_etcp_conn_cbk(conn, arg) |
|
├── etcp_conn_set_up_cbk(conn, route_bgp_on_conn_up, bgp) |
|
└── etcp_conn_set_down_cbk(conn, route_bgp_on_conn_down, bgp) |
|
|
|
|
|
=== УСТАНОВКА СОЕДИНЕНИЯ (сервер получает INIT_REQUEST) === |
|
|
|
etcp_connections_read_callback_socket(sock, arg) |
|
└── Получает ETCP_INIT_REQUEST |
|
├── etcp_connection_create(instance, name) [если новый peer] |
|
│ └── Вызывает instance->etcp_new_conn_cbk [route_bgp_etcp_conn_cbk] |
|
├── etcp_link_new(etcp, e_sock, remote_addr, is_server=1) |
|
├── Отправляет ETCP_INIT_RESPONSE (с NAT info) |
|
├── link->initialized = 1 |
|
└── etcp_conn_ready(link->etcp) |
|
└── conn->ready_cbk |
|
└── etcp_on_up(etcp) |
|
└── etcp->up_cbk = route_bgp_on_conn_up(etcp, bgp) |
|
|
|
|
|
=== УСТАНОВКА СОЕДИНЕНИЯ (клиент получает INIT_RESPONSE) === |
|
|
|
etcp_connections_read_callback_socket(sock, arg) |
|
└── Получает ETCP_INIT_RESPONSE |
|
├── Сохраняет NAT address: link->nat_ip, link->nat_port |
|
├── link->initialized = 1 |
|
└── etcp_conn_ready(link->etcp) |
|
└── etcp_on_up(etcp) |
|
└── etcp->up_cbk = route_bgp_on_conn_up(etcp, bgp) |
|
|
|
|
|
=== ЗАПУСК ПРОВЕРКИ NAT (при поднятии соединения) === |
|
|
|
route_bgp_on_conn_up(etcp, arg) |
|
└── route_bgp_new_conn(conn) |
|
├── route_bgp_add_to_senders(bgp, conn) |
|
└── Сканирует ВСЕ линки ВСЕХ соединений: |
|
if (link->initialized && link->conn && link->nat_check_status < NAT_CHECK_IN_PROGRESS) |
|
└── route_bgp_start_link_nat_check(bgp, link) |
|
├── if (nat_check_status == IN_PROGRESS) return |
|
├── route_bgp_find_third_node(bgp, exclude=link->etcp) |
|
│ └── Ищет другой ETCP_CONN в senders_list |
|
├── Определяет target_ip/target_port: |
|
│ ├── Если link->nat_ip != 0: использует nat_ip/nat_port |
|
│ └── Иначе: использует link->remote_addr |
|
├── Проверяет is_local_subnet(target_ip) [если запрещено - skip] |
|
├── route_bgp_extract_nat_addr(conn, &nat_ip, &nat_port) |
|
│ └── Ищет первый линк с nat_ip != 0 |
|
├── Создает nat_check_arg { link, nat_ip, nat_port } |
|
└── route_ping_send_req_addr(bgp, third_conn, target_ip, target_port, |
|
count=3, interval=500ms, timeout=1000ms, |
|
wait_timeout=5000ms, |
|
cb=nat_link_check_cb, arg=nat_check_arg, |
|
pubkey=peer_pubkey) |
|
|
|
|
|
=== ОТПРАВКА ЗАПРОСА НА ПИНГ (через third node) === |
|
|
|
route_ping_send_req_addr(bgp, to_conn, target_ip, target_port, ...) |
|
├── Создает BGP_PING_REQUEST { cmd, subcmd=PING_REQ, request_id, count, interval, timeout, target_ipv4, target_port, pubkey } |
|
├── etcp_send(to_conn, entry) [отправляет запрос third node] |
|
├── Создает route_ping_pending { request_id, callback=nat_link_check_cb, arg, timeout_timer } |
|
└── Добавляет в bgp->ping_pending |
|
|
|
|
|
=== ОБРАБОТКА PING_REQ (на third node) === |
|
|
|
route_bgp_receive_cbk(data, len, from_conn, bgp) |
|
└── ROUTE_SUBCMD_PING_REQ |
|
└── route_ping_handle_req(bgp, from_conn, data, len) |
|
├── Создает route_ping_series_ctx { reply_conn, request_id, target_addr, pubkey, local_sock, count_total } |
|
├── Находит первый IPv4 ETCP_SOCKET -> local_sock |
|
└── etcp_send_ping_to_socket(instance, local_sock, pubkey, &target_addr, |
|
timeout_ms, route_ping_single_cb, ctx, NULL, 0) |
|
└── Отправляет ETCP пинг на target_addr |
|
|
|
|
|
=== ОТВЕТ НА ПИНГ (целевой узел) === |
|
|
|
etcp_connections_read_callback_socket() |
|
└── Получает ETCP пинг -> отправляет pong |
|
|
|
|
|
=== ПОЛУЧЕНИЕ ОТВЕТА НА ПИНГ (third node) === |
|
|
|
route_ping_single_cb(success, rtt, arg, nonce, resp_data, resp_data_len) |
|
├── Обновляет статистику: count_sent++, count_ok++, sum_rtt += rtt |
|
├── Если count_sent < count_total: |
|
│ └── etcp_send_ping_to_socket(...) [следующий пинг] |
|
└── Иначе: |
|
└── route_ping_series_finish(ctx) |
|
├── Вычисляет avg_rtt |
|
└── Создает BGP_PING_RESPONSE { cmd, subcmd=PING_RESP, request_id, count_sent, count_ok, avg_rtt } |
|
└── etcp_send(reply_conn, entry) [отправляет результат инициатору] |
|
|
|
|
|
=== ПОЛУЧЕНИЕ PING_RESP (на инициаторе) === |
|
|
|
route_bgp_receive_cbk(data, len, from_conn, bgp) |
|
└── ROUTE_SUBCMD_PING_RESP |
|
└── route_ping_handle_resp(bgp, from_conn, data, len) |
|
├── Ищет route_ping_pending по request_id |
|
├── Отменяет timeout_timer |
|
└── Вызывает callback: nat_link_check_cb(success, avg_rtt, count_sent, count_ok, arg) |
|
|
|
|
|
=== CALLBACK ПРОВЕРКИ NAT === |
|
|
|
nat_link_check_cb(success, avg_rtt, count_sent, count_ok, arg) |
|
├── Определяет nat_type = success ? NAT_TYPE_OPEN : NAT_TYPE_RESTRICTED |
|
├── link->nat_type = nat_type |
|
├── link->nat_check_status = success ? NAT_CHECK_OPEN : NAT_CHECK_RESTRICTED |
|
└── route_bgp_send_nat_info(link->etcp, socket_id, nat_ip, nat_port, nat_type) |
|
├── Создает BGP_NAT_INFO { cmd, subcmd=NAT_INFO, socket_id, nat_ip[4], nat_port, nat_type } |
|
└── etcp_send(conn, entry) [отправляет результат клиенту] |
|
|
|
|
|
=== ПРИЕМ NAT_INFO (на клиенте) === |
|
|
|
route_bgp_receive_cbk(data, len, from_conn, bgp) |
|
└── ROUTE_SUBCMD_NAT_INFO |
|
└── route_bgp_handle_nat_info(bgp, from_conn, data, len) |
|
├── Ищет линки по remote_socket_id |
|
├── Устанавливает link->nat_type = info->nat_type |
|
└── Логирует результат NAT detection |
|
|
|
|
|
=== ЗАПРОС НА ПРОВЕРКУ NAT (NAT_CHECK_REQ - новый механизм) === |
|
|
|
route_bgp_send_nat_check_req(conn, socket_id) |
|
├── Создает BGP_NAT_CHECK_REQ { cmd, subcmd=NAT_CHECK_REQ, socket_id, interface_ip, interface_port } |
|
│ ├── Ищет линк с remote_socket_id == socket_id |
|
│ └── Берет interface_addr из линка -> interface_ip/interface_port |
|
└── etcp_send(conn, entry) |
|
|
|
route_bgp_handle_nat_check_req(bgp, from_conn, data, len) |
|
├── Принимает BGP_NAT_CHECK_REQ |
|
├── Сохраняет interface_ip/interface_port в struct sockaddr_storage dummy |
|
├── Ищет линк с remote_socket_id == req->socket_id |
|
└── Если линк найден и не в процессе проверки: |
|
└── route_bgp_start_link_nat_check(bgp, target_link) |
|
[далее по стандартному flow] |
|
|
|
|
|
=== СВЯЗЬ СТРУКТУР === |
|
|
|
struct ETCP_SOCKET |
|
├── local_addr [адрес бинда из конфига] |
|
├── interface_addr [IP интерфейса + порт: интерфейс/default route/конфиг] |
|
└── ... |
|
|
|
struct ETCP_LINK |
|
├── remote_addr [адрес удаленного узла] |
|
├── nat_ip [NAT IP, полученный из INIT_RESPONSE] |
|
├── nat_port [NAT port, полученный из INIT_RESPONSE] |
|
├── nat_type [OPEN/RESTRICTED, результат проверки] |
|
├── nat_check_status [NONE/WAITING/IN_PROGRESS/OPEN/RESTRICTED] |
|
├── initialized [0/1, флаг завершения handshake] |
|
└── ... |
|
|
|
struct ETCP_CONN |
|
├── links [список ETCP_LINK] |
|
├── up_cbk [route_bgp_on_conn_up] |
|
├── down_cbk [route_bgp_on_conn_down] |
|
├── ready_cbk [вызывается при etcp_conn_ready] |
|
├── initialized [0/1, флаг готовности] |
|
├── links_up [0/1, есть ли активные линки] |
|
└── ... |
|
|
|
|
|
=== СТАТУСЫ NAT CHECK === |
|
|
|
NAT_CHECK_NONE = 0 [не проверялся] |
|
NAT_CHECK_WAITING = 1 [ожидает] |
|
NAT_CHECK_IN_PROGRESS = 2 [проверка запущена] |
|
NAT_CHECK_OPEN = 3 [результат: OPEN] |
|
NAT_CHECK_RESTRICTED = 4 [результат: RESTRICTED] |
|
|
|
NAT_TYPE_UNKNOWN = 0 |
|
NAT_TYPE_OPEN = 1 |
|
NAT_TYPE_RESTRICTED = 2 |
|
|
|
NAT_VERIFIED_UNKNOWN = 4 |
|
NAT_VERIFIED_OPEN = 5 |
|
NAT_VERIFIED_RESTRICTED = 6 |
|
NAT_VERIFIED_DIRECT = 7 |
|
|
|
|
|
=== СООБЩЕНИЯ ПРОТОКОЛА === |
|
|
|
ETCP_INIT_REQUEST (0x02) [клиент -> сервер] |
|
ETCP_INIT_RESPONSE (0x03) [сервер -> клиент, включает NAT info] |
|
ETCP_INIT_REQUEST_NOINIT (0x04) |
|
ETCP_INIT_RESPONSE_NOINIT (0x05) |
|
ETCP_PING (0x06) |
|
ETCP_PONG (0x07) |
|
|
|
ROUTE_SUBCMD_NODEINFO (0x04) |
|
ROUTE_SUBCMD_REQUEST_TABLE (0x05) |
|
ROUTE_SUBCMD_WITHDRAW (0x06) |
|
ROUTE_SUBCMD_PING_REQ (0x07) |
|
ROUTE_SUBCMD_PING_RESP (0x08) |
|
ROUTE_SUBCMD_NAT_INFO (0x09) |
|
ROUTE_SUBCMD_NAT_CHECK_REQ (0x0A) |
|
|
|
|
|
=== ПОЛНЫЙ FLOW (одна строка) === |
|
|
|
Handshake: etcp_connections_read_callback_socket -> INIT_REQUEST/RESPONSE -> link->initialized=1 -> etcp_conn_ready -> etcp_on_up -> route_bgp_on_conn_up -> route_bgp_new_conn -> route_bgp_start_link_nat_check -> route_ping_send_req_addr -> (через ETCP) -> route_ping_handle_req -> etcp_send_ping_to_socket -> (UDP) -> route_ping_single_cb -> route_ping_series_finish -> route_ping_handle_resp -> nat_link_check_cb -> route_bgp_send_nat_info -> route_bgp_handle_nat_info |
|
|
|
NAT_CHECK_REQ flow: route_bgp_send_nat_check_req -> BGP_NAT_CHECK_REQ -> route_bgp_handle_nat_check_req -> route_bgp_start_link_nat_check -> [стандартный ping flow]
|
|
|