找回密码
 registerss
搜索
查看: 44|回复: 0

洱海月 v0-07-0300 封包解析:ID 355 CLConnect(登录服连接握手)

[复制链接]
  • 打卡等级:本地老炮
  • 打卡总天数:603
  • 打卡月天数:1
  • 打卡总奖励:600
  • 最近打卡:2026-10-03 06:32:28
Waylee 发表于 2026-4-14 13:13 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?registerss

×

CLConnect 是客户端进入登录服后的第一条连接握手包。当前 Game.exe 与现役 /home/ubuntu/Game2 登录服 Lua 都能确认:它是一条固定 110 字节请求,包体由 net_provider、account、version、ip 四段组成。现役服务端收到后不会直接做账号认证或版本拦截,而是先缓存 version,再立即回 LCRetConnect,等待后续 CLAskLogin 继续登录链路。

包信息

项目 内容
封包 ID 355
包名 CLConnect
方向 CL 客户端 -> 登录服
包长 固定 110 字节
专用回包 LCRetConnect(ID 311)
当前 Lua 协议定义 /home/ubuntu/Game2/services/login/packet.lua
当前 Lua 处理入口 /home/ubuntu/Game2/services/login/logind.lua
当前用途 建立登录服握手上下文,缓存客户端上报的版本串,并返回后续登录入口

当前 Game.exe 可直接确认:

GetPacketID()   = 355;
GetPacketSize() = 110;
Read()          = read_u32_net_provider + read_bytes_50_account + read_bytes_32_version + read_bytes_24_ip;
Write()         = write_u32_net_provider + write_bytes_50_account + write_bytes_32_version + write_bytes_24_ip;
Execute()       = 2;

包体结构

按当前 Game.exe 与现役登录服 packet.lua,包体结构如下:

偏移 长度 字段 类型 含义
0x00 0x04 net_provider uint32 网络线路/运营商线路标识;现役登录服未按此字段分流
0x04 0x32 account char[50] 连接阶段账号串;当前登录认证主链不使用该字段
0x36 0x20 version char[32] 客户端上报的版本串;现役登录服会先缓存到连接上下文
0x56 0x18 ip char[24] 客户端自报 IP;现役登录服不把它当成真实来源地址

总长度为:

0x6E = 110 字节

account、version、ip 当前都是按定长原始字节串读取;现役 Lua 不会自动裁掉末尾补零。

当前实际行为

/home/ubuntu/Game2/services/login/logind.lua 的 server.message(fd, idx, packet) 收到 CLConnect 后,当前处理顺序非常直接:

  1. 把 packet.version 缓存到 connect_versions[fd]
  2. 构造 LCRetConnect
  3. 把 login_ip、wan_ip 都写成 server_conf.server_ip
  4. 把 login_port 写成当前登录服监听端口 port
  5. 从 handshake[fd] 解析出对端字符串地址里的端口,写入 wan_port
  6. 立即回包 LCRetConnect

这条包当前并不会直接触发账号认证,也不会在这里执行登录版本强校验。现役版本校验发生在下一条 CLAskLogin 阶段,登录服会拿 packet.uVersion 调用 is_login_version_valid(...),而 CLConnect.version 主要作为连接阶段缓存值,后续用于登录日志记录与排查辅助。

从现役 Lua 可确认的实际使用情况如下:

  • version:当前实际使用,会先缓存到 connect_versions[fd]
  • account:当前未进入现役认证主链,真正账号口令解析发生在 CLAskLogin
  • ip:包里虽然自报了地址,但登录服后续真正使用的是 server.connect(fd, addr) 阶段记录到 handshake[fd] 的 socket 对端地址
  • net_provider:当前未看到现役登录链路按它分流或做策略判断

这条握手缓存也是一次性的。现役登录服会在两种时机清理 connect_versions[fd]:

  • 收到 CLAskLogin 并进入登录处理后
  • 连接断开 server.disconnect(fd) 时

服务端落点

  • 协议定义:/home/ubuntu/Game2/services/login/packet.lua
  • 登录包处理:/home/ubuntu/Game2/services/login/logind.lua
  • 连接建立与地址缓存:/home/ubuntu/Game2/services/login/logind.lua

当前直接相关的现役状态变量包括:

  • handshake[fd]:记录 server.connect(fd, addr) 阶段捕获的真实对端地址字符串
  • connect_versions[fd]:记录 CLConnect.version

关键代码

Game.exe 的当前包体读写顺序可概括为:

read net_provider(u32);
read account[50];
read version[32];
read ip[24];

现役 Lua 的协议读取与握手处理可概括为:

self.net_provider = stream:readuint()
self.account = stream:read(0x32)
self.version = stream:read(0x20)
self.ip = stream:read(0x18)
if packet.xy_id == packet_def.XYID_CLCONNECT then
    connect_versions[fd] = packet.version
    ret = packet_def.LCRetConnect.new()
    ret.login_ip = server_conf.server_ip
    ret.login_port = port
    ret.wan_ip = server_conf.server_ip
    local _, client_port = string.match(handshake[fd], "(.+):(.+)")
    ret.wan_port = client_port
    loginservice.send(fd, idx, ret)
end

登录服后续真正使用连接层地址和版本缓存的位置是:

local ip = string.match(handshake[fd], "(.+):(.+)")
local connect_version = connect_versions[fd]
handshake[fd] = nil
connect_versions[fd] = nil

结论

CLConnect 在当前版本中是活跃的登录握手包,但职责比较单纯:它负责把客户端的线路标识、账号串、版本串和自报 IP 送到登录服,并换回 LCRetConnect。从现役实现看,真正进入当前业务主链的只有 version,而且它也只是先缓存,供后续 CLAskLogin 阶段记录日志和辅助排查。

更关键的现役实现特征有两点:一是登录版本强校验并不发生在 CLConnect,而是在下一条 CLAskLogin;二是包体中的 ip 不是最终依据,登录服实际信任的是 socket 层握手时记录的 handshake[fd]。因此,把 CLConnect 理解为“登录服连接握手与上下文预热包”会比把它理解成“正式登录认证包”更准确。

您需要登录后才可以回帖 登录 | registerss

本版积分规则

QQ|手机版|雪舞知识库 ( 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 )|天天打卡

GMT+8, 2026-10-4 11:26 , Processed in 0.062873 second(s), 26 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表