From a1c22ce78a8b540e886104342cfe5e2df5e57313 Mon Sep 17 00:00:00 2001 From: Asim Date: Mon, 18 Jan 2016 00:10:04 +0000 Subject: [PATCH] Add transport tls --- broker/http_broker.go | 2 +- transport/http_transport.go | 58 +++++++++++++++++++++++++++++++++---- transport/options.go | 33 +++++++++++++++++++++ transport/transport.go | 8 +++-- 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/broker/http_broker.go b/broker/http_broker.go index ed5c3d70..cb8739de 100644 --- a/broker/http_broker.go +++ b/broker/http_broker.go @@ -79,7 +79,7 @@ func newTransport(config *tls.Config) *http.Transport { KeepAlive: 30 * time.Second, }).Dial, TLSHandshakeTimeout: 10 * time.Second, - TLSClientConfig: config, + TLSClientConfig: config, } runtime.SetFinalizer(&t, func(tr **http.Transport) { (*tr).CloseIdleConnections() diff --git a/transport/http_transport.go b/transport/http_transport.go index 40b26f06..b058066a 100644 --- a/transport/http_transport.go +++ b/transport/http_transport.go @@ -3,6 +3,7 @@ package transport import ( "bufio" "bytes" + "crypto/tls" "errors" "io" "io/ioutil" @@ -10,13 +11,17 @@ import ( "net/http" "net/url" "sync" + + mls "github.com/micro/misc/lib/tls" ) type buffer struct { io.ReadWriter } -type httpTransport struct{} +type httpTransport struct { + opts Options +} type httpTransportClient struct { ht *httpTransport @@ -284,7 +289,22 @@ func (h *httpTransport) Dial(addr string, opts ...DialOption) (Client, error) { opt(&dopts) } - conn, err := net.DialTimeout("tcp", addr, dopts.Timeout) + var conn net.Conn + var err error + + // TODO: support dial option here rather than using internal config + if h.opts.Secure || h.opts.TLSConfig != nil { + config := h.opts.TLSConfig + if config == nil { + config = &tls.Config{ + InsecureSkipVerify: true, + } + } + conn, err = tls.DialWithDialer(&net.Dialer{Timeout: dopts.Timeout}, "tcp", addr, config) + } else { + conn, err = net.DialTimeout("tcp", addr, dopts.Timeout) + } + if err != nil { return nil, err } @@ -299,8 +319,30 @@ func (h *httpTransport) Dial(addr string, opts ...DialOption) (Client, error) { }, nil } -func (h *httpTransport) Listen(addr string) (Listener, error) { - l, err := net.Listen("tcp", addr) +func (h *httpTransport) Listen(addr string, opts ...ListenOption) (Listener, error) { + var options ListenOptions + for _, o := range opts { + o(&options) + } + + var l net.Listener + var err error + + // TODO: support use of listen options + if h.opts.Secure || h.opts.TLSConfig != nil { + config := h.opts.TLSConfig + if config == nil { + cert, err := mls.Certificate(addr) + if err != nil { + return nil, err + } + config = &tls.Config{Certificates: []tls.Certificate{cert}} + } + l, err = tls.Listen("tcp", addr, config) + } else { + l, err = net.Listen("tcp", addr) + } + if err != nil { return nil, err } @@ -314,6 +356,10 @@ func (h *httpTransport) String() string { return "http" } -func newHttpTransport(addrs []string, opt ...Option) *httpTransport { - return &httpTransport{} +func newHttpTransport(addrs []string, opts ...Option) *httpTransport { + var options Options + for _, o := range opts { + o(&options) + } + return &httpTransport{opts: options} } diff --git a/transport/options.go b/transport/options.go index cbedfe8e..cb7ba98a 100644 --- a/transport/options.go +++ b/transport/options.go @@ -1,12 +1,16 @@ package transport import ( + "crypto/tls" "time" "golang.org/x/net/context" ) type Options struct { + Secure bool + TLSConfig *tls.Config + // Other options for implementations of the interface // can be stored in a context Context context.Context @@ -16,17 +20,46 @@ type DialOptions struct { Stream bool Timeout time.Duration + // TODO: add tls options when dialling + // Currently set in global options + // Other options for implementations of the interface // can be stored in a context Context context.Context } +type ListenOptions struct { + // TODO: add tls options when listening + // Currently set in global options + + // Other options for implementations of the interface + // can be stored in a context + Context context.Context +} + +// Use secure communication. If TLSConfig is not specified we +// use InsecureSkipVerify and generate a self signed cert +func Secure(b bool) Option { + return func(o *Options) { + o.Secure = b + } +} + +// TLSConfig to be used for the transport. +func TLSConfig(t *tls.Config) Option { + return func(o *Options) { + o.TLSConfig = t + } +} + +// Indicates whether this is a streaming connection func WithStream() DialOption { return func(o *DialOptions) { o.Stream = true } } +// Timeout used when dialling the remote side func WithTimeout(d time.Duration) DialOption { return func(o *DialOptions) { o.Timeout = d diff --git a/transport/transport.go b/transport/transport.go index 77838ca2..5b7401a0 100644 --- a/transport/transport.go +++ b/transport/transport.go @@ -29,7 +29,7 @@ type Listener interface { type Transport interface { Dial(addr string, opts ...DialOption) (Client, error) - Listen(addr string) (Listener, error) + Listen(addr string, opts ...ListenOption) (Listener, error) String() string } @@ -37,6 +37,8 @@ type Option func(*Options) type DialOption func(*DialOptions) +type ListenOption func(*ListenOptions) + var ( DefaultTransport Transport = newHttpTransport([]string{}) @@ -51,8 +53,8 @@ func Dial(addr string, opts ...DialOption) (Client, error) { return DefaultTransport.Dial(addr, opts...) } -func Listen(addr string) (Listener, error) { - return DefaultTransport.Listen(addr) +func Listen(addr string, opts ...ListenOption) (Listener, error) { + return DefaultTransport.Listen(addr, opts...) } func String() string {