chore: hy client should not force UDP addr for quic Dial

This commit is contained in:
Toby 2022-10-24 22:47:12 -07:00
parent 3d54cb43af
commit 8b0a157e0b
2 changed files with 63 additions and 29 deletions

View File

@ -26,6 +26,8 @@ var ErrClosed = errors.New("closed")
type Client struct { type Client struct {
serverAddr string serverAddr string
serverName string // QUIC SNI
sendBPS, recvBPS uint64 sendBPS, recvBPS uint64
auth []byte auth []byte
@ -50,8 +52,18 @@ func NewClient(serverAddr string, auth []byte, tlsConfig *tls.Config, quicConfig
pktConnFunc pktconns.ClientPacketConnFunc, sendBPS uint64, recvBPS uint64, quicReconnectFunc func(err error), pktConnFunc pktconns.ClientPacketConnFunc, sendBPS uint64, recvBPS uint64, quicReconnectFunc func(err error),
) (*Client, error) { ) (*Client, error) {
quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud.DisablePathMTUDiscovery quicConfig.DisablePathMTUDiscovery = quicConfig.DisablePathMTUDiscovery || pmtud.DisablePathMTUDiscovery
// QUIC wants server name, but our serverAddr is usually host:port,
// so we try to extract it from serverAddr.
serverName, _, err := net.SplitHostPort(serverAddr)
if err != nil {
// It's possible that we have some weird serverAddr combined with weird PacketConn implementation,
// that doesn't follow the standard host:port format. So it's ok if we run into error here.
// Server name should be set in tlsConfig in that case.
serverName = ""
}
c := &Client{ c := &Client{
serverAddr: serverAddr, serverAddr: serverAddr,
serverName: serverName,
sendBPS: sendBPS, sendBPS: sendBPS,
recvBPS: recvBPS, recvBPS: recvBPS,
auth: auth, auth: auth,
@ -75,16 +87,12 @@ func (c *Client) connect() error {
_ = c.pktConn.Close() _ = c.pktConn.Close()
} }
// New connection // New connection
pktConn, err := c.pktConnFunc(c.serverAddr) pktConn, sAddr, err := c.pktConnFunc(c.serverAddr)
if err != nil { if err != nil {
return err return err
} }
serverUDPAddr, err := net.ResolveUDPAddr("udp", c.serverAddr) // Dial QUIC
if err != nil { quicConn, err := quic.Dial(pktConn, sAddr, c.serverName, c.tlsConfig, c.quicConfig)
_ = pktConn.Close()
return err
}
quicConn, err := quic.Dial(pktConn, serverUDPAddr, c.serverAddr, c.tlsConfig, c.quicConfig)
if err != nil { if err != nil {
_ = pktConn.Close() _ = pktConn.Close()
return err return err

View File

@ -10,7 +10,7 @@ import (
) )
type ( type (
ClientPacketConnFunc func(server string) (net.PacketConn, error) ClientPacketConnFunc func(server string) (net.PacketConn, net.Addr, error)
ServerPacketConnFunc func(listen string) (net.PacketConn, error) ServerPacketConnFunc func(listen string) (net.PacketConn, error)
) )
@ -21,55 +21,81 @@ type (
func NewClientUDPConnFunc(obfsPassword string) ClientPacketConnFunc { func NewClientUDPConnFunc(obfsPassword string) ClientPacketConnFunc {
if obfsPassword == "" { if obfsPassword == "" {
return func(server string) (net.PacketConn, error) { return func(server string) (net.PacketConn, net.Addr, error) {
return net.ListenUDP("udp", nil) sAddr, err := net.ResolveUDPAddr("udp", server)
if err != nil {
return nil, nil, err
}
udpConn, err := net.ListenUDP("udp", nil)
return udpConn, sAddr, err
} }
} else { } else {
return func(server string) (net.PacketConn, error) { return func(server string) (net.PacketConn, net.Addr, error) {
ob := obfs.NewXPlusObfuscator([]byte(obfsPassword)) sAddr, err := net.ResolveUDPAddr("udp", server)
if err != nil {
return nil, nil, err
}
udpConn, err := net.ListenUDP("udp", nil) udpConn, err := net.ListenUDP("udp", nil)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return udp.NewObfsUDPConn(udpConn, ob), nil ob := obfs.NewXPlusObfuscator([]byte(obfsPassword))
return udp.NewObfsUDPConn(udpConn, ob), sAddr, nil
} }
} }
} }
func NewClientWeChatConnFunc(obfsPassword string) ClientPacketConnFunc { func NewClientWeChatConnFunc(obfsPassword string) ClientPacketConnFunc {
if obfsPassword == "" { if obfsPassword == "" {
return func(server string) (net.PacketConn, error) { return func(server string) (net.PacketConn, net.Addr, error) {
sAddr, err := net.ResolveUDPAddr("udp", server)
if err != nil {
return nil, nil, err
}
udpConn, err := net.ListenUDP("udp", nil) udpConn, err := net.ListenUDP("udp", nil)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return wechat.NewObfsWeChatUDPConn(udpConn, nil), nil return wechat.NewObfsWeChatUDPConn(udpConn, nil), sAddr, nil
} }
} else { } else {
return func(server string) (net.PacketConn, error) { return func(server string) (net.PacketConn, net.Addr, error) {
ob := obfs.NewXPlusObfuscator([]byte(obfsPassword)) sAddr, err := net.ResolveUDPAddr("udp", server)
if err != nil {
return nil, nil, err
}
udpConn, err := net.ListenUDP("udp", nil) udpConn, err := net.ListenUDP("udp", nil)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return wechat.NewObfsWeChatUDPConn(udpConn, ob), nil ob := obfs.NewXPlusObfuscator([]byte(obfsPassword))
return wechat.NewObfsWeChatUDPConn(udpConn, ob), sAddr, nil
} }
} }
} }
func NewClientFakeTCPConnFunc(obfsPassword string) ClientPacketConnFunc { func NewClientFakeTCPConnFunc(obfsPassword string) ClientPacketConnFunc {
if obfsPassword == "" { if obfsPassword == "" {
return func(server string) (net.PacketConn, error) { return func(server string) (net.PacketConn, net.Addr, error) {
return faketcp.Dial("tcp", server) sAddr, err := net.ResolveTCPAddr("tcp", server)
if err != nil {
return nil, nil, err
}
fTCPConn, err := faketcp.Dial("tcp", server)
return fTCPConn, sAddr, err
} }
} else { } else {
return func(server string) (net.PacketConn, error) { return func(server string) (net.PacketConn, net.Addr, error) {
ob := obfs.NewXPlusObfuscator([]byte(obfsPassword)) sAddr, err := net.ResolveTCPAddr("tcp", server)
fakeTCPConn, err := faketcp.Dial("tcp", server)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
return faketcp.NewObfsFakeTCPConn(fakeTCPConn, ob), nil fTCPConn, err := faketcp.Dial("tcp", server)
if err != nil {
return nil, nil, err
}
ob := obfs.NewXPlusObfuscator([]byte(obfsPassword))
return faketcp.NewObfsFakeTCPConn(fTCPConn, ob), sAddr, nil
} }
} }
} }