// Dial is used to create a new outgoing connection func (l *RaftLayer) Dial(address string, timeout time.Duration) (net.Conn, error) { conn, err := net.DialTimeout("tcp", address, timeout) if err != nil { return nil, err } // Check for tls mode if l.tlsConfig != nil { // Switch the connection into TLS mode if _, err := conn.Write([]byte{byte(rpcTLS)}); err != nil { conn.Close() return nil, err } // Wrap the connection in a TLS client conn, err = tlsutil.WrapTLSClient(conn, l.tlsConfig) if err != nil { return nil, err } } // Write the Raft byte to set the mode _, err = conn.Write([]byte{byte(rpcRaft)}) if err != nil { conn.Close() return nil, err } return conn, err }
// getNewConn is used to return a new connection func (p *ConnPool) getNewConn(addr net.Addr, version int) (*Conn, error) { // Try to dial the conn conn, err := net.DialTimeout("tcp", addr.String(), 10*time.Second) if err != nil { return nil, err } // Cast to TCPConn if tcp, ok := conn.(*net.TCPConn); ok { tcp.SetKeepAlive(true) tcp.SetNoDelay(true) } // Check if TLS is enabled if p.tlsConfig != nil { // Switch the connection into TLS mode if _, err := conn.Write([]byte{byte(rpcTLS)}); err != nil { conn.Close() return nil, err } // Wrap the connection in a TLS client tlsConn, err := tlsutil.WrapTLSClient(conn, p.tlsConfig) if err != nil { conn.Close() return nil, err } conn = tlsConn } // Switch the multiplexing based on version var session muxSession if version < 2 { // Write the Consul multiplex byte to set the mode if _, err := conn.Write([]byte{byte(rpcMultiplex)}); err != nil { conn.Close() return nil, err } // Create a multiplexed session session = &muxadoWrapper{muxado.Client(conn)} } else { // Write the Consul multiplex byte to set the mode if _, err := conn.Write([]byte{byte(rpcMultiplexV2)}); err != nil { conn.Close() return nil, err } // Setup the logger conf := yamux.DefaultConfig() conf.LogOutput = p.logOutput // Create a multiplexed session session, _ = yamux.Client(conn, conf) } // Wrap the connection var c *Conn // Track this connection, handle potential race condition p.Lock() defer p.Unlock() if existing := p.pool[addr.String()]; existing != nil { c = existing } else { c = &Conn{ refCount: 1, addr: addr, session: session, clients: list.New(), lastUsed: time.Now(), version: version, pool: p, } p.pool[addr.String()] = c } return c, nil }