| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package bittorrent
- import (
- "encoding/binary"
- "errors"
- "math"
- "time"
- "github.com/v2fly/v2ray-core/v4/common/buf"
- "github.com/v2fly/v2ray-core/v4/common"
- )
- 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.As(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
- }
|