1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-07-15 17:54:37 -04:00
v2fly/common/protocol/bittorrent/bittorrent.go

91 lines
1.9 KiB
Go
Raw Normal View History

2018-07-16 06:56:50 -04:00
package bittorrent
import (
2021-11-02 21:25:48 -04:00
"encoding/binary"
2018-07-16 06:56:50 -04:00
"errors"
2021-11-02 21:25:48 -04:00
"math"
"time"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/buf"
2018-07-16 06:56:50 -04:00
)
2021-05-19 17:28:52 -04:00
type SniffHeader struct{}
2018-07-16 06:56:50 -04:00
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
2018-07-16 06:56:50 -04:00
}
if b[0] == 19 && string(b[1:20]) == "BitTorrent protocol" {
return &SniffHeader{}, nil
}
return nil, errNotBittorrent
}
2021-11-02 21:25:48 -04:00
func SniffUTP(b []byte) (*SniffHeader, error) {
if len(b) < 20 {
return nil, common.ErrNoClue
}
2021-11-07 17:45:36 -05:00
buffer := buf.FromBytes(b)
2021-11-02 21:25:48 -04:00
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, &timestamp); 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
}