@@ -3,6 +3,7 @@ package hysteria
33import (
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-
297299type 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
364366func init () {
0 commit comments