mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-12 20:03:38 +00:00
Reconnect once if hysteria request fails
This allows graceful recovery when network isn't good enough.
[Original hysteria source
code](13d46da998/core/cs/client.go (L182)
)
has similar mechanism.
This commit is contained in:
parent
3c2c9cf317
commit
597248130f
|
@ -150,6 +150,7 @@ func (h *Hysteria) offer(ctx context.Context) (quic.Connection, error) {
|
||||||
if conn != nil && !common.Done(conn.Context()) {
|
if conn != nil && !common.Done(conn.Context()) {
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
common.Close(h.rawConn)
|
||||||
conn, err := h.offerNew(ctx)
|
conn, err := h.offerNew(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -260,14 +261,18 @@ func (h *Hysteria) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Hysteria) open(ctx context.Context) (quic.Connection, quic.Stream, error) {
|
func (h *Hysteria) open(ctx context.Context, reconnect bool) (quic.Connection, quic.Stream, error) {
|
||||||
conn, err := h.offer(ctx)
|
conn, err := h.offer(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect {
|
||||||
|
return h.open(ctx, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stream, err := conn.OpenStream()
|
stream, err := conn.OpenStream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
if nErr, ok := err.(net.Error); ok && !nErr.Temporary() && reconnect {
|
||||||
|
return h.open(ctx, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return conn, &hysteria.StreamWrapper{Stream: stream}, nil
|
return conn, &hysteria.StreamWrapper{Stream: stream}, nil
|
||||||
}
|
}
|
||||||
|
@ -276,7 +281,7 @@ func (h *Hysteria) DialContext(ctx context.Context, network string, destination
|
||||||
switch N.NetworkName(network) {
|
switch N.NetworkName(network) {
|
||||||
case N.NetworkTCP:
|
case N.NetworkTCP:
|
||||||
h.logger.InfoContext(ctx, "outbound connection to ", destination)
|
h.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||||
_, stream, err := h.open(ctx)
|
_, stream, err := h.open(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -302,7 +307,7 @@ func (h *Hysteria) DialContext(ctx context.Context, network string, destination
|
||||||
|
|
||||||
func (h *Hysteria) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
func (h *Hysteria) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||||
conn, stream, err := h.open(ctx)
|
conn, stream, err := h.open(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue