123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- package bittorrent
- import (
- "encoding/binary"
- "errors"
- "math"
- "time"
- "github.com/xtls/xray-core/common"
- "github.com/xtls/xray-core/common/buf"
- )
- type SniffHeader struct{}
- func (h *SniffHeader) Protocol() string {
- return "bittorrent"
- }
- func (h *SniffHeader) Domain() string {
- return ""
- }
- var errNotBittorrent = errors.New("not bittorrent header")
- func SniffBittorrent(b []byte) (*SniffHeader, error) {
- if len(b) < 20 {
- return nil, common.ErrNoClue
- }
- if b[0] == 19 && string(b[1:20]) == "BitTorrent protocol" {
- return &SniffHeader{}, nil
- }
- return nil, errNotBittorrent
- }
- func SniffUTP(b []byte) (*SniffHeader, error) {
- if len(b) < 20 {
- return nil, common.ErrNoClue
- }
- buffer := buf.FromBytes(b)
- var typeAndVersion uint8
- if binary.Read(buffer, binary.BigEndian, &typeAndVersion) != nil {
- return nil, common.ErrNoClue
- } else if b[0]>>4&0xF > 4 || b[0]&0xF != 1 {
- return nil, errNotBittorrent
- }
- var extension uint8
- if binary.Read(buffer, binary.BigEndian, &extension) != nil {
- return nil, common.ErrNoClue
- } else if extension != 0 && extension != 1 {
- return nil, errNotBittorrent
- }
- for extension != 0 {
- if extension != 1 {
- return nil, errNotBittorrent
- }
- if binary.Read(buffer, binary.BigEndian, &extension) != nil {
- return nil, common.ErrNoClue
- }
- var length uint8
- if err := binary.Read(buffer, binary.BigEndian, &length); err != nil {
- return nil, common.ErrNoClue
- }
- if common.Error2(buffer.ReadBytes(int32(length))) != nil {
- return nil, common.ErrNoClue
- }
- }
- if common.Error2(buffer.ReadBytes(2)) != nil {
- return nil, common.ErrNoClue
- }
- var timestamp uint32
- if err := binary.Read(buffer, binary.BigEndian, ×tamp); err != nil {
- return nil, common.ErrNoClue
- }
- if math.Abs(float64(time.Now().UnixMicro()-int64(timestamp))) > float64(24*time.Hour) {
- return nil, errNotBittorrent
- }
- return &SniffHeader{}, nil
- }
|