MCPcopy Create free account
hub / github.com/chainreactors/EvilProxy / routeMuxConnection

Method routeMuxConnection

internal/api/protocol_multiplexer.go:62–125  ·  view source on GitHub ↗

routeMuxConnection performs per-connection protocol detection and routing.

(conn net.Conn, httpListener *muxListener)

Source from the content-addressed store, hash-verified

60
61// routeMuxConnection performs per-connection protocol detection and routing.
62func (s *Server) routeMuxConnection(conn net.Conn, httpListener *muxListener) {
63 // Set a read deadline so that idle connections that never send bytes do not
64 // leak goroutines and file descriptors. The deadline is cleared once the
65 // connection is successfully routed to its handler.
66 const muxSniffDeadline = 10 * time.Second
67 _ = conn.SetReadDeadline(time.Now().Add(muxSniffDeadline))
68
69 tlsConn, ok := conn.(*tls.Conn)
70 if ok {
71 if errHandshake := tlsConn.Handshake(); errHandshake != nil {
72 if errClose := conn.Close(); errClose != nil {
73 log.Errorf("failed to close connection after TLS handshake error: %v", errClose)
74 }
75 return
76 }
77 proto := strings.TrimSpace(tlsConn.ConnectionState().NegotiatedProtocol)
78 if proto == "h2" || proto == "http/1.1" {
79 if httpListener == nil {
80 if errClose := conn.Close(); errClose != nil {
81 log.Errorf("failed to close connection: %v", errClose)
82 }
83 return
84 }
85 if errPut := httpListener.Put(tlsConn); errPut != nil {
86 if errClose := conn.Close(); errClose != nil {
87 log.Errorf("failed to close connection after HTTP routing failure: %v", errClose)
88 }
89 } else {
90 _ = conn.SetReadDeadline(time.Time{})
91 }
92 return
93 }
94 }
95
96 reader := bufio.NewReader(conn)
97 prefix, errPeek := reader.Peek(1)
98 if errPeek != nil {
99 if errClose := conn.Close(); errClose != nil {
100 log.Errorf("failed to close connection after protocol peek failure: %v", errClose)
101 }
102 return
103 }
104
105 if isRedisRESPPrefix(prefix[0]) {
106 _ = conn.SetReadDeadline(time.Time{})
107 s.handleRedisConnection(conn, reader)
108 return
109 }
110
111 if httpListener == nil {
112 if errClose := conn.Close(); errClose != nil {
113 log.Errorf("failed to close connection without HTTP listener: %v", errClose)
114 }
115 return
116 }
117
118 if errPut := httpListener.Put(&bufferedConn{Conn: conn, reader: reader}); errPut != nil {
119 if errClose := conn.Close(); errClose != nil {

Callers 1

acceptMuxConnectionsMethod · 0.95

Calls 5

handleRedisConnectionMethod · 0.95
isRedisRESPPrefixFunction · 0.85
ConnectionStateMethod · 0.80
PutMethod · 0.80
CloseMethod · 0.65

Tested by

no test coverage detected