mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-22 00:21:30 +00:00
Fix stream sniffer
This commit is contained in:
parent
b57abcc73c
commit
27d6b63e71
|
@ -18,33 +18,44 @@ type (
|
||||||
PacketSniffer = func(ctx context.Context, packet []byte) (*adapter.InboundContext, error)
|
PacketSniffer = func(ctx context.Context, packet []byte) (*adapter.InboundContext, error)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Skip(metadata adapter.InboundContext) bool {
|
||||||
|
// skip server first protocols
|
||||||
|
switch metadata.Destination.Port {
|
||||||
|
case 25, 465, 587:
|
||||||
|
// SMTP
|
||||||
|
return true
|
||||||
|
case 143, 993:
|
||||||
|
// IMAP
|
||||||
|
return true
|
||||||
|
case 110, 995:
|
||||||
|
// POP3
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func PeekStream(ctx context.Context, conn net.Conn, buffer *buf.Buffer, timeout time.Duration, sniffers ...StreamSniffer) (*adapter.InboundContext, error) {
|
func PeekStream(ctx context.Context, conn net.Conn, buffer *buf.Buffer, timeout time.Duration, sniffers ...StreamSniffer) (*adapter.InboundContext, error) {
|
||||||
if timeout == 0 {
|
if timeout == 0 {
|
||||||
timeout = C.ReadPayloadTimeout
|
timeout = C.ReadPayloadTimeout
|
||||||
}
|
}
|
||||||
deadline := time.Now().Add(timeout)
|
deadline := time.Now().Add(timeout)
|
||||||
var errors []error
|
var errors []error
|
||||||
|
err := conn.SetReadDeadline(deadline)
|
||||||
for i := 0; i < 3; i++ {
|
if err != nil {
|
||||||
err := conn.SetReadDeadline(deadline)
|
return nil, E.Cause(err, "set read deadline")
|
||||||
if err != nil {
|
}
|
||||||
return nil, E.Cause(err, "set read deadline")
|
defer conn.SetReadDeadline(time.Time{})
|
||||||
|
var metadata *adapter.InboundContext
|
||||||
|
for _, sniffer := range sniffers {
|
||||||
|
if buffer.IsEmpty() {
|
||||||
|
metadata, err = sniffer(ctx, io.TeeReader(conn, buffer))
|
||||||
|
} else {
|
||||||
|
metadata, err = sniffer(ctx, io.MultiReader(bytes.NewReader(buffer.Bytes()), io.TeeReader(conn, buffer)))
|
||||||
}
|
}
|
||||||
_, err = buffer.ReadOnceFrom(conn)
|
if metadata != nil {
|
||||||
err = E.Errors(err, conn.SetReadDeadline(time.Time{}))
|
return metadata, nil
|
||||||
if err != nil {
|
|
||||||
if i > 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return nil, E.Cause(err, "read payload")
|
|
||||||
}
|
|
||||||
for _, sniffer := range sniffers {
|
|
||||||
metadata, err := sniffer(ctx, bytes.NewReader(buffer.Bytes()))
|
|
||||||
if metadata != nil {
|
|
||||||
return metadata, nil
|
|
||||||
}
|
|
||||||
errors = append(errors, err)
|
|
||||||
}
|
}
|
||||||
|
errors = append(errors, err)
|
||||||
}
|
}
|
||||||
return nil, E.Errors(errors...)
|
return nil, E.Errors(errors...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -832,7 +832,7 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
||||||
conn = deadline.NewConn(conn)
|
conn = deadline.NewConn(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
if metadata.InboundOptions.SniffEnabled {
|
if metadata.InboundOptions.SniffEnabled && !sniff.Skip(metadata) {
|
||||||
buffer := buf.NewPacket()
|
buffer := buf.NewPacket()
|
||||||
sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
|
sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
|
||||||
if sniffMetadata != nil {
|
if sniffMetadata != nil {
|
||||||
|
|
Loading…
Reference in a new issue