#752·vegeta

ConnectTo 循环轮询地址选择中发生数据竞争

作者: queelius创建于 2026年3月25日更新于 2026年3月25日

□ 错误描述

" ConnectTo " 选项创建了一个 " DialContext " 关闭,它读取并写出一个圆形的相机计数器(`cm.n')而没有任何同步:

开始 tr.DialContext = func(ctx上下文). 背景 网络 添加字符串 (net. Conn, 错误) { 如果 cm, OK: = 连接到[addr]; ok{ cm.n = (cm.n + 1) % len(cm.adders) // 未同步读取-修改-写入 addr = cm.addrs [cm.n] (中文(简体) ). {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 返回拨号( ctx, 网络, 添加器) {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


`DialContext'被Go的HTTP运输同时叫作"DialContext",因此同时向同一目标主机提出的请求将在'cm.n'上进行比赛. 这可能会破坏反值,并有可能超出界限。

□再现.

用 " 种族 " 可靠地触发探测器:

开始
func TestConnectTo 同流合污(t *testing.T) {
// 设置多个后端服务器, 用 ConnectTo 创建攻击器,
/然后同时发射20发子弹
var wg 同步 。 等待组
对于i:=0;i < 20;i++ {
(单位:千美元)
开始 func () {
推迟时间。 完成( )
atk.hit(tr, a) (中文(简体) ).
• ()
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
w. 等待( )
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?

输出 :

警告:数据丢失
在0x00c0007e0b8读取由goroutine 34:
... ConnectTo. func4.1 () (中文(简体) ).
vegeta/lib/攻击. go:309
上一个写在 0x00c0007e0b8 by goroutine 33:
... ConnectTo. func4.1 () (中文(简体) ).
vegeta/lib/攻击. go:309

□ 修补

增加"同步". 每轮 Robin 组的 Mutex 并锁定计数器的更新。

公关即将到来.