mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-06-03 06:30:42 +00:00
2c5a714903
* generate .pb.go * health checker conf * check logic * implement ping * fix check interval * improve check results * health check on add outbounds * fix tests * fix ping handler * fix min rtt < 0 * random alive * fix check all on add outbounds * least load strategy * conf codes optimize * improve least load strategy * improve health check on AddOutboundHandler * cleanup results with scheduler code optimize * health ping timeout default 5s * remove config of health ping round round 1 seems to be good enough * fix TestSimpleBalancer * add TestLeastLoadBalancer * add todos * lint and test fix * balancer fallback * api health stats command * add hc cmd to perform health checks * rename 'health stats' cmd to hci * many code optimizations * fix typo * select none if no match for baselines only config > prev 'select 1' behavior can achieved by baselines+expected=1 * add LeastLoadStrategy tests * don't select alive on no match, go to fallback * api hci refactor * more detailed info * ready for future new strategies * apply lint style * refactor: strategies don't need ref of balancer * change check interval unit to seconds > to reduce influence caused by what is described by new added FIXME * fix test * RouterService->RoutingService * Revert "generate .pb.go" This reverts commit 0e6fa1be889470d0ad9692f7279da45c030e1919. * make checks distributed > but `api hc` is the exception * BalancingStrategy interface optimize * fix random selects unchecked * upgrade cmd hci to bi & rename hc to bc * bi shows all balancers, while hci shows only heath-check-enabled ones * shows more info * fix test * api bi sort output * update according to review * remove checks on add outbound * refactor: move health checker inside to strategy * enables rounds setting for health ping * restore the random behavior, no ping, no pick alive > if future strategy based on HealthPing, just embed it like what LeastLoad does * apply lint style * code optimize * fix typo * update desc of bc bi * ping with head code optimize * force rouds to 1 if checks not distributed * leatload: select by standard deviations * health ping refactor * continuously applying results * config is easier to understand * checker interfaces simplifying * add maxRTT config to filter away high delay nodes * apply lint * cost for leastload * api bo to override balancer selecting * fix health ping statistics & fix test * check connectivity if ping fail * add tolerance setting & more detailed bi output * fix connectivity check * optimize bi output * should not put results when network is down * fixes @_@ * mux optimize * remove pause option of selecting overriding > it causes data racing * update bo desc * fix potential racing * simplify locking * switch sync.Mutex to avoid potential racing * add more tests * code optimize * code optimize * fix connectivity check when url not set
82 lines
1.9 KiB
Go
82 lines
1.9 KiB
Go
package router
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
"v2ray.com/core/common/net"
|
|
"v2ray.com/core/common/session"
|
|
"v2ray.com/core/features/routing"
|
|
)
|
|
|
|
type pingClient struct {
|
|
destination string
|
|
httpClient *http.Client
|
|
}
|
|
|
|
func newPingClient(destination string, timeout time.Duration, handler string, dispatcher routing.Dispatcher) *pingClient {
|
|
return &pingClient{
|
|
destination: destination,
|
|
httpClient: newHTTPClient(handler, dispatcher, timeout),
|
|
}
|
|
}
|
|
|
|
func newDirectPingClient(destination string, timeout time.Duration) *pingClient {
|
|
return &pingClient{
|
|
destination: destination,
|
|
httpClient: &http.Client{Timeout: timeout},
|
|
}
|
|
}
|
|
|
|
func newHTTPClient(handler string, dispatcher routing.Dispatcher, timeout time.Duration) *http.Client {
|
|
tr := &http.Transport{
|
|
DisableKeepAlives: true,
|
|
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
|
dest, err := net.ParseDestination(network + ":" + addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
h := &session.Handler{
|
|
Tag: handler,
|
|
}
|
|
ctx = session.ContextWithHandler(ctx, h)
|
|
link, err := dispatcher.Dispatch(ctx, dest)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return net.NewConnection(
|
|
net.ConnectionInputMulti(link.Writer),
|
|
net.ConnectionOutputMulti(link.Reader),
|
|
), nil
|
|
},
|
|
}
|
|
return &http.Client{
|
|
Transport: tr,
|
|
Timeout: timeout,
|
|
// don't follow redirect
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
return http.ErrUseLastResponse
|
|
},
|
|
}
|
|
}
|
|
|
|
// MeasureDelay returns the delay time of the request to dest
|
|
func (s *pingClient) MeasureDelay() (time.Duration, error) {
|
|
if s.httpClient == nil {
|
|
panic("pingClient no initialized")
|
|
}
|
|
req, err := http.NewRequest(http.MethodHead, s.destination, nil)
|
|
if err != nil {
|
|
return rttFailed, err
|
|
}
|
|
start := time.Now()
|
|
resp, err := s.httpClient.Do(req)
|
|
if err != nil {
|
|
return rttFailed, err
|
|
}
|
|
// don't wait for body
|
|
resp.Body.Close()
|
|
return time.Since(start), nil
|
|
}
|