Skip to content

Commit 756a2d1

Browse files
authored
Hysteria client: Fix sendThrough (#6063)
And fixes #6046
1 parent b279076 commit 756a2d1

14 files changed

Lines changed: 81 additions & 218 deletions

File tree

transport/internet/config.pb.go

Lines changed: 2 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

transport/internet/config.proto

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,6 @@ message SocketConfig {
124124
// option. This option is for UDP only.
125125
bool receive_original_dest_address = 4;
126126

127-
bytes bind_address = 5;
128-
129-
uint32 bind_port = 6;
130-
131127
bool accept_proxy_protocol = 7;
132128

133129
DomainStrategy domain_strategy = 8;

transport/internet/hysteria/dialer.go

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package hysteria
33
import (
44
"context"
55
go_tls "crypto/tls"
6+
"math/rand"
67
"net/http"
78
"net/url"
89
"reflect"
@@ -64,7 +65,7 @@ func (c *client) close() {
6465
c.udpSM = nil
6566
}
6667

67-
func (c *client) dial() error {
68+
func (c *client) dial(ctx context.Context) error {
6869
status := c.status()
6970
if status == StatusActive {
7071
return nil
@@ -113,30 +114,54 @@ func (c *client) dial() error {
113114
// quicConfig.KeepAlivePeriod = 10 * time.Second
114115
// }
115116

117+
udpHopDialer := func(addr *net.UDPAddr) (net.PacketConn, error) {
118+
conn, err := internet.DialSystem(ctx, net.UDPDestination(net.IPAddress(addr.IP), net.Port(addr.Port)), c.socketConfig)
119+
if err != nil {
120+
errors.LogInfoInner(context.Background(), err, "skip hop: failed to dial to dest")
121+
return nil, errors.New("")
122+
}
123+
124+
var pktConn net.PacketConn
125+
126+
switch c := conn.(type) {
127+
case *internet.PacketConnWrapper:
128+
pktConn = c.PacketConn
129+
default:
130+
panic(reflect.TypeOf(c))
131+
}
132+
133+
return pktConn, nil
134+
}
135+
116136
var pktConn net.PacketConn
117137
var udpAddr *net.UDPAddr
118-
var err error
119-
udpAddr, err = net.ResolveUDPAddr("udp", c.dest.NetAddr())
120-
if err != nil {
121-
return err
122-
}
123138
if len(quicParams.UdpHop.Ports) > 0 {
124-
pktConn, err = udphop.NewUDPHopPacketConn(udphop.ToAddrs(udpAddr.IP, quicParams.UdpHop.Ports), time.Duration(quicParams.UdpHop.IntervalMin)*time.Second, time.Duration(quicParams.UdpHop.IntervalMax)*time.Second, c.udpHopDialer)
139+
index := rand.Intn(len(quicParams.UdpHop.Ports))
140+
c.dest.Port = net.Port(quicParams.UdpHop.Ports[index])
141+
conn, err := internet.DialSystem(ctx, c.dest, c.socketConfig)
125142
if err != nil {
126-
return err
143+
return errors.New("failed to dial to dest").Base(err)
127144
}
145+
switch c := conn.(type) {
146+
case *internet.PacketConnWrapper:
147+
pktConn = c.PacketConn
148+
udpAddr = conn.RemoteAddr().(*net.UDPAddr)
149+
default:
150+
panic(reflect.TypeOf(c))
151+
}
152+
pktConn = udphop.NewUDPHopPacketConn(udphop.ToAddrs(udpAddr.IP, quicParams.UdpHop.Ports), time.Duration(quicParams.UdpHop.IntervalMin)*time.Second, time.Duration(quicParams.UdpHop.IntervalMax)*time.Second, udpHopDialer, pktConn, index)
128153
} else {
129-
conn, err := internet.DialSystem(context.Background(), c.dest, c.socketConfig)
154+
conn, err := internet.DialSystem(ctx, c.dest, c.socketConfig)
130155
if err != nil {
131-
return err
156+
return errors.New("failed to dial to dest").Base(err)
132157
}
133158
switch c := conn.(type) {
134159
case *internet.PacketConnWrapper:
135160
pktConn = c.PacketConn
136-
case *net.UDPConn:
137-
pktConn = c
161+
udpAddr = c.RemoteAddr().(*net.UDPAddr)
138162
case *cnc.Connection:
139163
pktConn = &internet.FakePacketConn{Conn: c}
164+
udpAddr = &net.UDPAddr{IP: c.RemoteAddr().(*net.TCPAddr).IP, Port: c.RemoteAddr().(*net.TCPAddr).Port}
140165
default:
141166
panic(reflect.TypeOf(c))
142167
}
@@ -228,11 +253,11 @@ func (c *client) dial() error {
228253
return nil
229254
}
230255

231-
func (c *client) tcp() (stat.Connection, error) {
256+
func (c *client) tcp(ctx context.Context) (stat.Connection, error) {
232257
c.Lock()
233258
defer c.Unlock()
234259

235-
err := c.dial()
260+
err := c.dial(ctx)
236261
if err != nil {
237262
return nil, err
238263
}
@@ -251,11 +276,11 @@ func (c *client) tcp() (stat.Connection, error) {
251276
}, nil
252277
}
253278

254-
func (c *client) udp() (stat.Connection, error) {
279+
func (c *client) udp(ctx context.Context) (stat.Connection, error) {
255280
c.Lock()
256281
defer c.Unlock()
257282

258-
err := c.dial()
283+
err := c.dial(ctx)
259284
if err != nil {
260285
return nil, err
261286
}
@@ -271,29 +296,6 @@ func (c *client) clean() {
271296
c.Unlock()
272297
}
273298

274-
func (c *client) udpHopDialer(addr *net.UDPAddr) (net.PacketConn, error) {
275-
conn, err := internet.DialSystem(context.Background(), net.UDPDestination(net.IPAddress(addr.IP), net.Port(addr.Port)), c.socketConfig)
276-
if err != nil {
277-
errors.LogInfoInner(context.Background(), err, "skip hop: failed to dial to dest")
278-
return nil, errors.New("failed to dial to dest").Base(err)
279-
}
280-
281-
var pktConn net.PacketConn
282-
283-
switch c := conn.(type) {
284-
case *internet.PacketConnWrapper:
285-
pktConn = c.PacketConn
286-
case *net.UDPConn:
287-
pktConn = c
288-
default:
289-
errors.LogInfo(context.Background(), "skip hop: invalid conn ", reflect.TypeOf(c))
290-
conn.Close()
291-
return nil, errors.New("invalid conn ", reflect.TypeOf(c))
292-
}
293-
294-
return pktConn, nil
295-
}
296-
297299
type dialerConf struct {
298300
net.Destination
299301
*internet.MemoryStreamConfig
@@ -356,9 +358,9 @@ func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.Me
356358
}
357359

358360
if datagram {
359-
return c.udp()
361+
return c.udp(ctx)
360362
}
361-
return c.tcp()
363+
return c.tcp(ctx)
362364
}
363365

364366
func init() {

transport/internet/hysteria/udphop/conn.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ type udpPacket struct {
4747
Err error
4848
}
4949

50-
func NewUDPHopPacketConn(addrs []net.Addr, hopIntervalMin time.Duration, hopIntervalMax time.Duration, listenUDPFunc func(addr *net.UDPAddr) (net.PacketConn, error)) (net.PacketConn, error) {
50+
func NewUDPHopPacketConn(addrs []net.Addr, hopIntervalMin time.Duration, hopIntervalMax time.Duration, listenUDPFunc func(addr *net.UDPAddr) (net.PacketConn, error), currentConn net.PacketConn, addrIndex int) net.PacketConn {
5151
if len(addrs) == 0 {
5252
panic("len(addrs) == 0")
5353
}
@@ -75,8 +75,8 @@ func NewUDPHopPacketConn(addrs []net.Addr, hopIntervalMin time.Duration, hopInte
7575
HopIntervalMax: hopIntervalMax,
7676
ListenUDPFunc: listenUDPFunc,
7777
prevConn: nil,
78-
currentConn: nil,
79-
addrIndex: rand.Intn(len(addrs)),
78+
currentConn: currentConn,
79+
addrIndex: addrIndex,
8080
recvQueue: make(chan *udpPacket, packetQueueSize),
8181
closeChan: make(chan struct{}),
8282
bufPool: sync.Pool{
@@ -85,14 +85,9 @@ func NewUDPHopPacketConn(addrs []net.Addr, hopIntervalMin time.Duration, hopInte
8585
},
8686
},
8787
}
88-
var err error
89-
hConn.currentConn, err = listenUDPFunc(hConn.Addrs[hConn.addrIndex].(*net.UDPAddr))
90-
if err != nil {
91-
return nil, err
92-
}
9388
go hConn.recvLoop(hConn.currentConn)
9489
go hConn.hopLoop()
95-
return hConn, nil
90+
return hConn
9691
}
9792

9893
func (u *UdpHopPacketConn) recvLoop(conn net.PacketConn) {

transport/internet/kcp/dialer.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ func DialKCP(ctx context.Context, dest net.Destination, streamSettings *internet
5858

5959
if streamSettings.UdpmaskManager != nil {
6060
var pktConn net.PacketConn
61-
var udpAddr = conn.RemoteAddr().(*net.UDPAddr)
61+
var udpAddr *net.UDPAddr
6262
switch c := conn.(type) {
6363
case *internet.PacketConnWrapper:
6464
pktConn = c.PacketConn
65-
case *net.UDPConn:
66-
pktConn = c
65+
udpAddr = c.RemoteAddr().(*net.UDPAddr)
6766
case *cnc.Connection:
6867
pktConn = &internet.FakePacketConn{Conn: c}
68+
udpAddr = &net.UDPAddr{IP: c.RemoteAddr().(*net.TCPAddr).IP, Port: c.RemoteAddr().(*net.TCPAddr).Port}
6969
default:
7070
panic(reflect.TypeOf(c))
7171
}

transport/internet/sockopt_darwin.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -288,32 +288,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
288288
return nil
289289
}
290290

291-
func bindAddr(fd uintptr, address []byte, port uint32) error {
292-
setReuseAddr(fd)
293-
setReusePort(fd)
294-
295-
var sockaddr unix.Sockaddr
296-
297-
switch len(address) {
298-
case net.IPv4len:
299-
a4 := &unix.SockaddrInet4{
300-
Port: int(port),
301-
}
302-
copy(a4.Addr[:], address)
303-
sockaddr = a4
304-
case net.IPv6len:
305-
a6 := &unix.SockaddrInet6{
306-
Port: int(port),
307-
}
308-
copy(a6.Addr[:], address)
309-
sockaddr = a6
310-
default:
311-
return errors.New("unexpected length of ip")
312-
}
313-
314-
return unix.Bind(int(fd), sockaddr)
315-
}
316-
317291
func setReuseAddr(fd uintptr) error {
318292
if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
319293
return errors.New("failed to set SO_REUSEADDR").Base(err).AtWarning()

transport/internet/sockopt_freebsd.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -222,32 +222,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
222222
return nil
223223
}
224224

225-
func bindAddr(fd uintptr, ip []byte, port uint32) error {
226-
setReuseAddr(fd)
227-
setReusePort(fd)
228-
229-
var sockaddr syscall.Sockaddr
230-
231-
switch len(ip) {
232-
case net.IPv4len:
233-
a4 := &syscall.SockaddrInet4{
234-
Port: int(port),
235-
}
236-
copy(a4.Addr[:], ip)
237-
sockaddr = a4
238-
case net.IPv6len:
239-
a6 := &syscall.SockaddrInet6{
240-
Port: int(port),
241-
}
242-
copy(a6.Addr[:], ip)
243-
sockaddr = a6
244-
default:
245-
return errors.New("unexpected length of ip")
246-
}
247-
248-
return syscall.Bind(int(fd), sockaddr)
249-
}
250-
251225
func setReuseAddr(fd uintptr) error {
252226
if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
253227
return errors.New("failed to set SO_REUSEADDR").Base(err).AtWarning()

transport/internet/sockopt_linux.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package internet
22

33
import (
44
"context"
5-
"net"
65
"runtime"
76
"strconv"
87
"strings"
@@ -12,32 +11,6 @@ import (
1211
"golang.org/x/sys/unix"
1312
)
1413

15-
func bindAddr(fd uintptr, ip []byte, port uint32) error {
16-
setReuseAddr(fd)
17-
setReusePort(fd)
18-
19-
var sockaddr syscall.Sockaddr
20-
21-
switch len(ip) {
22-
case net.IPv4len:
23-
a4 := &syscall.SockaddrInet4{
24-
Port: int(port),
25-
}
26-
copy(a4.Addr[:], ip)
27-
sockaddr = a4
28-
case net.IPv6len:
29-
a6 := &syscall.SockaddrInet6{
30-
Port: int(port),
31-
}
32-
copy(a6.Addr[:], ip)
33-
sockaddr = a6
34-
default:
35-
return errors.New("unexpected length of ip")
36-
}
37-
38-
return syscall.Bind(int(fd), sockaddr)
39-
}
40-
4114
// applyOutboundSocketOptions applies socket options for outbound connection.
4215
// note that unlike other part of Xray, this function needs network with speified network stack(tcp4/tcp6/udp4/udp6)
4316
func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error {

transport/internet/sockopt_other.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
1111
return nil
1212
}
1313

14-
func bindAddr(fd uintptr, ip []byte, port uint32) error {
15-
return nil
16-
}
17-
1814
func setReuseAddr(fd uintptr) error {
1915
return nil
2016
}

transport/internet/sockopt_windows.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
181181
return nil
182182
}
183183

184-
func bindAddr(fd uintptr, ip []byte, port uint32) error {
185-
return nil
186-
}
187-
188184
func setReuseAddr(fd uintptr) error {
189185
return nil
190186
}

0 commit comments

Comments
 (0)