Skip to content

Commit c90f983

Browse files
authored
refactor: remove hybridStart and improve error handling in start method
1 parent 7fbe355 commit c90f983

File tree

1 file changed

+1
-80
lines changed

1 file changed

+1
-80
lines changed

internal/client.go

Lines changed: 1 addition & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package internal
44
import (
55
"bufio"
66
"context"
7-
"crypto/rand"
87
"fmt"
98
"io"
109
"net"
@@ -114,7 +113,7 @@ func (c *Client) start() error {
114113
if err := c.initTunnelListener(); err == nil {
115114
return c.singleStart()
116115
} else {
117-
return c.hybridStart()
116+
return fmt.Errorf("start: initTunnelListener failed: %w", err)
118117
}
119118
case "2": // 双端模式
120119
return c.commonStart()
@@ -224,81 +223,3 @@ func (c *Client) tunnelHandshake() error {
224223
c.logger.Info("Tunnel handshaked: %v <-> %v", c.tunnelTCPConn.LocalAddr(), c.tunnelTCPConn.RemoteAddr())
225224
return nil
226225
}
227-
228-
// hybridStart 启动混合穿透模式
229-
func (c *Client) hybridStart() error {
230-
udpConn, err := net.DialTimeout("udp", c.tunnelTCPAddr.String(), udpDialTimeout)
231-
if err != nil {
232-
return fmt.Errorf("hybridStart: STUN dial failed: %w", err)
233-
}
234-
defer udpConn.Close()
235-
236-
magic := [4]byte{0x21, 0x12, 0xA4, 0x42}
237-
238-
// 构造STUN请求
239-
req := make([]byte, 20)
240-
req[0], req[1] = 0x00, 0x01
241-
req[4], req[5], req[6], req[7] = magic[0], magic[1], magic[2], magic[3]
242-
rand.Read(req[8:20])
243-
244-
// 发送STUN请求
245-
if _, err := udpConn.Write(req); err != nil {
246-
return fmt.Errorf("hybridStart: STUN write failed: %w", err)
247-
}
248-
249-
// 解析STUN响应
250-
resp := make([]byte, 1500)
251-
udpConn.SetReadDeadline(time.Now().Add(udpReadTimeout))
252-
n, err := udpConn.Read(resp)
253-
if err != nil {
254-
return fmt.Errorf("hybridStart: STUN read failed: %w", err)
255-
}
256-
if n < 20 || resp[0] != 0x01 || resp[1] != 0x01 {
257-
return fmt.Errorf("hybridStart: invalid STUN response")
258-
}
259-
260-
// 保活NAT映射
261-
go func() {
262-
dummy := []byte{0}
263-
ticker := time.NewTicker(time.Second)
264-
defer ticker.Stop()
265-
for {
266-
select {
267-
case <-c.ctx.Done():
268-
return
269-
case <-ticker.C:
270-
udpConn.Write(dummy)
271-
}
272-
}
273-
}()
274-
275-
// 查找映射地址
276-
var extAddr string
277-
for pos := 20; pos+4 <= n; pos += 4 + int(uint16(resp[pos+2])<<8|uint16(resp[pos+3])) + (4 - int((uint16(resp[pos+2])<<8|uint16(resp[pos+3]))%4)) {
278-
if uint16(resp[pos])<<8|uint16(resp[pos+1]) == 0x0020 && pos+12 <= n && resp[pos+5] == 0x01 {
279-
port := (uint16(resp[pos+6])<<8 | uint16(resp[pos+7])) ^ 0x2112
280-
extAddr = net.JoinHostPort(net.IPv4(resp[pos+8]^magic[0], resp[pos+9]^magic[1], resp[pos+10]^magic[2], resp[pos+11]^magic[3]).String(), fmt.Sprintf("%d", port))
281-
break
282-
}
283-
}
284-
if extAddr == "" {
285-
return fmt.Errorf("hybridStart: address not found in STUN response")
286-
}
287-
288-
// 设置隧道地址
289-
c.tunnelTCPAddr = &net.TCPAddr{IP: net.IPv4zero, Port: udpConn.LocalAddr().(*net.UDPAddr).Port}
290-
c.tunnelUDPAddr = nil
291-
292-
// 初始化隧道监听器
293-
if err := c.initTunnelListener(); err != nil {
294-
return fmt.Errorf("hybridStart: initTunnelListener failed: %w", err)
295-
}
296-
297-
// 输出映射地址信息
298-
c.logger.Info("External endpoint: %v -> %v -> %v", extAddr, c.tunnelTCPAddr, c.getTargetAddrsString())
299-
300-
if err := c.singleControl(); err != nil {
301-
return fmt.Errorf("hybridStart: singleControl failed: %w", err)
302-
}
303-
return nil
304-
}

0 commit comments

Comments
 (0)