Files
Archive/nodepass/docs/zh/how-it-works.md
2025-07-14 14:45:44 +02:00

12 KiB
Raw Blame History

NodePass 工作原理

本页解释了 NodePass 的内部架构和数据流机制,提供了不同组件如何交互以创建高效、安全的隧道的深入见解。

架构概述

NodePass 创建了一个具有独立控制和数据通道的网络架构:

  1. 控制通道(隧道)

    • 客户端和服务器之间的未加密 TCP 连接
    • 专门用于信号传输和协调
    • 在隧道生命周期内维持持久连接
  2. 数据通道(目标)

    • 可配置的 TLS 加密选项:
      • 模式 0:未加密数据传输(最快,安全性最低)
      • 模式 1:自签名证书加密(良好安全性,无验证)
      • 模式 2:验证证书加密(最高安全性,需要有效证书)
    • 按需为每个连接或数据报创建
    • 用于实际应用数据传输
  3. 服务端模式操作

    • 在隧道端点监听控制连接
    • 当流量到达目标端点时,通过控制通道向客户端发送信号
    • 在需要时使用指定的 TLS 模式建立数据通道
    • 支持双向数据流:可以从服务端或客户端发起连接
  4. 客户端模式操作

    • 连接到服务端的控制通道
    • 监听指示传入连接的信号
    • 使用服务端指定的 TLS 安全级别创建数据连接
    • 在安全通道和本地目标之间转发数据
    • 支持双向数据流:根据目标地址自动选择数据流方向
  5. 客户端单端转发模式

    • 当隧道地址为本地地址时如127.0.0.1)自动启用
    • 客户端直接在本地监听端口,无需服务端的控制通道协调
    • 对于TCP连接使用连接池技术显著提高转发性能
    • 适用于纯本地转发场景,减少网络开销和延迟
    • 支持TCP和UDP协议的高性能单端转发
  6. 协议支持

    • TCP:具有持久连接的全双工流式传输,在客户端单端转发模式下支持连接池优化
    • UDP:具有可配置缓冲区大小和超时的数据报转发

数据传输流

NodePass 通过其隧道架构建立双向数据流,支持 TCP 和 UDP 协议。系统支持三种数据流模式:

数据流模式说明

  • 服务端接收模式dataFlow: "-":服务端在目标地址监听,客户端在本地监听,数据从目标地址流向客户端本地
  • 服务端发送模式dataFlow: "+":服务端连接到远程目标地址,客户端在本地监听,数据从客户端本地流向远程目标
  • 客户端单端转发模式:客户端在本地直接监听并转发到目标地址,无需服务端协调,使用连接池技术实现高性能转发

数据流模式根据隧道地址和目标地址自动确定:

  • 如果隧道地址是本地地址localhost、127.0.0.1等),启用客户端单端转发模式
  • 如果目标地址是本地地址,使用服务端接收模式
  • 如果目标地址是远程地址,使用服务端发送模式

服务端流程(服务端接收模式)

  1. 连接初始化

    [目标客户端] → [目标监听器] → [服务器:目标连接已创建]
    
    • 对于 TCP客户端建立到目标监听器的持久连接
    • 对于 UDP服务器在绑定到目标地址的 UDP 套接字上接收数据报
  2. 信号生成

    [服务端] → [生成唯一连接 ID] → [通过未加密的 TCP 隧道向客户端发送信号]
    
    • 对于 TCP生成 //<connection_id>#1 信号
    • 对于 UDP生成 //<connection_id>#2 信号
  3. 连接准备

    [服务端] → [在池中创建具有配置的 TLS 模式的远程连接] → [等待客户端连接]
    
    • 两种协议都使用相同的具有唯一连接 ID 的连接池机制
    • 根据指定模式0、1 或 2应用 TLS 配置
  4. 数据交换

    [目标连接] ⟷ [交换/传输] ⟷ [远程连接]
    
    • 对于 TCP使用 conn.DataExchange() 进行持续的双向数据流传输
    • 对于 UDP使用可配置的缓冲区大小转发单个数据报

客户端流程

  1. 信号接收

    [客户端] → [从 TCP 隧道读取信号] → [解析连接 ID]
    
    • 客户端根据 URL 方案区分 TCP 和 UDP 信号
  2. 连接建立

    [客户端] → [从池中检索连接] → [连接到远程端点]
    
    • 此阶段的连接管理与协议无关
  3. 本地连接

    [客户端] → [连接到本地目标] → [建立本地连接]
    
    • 对于 TCP建立到本地目标的持久 TCP 连接
    • 对于 UDP创建用于与本地目标交换数据报的 UDP 套接字
  4. 数据交换

    [远程连接] ⟷ [交换/传输] ⟷ [本地目标连接]
    
    • 对于 TCP使用 conn.DataExchange() 进行持续的双向数据流传输
    • 对于 UDP读取单个数据报转发它使用超时等待响应然后返回响应

客户端单端转发流程

  1. 模式识别

    [客户端] → [检测隧道地址为本地地址] → [启用单端转发模式]
    
    • 自动检测隧道地址是否为localhost、127.0.0.1等本地地址
    • 启用单端转发模式,跳过服务端控制通道建立
  2. 本地监听

    [客户端] → [在隧道端口启动监听器] → [等待本地连接]
    
    • 直接在指定的隧道端口启动TCP或UDP监听器
    • 无需连接到远程服务端,实现零延迟启动
  3. 连接池初始化仅TCP

    [客户端] → [初始化目标连接池] → [预建立连接到目标地址]
    
    • 为TCP转发创建高性能连接池
    • 预先建立多个到目标地址的连接,显著减少连接建立延迟
    • 连接池大小可根据并发需求动态调整
  4. 高性能转发

    [本地连接] → [从连接池获取目标连接] → [直接数据交换] → [连接复用或释放]
    
    • 对于TCP从连接池中快速获取预建立的目标连接进行高效数据交换
    • 对于UDP直接转发数据报到目标地址无需连接池
    • 优化的数据路径,最小化转发开销和延迟

