mirror of
https://github.com/daeuniverse/dae.git
synced 2025-01-22 02:07:50 +07:00
optimize: sniffer
This commit is contained in:
parent
ebdbf9a4a7
commit
6b68e74335
@ -5,12 +5,21 @@
|
|||||||
|
|
||||||
package sniffing
|
package sniffing
|
||||||
|
|
||||||
import "bytes"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
func (s *Sniffer) SniffHttp() (d string, err error) {
|
func (s *Sniffer) SniffHttp() (d string, err error) {
|
||||||
|
// First byte should be printable.
|
||||||
|
if len(s.buf) == 0 || !unicode.IsPrint(rune(s.buf[0])) {
|
||||||
|
return "", NotApplicableError
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search method.
|
||||||
search := s.buf
|
search := s.buf
|
||||||
if len(search) > 20 {
|
if len(search) > 12 {
|
||||||
search = search[:20]
|
search = search[:12]
|
||||||
}
|
}
|
||||||
method, _, found := bytes.Cut(search, []byte(" "))
|
method, _, found := bytes.Cut(search, []byte(" "))
|
||||||
if !found {
|
if !found {
|
||||||
@ -21,6 +30,10 @@ func (s *Sniffer) SniffHttp() (d string, err error) {
|
|||||||
default:
|
default:
|
||||||
return "", NotApplicableError
|
return "", NotApplicableError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now we assume it is an HTTP packet. We should not return NotApplicableError after here.
|
||||||
|
|
||||||
|
// Search Host.
|
||||||
search = s.buf
|
search = s.buf
|
||||||
prefix := []byte("Host: ")
|
prefix := []byte("Host: ")
|
||||||
_, afterHostKey, found := bytes.Cut(search, prefix)
|
_, afterHostKey, found := bytes.Cut(search, prefix)
|
||||||
|
@ -8,6 +8,7 @@ package quicutils
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mzz2017/softwind/pool"
|
"github.com/mzz2017/softwind/pool"
|
||||||
|
"io/fs"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -124,6 +125,8 @@ func ExtractCryptoFrameOffset(remainder []byte, transportOffset int) (offset *Cr
|
|||||||
UpperAppOffset: int(offset),
|
UpperAppOffset: int(offset),
|
||||||
Data: remainder[nextField : nextField+int(length)],
|
Data: remainder[nextField : nextField+int(length)],
|
||||||
}, nextField + int(length), nil
|
}, nextField + int(length), nil
|
||||||
|
case Quic_FrameType_ConnectionClose, Quic_FrameType_ConnectionClose2:
|
||||||
|
return nil, 0, fmt.Errorf("connection closed: %w", fs.ErrClosed)
|
||||||
default:
|
default:
|
||||||
return nil, 0, fmt.Errorf("%w: %v", UnknownFrameTypeError, frameType)
|
return nil, 0, fmt.Errorf("%w: %v", UnknownFrameTypeError, frameType)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/mzz2017/softwind/pool"
|
"github.com/mzz2017/softwind/pool"
|
||||||
"github.com/v2rayA/dae/component/sniffing/internal/quicutils"
|
"github.com/v2rayA/dae/component/sniffing/internal/quicutils"
|
||||||
|
"io/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -54,6 +55,10 @@ func (s *Sniffer) SniffQuic() (d string, err error) {
|
|||||||
}
|
}
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
if errors.Is(err, fs.ErrClosed) {
|
||||||
|
// ConnectionClose sniffed.
|
||||||
|
return "", NotFoundError
|
||||||
|
}
|
||||||
// Error is not NotApplicableError, should be quic block.
|
// Error is not NotApplicableError, should be quic block.
|
||||||
isQuic = true
|
isQuic = true
|
||||||
if len(nextBlock) == 0 {
|
if len(nextBlock) == 0 {
|
||||||
@ -127,10 +132,10 @@ func sniffQuicBlock(buf []byte) (d string, next []byte, err error) {
|
|||||||
firstByte := header[0]
|
firstByte := header[0]
|
||||||
rawPacketNumber := pool.Get(quicutils.MaxPacketNumberLength)
|
rawPacketNumber := pool.Get(quicutils.MaxPacketNumberLength)
|
||||||
copy(rawPacketNumber, header[boundary-quicutils.MaxPacketNumberLength:])
|
copy(rawPacketNumber, header[boundary-quicutils.MaxPacketNumberLength:])
|
||||||
defer pool.Put(rawPacketNumber)
|
|
||||||
defer func() {
|
defer func() {
|
||||||
header[0] = firstByte
|
header[0] = firstByte
|
||||||
copy(header[boundary-quicutils.MaxPacketNumberLength:], rawPacketNumber)
|
copy(header[boundary-quicutils.MaxPacketNumberLength:], rawPacketNumber)
|
||||||
|
pool.Put(rawPacketNumber)
|
||||||
}()
|
}()
|
||||||
plaintext, err := quicutils.DecryptQuicFromPool_(header, blockEnd, destConnId)
|
plaintext, err := quicutils.DecryptQuicFromPool_(header, blockEnd, destConnId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -141,6 +146,9 @@ func sniffQuicBlock(buf []byte) (d string, next []byte, err error) {
|
|||||||
// After here, we should not return NotApplicableError.
|
// After here, we should not return NotApplicableError.
|
||||||
// And we should return nextFrame.
|
// And we should return nextFrame.
|
||||||
if d, err = extractSniFromQuicPayload(plaintext); err != nil {
|
if d, err = extractSniFromQuicPayload(plaintext); err != nil {
|
||||||
|
if errors.Is(err, fs.ErrClosed) {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
return "", buf[blockEnd:], NotFoundError
|
return "", buf[blockEnd:], NotFoundError
|
||||||
}
|
}
|
||||||
return d, buf[blockEnd:], nil
|
return d, buf[blockEnd:], nil
|
||||||
|
@ -103,7 +103,7 @@ func findSniExtension(search quicutils.Locator) (string, error) {
|
|||||||
var b []byte
|
var b []byte
|
||||||
for {
|
for {
|
||||||
if i+4 >= search.Len() {
|
if i+4 >= search.Len() {
|
||||||
return "", NotApplicableError
|
return "", NotFoundError
|
||||||
}
|
}
|
||||||
b = search.Range(i, i+4)
|
b = search.Range(i, i+4)
|
||||||
typ := binary.BigEndian.Uint16(b)
|
typ := binary.BigEndian.Uint16(b)
|
||||||
|
Loading…
Reference in New Issue
Block a user