网关是怎么工作的
一个请求从你的客户端到目标站中间经过哪几步,以及每一步会在哪些情况下拒绝你。
知道这条链路长什么样,排错时能少走很多弯路——大部分"连不上"其实卡在前三步,跟目标站没关系。
一个请求的完整路径
建立 TCP 连接
你的客户端连到 GATEWAY_HOST:58971。网关先做几层与身份无关的保护:全局连接数、单来源 IP 并发、新连接速率。在这一层被拒时连接会直接关闭,不会有 HTTP 状态码可看。
识别协议
网关 peek 第一个字节。是 0x05 就按 SOCKS5 握手,否则按 HTTP 解析(CONNECT 或普通 forward)。
同一个端口同时服务两种协议,所以不存在"用错端口"这种问题。
解析用户名参数
把用户名按 - 拆开,从第二段开始找第一个已知参数键。找不到就整段当普通用户名;找到之后,后面的每一段都必须是合法的键值对,顺序、重复、未知键都会被拒。
参数格式错误返回 HTTP 400 invalid_proxy_parameters,缺少或不匹配的凭据返回 407;SOCKS5 认证子协商返回失败。
认证与额度检查
网关拿账号和密码去控制面换一份账号快照,检查账号状态、有效期、以及剩余流量。
流量余额的口径是 min(用户流量池剩余, 该子账号上限 − 该子账号已用)——子账号设了上限时,用户池里还有量也不代表这个子账号能用。
禁用或过期返回 HTTP 403,流量或独立额度耗尽返回 402,账号并发/频率超限返回 429。认证服务不可用或调用超时返回 503;目标连接超时返回 504。
选路
按你给的国家、州省、城市、ASN,加上账号被授权的产品,筛出能满足条件的出口线路。带 session 时先查会话绑定,命中就继续用原线路。
没有任何线路能同时满足全部条件时:HTTP 503 service_unavailable,SOCKS5 reply 0x01。
目标策略检查
检查目标地址和端口是否被允许。私网、环回、链路本地地址一律拒绝;域名先在网关侧解析并锁定到解析结果的第一个 IP,防止校验通过后 DNS 再变。
这一步失败:HTTP 403。详见 目标地址限制。
建立出口连接、开始转发
网关向选中的出口发起连接与握手,成功后回你 200 Connection Established(HTTP)或 reply 0x00(SOCKS5),之后就是纯 TCP 双向转发。
从这一刻起才开始计流量。
哪一步开始计费
计费只统计成功写入对端 socket 的双向 payload 字节。也就是说:
算进流量的:
- CONNECT 隧道建立之后隧道内的全部字节,包括 TLS 握手记录、HTTP 头、正文
- 普通 HTTP forward 模式下重建后的请求行与请求头
- 上传和下载两个方向
不算进流量的:
- 你发给网关的
CONNECT请求行和请求头 - 网关回你的
200 Connection Established - SOCKS5 的问候、认证、CONNECT 请求与响应
- 网关与出口之间的握手
- TCP/IP 包头
所以"握手不要钱,隧道里的都要钱"。更细的口径和倍率见 流量计费口径。
会话绑定绑的是什么
粘性会话的键是 账号ID : 产品ID : session值,绑定的对象默认是出口线路,不是某一个具体 IP。
这个区别在实践中很重要:同一个 session 值能让你稳定落在同一条线路上,从而在绝大多数情况下拿到同一个出口 IP;但住宅 IP 本身是流动的,那个 IP 一旦从线路里掉了,网关没有办法把它变回来。需要严格"同一个 IP 一直不变"的场景应该用静态住宅或数据中心,而不是靠动态住宅的粘性会话。
不带 session 的时候呢
不带 session 就不建立会话绑定,每个新 TCP 连接独立参与一次选路。
要注意这不等于"每个 HTTP 请求换一个 IP":在一条 CONNECT 隧道或一条 keep-alive 连接里发多个请求,它们走的是同一条隧道、同一个出口。想让 IP 换,得让客户端建立新连接。各语言里怎么做见 接入示例。