From c5969cd684e73eea509078cc0cca4c37a6c51938 Mon Sep 17 00:00:00 2001 From: Chris Van de Gejuchte Date: Tue, 12 Sep 2017 12:00:04 +0200 Subject: [PATCH] Adds tls support --- example/clone.go | 2 +- redcon.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/example/clone.go b/example/clone.go index f32bc1c..6c1cbcb 100644 --- a/example/clone.go +++ b/example/clone.go @@ -5,7 +5,7 @@ import ( "strings" "sync" - "github.com/tidwall/redcon" + "github.com/chrisvdg/redcon" ) var addr = ":6380" diff --git a/redcon.go b/redcon.go index 26ba003..909f9d5 100644 --- a/redcon.go +++ b/redcon.go @@ -3,6 +3,7 @@ package redcon import ( "bufio" + "crypto/tls" "errors" "io" "net" @@ -100,7 +101,7 @@ func NewServer(addr string, return NewServerNetwork("tcp", addr, handler, accept, closed) } -// NewServerNetworkType returns a new Redcon server. The network net must be +// NewServerNetwork returns a new Redcon server. The network net must be // a stream-oriented network: "tcp", "tcp4", "tcp6", "unix" or "unixpacket" func NewServerNetwork( net, laddr string, @@ -122,6 +123,34 @@ func NewServerNetwork( return s } +// NewServerNetworkTLS returns a new TLS Redcon server. The network net must be +// a stream-oriented network: "tcp", "tcp4", "tcp6", "unix" or "unixpacket" +func NewServerNetworkTLS( + net, laddr string, + handler func(conn Conn, cmd Command), + accept func(conn Conn) bool, + closed func(conn Conn, err error), + config *tls.Config, +) *TLSServer { + if handler == nil { + panic("handler is nil") + } + s := Server{ + net: net, + laddr: laddr, + handler: handler, + accept: accept, + closed: closed, + conns: make(map[*conn]bool), + } + + tls := &TLSServer{ + config: config, + Server: &s, + } + return tls +} + // Close stops listening on the TCP address. // Already Accepted connections will be closed. func (s *Server) Close() error { @@ -148,7 +177,17 @@ func ListenAndServe(addr string, return ListenAndServeNetwork("tcp", addr, handler, accept, closed) } -// ListenAndServe creates a new server and binds to addr. The network net must be +// ListenAndServeTLS creates a new TLS server and binds to addr configured on "tcp" network net. +func ListenAndServeTLS(addr string, + handler func(conn Conn, cmd Command), + accept func(conn Conn) bool, + closed func(conn Conn, err error), + config *tls.Config, +) error { + return ListenAndServeNetworkTLS("tcp", addr, handler, accept, closed, config) +} + +// ListenAndServeNetwork creates a new server and binds to addr. The network net must be // a stream-oriented network: "tcp", "tcp4", "tcp6", "unix" or "unixpacket" func ListenAndServeNetwork( net, laddr string, @@ -159,6 +198,18 @@ func ListenAndServeNetwork( return NewServerNetwork(net, laddr, handler, accept, closed).ListenAndServe() } +// ListenAndServeNetworkTLS creates a new TLS server and binds to addr. The network net must be +// a stream-oriented network: "tcp", "tcp4", "tcp6", "unix" or "unixpacket" +func ListenAndServeNetworkTLS( + net, laddr string, + handler func(conn Conn, cmd Command), + accept func(conn Conn) bool, + closed func(conn Conn, err error), + config *tls.Config, +) error { + return NewServerNetworkTLS(net, laddr, handler, accept, closed, config).ListenAndServe() +} + // ListenServeAndSignal serves incoming connections and passes nil or error // when listening. signal can be nil. func (s *Server) ListenServeAndSignal(signal chan error) error { @@ -172,6 +223,26 @@ func (s *Server) ListenServeAndSignal(signal chan error) error { if signal != nil { signal <- nil } + return listenServeAndSignal(s, ln) +} + +// ListenServeAndSignal serves incoming connections and passes nil or error +// when listening. signal can be nil. +func (s *TLSServer) ListenServeAndSignal(signal chan error) error { + ln, err := tls.Listen(s.net, s.laddr, s.config) + if err != nil { + if signal != nil { + signal <- err + } + return err + } + if signal != nil { + signal <- nil + } + return listenServeAndSignal(s.Server, ln) +} + +func listenServeAndSignal(s *Server, ln net.Listener) error { s.mu.Lock() s.ln = ln s.mu.Unlock() @@ -397,6 +468,12 @@ type Server struct { done bool } +// TLSServer defines a server for clients for managing client connections. +type TLSServer struct { + *Server + config *tls.Config +} + // Writer allows for writing RESP messages. type Writer struct { w io.Writer