github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/transport/tcp.go (about) 1 package transport 2 3 import ( 4 "crypto/tls" 5 "net" 6 7 vaddr "github.com/volts-dev/volts/internal/addr" 8 vnet "github.com/volts-dev/volts/internal/net" 9 mls "github.com/volts-dev/volts/internal/tls" 10 ) 11 12 type tcpTransport struct { 13 config *Config 14 } 15 16 func NewTCPTransport(opts ...Option) ITransport { 17 return &tcpTransport{ 18 config: newConfig(opts...), 19 } 20 } 21 22 func (self *tcpTransport) Dial(addr string, opts ...DialOption) (IClient, error) { 23 dialCfg := DialConfig{ 24 DialTimeout: self.config.DialTimeout, 25 ReadTimeout: self.config.ReadTimeout, 26 WriteTimeout: self.config.WriteTimeout, 27 } 28 dialCfg.Init(opts...) 29 30 var conn net.Conn 31 var err error 32 33 // TODO: support dial option here rather than using internal config 34 if self.config.Secure || self.config.TlsConfig != nil { 35 config := self.config.TlsConfig 36 if config == nil { 37 config = &tls.Config{ 38 InsecureSkipVerify: true, 39 } 40 } 41 conn, err = tls.DialWithDialer(&net.Dialer{Timeout: dialCfg.DialTimeout}, "tcp", addr, config) 42 } else { 43 conn, err = net.DialTimeout("tcp", addr, dialCfg.DialTimeout) 44 } 45 46 if err != nil { 47 return nil, err 48 } 49 50 //encBuf := bufio.NewWriter(conn) 51 return &tcpTransportClient{ 52 tcpTransportSocket: *NewTcpTransportSocket(conn, dialCfg.ReadTimeout, dialCfg.WriteTimeout), 53 transport: self, 54 config: dialCfg, 55 conn: conn, 56 }, nil 57 } 58 59 func (self *tcpTransport) Listen(addr string, opts ...ListenOption) (IListener, error) { 60 var options ListenConfig 61 for _, o := range opts { 62 o(&options) 63 } 64 65 var l net.Listener 66 var err error 67 68 // TODO: support use of listen options 69 if self.config.Secure || self.config.TlsConfig != nil { 70 config := self.config.TlsConfig 71 72 fn := func(addr string) (net.Listener, error) { 73 if config == nil { 74 hosts := []string{addr} 75 76 // check if its a valid host:port 77 if host, _, err := net.SplitHostPort(addr); err == nil { 78 if len(host) == 0 { 79 hosts = vaddr.IPs() 80 } else { 81 hosts = []string{host} 82 } 83 } 84 85 // generate a certificate 86 cert, err := mls.Certificate(hosts...) 87 if err != nil { 88 return nil, err 89 } 90 config = &tls.Config{Certificates: []tls.Certificate{cert}} 91 } 92 return tls.Listen("tcp", addr, config) 93 } 94 95 l, err = vnet.Listen(addr, fn) 96 } else { 97 fn := func(addr string) (net.Listener, error) { 98 return net.Listen("tcp", addr) 99 } 100 101 l, err = vnet.Listen(addr, fn) 102 } 103 104 if err != nil { 105 return nil, err 106 } 107 108 self.config.Listener = &tcpTransportListener{ 109 transport: self, 110 listener: l, 111 } 112 113 return self.config.Listener, nil 114 } 115 116 func (t *tcpTransport) Init(opts ...Option) error { 117 for _, o := range opts { 118 o(t.config) 119 } 120 return nil 121 } 122 123 func (t *tcpTransport) Config() *Config { 124 return t.config 125 } 126 127 func (*tcpTransport) String() string { 128 return "TcpTransport" 129 } 130 131 func (*tcpTransport) Protocol() string { 132 return "TCP" 133 }