in internal/proxy/proxy.go [797:871]
func (c *Client) newSocketMount(ctx context.Context, conf *Config, pc *portConfig, inst InstanceConnConfig) (*socketMount, error) {
var (
// network is one of "tcp" or "unix"
network string
// address is either a TCP host port, or a Unix socket
address string
err error
)
// IF
// a global Unix socket directory is NOT set AND
// an instance-level Unix socket is NOT set
// (e.g., I didn't set a Unix socket globally or for this instance)
// OR
// an instance-level TCP address or port IS set
// (e.g., I'm overriding any global settings to use TCP for this
// instance)
// use a TCP listener.
// Otherwise, use a Unix socket.
if networkType(conf, inst) == "tcp" {
network = "tcp"
a := conf.Addr
if inst.Addr != "" {
a = inst.Addr
}
var np int
switch {
case inst.Port != 0:
np = inst.Port
case conf.Port != 0:
np = pc.nextPort()
default:
version, err := c.dialer.EngineVersion(ctx, inst.Name)
// Exit if the port is not specified for inactive instance
if err != nil {
c.logger.Errorf("[%v] could not resolve instance version: %v", inst.Name, err)
return nil, err
}
np = pc.nextDBPort(version)
}
address = net.JoinHostPort(a, fmt.Sprint(np))
} else {
network = "unix"
version, err := c.dialer.EngineVersion(ctx, inst.Name)
if err != nil {
c.logger.Errorf("[%v] could not resolve instance version: %v", inst.Name, err)
return nil, err
}
address, err = newUnixSocketMount(inst, conf.UnixSocket, strings.HasPrefix(version, "POSTGRES"))
if err != nil {
c.logger.Errorf("[%v] could not mount unix socket %q: %v", inst.Name, conf.UnixSocket, err)
return nil, err
}
}
lc := net.ListenConfig{KeepAlive: 30 * time.Second}
ln, err := lc.Listen(ctx, network, address)
if err != nil {
c.logger.Errorf("[%v] could not listen to address %v: %v", inst.Name, address, err)
return nil, err
}
// Change file permissions to allow access for user, group, and other.
if network == "unix" {
// Best effort. If this call fails, group and other won't have write
// access.
_ = os.Chmod(address, 0777)
}
opts := dialOptions(*conf, inst)
m := &socketMount{inst: inst.Name, dialOpts: opts, listener: ln}
return m, nil
}