mirror of
https://github.com/fatedier/frp.git
synced 2026-10-20 00:53:28 +08:00
fix: release listeners when frps fails to start (#5574)
A constructor that binds a port before its fallible preparation leaks the listener when a later step returns an error, and no one can close it because the returned service is nil. pkg/util/http: load the TLS keypair and build the auth middleware before net.Listen, so binding is the last step that can run and a failure leaves no bound port behind. server: create the web server after auth, the tcpmux, main, kcp, quic, ssh gateway and vhost listeners, and the nat hole controller, following what frpc already does. If the web server itself fails, close the resources created so far before returning. The port managers start their cleanup workers on creation, so they are created after every fallible step too, and the metrics collectors keep being enabled only when the web server is configured. Add regression tests for all three failure paths.
This commit is contained in:
@@ -53,11 +53,6 @@ func NewServer(cfg v1.WebServerConfig) (*Server, error) {
|
||||
addr = ":http"
|
||||
}
|
||||
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
hs := &http.Server{
|
||||
Addr: addr,
|
||||
@@ -67,7 +62,6 @@ func NewServer(cfg v1.WebServerConfig) (*Server, error) {
|
||||
}
|
||||
s := &Server{
|
||||
addr: addr,
|
||||
ln: ln,
|
||||
hs: hs,
|
||||
router: router,
|
||||
}
|
||||
@@ -84,6 +78,13 @@ func NewServer(cfg v1.WebServerConfig) (*Server, error) {
|
||||
}
|
||||
}
|
||||
s.authMiddleware = netpkg.NewHTTPAuthMiddleware(cfg.User, cfg.Password).SetAuthFailDelay(200 * time.Millisecond).Middleware
|
||||
|
||||
// Bind only after all fallible preparation so an error cannot leak the listener.
|
||||
ln, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.ln = ln
|
||||
return s, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user