github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/sniffy/bittorrent/bittorrent.go (about) 1 package bittorrent 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "errors" 7 "io" 8 "math" 9 "time" 10 ) 11 12 type SniffHeader struct{} 13 14 func (h *SniffHeader) Protocol() string { 15 return "bittorrent" 16 } 17 18 func (h *SniffHeader) Domain() string { 19 return "" 20 } 21 22 var errNotBittorrent = errors.New("not bittorrent header") 23 var ErrNoClue = errors.New("no rule") 24 25 func SniffBittorrent(b []byte) (*SniffHeader, error) { 26 if len(b) < 20 { 27 return nil, ErrNoClue 28 } 29 30 if b[0] == 19 && string(b[1:20]) == "BitTorrent protocol" { 31 return &SniffHeader{}, nil 32 } 33 34 return nil, errNotBittorrent 35 } 36 37 func SniffUTP(b []byte) (*SniffHeader, error) { 38 if len(b) < 20 { 39 return nil, ErrNoClue 40 } 41 42 buffer := bytes.NewBuffer(b) 43 44 var typeAndVersion uint8 45 46 if binary.Read(buffer, binary.BigEndian, &typeAndVersion) != nil { 47 return nil, ErrNoClue 48 } else if b[0]>>4&0xF > 4 || b[0]&0xF != 1 { 49 return nil, errNotBittorrent 50 } 51 52 var extension uint8 53 54 if binary.Read(buffer, binary.BigEndian, &extension) != nil { 55 return nil, ErrNoClue 56 } else if extension != 0 && extension != 1 { 57 return nil, errNotBittorrent 58 } 59 60 for extension != 0 { 61 if extension != 1 { 62 return nil, errNotBittorrent 63 } 64 if binary.Read(buffer, binary.BigEndian, &extension) != nil { 65 return nil, ErrNoClue 66 } 67 68 var length uint8 69 if err := binary.Read(buffer, binary.BigEndian, &length); err != nil { 70 return nil, ErrNoClue 71 } 72 if ReadBytes(buffer, int(length)) != nil { 73 return nil, ErrNoClue 74 } 75 } 76 77 if ReadBytes(buffer, 2) != nil { 78 return nil, ErrNoClue 79 } 80 81 var timestamp uint32 82 if err := binary.Read(buffer, binary.BigEndian, ×tamp); err != nil { 83 return nil, ErrNoClue 84 } 85 if math.Abs(float64(time.Now().UnixMicro()-int64(timestamp))) > float64(24*time.Hour) { 86 return nil, errNotBittorrent 87 } 88 89 return &SniffHeader{}, nil 90 } 91 92 func ReadBytes(buf *bytes.Buffer, n int) error { 93 if buf.Len() < n { 94 return io.EOF 95 } 96 97 buf.Next(n) 98 return nil 99 }