diff --git a/cmd/gost/route.go b/cmd/gost/route.go index 434d6e3..7ececfb 100644 --- a/cmd/gost/route.go +++ b/cmd/gost/route.go @@ -438,6 +438,7 @@ func (r *route) GenRouters() ([]router, error) { gost.RetryHandlerOption(node.GetInt("retry")), // override the global retry option. gost.TimeoutHandlerOption(time.Duration(node.GetInt("timeout"))*time.Second), gost.ProbeResistHandlerOption(node.Get("probe_resist")), + gost.KnockingHandlerOption(node.Get("knock")), gost.NodeHandlerOption(node), gost.IPsHandlerOption(ips), ) diff --git a/handler.go b/handler.go index 568c341..b0521fe 100644 --- a/handler.go +++ b/handler.go @@ -34,6 +34,7 @@ type HandlerOptions struct { Resolver Resolver Hosts *Hosts ProbeResist string + KnockingHost string Node Node Host string IPs []string @@ -150,6 +151,13 @@ func ProbeResistHandlerOption(pr string) HandlerOption { } } +// KnockingHandlerOption adds the knocking host for probe resistance. +func KnockingHandlerOption(host string) HandlerOption { + return func(opts *HandlerOptions) { + opts.KnockingHost = host + } +} + // NodeHandlerOption set the server node for server handler. func NodeHandlerOption(node Node) HandlerOption { return func(opts *HandlerOptions) { diff --git a/http.go b/http.go index 75913d7..a9de1f5 100644 --- a/http.go +++ b/http.go @@ -302,8 +302,9 @@ func (h *httpHandler) authenticate(conn net.Conn, req *http.Request, resp *http. return true } - // probing resistance is enabled - if ss := strings.SplitN(h.options.ProbeResist, ":", 2); len(ss) == 2 { + // probing resistance is enabled, and knocking host is mismatch. + if ss := strings.SplitN(h.options.ProbeResist, ":", 2); len(ss) == 2 && + (h.options.KnockingHost == "" || !strings.EqualFold(req.URL.Hostname(), h.options.KnockingHost)) { resp.StatusCode = http.StatusServiceUnavailable // default status code switch ss[0] { diff --git a/http2.go b/http2.go index a750b89..ff72480 100644 --- a/http2.go +++ b/http2.go @@ -461,8 +461,9 @@ func (h *http2Handler) authenticate(w http.ResponseWriter, r *http.Request, resp return true } - // probing resistance is enabled - if ss := strings.SplitN(h.options.ProbeResist, ":", 2); len(ss) == 2 { + // probing resistance is enabled, and knocking host is mismatch. + if ss := strings.SplitN(h.options.ProbeResist, ":", 2); len(ss) == 2 && + (h.options.KnockingHost == "" || !strings.EqualFold(r.URL.Hostname(), h.options.KnockingHost)) { resp.StatusCode = http.StatusServiceUnavailable // default status code w.Header().Del("Proxy-Agent")