mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-16 04:42:22 +08:00
Fix stream sniffer
This commit is contained in:
parent
b57abcc73c
commit
27d6b63e71
|
@ -18,34 +18,45 @@ type (
|
|||
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) {
|
||||
if timeout == 0 {
|
||||
timeout = C.ReadPayloadTimeout
|
||||
}
|
||||
deadline := time.Now().Add(timeout)
|
||||
var errors []error
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
err := conn.SetReadDeadline(deadline)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "set read deadline")
|
||||
}
|
||||
_, err = buffer.ReadOnceFrom(conn)
|
||||
err = E.Errors(err, conn.SetReadDeadline(time.Time{}))
|
||||
if err != nil {
|
||||
if i > 0 {
|
||||
break
|
||||
}
|
||||
return nil, E.Cause(err, "read payload")
|
||||
}
|
||||
defer conn.SetReadDeadline(time.Time{})
|
||||
var metadata *adapter.InboundContext
|
||||
for _, sniffer := range sniffers {
|
||||
metadata, err := sniffer(ctx, bytes.NewReader(buffer.Bytes()))
|
||||
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)))
|
||||
}
|
||||
if metadata != nil {
|
||||
return metadata, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
if metadata.InboundOptions.SniffEnabled {
|
||||
if metadata.InboundOptions.SniffEnabled && !sniff.Skip(metadata) {
|
||||
buffer := buf.NewPacket()
|
||||
sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, time.Duration(metadata.InboundOptions.SniffTimeout), sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
|
||||
if sniffMetadata != nil {
|
||||
|
|
Loading…
Reference in New Issue
Block a user