add support for hysteria udp port hopping (#269)

* add support for hysteria udp port hopping

* add ports field for hysteria

* change method for udp connection

Co-authored-by: geoleonsh <geoleonsh@live.com>
This commit is contained in:
wwqgtxx
2022-11-27 11:09:56 +08:00
parent 0647cee02a
commit 17c081a40c
5 changed files with 416 additions and 31 deletions

View File

@ -6,18 +6,20 @@ import (
"crypto/tls"
"errors"
"fmt"
"github.com/Dreamacro/clash/transport/hysteria/obfs"
"github.com/Dreamacro/clash/transport/hysteria/pmtud_fix"
"github.com/Dreamacro/clash/transport/hysteria/transport"
"github.com/Dreamacro/clash/transport/hysteria/utils"
"github.com/lunixbochs/struc"
"github.com/metacubex/quic-go"
"github.com/metacubex/quic-go/congestion"
"math/rand"
"net"
"strconv"
"sync"
"time"
"github.com/lunixbochs/struc"
"github.com/metacubex/quic-go"
"github.com/metacubex/quic-go/congestion"
"github.com/Dreamacro/clash/transport/hysteria/obfs"
"github.com/Dreamacro/clash/transport/hysteria/pmtud_fix"
"github.com/Dreamacro/clash/transport/hysteria/transport"
"github.com/Dreamacro/clash/transport/hysteria/utils"
)
var (
@ -45,12 +47,13 @@ type Client struct {
udpSessionMutex sync.RWMutex
udpSessionMap map[uint32]chan *udpMessage
udpDefragger defragger
hopInterval time.Duration
fastOpen bool
}
func NewClient(serverAddr string, protocol string, auth []byte, tlsConfig *tls.Config, quicConfig *quic.Config,
transport *transport.ClientTransport, sendBPS uint64, recvBPS uint64, congestionFactory CongestionFactory,
obfuscator obfs.Obfuscator,fastOpen bool) (*Client, error) {
obfuscator obfs.Obfuscator, hopInterval time.Duration, fastOpen bool) (*Client, error) {
quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud_fix.DisablePathMTUDiscovery
c := &Client{
transport: transport,
@ -63,13 +66,14 @@ func NewClient(serverAddr string, protocol string, auth []byte, tlsConfig *tls.C
obfuscator: obfuscator,
tlsConfig: tlsConfig,
quicConfig: quicConfig,
fastOpen: fastOpen,
hopInterval: hopInterval,
fastOpen: fastOpen,
}
return c, nil
}
func (c *Client) connectToServer(dialer transport.PacketDialer) error {
qs, err := c.transport.QUICDial(c.protocol, c.serverAddr, c.tlsConfig, c.quicConfig, c.obfuscator, dialer)
func (c *Client) connectToServer(dialer utils.PacketDialer) error {
qs, err := c.transport.QUICDial(c.protocol, c.serverAddr, c.tlsConfig, c.quicConfig, c.obfuscator, c.hopInterval, dialer)
if err != nil {
return err
}
@ -156,7 +160,7 @@ func (c *Client) handleMessage(qs quic.Connection) {
}
}
func (c *Client) openStreamWithReconnect(dialer transport.PacketDialer) (quic.Connection, quic.Stream, error) {
func (c *Client) openStreamWithReconnect(dialer utils.PacketDialer) (quic.Connection, quic.Stream, error) {
c.reconnectMutex.Lock()
defer c.reconnectMutex.Unlock()
if c.closed {
@ -188,7 +192,7 @@ func (c *Client) openStreamWithReconnect(dialer transport.PacketDialer) (quic.Co
return c.quicSession, &wrappedQUICStream{stream}, err
}
func (c *Client) DialTCP(addr string, dialer transport.PacketDialer) (net.Conn, error) {
func (c *Client) DialTCP(addr string, dialer utils.PacketDialer) (net.Conn, error) {
host, port, err := utils.SplitHostPort(addr)
if err != nil {
return nil, err
@ -227,11 +231,11 @@ func (c *Client) DialTCP(addr string, dialer transport.PacketDialer) (net.Conn,
Orig: stream,
PseudoLocalAddr: session.LocalAddr(),
PseudoRemoteAddr: session.RemoteAddr(),
Established: !c.fastOpen,
Established: !c.fastOpen,
}, nil
}
func (c *Client) DialUDP(dialer transport.PacketDialer) (UDPConn, error) {
func (c *Client) DialUDP(dialer utils.PacketDialer) (UDPConn, error) {
session, stream, err := c.openStreamWithReconnect(dialer)
if err != nil {
return nil, err