mirror of
https://github.com/cmz0228/hysteria-dev.git
synced 2025-06-09 13:59:54 +00:00
fix: incorrect reconnect logic that causes blocking when dialing connections
This commit is contained in:
parent
e648321b96
commit
84b54eb702
@ -58,53 +58,61 @@ func (rc *reconnectableClientImpl) reconnect() error {
|
|||||||
|
|
||||||
func (rc *reconnectableClientImpl) TCP(addr string) (net.Conn, error) {
|
func (rc *reconnectableClientImpl) TCP(addr string) (net.Conn, error) {
|
||||||
rc.m.Lock()
|
rc.m.Lock()
|
||||||
defer rc.m.Unlock()
|
|
||||||
if rc.closed {
|
if rc.closed {
|
||||||
|
rc.m.Unlock()
|
||||||
return nil, coreErrs.ClosedError{}
|
return nil, coreErrs.ClosedError{}
|
||||||
}
|
}
|
||||||
if rc.client == nil {
|
if rc.client == nil {
|
||||||
// No active connection, connect first
|
// No active connection, connect first
|
||||||
if err := rc.reconnect(); err != nil {
|
if err := rc.reconnect(); err != nil {
|
||||||
|
rc.m.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn, err := rc.client.TCP(addr)
|
client := rc.client
|
||||||
|
rc.m.Unlock()
|
||||||
|
|
||||||
|
conn, err := client.TCP(addr)
|
||||||
if _, ok := err.(coreErrs.ClosedError); ok {
|
if _, ok := err.(coreErrs.ClosedError); ok {
|
||||||
// Connection closed, reconnect
|
// Connection closed, set client to nil for reconnect next time
|
||||||
if err := rc.reconnect(); err != nil {
|
rc.m.Lock()
|
||||||
return nil, err
|
// In case the client has already been reconnected by another goroutine
|
||||||
|
if rc.client == client {
|
||||||
|
rc.client = nil
|
||||||
|
}
|
||||||
|
rc.m.Unlock()
|
||||||
}
|
}
|
||||||
return rc.client.TCP(addr)
|
|
||||||
} else {
|
|
||||||
// OK or some other temporary error
|
|
||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *reconnectableClientImpl) UDP() (HyUDPConn, error) {
|
func (rc *reconnectableClientImpl) UDP() (HyUDPConn, error) {
|
||||||
rc.m.Lock()
|
rc.m.Lock()
|
||||||
defer rc.m.Unlock()
|
|
||||||
if rc.closed {
|
if rc.closed {
|
||||||
|
rc.m.Unlock()
|
||||||
return nil, coreErrs.ClosedError{}
|
return nil, coreErrs.ClosedError{}
|
||||||
}
|
}
|
||||||
if rc.client == nil {
|
if rc.client == nil {
|
||||||
// No active connection, connect first
|
// No active connection, connect first
|
||||||
if err := rc.reconnect(); err != nil {
|
if err := rc.reconnect(); err != nil {
|
||||||
|
rc.m.Unlock()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn, err := rc.client.UDP()
|
client := rc.client
|
||||||
|
rc.m.Unlock()
|
||||||
|
|
||||||
|
conn, err := client.UDP()
|
||||||
if _, ok := err.(coreErrs.ClosedError); ok {
|
if _, ok := err.(coreErrs.ClosedError); ok {
|
||||||
// Connection closed, reconnect
|
// Connection closed, set client to nil for reconnect next time
|
||||||
if err := rc.reconnect(); err != nil {
|
rc.m.Lock()
|
||||||
return nil, err
|
// In case the client has already been reconnected by another goroutine
|
||||||
|
if rc.client == client {
|
||||||
|
rc.client = nil
|
||||||
|
}
|
||||||
|
rc.m.Unlock()
|
||||||
}
|
}
|
||||||
return rc.client.UDP()
|
|
||||||
} else {
|
|
||||||
// OK or some other temporary error
|
|
||||||
return conn, err
|
return conn, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (rc *reconnectableClientImpl) Close() error {
|
func (rc *reconnectableClientImpl) Close() error {
|
||||||
rc.m.Lock()
|
rc.m.Lock()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user