1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.3 KiB
Go

package tcp
import (
"crypto/tls"
"fmt"
"net"
"time"
)
// Transport is the network layer for internode communications.
type Transport struct {
ln net.Listener
certFile string // Path to local X.509 cert.
certKey string // Path to corresponding X.509 key.
remoteEncrypted bool // Remote nodes use encrypted communication.
skipVerify bool // Skip verification of remote node certs.
}
// NewTransport returns an initialized unencrypted Transport.
func NewTransport() *Transport {
return &Transport{}
}
// NewTLSTransport returns an initialized TLS-encrypted Transport.
func NewTLSTransport(certFile, keyPath string, skipVerify bool) *Transport {
return &Transport{
certFile: certFile,
certKey: keyPath,
remoteEncrypted: true,
skipVerify: skipVerify,
}
}
// Open opens the transport, binding to the supplied address.
func (t *Transport) Open(addr string) error {
ln, err := net.Listen("tcp", addr)
if err != nil {
return err
}
if t.certFile != "" {
config, err := createTLSConfig(t.certFile, t.certKey)
if err != nil {
return err
}
ln = tls.NewListener(ln, config)
}
t.ln = ln
return nil
}
// Dial opens a network connection.
func (t *Transport) Dial(addr string, timeout time.Duration) (net.Conn, error) {
dialer := &net.Dialer{Timeout: timeout}
var err error
var conn net.Conn
if t.remoteEncrypted {
conf := &tls.Config{
InsecureSkipVerify: t.skipVerify,
}
fmt.Println("doing a TLS dial")
conn, err = tls.DialWithDialer(dialer, "tcp", addr, conf)
} else {
conn, err = dialer.Dial("tcp", addr)
}
return conn, err
}
// Accept waits for the next connection.
func (t *Transport) Accept() (net.Conn, error) {
c, err := t.ln.Accept()
if err != nil {
fmt.Println("error accepting: ", err.Error())
}
return c, err
}
// Close closes the transport
func (t *Transport) Close() error {
return t.ln.Close()
}
// Addr returns the binding address of the transport.
func (t *Transport) Addr() net.Addr {
return t.ln.Addr()
}
// createTLSConfig returns a TLS config from the given cert and key.
func createTLSConfig(certFile, keyFile string) (*tls.Config, error) {
var err error
config := &tls.Config{}
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
return config, nil
}