Skip to content

Commit

Permalink
server: if status address already in use, return an error (#15177) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sre-bot authored Apr 10, 2020
1 parent b2d6f52 commit 1347df8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
57 changes: 31 additions & 26 deletions server/http_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,34 @@ func sleepWithCtx(ctx context.Context, d time.Duration) {
}
}

func (s *Server) listenStatusHTTPServer() error {
s.statusAddr = fmt.Sprintf("%s:%d", s.cfg.Status.StatusHost, s.cfg.Status.StatusPort)
if s.cfg.Status.StatusPort == 0 {
s.statusAddr = fmt.Sprintf("%s:%d", s.cfg.Status.StatusHost, defaultStatusPort)
}

var err error
logutil.Logger(context.Background()).Info("for status and metrics report", zap.String("listening on addr", s.statusAddr))
s.statusListener, err = net.Listen("tcp", s.statusAddr)
if err != nil {
logutil.Logger(context.Background()).Info("listen failed", zap.Error(err))
return errors.Trace(err)
}

if len(s.cfg.Security.ClusterSSLCA) != 0 {
tlsConfig, err := s.cfg.Security.ToTLSConfig()
if err != nil {
logutil.Logger(context.Background()).Error("invalid TLS config", zap.Error(err))
return errors.Trace(err)
}
tlsConfig = s.setCNChecker(tlsConfig)
logutil.Logger(context.Background()).Info("HTTP/gRPC status server secure connection is enabled", zap.Bool("CN verification enabled", tlsConfig.VerifyPeerCertificate != nil))
s.statusListener = tls.NewListener(s.statusListener, tlsConfig)
}

return nil
}

func (s *Server) startHTTPServer() {
router := mux.NewRouter()

Expand Down Expand Up @@ -113,13 +141,9 @@ func (s *Server) startHTTPServer() {
router.Handle("/mvcc/hex/{hexKey}", mvccTxnHandler{tikvHandlerTool, opMvccGetByHex})
router.Handle("/mvcc/index/{db}/{table}/{index}/{handle}", mvccTxnHandler{tikvHandlerTool, opMvccGetByIdx})
}
addr := fmt.Sprintf("%s:%d", s.cfg.Status.StatusHost, s.cfg.Status.StatusPort)
if s.cfg.Status.StatusPort == 0 {
addr = fmt.Sprintf("%s:%d", s.cfg.Status.StatusHost, defaultStatusPort)
}

// HTTP path for web UI.
if host, port, err := net.SplitHostPort(addr); err == nil {
if host, port, err := net.SplitHostPort(s.statusAddr); err == nil {
if host == "" {
host = "localhost"
}
Expand Down Expand Up @@ -255,27 +279,8 @@ func (s *Server) startHTTPServer() {
}
})

logutil.Logger(context.Background()).Info("for status and metrics report", zap.String("listening on addr", addr))
s.statusServer = &http.Server{Addr: addr, Handler: CorsHandler{handler: serverMux, cfg: s.cfg}}

ln, err := net.Listen("tcp", addr)
if err != nil {
logutil.Logger(context.Background()).Info("listen failed", zap.Error(err))
return
}

if len(s.cfg.Security.ClusterSSLCA) != 0 {
tlsConfig, err := s.cfg.Security.ToTLSConfig()
if err != nil {
logutil.Logger(context.Background()).Error("invalid TLS config", zap.Error(err))
return
}
tlsConfig = s.setCNChecker(tlsConfig)
logutil.Logger(context.Background()).Info("HTTP/gRPC status server secure connection is enabled", zap.Bool("CN verification enabled", tlsConfig.VerifyPeerCertificate != nil))
ln = tls.NewListener(ln, tlsConfig)
}

err = s.statusServer.Serve(ln)
s.statusServer = &http.Server{Addr: s.statusAddr, Handler: CorsHandler{handler: serverMux, cfg: s.cfg}}
err = s.statusServer.Serve(s.statusListener)
if err != nil {
logutil.Logger(context.Background()).Info("serve status port failed", zap.Error(err))
}
Expand Down
5 changes: 5 additions & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ type Server struct {
concurrentLimiter *TokenLimiter
clients map[uint32]*clientConn
capability uint32
statusAddr string
statusListener net.Listener
statusServer *http.Server
}

Expand Down Expand Up @@ -247,6 +249,9 @@ func NewServer(cfg *config.Config, driver IDriver) (*Server, error) {
s.listener = pplistener
}

if s.cfg.Status.ReportStatus && err == nil {
err = s.listenStatusHTTPServer()
}
if err != nil {
return nil, errors.Trace(err)
}
Expand Down
13 changes: 13 additions & 0 deletions server/tidb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,19 @@ func (ts *TidbTestSuite) TestStatusAPI(c *C) {
runTestStatusAPI(c)
}

func (ts *TidbTestSuite) TestStatusPort(c *C) {
cfg := config.NewConfig()
cfg.Port = 4008
cfg.Status.ReportStatus = true
cfg.Status.StatusPort = 10090

server, err := NewServer(cfg, ts.tidbdrv)
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals,
fmt.Sprintf("listen tcp 0.0.0.0:%d: bind: address already in use", cfg.Status.StatusPort))
c.Assert(server, IsNil)
}

func (ts *TidbTestSuite) TestStatusAPIWithTLSCNCheck(c *C) {
caPath := filepath.Join(os.TempDir(), "ca-cert-cn.pem")
serverKeyPath := filepath.Join(os.TempDir(), "server-key-cn.pem")
Expand Down

0 comments on commit 1347df8

Please sign in to comment.