MCPcopy Create free account
hub / github.com/cppla/moto / HandleRegexp

Function HandleRegexp

controller/regex.go:15–76  ·  view source on GitHub ↗

HandleRegexp 通过正则检测首包选出目标,再转发后续数据流。

(conn net.Conn, rule *config.Rule)

Source from the content-addressed store, hash-verified

13
14// HandleRegexp 通过正则检测首包选出目标,再转发后续数据流。
15func HandleRegexp(conn net.Conn, rule *config.Rule) {
16 defer conn.Close()
17
18 //正则模式下需要客户端的第一个数据包判断特征,所以需要设置一个超时
19 conn.SetReadDeadline(time.Now().Add(time.Millisecond * time.Duration(rule.Timeout)))
20 //获取第一个数据包
21 firstPacket := new(bytes.Buffer)
22 if _, err := io.CopyN(firstPacket, conn, 4096); err != nil {
23 utils.Logger.Error("无法处理连接,读取首包失败",
24 zap.String("ruleName", rule.Name),
25 zap.String("remoteAddr", conn.RemoteAddr().String()),
26 zap.Error(err))
27 return
28 }
29
30 var target net.Conn
31 //挨个匹配正则
32 for _, v := range rule.Targets {
33 if !v.Re.Match(firstPacket.Bytes()) {
34 continue
35 }
36 c, err := outboundDial(v.Address)
37 if err != nil {
38 utils.Logger.Error("无法建立连接",
39 zap.String("ruleName", rule.Name),
40 zap.String("remoteAddr", conn.RemoteAddr().String()),
41 zap.String("targetAddr", v.Address))
42 continue
43 }
44 if tc, ok := c.(*net.TCPConn); ok {
45 _ = tc.SetNoDelay(true)
46 _ = tc.SetKeepAlive(true)
47 _ = tc.SetKeepAlivePeriod(30 * time.Second)
48 }
49 target = c
50 break
51 }
52 if target == nil {
53 utils.Logger.Error("未匹配到任何目标,无法处理连接",
54 zap.String("ruleName", rule.Name),
55 zap.String("remoteAddr", conn.RemoteAddr().String()))
56 return
57 }
58
59 utils.Logger.Debug("建立连接",
60 zap.String("ruleName", rule.Name),
61 zap.String("remoteAddr", conn.RemoteAddr().String()),
62 zap.String("targetAddr", target.RemoteAddr().String()))
63 //匹配到了,去除掉刚才设定的超时
64 conn.SetReadDeadline(time.Time{})
65 //把第一个数据包发送给目标
66 io.Copy(target, firstPacket)
67
68 defer target.Close()
69
70 go func() {
71 io.Copy(conn, target)
72 conn.Close()

Callers 1

ListenFunction · 0.85

Calls 1

outboundDialFunction · 0.85

Tested by

no test coverage detected