Skip to content

Commit

Permalink
server: Fix race in baseHTTPListener.Addr()
Browse files Browse the repository at this point in the history
There was a potential race with initializing a listener and saving the
reference to it and using the reference when checking on the address
for the listener.

This change is doing two things:

* Getting the address from the listener a single time _after_ it has
  been initialized.
* Using a mutex to protect access to the address (common use-case
  being to start the listener on a background thread and check for
  the address it is listening on from another one).

`go test -tags=slow -race -vet=off ./cmd/` is now passing with these
changes.

Signed-off-by: Patrick East <[email protected]>
  • Loading branch information
patrick-east authored and tsandall committed Jul 16, 2020
1 parent b93704c commit 2380c37
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,11 @@ type httpListener interface {

// baseHTTPListener is just a wrapper around http.Server
type baseHTTPListener struct {
s *http.Server
l net.Listener
t httpListenerType
s *http.Server
l net.Listener
t httpListenerType
addr string
addrMtx sync.RWMutex
}

var _ httpListener = (*baseHTTPListener)(nil)
Expand All @@ -432,16 +434,23 @@ func (b *baseHTTPListener) ListenAndServe() error {
return err
}

b.initAddr()

return b.s.Serve(tcpKeepAliveListener{b.l.(*net.TCPListener)})
}

func (b *baseHTTPListener) Addr() string {
if b.l != nil {
if addr := b.l.(*net.TCPListener).Addr(); addr != nil {
return addr.String()
}
func (b *baseHTTPListener) initAddr() {
b.addrMtx.Lock()
if addr := b.l.(*net.TCPListener).Addr(); addr != nil {
b.addr = addr.String()
}
return ""
b.addrMtx.Unlock()
}

func (b *baseHTTPListener) Addr() string {
b.addrMtx.Lock()
defer b.addrMtx.Unlock()
return b.addr
}

func (b *baseHTTPListener) ListenAndServeTLS(certFile, keyFile string) error {
Expand All @@ -456,6 +465,8 @@ func (b *baseHTTPListener) ListenAndServeTLS(certFile, keyFile string) error {
return err
}

b.initAddr()

defer b.l.Close()

return b.s.ServeTLS(tcpKeepAliveListener{b.l.(*net.TCPListener)}, certFile, keyFile)
Expand Down

0 comments on commit 2380c37

Please sign in to comment.