// FIXME: This ought to be refactored with the node func (ic *incomingConnection) sslHandshake() error { ic.Trace("Listener for %d in sslHandshake", ic.server.ID) // FIXME: Demeter is yelling at me here. if ic.nodeListener.failOnSSLHandshake { ic.Trace("But I've been told to fail the handshake hard") ic.terminate() return errors.New("ssl handshake simulating failure") } tlsConfig := ic.nodeListener.connectionServer.Cluster.tlsConfig(ic.server.ID) tls := tls.Server(ic.conn, tlsConfig) ic.Trace("Listener for %d made the tlsConn, handshaking", ic.server.ID) err := tls.Handshake() ic.Trace("Listener for %d handshook err: %s", ic.server.ID, myString(err)) if err != nil { return err } ic.tls = tls ic.conn = tls ic.output = gob.NewEncoder(ic.conn) ic.input = gob.NewDecoder(ic.conn) return nil }
// The accept loop of the server. func (s *Server) ListenAndMurmur() { // Launch the event handler goroutine go s.handler() s.running = true // Setup our UDP listener and spawn our reader and writer goroutines s.SetupUDP() go s.ListenUDP() go s.SendUDP() // Create a new listening TLS socket. l := NewTLSListener(s.port) if l == nil { log.Printf("Unable to create TLS listener") return } log.Printf("Created new Murmur instance on port %v", s.port) // The main accept loop. Basically, we block // until we get a new client connection, and // when we do get a new connection, we spawn // a new Go-routine to handle the client. for { // New client connected conn, err := l.Accept() if err != nil { log.Printf("Unable to accept() new client.") } tls, ok := conn.(*tls.Conn) if !ok { log.Panic("Internal inconsistency error.") } // Force the TLS handshake to get going. We'd like // this to happen as soon as possible, so we can get // at client certificates sooner. tls.Handshake() // Create a new client connection from our *tls.Conn // which wraps net.TCPConn. err = s.NewClient(conn) if err != nil { log.Printf("Unable to start new client") } log.Printf("num clients = %v", len(s.clients)) } }
// StartTLS sends the STARTTLS command and encrypts all further communication. // Only servers that advertise the STARTTLS extension support this function. func (c *Client) StartTLS(config *tls.Config) error { if err := c.hello(); err != nil { return err } _, _, err := c.cmd(220, "STARTTLS") if err != nil { return err } tls := tls.Client(c.conn, config) if err = tls.Handshake(); err != nil { return err } c.TLSState = tls.ConnectionState() c.conn = tls c.Text = textproto.NewConn(c.conn) c.tls = true return c.ehlo() }