特定协议特性

  • TCP 交换

    • 用于全双工通信的持久连接
    • 连接终止前的持续数据流传输
    • 具有自动重连的错误处理
    • 客户端单端转发优化:通过连接池技术预建立连接,显著减少连接建立延迟
  • UDP 交换

    • 具有可配置缓冲区大小的一次性数据报转发 (UDP_DATA_BUF_SIZE)
    • 响应等待的读取超时控制 (UDP_READ_TIMEOUT)
    • 针对低延迟、无状态通信进行了优化
    • 客户端单端转发优化:直接转发机制,无需连接池,实现最低延迟

信号通信机制

NodePass 通过 TCP 隧道使用复杂的基于 URL 的信号协议:

信号类型

  1. 隧道信号

    • 格式:#<tls>
    • 目的:通知客户端 TLS 代号
    • 时机:在隧道握手时发送
  2. TCP 启动信号

    • 格式://<connection_id>#1
    • 目的:请求客户端为特定 ID 建立 TCP 连接
    • 时机:当接收到目标服务的新 TCP 连接时发送
  3. UDP 启动信号

    • 格式://<connection_id>#2
    • 目的:请求客户端处理特定 ID 的 UDP 流量
    • 时机:当在目标端口接收到 UDP 数据时发送

信号流程

  1. 信号生成

    • 服务端为特定事件创建 URL 格式的信号
    • 信号以换行符终止,以便正确解析
  2. 信号传输

    • 服务端将信号写入 TCP 隧道连接
    • 使用互斥锁防止对隧道的并发写入
  3. 信号接收

    • 客户端使用缓冲读取器从隧道读取信号
    • 信号被修剪并解析为 URL 格式
  4. 信号处理

    • 客户端将有效信号放入缓冲通道 (signalChan)
    • 专用 goroutine 处理来自通道的信号
    • 信号量模式防止信号溢出
  5. 信号执行

    • 远程信号更新客户端的远程地址配置
    • 启动信号触发 clientOnce() 方法建立连接

信号弹性

  • 具有可配置容量的缓冲通道防止在高负载下信号丢失
  • 信号量实现确保受控并发
  • 对格式错误或意外信号的错误处理

连接池架构

NodePass 实现了一个高效的连接池系统来管理网络连接:

池设计

  1. 池类型

    • 客户端池:预先建立到远程端点的连接
    • 服务器池:管理来自客户端的传入连接
  2. 池组件

    • 连接存储:线程安全的连接 ID 到 net.Conn 对象的映射
    • ID 通道:用于可用连接 ID 的缓冲通道
    • 容量管理:基于使用模式的动态调整
    • 间隔控制:连接创建之间的基于时间的限流
    • 连接工厂:可定制的连接创建函数

连接生命周期

  1. 连接创建

    • 连接创建数量不超过配置的容量
    • 每个连接都分配一个唯一 ID
    • ID 和连接存储在池中
  2. 连接获取

    • 客户端使用连接 ID 检索连接
    • 服务端从池中检索下一个可用连接
    • 在返回前验证连接
  3. 连接使用

    • 获取时从池中移除连接
    • 用于端点之间的数据交换
    • 无连接重用(一次性使用模型)
  4. 连接终止

    • 使用后关闭连接
    • 正确释放资源
    • 错误处理确保干净终止

池管理

  1. 容量控制

    • MIN_POOL_CAPACITY:确保最小可用连接数
    • MAX_POOL_CAPACITY:防止过度资源消耗
    • 基于需求模式的动态缩放
  2. 间隔控制

    • MIN_POOL_INTERVAL:连接创建尝试之间的最小时间
    • MAX_POOL_INTERVAL:连接创建尝试之间的最大时间
    • 自适应基于时间的限流以优化资源使用
  3. 动态池适应 连接池采用双重自适应机制以确保最佳性能:

    A. 容量调整

    • 池容量根据实时使用模式动态调整
    • 如果连接创建成功率低(<20%),容量减少以最小化资源浪费
    • 如果连接创建成功率高(>80%),容量增加以适应更高的流量
    • 渐进缩放防止振荡并提供稳定性
    • 遵守配置的最小和最大容量边界

    B. 间隔调整

    • 创建间隔根据池空闲连接数调整
    • 当空闲连接较少(容量的<20%)时,间隔向最小间隔减少
    • 当空闲连接较多(容量的>80%)时,间隔向最大间隔增加
    • 防止在低需求期间压垮网络资源
    • 在池耗尽的高需求期间加速连接创建

主控API架构

在主控模式下NodePass提供RESTful API进行集中管理

API组件

  1. HTTP/HTTPS服务器

    • 在配置的地址和端口上监听
    • 可选的TLS加密与隧道服务器使用相同模式
    • 可配置的API前缀路径
  2. 实例管理

    • NodePass实例的内存注册表
    • 基于UID的实例标识
    • 每个实例的状态跟踪(运行中、已停止等)
  3. RESTful端点

    • 实例的标准CRUD操作
    • 实例控制操作(启动、停止、重启)
    • 健康状态报告
    • API文档的OpenAPI规范

实例生命周期管理

  1. 实例创建

    • 基于URL的配置类似于命令行
    • 基于实例类型的动态初始化
    • 实例创建前的参数验证
  2. 实例控制

    • 启动/停止/重启能力
    • 可配置超时的优雅关闭
    • 终止时的资源清理
  3. API安全

    • API连接的TLS加密选项
    • 与隧道服务端相同的安全模式
    • HTTPS的证书管理

下一步