server-go/net/client.go
crusader f85b949e66 ing
2018-04-04 13:01:26 +09:00

88 lines
1.4 KiB
Go

package net
import (
"crypto/tls"
"fmt"
"net"
"time"
)
type Client struct {
Name string
Network string
Address string
TLSConfig *tls.Config
HandshakeTimeout time.Duration
KeepAlive time.Duration
LocalAddress net.Addr
MaxConnections int
}
func (c *Client) Dial() (net.Conn, error) {
if err := c.Validate(); nil != err {
return nil, err
}
var deadline time.Time
if 0 != c.HandshakeTimeout {
deadline = time.Now().Add(c.HandshakeTimeout)
}
d := &net.Dialer{
KeepAlive: c.KeepAlive,
Deadline: deadline,
LocalAddr: c.LocalAddress,
}
conn, err := d.Dial(c.Network, c.Address)
if nil != err {
return nil, err
}
if nil != c.TLSConfig {
cfg := c.TLSConfig.Clone()
tlsConn := tls.Client(conn, cfg)
if err := tlsConn.Handshake(); err != nil {
tlsConn.Close()
return nil, err
}
if !cfg.InsecureSkipVerify {
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
return nil, err
}
}
conn = tlsConn
}
return conn, nil
}
func (c *Client) Validate() error {
if "" == c.Name {
c.Name = "Client"
}
if "" == c.Network {
return fmt.Errorf("Client: Network is not valid")
}
if "" == c.Address {
return fmt.Errorf("Client: Address is not valid")
}
if 0 >= c.MaxConnections {
c.MaxConnections = 1
}
if 0 >= c.KeepAlive {
c.KeepAlive = DefaultKeepAlive
}
if 0 >= c.HandshakeTimeout {
c.HandshakeTimeout = DefaultHandshakeTimeout
}
return nil
}