Skip to content

Commit 4af24e9

Browse files
hossinasaadiLjhAUMEM
authored andcommitted
Hysteria client: Prevent panic on cnc.Connection (#6320)
Fixes #6320 (comment) --------- Co-authored-by: LjhAUMEM <llnu14702@gmail.com>
1 parent 8626311 commit 4af24e9

3 files changed

Lines changed: 49 additions & 67 deletions

File tree

transport/internet/hysteria/dialer.go

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ func (c *client) dial(ctx context.Context) error {
126126
switch c := conn.(type) {
127127
case *internet.PacketConnWrapper:
128128
pktConn = c.PacketConn
129+
case *cnc.Connection:
130+
pktConn = &internet.FakePacketConn{Conn: c}
129131
default:
130132
panic(reflect.TypeOf(c))
131133
}
@@ -135,36 +137,30 @@ func (c *client) dial(ctx context.Context) error {
135137

136138
var pktConn net.PacketConn
137139
var udpAddr *net.UDPAddr
140+
var index int
141+
138142
if len(quicParams.UdpHop.Ports) > 0 {
139-
index := rand.Intn(len(quicParams.UdpHop.Ports))
143+
index = rand.Intn(len(quicParams.UdpHop.Ports))
140144
c.dest.Port = net.Port(quicParams.UdpHop.Ports[index])
141-
conn, err := internet.DialSystem(ctx, c.dest, c.socketConfig)
142-
if err != nil {
143-
return errors.New("failed to dial to dest").Base(err)
144-
}
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-
}
145+
}
146+
147+
raw, err := internet.DialSystem(ctx, c.dest, c.socketConfig)
148+
if err != nil {
149+
return errors.New("failed to dial to dest").Base(err)
150+
}
151+
switch c := raw.(type) {
152+
case *internet.PacketConnWrapper:
153+
pktConn = c.PacketConn
154+
udpAddr = raw.RemoteAddr().(*net.UDPAddr)
155+
case *cnc.Connection:
156+
pktConn = &internet.FakePacketConn{Conn: c}
157+
udpAddr = &net.UDPAddr{IP: c.RemoteAddr().(*net.TCPAddr).IP, Port: c.RemoteAddr().(*net.TCPAddr).Port}
158+
default:
159+
panic(reflect.TypeOf(c))
160+
}
161+
162+
if len(quicParams.UdpHop.Ports) > 0 {
152163
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)
153-
} else {
154-
conn, err := internet.DialSystem(ctx, c.dest, c.socketConfig)
155-
if err != nil {
156-
return errors.New("failed to dial to dest").Base(err)
157-
}
158-
switch c := conn.(type) {
159-
case *internet.PacketConnWrapper:
160-
pktConn = c.PacketConn
161-
udpAddr = c.RemoteAddr().(*net.UDPAddr)
162-
case *cnc.Connection:
163-
pktConn = &internet.FakePacketConn{Conn: c}
164-
udpAddr = &net.UDPAddr{IP: c.RemoteAddr().(*net.TCPAddr).IP, Port: c.RemoteAddr().(*net.TCPAddr).Port}
165-
default:
166-
panic(reflect.TypeOf(c))
167-
}
168164
}
169165

170166
if c.udpmaskManager != nil {

transport/internet/hysteria/udphop/conn.go

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"math/rand"
66
"net"
77
"sync"
8-
"syscall"
98
"time"
109

1110
"github.com/xtls/xray-core/transport/internet/finalmask"
@@ -138,15 +137,16 @@ func (u *UdpHopPacketConn) hop() {
138137
if u.closed {
139138
return
140139
}
141-
u.addrIndex = rand.Intn(len(u.Addrs))
142-
newConn, err := u.ListenUDPFunc(u.Addrs[u.addrIndex].(*net.UDPAddr))
140+
addrIndex := rand.Intn(len(u.Addrs))
141+
newConn, err := u.ListenUDPFunc(u.Addrs[addrIndex].(*net.UDPAddr))
143142
if err != nil {
144143
return
145144
}
146145
if u.prevConn != nil {
147146
_ = u.prevConn.Close()
148147
}
149148
u.prevConn = u.currentConn
149+
u.addrIndex = addrIndex
150150
u.currentConn = newConn
151151
if !u.deadline.IsZero() {
152152
_ = u.currentConn.SetDeadline(u.deadline)
@@ -241,16 +241,6 @@ func (u *UdpHopPacketConn) SetWriteDeadline(t time.Time) error {
241241
return u.currentConn.SetWriteDeadline(t)
242242
}
243243

244-
func (u *UdpHopPacketConn) SyscallConn() (syscall.RawConn, error) {
245-
u.connMutex.RLock()
246-
defer u.connMutex.RUnlock()
247-
sc, ok := u.currentConn.(syscall.Conn)
248-
if !ok {
249-
return nil, errors.New("not supported")
250-
}
251-
return sc.SyscallConn()
252-
}
253-
254244
func ToAddrs(ip net.IP, ports []uint32) []net.Addr {
255245
var addrs []net.Addr
256246
for _, port := range ports {

transport/internet/splithttp/dialer.go

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
209209
switch c := conn.(type) {
210210
case *internet.PacketConnWrapper:
211211
pktConn = c.PacketConn
212+
case *cnc.Connection:
213+
pktConn = &internet.FakePacketConn{Conn: c}
212214
default:
213215
panic(reflect.TypeOf(c))
214216
}
@@ -218,36 +220,30 @@ func createHTTPClient(dest net.Destination, streamSettings *internet.MemoryStrea
218220

219221
var pktConn net.PacketConn
220222
var udpAddr *net.UDPAddr
223+
var index int
224+
221225
if len(quicParams.UdpHop.Ports) > 0 {
222-
index := rand.Intn(len(quicParams.UdpHop.Ports))
226+
index = rand.Intn(len(quicParams.UdpHop.Ports))
223227
dest.Port = net.Port(quicParams.UdpHop.Ports[index])
224-
conn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
225-
if err != nil {
226-
return nil, errors.New("failed to dial to dest").Base(err)
227-
}
228-
switch c := conn.(type) {
229-
case *internet.PacketConnWrapper:
230-
pktConn = c.PacketConn
231-
udpAddr = conn.RemoteAddr().(*net.UDPAddr)
232-
default:
233-
panic(reflect.TypeOf(c))
234-
}
228+
}
229+
230+
raw, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
231+
if err != nil {
232+
return nil, errors.New("failed to dial to dest").Base(err)
233+
}
234+
switch c := raw.(type) {
235+
case *internet.PacketConnWrapper:
236+
pktConn = c.PacketConn
237+
udpAddr = raw.RemoteAddr().(*net.UDPAddr)
238+
case *cnc.Connection:
239+
pktConn = &internet.FakePacketConn{Conn: c}
240+
udpAddr = &net.UDPAddr{IP: c.RemoteAddr().(*net.TCPAddr).IP, Port: c.RemoteAddr().(*net.TCPAddr).Port}
241+
default:
242+
panic(reflect.TypeOf(c))
243+
}
244+
245+
if len(quicParams.UdpHop.Ports) > 0 {
235246
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)
236-
} else {
237-
conn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
238-
if err != nil {
239-
return nil, errors.New("failed to dial to dest").Base(err)
240-
}
241-
switch c := conn.(type) {
242-
case *internet.PacketConnWrapper:
243-
pktConn = c.PacketConn
244-
udpAddr = c.RemoteAddr().(*net.UDPAddr)
245-
case *cnc.Connection:
246-
pktConn = &internet.FakePacketConn{Conn: c}
247-
udpAddr = &net.UDPAddr{IP: c.RemoteAddr().(*net.TCPAddr).IP, Port: c.RemoteAddr().(*net.TCPAddr).Port}
248-
default:
249-
panic(reflect.TypeOf(c))
250-
}
251247
}
252248

253249
if streamSettings.UdpmaskManager != nil {

0 commit comments

Comments
 (0)