Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions infra/conf/transport_internet.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ func (b Bandwidth) Bps() (uint64, error) {

type UdpHop struct {
PortList json.RawMessage `json:"port"`
Interval int64 `json:"interval"`
Interval *Int32Range `json:"interval"`
}

type HysteriaConfig struct {
Expand Down Expand Up @@ -431,13 +431,19 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
hop = &PortList{}
}

var inertvalMin, inertvalMax int64
if c.UdpHop.Interval != nil {
inertvalMin = int64(c.UdpHop.Interval.From)
inertvalMax = int64(c.UdpHop.Interval.To)
}

if up > 0 && up < 65536 {
return nil, errors.New("Up must be at least 65536 Bps")
}
if down > 0 && down < 65536 {
return nil, errors.New("Down must be at least 65536 Bps")
}
if c.UdpHop.Interval != 0 && c.UdpHop.Interval < 5 {
if (inertvalMin != 0 && inertvalMin < 5) || (inertvalMax != 0 && inertvalMax < 5) {
return nil, errors.New("Interval must be at least 5")
}

Expand Down Expand Up @@ -467,7 +473,8 @@ func (c *HysteriaConfig) Build() (proto.Message, error) {
config.Up = up
config.Down = down
config.Ports = hop.Build().Ports()
config.Interval = c.UdpHop.Interval
config.IntervalMin = inertvalMin
config.IntervalMax = inertvalMax
config.InitStreamReceiveWindow = c.InitStreamReceiveWindow
config.MaxStreamReceiveWindow = c.MaxStreamReceiveWindow
config.InitConnReceiveWindow = c.InitConnectionReceiveWindow
Expand Down
51 changes: 30 additions & 21 deletions transport/internet/hysteria/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions transport/internet/hysteria/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ message Config {
uint64 up = 4;
uint64 down = 5;
repeated uint32 ports = 6;
int64 interval = 7;
int64 interval_min = 7;
int64 interval_max = 8;

uint64 init_stream_receive_window = 8;
uint64 max_stream_receive_window = 9;
uint64 init_conn_receive_window = 10;
uint64 max_conn_receive_window = 11;
int64 max_idle_timeout = 12;
int64 keep_alive_period = 13;
bool disable_path_mtu_discovery = 14;
uint64 init_stream_receive_window = 9;
uint64 max_stream_receive_window = 10;
uint64 init_conn_receive_window = 11;
uint64 max_conn_receive_window = 12;
int64 max_idle_timeout = 13;
int64 keep_alive_period = 14;
bool disable_path_mtu_discovery = 15;
}

2 changes: 1 addition & 1 deletion transport/internet/hysteria/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (c *client) dial() error {
IP: remote.(*net.UDPAddr).IP,
Ports: c.config.Ports,
}
pktConn, err = udphop.NewUDPHopPacketConn(addr, time.Duration(c.config.Interval)*time.Second, c.udphopDialer, pktConn, index)
pktConn, err = udphop.NewUDPHopPacketConn(addr, c.config.IntervalMin, c.config.IntervalMax, c.udphopDialer, pktConn, index)
if err != nil {
return errors.New("udphop err").Base(err)
}
Expand Down
43 changes: 25 additions & 18 deletions transport/internet/hysteria/udphop/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"sync"
"syscall"
"time"

"github.com/xtls/xray-core/common/crypto"
)

const (
Expand All @@ -17,10 +19,11 @@ const (
)

type udpHopPacketConn struct {
Addr net.Addr
Addrs []net.Addr
HopInterval time.Duration
ListenUDPFunc ListenUDPFunc
Addr net.Addr
Addrs []net.Addr
HopIntervalMin int64
HopIntervalMax int64
ListenUDPFunc ListenUDPFunc

connMutex sync.RWMutex
prevConn net.PacketConn
Expand All @@ -46,10 +49,12 @@ type udpPacket struct {

type ListenUDPFunc = func(*net.UDPAddr) (net.PacketConn, error)

func NewUDPHopPacketConn(addr *UDPHopAddr, hopInterval time.Duration, listenUDPFunc ListenUDPFunc, pktConn net.PacketConn, index int) (net.PacketConn, error) {
if hopInterval == 0 {
hopInterval = defaultHopInterval
} else if hopInterval < 5*time.Second {
func NewUDPHopPacketConn(addr *UDPHopAddr, intervalMin int64, intervalMax int64, listenUDPFunc ListenUDPFunc, pktConn net.PacketConn, index int) (net.PacketConn, error) {
if intervalMin == 0 || intervalMax == 0 {
intervalMin = int64(defaultHopInterval)
intervalMax = int64(defaultHopInterval)
}
if intervalMin < 5 || intervalMax < 5 {
return nil, errors.New("hop interval must be at least 5 seconds")
}
// if listenUDPFunc == nil {
Expand All @@ -69,15 +74,16 @@ func NewUDPHopPacketConn(addr *UDPHopAddr, hopInterval time.Duration, listenUDPF
// return nil, err
// }
hConn := &udpHopPacketConn{
Addr: addr,
Addrs: addrs,
HopInterval: hopInterval,
ListenUDPFunc: listenUDPFunc,
prevConn: nil,
currentConn: pktConn,
addrIndex: index,
recvQueue: make(chan *udpPacket, packetQueueSize),
closeChan: make(chan struct{}),
Addr: addr,
Addrs: addrs,
HopIntervalMin: intervalMin,
HopIntervalMax: intervalMax,
ListenUDPFunc: listenUDPFunc,
prevConn: nil,
currentConn: pktConn,
addrIndex: index,
recvQueue: make(chan *udpPacket, packetQueueSize),
closeChan: make(chan struct{}),
bufPool: sync.Pool{
New: func() interface{} {
return make([]byte, udpBufferSize)
Expand Down Expand Up @@ -115,12 +121,13 @@ func (u *udpHopPacketConn) recvLoop(conn net.PacketConn) {
}

func (u *udpHopPacketConn) hopLoop() {
ticker := time.NewTicker(u.HopInterval)
ticker := time.NewTicker(time.Duration(crypto.RandBetween(u.HopIntervalMin, u.HopIntervalMax)) * time.Second)
defer ticker.Stop()
for {
select {
case <-ticker.C:
u.hop()
ticker.Reset(time.Duration(crypto.RandBetween(u.HopIntervalMin, u.HopIntervalMax)) * time.Second)
case <-u.closeChan:
return
}
Expand Down