Add stun sniffer

This commit is contained in:
世界 2022-07-16 12:01:02 +08:00
parent 8619e07d66
commit fe5618c35d
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 54 additions and 1 deletions

24
common/sniff/stun.go Normal file
View file

@ -0,0 +1,24 @@
package sniff
import (
"context"
"encoding/binary"
"os"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
)
func STUNMessage(ctx context.Context, packet []byte) (*adapter.InboundContext, error) {
pLen := len(packet)
if pLen < 20 {
return nil, os.ErrInvalid
}
if binary.BigEndian.Uint32(packet[4:8]) != 0x2112A442 {
return nil, os.ErrInvalid
}
if len(packet) < 20+int(binary.BigEndian.Uint16(packet[2:4])) {
return nil, os.ErrInvalid
}
return &adapter.InboundContext{Protocol: C.ProtocolSTUN}, nil
}

28
common/sniff/stun_test.go Normal file
View file

@ -0,0 +1,28 @@
package sniff_test
import (
"context"
"encoding/hex"
"testing"
"github.com/sagernet/sing-box/common/sniff"
C "github.com/sagernet/sing-box/constant"
"github.com/stretchr/testify/require"
)
func TestSniffSTUN(t *testing.T) {
packet, err := hex.DecodeString("000100002112a44224b1a025d0c180c484341306")
require.NoError(t, err)
metadata, err := sniff.STUNMessage(context.Background(), packet)
require.NoError(t, err)
require.Equal(t, metadata.Protocol, C.ProtocolSTUN)
}
func FuzzSniffSTUN(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
if _, err := sniff.STUNMessage(context.Background(), data); err == nil {
t.Fail()
}
})
}

View file

@ -5,4 +5,5 @@ const (
ProtocolHTTP = "http" ProtocolHTTP = "http"
ProtocolQUIC = "quic" ProtocolQUIC = "quic"
ProtocolDNS = "dns" ProtocolDNS = "dns"
ProtocolSTUN = "stun"
) )

View file

@ -457,7 +457,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
if err != nil { if err != nil {
return err return err
} }
sniffMetadata, err := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.QUICClientHello) sniffMetadata, err := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.QUICClientHello, sniff.STUNMessage)
originDestination := metadata.Destination originDestination := metadata.Destination
if err == nil { if err == nil {
metadata.Protocol = sniffMetadata.Protocol metadata.Protocol = sniffMetadata.Protocol