@@ -32,6 +32,7 @@ type UDPTracerIPv6 struct {
32
32
33
33
sem * semaphore.Weighted
34
34
fetchLock sync.Mutex
35
+ udpMutex sync.Mutex
35
36
}
36
37
37
38
func (t * UDPTracerIPv6 ) Execute () (* Result , error ) {
@@ -118,7 +119,7 @@ func (t *UDPTracerIPv6) listenICMP() {
118
119
}
119
120
120
121
// handleICMPMessage 处理 ICMPv6 消息并提取 UDP 源端口
121
- //
122
+ //
122
123
// ICMPv6 错误消息格式:
123
124
// - ICMPv6 头部 (8 字节)
124
125
// - 原始 IPv6 包 (包含 IPv6 头部和 UDP 头部)
@@ -131,74 +132,74 @@ func (t *UDPTracerIPv6) listenICMP() {
131
132
// 5. 提取 UDP 源端口
132
133
// 6. 发送结果到对应通道
133
134
func (t * UDPTracerIPv6 ) handleICMPMessage (msg ReceivedMessage ) {
134
- // ICMPv6 错误消息至少需要包含 IPv6 头部(40字节)和部分 UDP 头部
135
- if len (msg .Msg ) < 48 {
136
- return
137
- }
138
-
139
- // 尝试解析 ICMPv6 消息中包含的原始数据包
140
- var offset int = 8 // ICMPv6 头部长度
141
-
142
- // 检查剩余长度是否足够包含 IPv6 头部
143
- if len (msg .Msg ) < offset + 40 {
144
- return
145
- }
146
-
147
- // 验证 IPv6 版本 (前4位应该是6)
148
- if (msg .Msg [offset ] >> 4 ) != 6 {
149
- return
150
- }
151
-
152
- // 获取下一个头部类型
153
- nextHeader := msg .Msg [offset + 6 ]
154
-
155
- // 跳过 IPv6 基本头部
156
- offset += 40
157
-
158
- // 处理可能的扩展头部
159
- for nextHeader != 17 && offset + 2 < len (msg .Msg ) { // 17 是 UDP 协议号
160
- switch nextHeader {
161
- case 0 : // Hop-by-Hop Options
162
- case 43 : // Routing
163
- case 44 : // Fragment
164
- case 50 : // ESP
165
- case 51 : // AH
166
- case 60 : // Destination Options
167
- if offset + 2 >= len (msg .Msg ) {
168
- return // 不够长,无法读取扩展头部长度
169
- }
170
- nextHeader = msg .Msg [offset ]
171
- headerLen := int (msg .Msg [offset + 1 ])* 8 + 8
172
- offset += headerLen
173
- default :
174
- // 未知或不支持的扩展头部类型
175
- return
176
- }
177
- }
178
-
179
- // 确认下一个头部是 UDP (17)
180
- if nextHeader != 17 {
181
- return
182
- }
183
-
184
- // 确保有足够的数据来读取 UDP 源端口
185
- if offset + 2 > len (msg .Msg ) {
186
- return
187
- }
188
-
189
- // 从 UDP 头部提取源端口(前2字节)
190
- srcPort := int (uint16 (msg .Msg [offset ])<< 8 | uint16 (msg .Msg [offset + 1 ]))
191
-
192
- t .inflightRequestLock .Lock ()
193
- defer t .inflightRequestLock .Unlock ()
194
- ch , ok := t .inflightRequest [srcPort ]
195
- if ! ok {
196
- return
197
- }
198
- ch <- Hop {
199
- Success : true ,
200
- Address : msg .Peer ,
201
- }
135
+ // ICMPv6 错误消息至少需要包含 IPv6 头部(40字节)和部分 UDP 头部
136
+ if len (msg .Msg ) < 48 {
137
+ return
138
+ }
139
+
140
+ // 尝试解析 ICMPv6 消息中包含的原始数据包
141
+ var offset int = 8 // ICMPv6 头部长度
142
+
143
+ // 检查剩余长度是否足够包含 IPv6 头部
144
+ if len (msg .Msg ) < offset + 40 {
145
+ return
146
+ }
147
+
148
+ // 验证 IPv6 版本 (前4位应该是6)
149
+ if (msg .Msg [offset ] >> 4 ) != 6 {
150
+ return
151
+ }
152
+
153
+ // 获取下一个头部类型
154
+ nextHeader := msg .Msg [offset + 6 ]
155
+
156
+ // 跳过 IPv6 基本头部
157
+ offset += 40
158
+
159
+ // 处理可能的扩展头部
160
+ for nextHeader != 17 && offset + 2 < len (msg .Msg ) { // 17 是 UDP 协议号
161
+ switch nextHeader {
162
+ case 0 : // Hop-by-Hop Options
163
+ case 43 : // Routing
164
+ case 44 : // Fragment
165
+ case 50 : // ESP
166
+ case 51 : // AH
167
+ case 60 : // Destination Options
168
+ if offset + 2 >= len (msg .Msg ) {
169
+ return // 不够长,无法读取扩展头部长度
170
+ }
171
+ nextHeader = msg .Msg [offset ]
172
+ headerLen := int (msg .Msg [offset + 1 ])* 8 + 8
173
+ offset += headerLen
174
+ default :
175
+ // 未知或不支持的扩展头部类型
176
+ return
177
+ }
178
+ }
179
+
180
+ // 确认下一个头部是 UDP (17)
181
+ if nextHeader != 17 {
182
+ return
183
+ }
184
+
185
+ // 确保有足够的数据来读取 UDP 源端口
186
+ if offset + 2 > len (msg .Msg ) {
187
+ return
188
+ }
189
+
190
+ // 从 UDP 头部提取源端口(前2字节)
191
+ srcPort := int (uint16 (msg .Msg [offset ])<< 8 | uint16 (msg .Msg [offset + 1 ]))
192
+
193
+ t .inflightRequestLock .Lock ()
194
+ defer t .inflightRequestLock .Unlock ()
195
+ ch , ok := t .inflightRequest [srcPort ]
196
+ if ! ok {
197
+ return
198
+ }
199
+ ch <- Hop {
200
+ Success : true ,
201
+ Address : msg .Peer ,
202
+ }
202
203
}
203
204
204
205
var cachedLocalPortv6 int
@@ -257,6 +258,11 @@ func (t *UDPTracerIPv6) send(ttl int) error {
257
258
return nil
258
259
}
259
260
261
+ if util .GetenvDefault ("NEXTTRACE_RANDOMPORT" , "" ) == "" {
262
+ t .udpMutex .Lock ()
263
+ defer t .udpMutex .Unlock ()
264
+ }
265
+
260
266
srcIP , srcPort , udpConn , err := t .getUDPConn (0 )
261
267
if err != nil {
262
268
return err
0 commit comments