From fce701a54d482ff56c5a1c25cf562cf61eae53f4 Mon Sep 17 00:00:00 2001 From: Fatih Arslan Date: Tue, 2 Mar 2021 13:11:44 +0300 Subject: [PATCH] proxy: add LocalAddr() method This method exposes the underlying listener's local address. It will be useful to get the address if the listener binds to an address in the form "127.0.0.1:0", which picks up a random port. /xref https://github.com/planetscale/project-big-bang/issues/111 --- proxy/client.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/proxy/client.go b/proxy/client.go index 70f9081..5a90538 100644 --- a/proxy/client.go +++ b/proxy/client.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "crypto/x509" + "errors" "fmt" "io" "net" @@ -52,6 +53,10 @@ type Client struct { // configCache contains the TLS certificate chache for each indiviual // database configCache *tlsCache + + listener net.Listener + // done is closed after a successfull net.Listen bind. + done chan struct{} } // Options are the options for creating a new Client. @@ -89,6 +94,7 @@ func NewClient(opts Options) (*Client, error) { remoteAddr: opts.RemoteAddr, instance: opts.Instance, configCache: newtlsCache(), + done: make(chan struct{}, 0), } if opts.Logger != nil { @@ -129,9 +135,24 @@ func (c *Client) Run(ctx context.Context) error { } defer c.log.Sync() // nolint: errcheck + c.listener = l + close(c.done) + return c.run(ctx, l) } +// LocalAddr returns the address of the local listener. This is by default +// blocking and will only return if the proxy is invoked with the Run() method. +func (c *Client) LocalAddr() (net.Addr, error) { + <-c.done + + if c.listener == nil { + return nil, errors.New("listener is not set") + + } + return c.listener.Addr(), nil +} + func (c *Client) getListener() (net.Listener, error) { if strings.HasPrefix(c.localAddr, "unix://") { p := strings.TrimPrefix(c.localAddr, "unix://")