add network param for sniffing
This commit is contained in:
@@ -405,14 +405,14 @@ func (h *httpHandler) handleRequest(ctx context.Context, conn net.Conn, req *htt
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -206,7 +206,7 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithBypass(h.options.Bypass),
|
||||
@@ -214,7 +214,9 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx,
|
||||
ro.Network,
|
||||
conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithBypass(h.options.Bypass),
|
||||
|
||||
@@ -185,14 +185,14 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -159,7 +159,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithBypass(h.options.Bypass),
|
||||
@@ -167,7 +167,7 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithBypass(h.options.Bypass),
|
||||
|
||||
@@ -304,14 +304,14 @@ func (h *socks4Handler) handleConnect(ctx context.Context, conn net.Conn, req *g
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -123,14 +123,14 @@ func (h *socks5Handler) handleConnect(ctx context.Context, conn net.Conn, networ
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -210,14 +210,14 @@ func (h *ssHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.H
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -205,14 +205,14 @@ func (h *forwardHandler) handleDirectForward(ctx context.Context, conn *sshd_uti
|
||||
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, xnet.NewReadWriteConn(br, conn, conn),
|
||||
return sniffer.HandleHTTP(ctx, "tcp", xnet.NewReadWriteConn(br, conn, conn),
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, xnet.NewReadWriteConn(br, conn, conn),
|
||||
return sniffer.HandleTLS(ctx, "tcp", xnet.NewReadWriteConn(br, conn, conn),
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -125,6 +125,8 @@ func (h *tungoHandler) Handle(ctx context.Context, conn net.Conn, opts ...handle
|
||||
recorder: h.recorder,
|
||||
stats: h.stats,
|
||||
|
||||
ipv6: h.md.ipv6,
|
||||
|
||||
opts: &h.options,
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ type metadata struct {
|
||||
|
||||
multicastGroups []netip.Addr
|
||||
|
||||
ipv6 bool
|
||||
|
||||
tcpSendBufferSize int
|
||||
tcpReceiveBufferSize int
|
||||
tcpModerateReceiveBuffer bool
|
||||
@@ -73,6 +75,8 @@ func (h *tungoHandler) parseMetadata(md mdata.Metadata) (err error) {
|
||||
h.md.multicastGroups = append(h.md.multicastGroups, addr)
|
||||
}
|
||||
|
||||
h.md.ipv6 = mdutil.GetBool(md, "ipv6")
|
||||
|
||||
h.md.tcpSendBufferSize = mdutil.GetInt(md, "tcpSendBufferSize", "tungo.tcpSendBufferSize")
|
||||
h.md.tcpReceiveBufferSize = mdutil.GetInt(md, "tcpReceiveBufferSize", "tungo.tcpReceiveBufferSize")
|
||||
h.md.tcpModerateReceiveBuffer = mdutil.GetBool(md, "tcpModerateReceiveBuffer", "tungo.tcpModerateReceiveBuffer")
|
||||
|
||||
+14
-7
@@ -57,6 +57,8 @@ type transportHandler struct {
|
||||
stats *stats_util.HandlerStats
|
||||
recorder recorder.RecorderObject
|
||||
|
||||
ipv6 bool
|
||||
|
||||
opts *handler.Options
|
||||
}
|
||||
|
||||
@@ -111,9 +113,14 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
|
||||
sid := xid.New().String()
|
||||
ctx := xctx.ContextWithSid(context.Background(), xctx.Sid(sid))
|
||||
|
||||
network := "tcp"
|
||||
if remoteIP.Unmap().Is6() && h.ipv6 {
|
||||
network = "tcp6"
|
||||
}
|
||||
|
||||
ro := &xrecorder.HandlerRecorderObject{
|
||||
Service: h.opts.Service,
|
||||
Network: "tcp",
|
||||
Network: network,
|
||||
RemoteAddr: remoteAddr.String(),
|
||||
DstAddr: dstAddr.String(),
|
||||
Host: dstAddr.String(),
|
||||
@@ -191,7 +198,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
|
||||
ro.Host = address
|
||||
|
||||
var buf bytes.Buffer
|
||||
cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address)
|
||||
cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, address)
|
||||
ro.Route = buf.String()
|
||||
if err != nil && !h.sniffingFallback {
|
||||
return nil, err
|
||||
@@ -200,7 +207,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
|
||||
|
||||
if cc == nil {
|
||||
var buf bytes.Buffer
|
||||
cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String())
|
||||
cc, err = h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, dstAddr.String())
|
||||
ro.Route = buf.String()
|
||||
ro.Host = dstAddr.String()
|
||||
}
|
||||
@@ -221,7 +228,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
sniffer.HandleHTTP(ctx, conn,
|
||||
sniffer.HandleHTTP(ctx, network, conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithBypass(h.opts.Bypass),
|
||||
@@ -230,7 +237,7 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
|
||||
)
|
||||
return
|
||||
case sniffing.ProtoTLS:
|
||||
sniffer.HandleTLS(ctx, conn,
|
||||
sniffer.HandleTLS(ctx, network, conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithBypass(h.opts.Bypass),
|
||||
@@ -242,13 +249,13 @@ func (h *transportHandler) handleTCPConn(originConn adapter.TCPConn) {
|
||||
}
|
||||
|
||||
if h.opts.Bypass != nil &&
|
||||
h.opts.Bypass.Contains(ctx, "tcp", dstAddr.String()) {
|
||||
h.opts.Bypass.Contains(ctx, network, dstAddr.String()) {
|
||||
log.Debug("bypass: ", dstAddr)
|
||||
return
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
cc, err := h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", dstAddr.String())
|
||||
cc, err := h.opts.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), network, dstAddr.String())
|
||||
ro.Route = buf.String()
|
||||
if err != nil {
|
||||
log.Errorf("dial %s: %v", dstAddr.String(), err)
|
||||
|
||||
@@ -176,14 +176,14 @@ func (h *unixHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler
|
||||
conn = xnet.NewReadWriteConn(br, conn, conn)
|
||||
switch proto {
|
||||
case sniffing.ProtoHTTP:
|
||||
return sniffer.HandleHTTP(ctx, conn,
|
||||
return sniffer.HandleHTTP(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
sniffing.WithLog(log),
|
||||
)
|
||||
case sniffing.ProtoTLS:
|
||||
return sniffer.HandleTLS(ctx, conn,
|
||||
return sniffer.HandleTLS(ctx, "tcp", conn,
|
||||
sniffing.WithDial(dial),
|
||||
sniffing.WithDialTLS(dialTLS),
|
||||
sniffing.WithRecorderObject(ro),
|
||||
|
||||
@@ -51,57 +51,56 @@ var (
|
||||
)
|
||||
|
||||
type HandleOptions struct {
|
||||
Dial func(ctx context.Context, network, address string) (net.Conn, error)
|
||||
|
||||
HTTPKeepalive bool
|
||||
Node *chain.Node
|
||||
Hop hop.Hop
|
||||
Bypass bypass.Bypass
|
||||
RecorderObject *xrecorder.HandlerRecorderObject
|
||||
Log logger.Logger
|
||||
dial func(ctx context.Context, network, address string) (net.Conn, error)
|
||||
httpKeepalive bool
|
||||
node *chain.Node
|
||||
hop hop.Hop
|
||||
bypass bypass.Bypass
|
||||
recorderObject *xrecorder.HandlerRecorderObject
|
||||
log logger.Logger
|
||||
}
|
||||
|
||||
type HandleOption func(opts *HandleOptions)
|
||||
|
||||
func WithDial(dial func(ctx context.Context, network, address string) (net.Conn, error)) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Dial = dial
|
||||
opts.dial = dial
|
||||
}
|
||||
}
|
||||
|
||||
func WithHTTPKeepalive(keepalive bool) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.HTTPKeepalive = keepalive
|
||||
opts.httpKeepalive = keepalive
|
||||
}
|
||||
}
|
||||
|
||||
func WithNode(node *chain.Node) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Node = node
|
||||
opts.node = node
|
||||
}
|
||||
}
|
||||
|
||||
func WithHop(hop hop.Hop) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Hop = hop
|
||||
opts.hop = hop
|
||||
}
|
||||
}
|
||||
|
||||
func WithBypass(bypass bypass.Bypass) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Bypass = bypass
|
||||
opts.bypass = bypass
|
||||
}
|
||||
}
|
||||
|
||||
func WithRecorderObject(ro *xrecorder.HandlerRecorderObject) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.RecorderObject = ro
|
||||
opts.recorderObject = ro
|
||||
}
|
||||
}
|
||||
|
||||
func WithLog(log logger.Logger) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Log = log
|
||||
opts.log = log
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,12 +140,12 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
return err
|
||||
}
|
||||
|
||||
if ho.Log.IsLevelEnabled(logger.TraceLevel) {
|
||||
if ho.log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(req, false)
|
||||
ho.Log.Trace(string(dump))
|
||||
ho.log.Trace(string(dump))
|
||||
}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
ro := ho.recorderObject
|
||||
ro.HTTP = &xrecorder.HTTPRecorderObject{
|
||||
Host: req.Host,
|
||||
Proto: req.Proto,
|
||||
@@ -176,8 +175,8 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
}
|
||||
defer cc.Close()
|
||||
|
||||
ho.Log = ho.Log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()})
|
||||
log := ho.Log
|
||||
ho.log = ho.log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()})
|
||||
log := ho.log
|
||||
log.Debugf("connected to node %s(%s)", node.Name, node.Addr)
|
||||
|
||||
ro.SrcAddr = cc.LocalAddr().String()
|
||||
@@ -212,17 +211,17 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
}
|
||||
|
||||
func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho *HandleOptions) (node *chain.Node, cc net.Conn, err error) {
|
||||
dial := ho.Dial
|
||||
dial := ho.dial
|
||||
if dial == nil {
|
||||
dial = (&net.Dialer{}).DialContext
|
||||
}
|
||||
|
||||
if node = ho.Node; node != nil {
|
||||
if node = ho.node; node != nil {
|
||||
cc, err = dial(ctx, "tcp", node.Addr)
|
||||
return
|
||||
}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
ro := ho.recorderObject
|
||||
|
||||
res := &http.Response{
|
||||
ProtoMajor: req.ProtoMajor,
|
||||
@@ -237,13 +236,13 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
|
||||
host = net.JoinHostPort(strings.Trim(host, "[]"), "80")
|
||||
}
|
||||
ro.Host = host
|
||||
ho.Log = ho.Log.WithFields(map[string]any{
|
||||
ho.log = ho.log.WithFields(map[string]any{
|
||||
"host": host,
|
||||
})
|
||||
|
||||
if ho.Bypass != nil &&
|
||||
ho.Bypass.Contains(ctx, "tcp", host, bypass.WithPathOption(req.RequestURI)) {
|
||||
ho.Log.Debugf("bypass: %s %s", host, req.RequestURI)
|
||||
if ho.bypass != nil &&
|
||||
ho.bypass.Contains(ctx, "tcp", host, bypass.WithPathOption(req.RequestURI)) {
|
||||
ho.log.Debugf("bypass: %s %s", host, req.RequestURI)
|
||||
res.StatusCode = http.StatusForbidden
|
||||
ro.HTTP.StatusCode = res.StatusCode
|
||||
res.Write(conn)
|
||||
@@ -252,13 +251,13 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
|
||||
}
|
||||
|
||||
node = &chain.Node{}
|
||||
if ho.Hop != nil {
|
||||
if ho.hop != nil {
|
||||
var clientIP net.IP
|
||||
if clientAddr, _ := net.ResolveTCPAddr("tcp", ro.ClientAddr); clientAddr != nil {
|
||||
clientIP = clientAddr.IP
|
||||
}
|
||||
|
||||
node = ho.Hop.Select(ctx,
|
||||
node = ho.hop.Select(ctx,
|
||||
hop.ClientIPSelectOption(clientIP),
|
||||
hop.ProtocolSelectOption(sniffing.ProtoHTTP),
|
||||
hop.HostSelectOption(host),
|
||||
@@ -269,7 +268,7 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
|
||||
)
|
||||
}
|
||||
if node == nil {
|
||||
ho.Log.Warnf("node for %s not found", host)
|
||||
ho.log.Warnf("node for %s not found", host)
|
||||
res.StatusCode = http.StatusBadGateway
|
||||
ro.HTTP.StatusCode = res.StatusCode
|
||||
res.Write(conn)
|
||||
@@ -283,11 +282,11 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
|
||||
}
|
||||
|
||||
ro.Host = node.Addr
|
||||
ho.Log = ho.Log.WithFields(map[string]any{
|
||||
ho.log = ho.log.WithFields(map[string]any{
|
||||
"node": node.Name,
|
||||
"dst": node.Addr,
|
||||
})
|
||||
ho.Log.Debugf("find node for host %s -> %s(%s)", host, node.Name, node.Addr)
|
||||
ho.log.Debugf("find node for host %s -> %s(%s)", host, node.Name, node.Addr)
|
||||
|
||||
cc, err = dial(ctx, "tcp", node.Addr)
|
||||
if err != nil {
|
||||
@@ -296,7 +295,7 @@ func (h *Sniffer) dial(ctx context.Context, conn net.Conn, req *http.Request, ho
|
||||
if marker := node.Marker(); marker != nil {
|
||||
marker.Mark()
|
||||
}
|
||||
ho.Log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err)
|
||||
ho.log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err)
|
||||
res.Write(conn)
|
||||
return
|
||||
}
|
||||
@@ -332,8 +331,8 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions)
|
||||
return errors.New("h2: invalid client preface")
|
||||
}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
log := ho.Log
|
||||
ro := ho.recorderObject
|
||||
log := ho.log
|
||||
|
||||
ro.Time = time.Time{}
|
||||
|
||||
@@ -370,9 +369,9 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions)
|
||||
func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriteCloser, node *chain.Node, req *http.Request, pStats stats.Stats, ho *HandleOptions) (close bool, err error) {
|
||||
close = true
|
||||
|
||||
log := ho.Log
|
||||
log := ho.log
|
||||
ro := &xrecorder.HandlerRecorderObject{}
|
||||
*ro = *ho.RecorderObject
|
||||
*ro = *ho.recorderObject
|
||||
|
||||
ro.Time = time.Now()
|
||||
log.Infof("%s <-> %s", ro.RemoteAddr, req.Host)
|
||||
@@ -540,7 +539,7 @@ func (h *Sniffer) httpRoundTrip(ctx context.Context, rw, cc io.ReadWriteCloser,
|
||||
resp.ProtoMinor = req.ProtoMinor
|
||||
}
|
||||
|
||||
if !ho.HTTPKeepalive {
|
||||
if !ho.httpKeepalive {
|
||||
resp.Header.Set("Connection", "close")
|
||||
}
|
||||
|
||||
@@ -790,7 +789,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
return err
|
||||
}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
ro := ho.recorderObject
|
||||
ro.TLS = &xrecorder.TLSRecorderObject{
|
||||
ServerName: clientHello.ServerName,
|
||||
ClientHello: hex.EncodeToString(buf.Bytes()),
|
||||
@@ -808,7 +807,7 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
}
|
||||
ro.Host = host
|
||||
|
||||
if ho.Bypass != nil && ho.Bypass.Contains(ctx, "tcp", host) {
|
||||
if ho.bypass != nil && ho.bypass.Contains(ctx, "tcp", host) {
|
||||
return xbypass.ErrBypass
|
||||
}
|
||||
}
|
||||
@@ -818,9 +817,9 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
return err
|
||||
}
|
||||
defer cc.Close()
|
||||
ho.Node = node
|
||||
ho.node = node
|
||||
|
||||
log := ho.Log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()})
|
||||
log := ho.log.WithFields(map[string]any{"src": cc.LocalAddr().String(), "dst": cc.RemoteAddr().String()})
|
||||
log.Debugf("connected to node %s(%s)", node.Name, node.Addr)
|
||||
|
||||
ro.SrcAddr = cc.LocalAddr().String()
|
||||
@@ -874,26 +873,26 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
}
|
||||
|
||||
func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) (node *chain.Node, cc net.Conn, err error) {
|
||||
dial := ho.Dial
|
||||
dial := ho.dial
|
||||
if dial == nil {
|
||||
dial = (&net.Dialer{}).DialContext
|
||||
}
|
||||
|
||||
if node = ho.Node; node != nil {
|
||||
if node = ho.node; node != nil {
|
||||
cc, err = dial(ctx, "tcp", node.Addr)
|
||||
return
|
||||
}
|
||||
|
||||
node = &chain.Node{}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
if ho.Hop != nil {
|
||||
ro := ho.recorderObject
|
||||
if ho.hop != nil {
|
||||
var clientIP net.IP
|
||||
if clientAddr, _ := net.ResolveTCPAddr("tcp", ro.ClientAddr); clientAddr != nil {
|
||||
clientIP = clientAddr.IP
|
||||
}
|
||||
|
||||
node = ho.Hop.Select(ctx,
|
||||
node = ho.hop.Select(ctx,
|
||||
hop.ClientIPSelectOption(clientIP),
|
||||
hop.HostSelectOption(host),
|
||||
hop.ProtocolSelectOption(sniffing.ProtoTLS),
|
||||
@@ -923,12 +922,12 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) (
|
||||
}
|
||||
ro.Host = addr
|
||||
|
||||
ho.Log = ho.Log.WithFields(map[string]any{
|
||||
ho.log = ho.log.WithFields(map[string]any{
|
||||
"host": host,
|
||||
"node": node.Name,
|
||||
"dst": fmt.Sprintf("%s/%s", addr, ro.Network),
|
||||
})
|
||||
ho.Log.Debugf("find node for host %s -> %s(%s)", host, node.Name, addr)
|
||||
ho.log.Debugf("find node for host %s -> %s(%s)", host, node.Name, addr)
|
||||
|
||||
cc, err = dial(ctx, ro.Network, addr)
|
||||
if err != nil {
|
||||
@@ -937,7 +936,7 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) (
|
||||
if marker := node.Marker(); marker != nil {
|
||||
marker.Mark()
|
||||
}
|
||||
ho.Log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err)
|
||||
ho.log.Warnf("connect to node %s(%s) failed: %v", node.Name, node.Addr, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -962,8 +961,8 @@ func (h *Sniffer) dialTLS(ctx context.Context, host string, ho *HandleOptions) (
|
||||
}
|
||||
|
||||
func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHello *dissector.ClientHelloInfo, ho *HandleOptions) error {
|
||||
ro := ho.RecorderObject
|
||||
log := ho.Log
|
||||
ro := ho.recorderObject
|
||||
log := ho.log
|
||||
|
||||
nextProtos := clientHello.SupportedProtos
|
||||
if h.NegotiatedProtocol != "" {
|
||||
@@ -1063,7 +1062,7 @@ func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHel
|
||||
return clientConn, nil
|
||||
}),
|
||||
WithHTTPKeepalive(true),
|
||||
WithNode(ho.Node),
|
||||
WithNode(ho.node),
|
||||
WithRecorderObject(ro),
|
||||
WithLog(log),
|
||||
}
|
||||
|
||||
@@ -54,43 +54,43 @@ var (
|
||||
)
|
||||
|
||||
type HandleOptions struct {
|
||||
Dial func(ctx context.Context, network, address string) (net.Conn, error)
|
||||
DialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error)
|
||||
dial func(ctx context.Context, network, address string) (net.Conn, error)
|
||||
dialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error)
|
||||
|
||||
Bypass bypass.Bypass
|
||||
RecorderObject *xrecorder.HandlerRecorderObject
|
||||
Log logger.Logger
|
||||
bypass bypass.Bypass
|
||||
recorderObject *xrecorder.HandlerRecorderObject
|
||||
log logger.Logger
|
||||
}
|
||||
|
||||
type HandleOption func(opts *HandleOptions)
|
||||
|
||||
func WithDial(dial func(ctx context.Context, network, address string) (net.Conn, error)) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Dial = dial
|
||||
opts.dial = dial
|
||||
}
|
||||
}
|
||||
|
||||
func WithDialTLS(dialTLS func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error)) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.DialTLS = dialTLS
|
||||
opts.dialTLS = dialTLS
|
||||
}
|
||||
}
|
||||
|
||||
func WithBypass(bypass bypass.Bypass) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Bypass = bypass
|
||||
opts.bypass = bypass
|
||||
}
|
||||
}
|
||||
|
||||
func WithRecorderObject(ro *xrecorder.HandlerRecorderObject) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.RecorderObject = ro
|
||||
opts.recorderObject = ro
|
||||
}
|
||||
}
|
||||
|
||||
func WithLog(log logger.Logger) HandleOption {
|
||||
return func(opts *HandleOptions) {
|
||||
opts.Log = log
|
||||
opts.log = log
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ type Sniffer struct {
|
||||
ReadTimeout time.Duration
|
||||
}
|
||||
|
||||
func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleOption) error {
|
||||
func (h *Sniffer) HandleHTTP(ctx context.Context, network string, conn net.Conn, opts ...HandleOption) error {
|
||||
var ho HandleOptions
|
||||
for _, opt := range opts {
|
||||
opt(&ho)
|
||||
@@ -130,13 +130,13 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
return err
|
||||
}
|
||||
|
||||
log := ho.Log
|
||||
log := ho.log
|
||||
if log.IsLevelEnabled(logger.TraceLevel) {
|
||||
dump, _ := httputil.DumpRequest(req, false)
|
||||
log.Trace(string(dump))
|
||||
}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
ro := ho.recorderObject
|
||||
ro.HTTP = &xrecorder.HTTPRecorderObject{
|
||||
Host: req.Host,
|
||||
Proto: req.Proto,
|
||||
@@ -156,7 +156,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
|
||||
// http/2
|
||||
if req.Method == "PRI" && len(req.Header) == 0 && req.URL.Path == "*" && req.Proto == "HTTP/2.0" {
|
||||
return h.serveH2(ctx, xnet.NewReadWriteConn(br, conn, conn), &ho)
|
||||
return h.serveH2(ctx, network, xnet.NewReadWriteConn(br, conn, conn), &ho)
|
||||
}
|
||||
|
||||
host := req.Host
|
||||
@@ -170,16 +170,16 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
"host": host,
|
||||
})
|
||||
|
||||
if ho.Bypass != nil && ho.Bypass.Contains(ctx, "tcp", host) {
|
||||
if ho.bypass != nil && ho.bypass.Contains(ctx, network, host) {
|
||||
return xbypass.ErrBypass
|
||||
}
|
||||
}
|
||||
|
||||
dial := ho.Dial
|
||||
dial := ho.dial
|
||||
if dial == nil {
|
||||
dial = (&net.Dialer{}).DialContext
|
||||
}
|
||||
cc, err := dial(ctx, "tcp", host)
|
||||
cc, err := dial(ctx, network, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -218,7 +218,7 @@ func (h *Sniffer) HandleHTTP(ctx context.Context, conn net.Conn, opts ...HandleO
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions) error {
|
||||
func (h *Sniffer) serveH2(ctx context.Context, network string, conn net.Conn, ho *HandleOptions) error {
|
||||
const expectedBody = "SM\r\n\r\n"
|
||||
|
||||
buf := make([]byte, len(expectedBody))
|
||||
@@ -230,14 +230,14 @@ func (h *Sniffer) serveH2(ctx context.Context, conn net.Conn, ho *HandleOptions)
|
||||
return errors.New("h2: invalid client preface")
|
||||
}
|
||||
|
||||
ro := ho.RecorderObject
|
||||
log := ho.Log
|
||||
ro := ho.recorderObject
|
||||
log := ho.log
|
||||
|
||||
ro.Time = time.Time{}
|
||||
|
||||
tr := &http2.Transport{
|
||||
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
if dial := ho.DialTLS; dial != nil {
|
||||
DialTLSContext: func(ctx context.Context, nw, addr string, cfg *tls.Config) (net.Conn, error) {
|
||||
if dial := ho.dialTLS; dial != nil {
|
||||
return dial(ctx, network, addr, cfg)
|
||||
}
|
||||
|
||||
@@ -564,7 +564,7 @@ func (h *Sniffer) copyWebsocketFrame(w io.Writer, r io.Reader, buf *bytes.Buffer
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOption) error {
|
||||
func (h *Sniffer) HandleTLS(ctx context.Context, network string, conn net.Conn, opts ...HandleOption) error {
|
||||
var ho HandleOptions
|
||||
for _, opt := range opts {
|
||||
opt(&ho)
|
||||
@@ -580,9 +580,9 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
return err
|
||||
}
|
||||
|
||||
log := ho.Log
|
||||
log := ho.log
|
||||
|
||||
ro := ho.RecorderObject
|
||||
ro := ho.recorderObject
|
||||
ro.TLS = &xrecorder.TLSRecorderObject{
|
||||
ServerName: clientHello.ServerName,
|
||||
ClientHello: hex.EncodeToString(buf.Bytes()),
|
||||
@@ -600,16 +600,16 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
}
|
||||
ro.Host = host
|
||||
|
||||
if ho.Bypass != nil && ho.Bypass.Contains(ctx, "tcp", host) {
|
||||
if ho.bypass != nil && ho.bypass.Contains(ctx, network, host) {
|
||||
return xbypass.ErrBypass
|
||||
}
|
||||
}
|
||||
|
||||
dial := ho.Dial
|
||||
dial := ho.dial
|
||||
if dial == nil {
|
||||
dial = (&net.Dialer{}).DialContext
|
||||
}
|
||||
cc, err := dial(ctx, "tcp", host)
|
||||
cc, err := dial(ctx, network, host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -624,8 +624,8 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
if host == "" {
|
||||
host = ro.Host
|
||||
}
|
||||
if h.MitmBypass == nil || !h.MitmBypass.Contains(ctx, "tcp", host) {
|
||||
return h.terminateTLS(ctx, xnet.NewReadWriteConn(io.MultiReader(buf, conn), conn, conn), cc, clientHello, &ho)
|
||||
if h.MitmBypass == nil || !h.MitmBypass.Contains(ctx, network, host) {
|
||||
return h.terminateTLS(ctx, network, xnet.NewReadWriteConn(io.MultiReader(buf, conn), conn, conn), cc, clientHello, &ho)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,9 +666,9 @@ func (h *Sniffer) HandleTLS(ctx context.Context, conn net.Conn, opts ...HandleOp
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHello *dissector.ClientHelloInfo, ho *HandleOptions) error {
|
||||
ro := ho.RecorderObject
|
||||
log := ho.Log
|
||||
func (h *Sniffer) terminateTLS(ctx context.Context, network string, conn, cc net.Conn, clientHello *dissector.ClientHelloInfo, ho *HandleOptions) error {
|
||||
ro := ho.recorderObject
|
||||
log := ho.log
|
||||
|
||||
nextProtos := clientHello.SupportedProtos
|
||||
if h.NegotiatedProtocol != "" {
|
||||
@@ -773,7 +773,7 @@ func (h *Sniffer) terminateTLS(ctx context.Context, conn, cc net.Conn, clientHel
|
||||
WithRecorderObject(ro),
|
||||
WithLog(log),
|
||||
}
|
||||
return h.HandleHTTP(ctx, serverConn, opts...)
|
||||
return h.HandleHTTP(ctx, network, serverConn, opts...)
|
||||
}
|
||||
|
||||
type h2Handler struct {
|
||||
|
||||
Reference in New Issue
Block a user