diff --git a/internal/nodes/listener_tcp.go b/internal/nodes/listener_tcp.go index fbfbb54..0bd93ec 100644 --- a/internal/nodes/listener_tcp.go +++ b/internal/nodes/listener_tcp.go @@ -231,8 +231,17 @@ func (this *TCPListener) connectOrigin(serverId int64, requestHost string, rever var retries = 3 var addr string + + var failedOriginIds []int64 + for i := 0; i < retries; i++ { - var origin = reverseProxy.NextOrigin(requestCall) + var origin *serverconfigs.OriginConfig + if len(failedOriginIds) > 0 { + origin = reverseProxy.AnyOrigin(requestCall, failedOriginIds) + } + if origin == nil { + origin = reverseProxy.NextOrigin(requestCall) + } if origin == nil { continue } @@ -246,6 +255,8 @@ func (this *TCPListener) connectOrigin(serverId int64, requestHost string, rever conn, addr, err = OriginConnect(origin, this.port, remoteAddr, requestHost) if err != nil { + failedOriginIds = append(failedOriginIds, origin.Id) + remotelogs.ServerError(serverId, "TCP_LISTENER", "unable to connect origin server: "+addr+": "+err.Error(), "", nil) SharedOriginStateManager.Fail(origin, requestHost, reverseProxy, func() { @@ -263,7 +274,10 @@ func (this *TCPListener) connectOrigin(serverId int64, requestHost string, rever return } } - err = errors.New("server '" + types.String(serverId) + "': no available origin server can be used") + + if err == nil { + err = errors.New("server '" + types.String(serverId) + "': no available origin server can be used") + } return } diff --git a/internal/nodes/listener_udp.go b/internal/nodes/listener_udp.go index 491c73d..aedf025 100644 --- a/internal/nodes/listener_udp.go +++ b/internal/nodes/listener_udp.go @@ -139,16 +139,39 @@ func (this *UDPListener) connectOrigin(serverId int64, reverseProxy *serverconfi var retries = 3 var addr string + + var failedOriginIds []int64 + for i := 0; i < retries; i++ { - var origin = reverseProxy.NextOrigin(nil) + var origin *serverconfigs.OriginConfig + if len(failedOriginIds) > 0 { + origin = reverseProxy.AnyOrigin(nil, failedOriginIds) + } + if origin == nil { + origin = reverseProxy.NextOrigin(nil) + } if origin == nil { continue } + conn, addr, err = OriginConnect(origin, this.port, remoteAddr.String(), "") if err != nil { + failedOriginIds = append(failedOriginIds, origin.Id) + remotelogs.ServerError(serverId, "UDP_LISTENER", "unable to connect origin server: "+addr+": "+err.Error(), "", nil) + + SharedOriginStateManager.Fail(origin, "", reverseProxy, func() { + reverseProxy.ResetScheduling() + }) + continue } else { + if !origin.IsOk { + SharedOriginStateManager.Success(origin, func() { + reverseProxy.ResetScheduling() + }) + } + // PROXY Protocol if reverseProxy != nil && reverseProxy.ProxyProtocol != nil && @@ -175,7 +198,10 @@ func (this *UDPListener) connectOrigin(serverId int64, reverseProxy *serverconfi return } } - err = errors.New("server '" + types.String(serverId) + "': no available origin server can be used") + + if err == nil { + err = errors.New("server '" + types.String(serverId) + "': no available origin server can be used") + } return }