github.com/iDigitalFlame/xmt@v0.5.4/com/tcp.go (about) 1 // Copyright (C) 2020 - 2023 iDigitalFlame 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 // 16 17 package com 18 19 import ( 20 "context" 21 "crypto/tls" 22 "net" 23 "time" 24 ) 25 26 type tcpClient struct { 27 c tcpConnector 28 } 29 type tcpListener struct { 30 _ [0]func() 31 net.Listener 32 timeout time.Duration 33 } 34 type tcpConnector struct { 35 tls *tls.Config 36 net.Dialer 37 } 38 39 // NewTCP creates a new simple TCP based connector with the supplied timeout. 40 func NewTCP(t time.Duration) Connector { 41 if t < 0 { 42 t = DefaultTimeout 43 } 44 return &tcpConnector{Dialer: net.Dialer{Timeout: t, KeepAlive: t}} 45 } 46 func (t *tcpListener) Accept() (net.Conn, error) { 47 if d, ok := t.Listener.(deadliner); ok { 48 d.SetDeadline(time.Now().Add(t.timeout)) 49 } 50 c, err := t.Listener.Accept() 51 if err != nil { 52 return nil, err 53 } 54 return c, nil 55 } 56 57 // NewTLS creates a new simple TLS wrapped TCP based connector with the supplied 58 // timeout. 59 func NewTLS(t time.Duration, c *tls.Config) Connector { 60 if t < 0 { 61 t = DefaultTimeout 62 } 63 return &tcpConnector{tls: c, Dialer: net.Dialer{Timeout: t, KeepAlive: t}} 64 } 65 func (t tcpClient) Connect(x context.Context, s string) (net.Conn, error) { 66 return t.c.Connect(x, s) 67 } 68 func (t *tcpConnector) Connect(x context.Context, s string) (net.Conn, error) { 69 c, err := newStreamConn(x, NameTCP, s, t) 70 if err != nil { 71 return nil, err 72 } 73 return c, nil 74 } 75 func (t *tcpConnector) Listen(x context.Context, s string) (net.Listener, error) { 76 c, err := newStreamListener(x, NameTCP, s, t) 77 if err != nil { 78 return nil, err 79 } 80 return &tcpListener{timeout: t.Timeout, Listener: c}, nil 81 } 82 func newStreamListener(x context.Context, n, s string, t *tcpConnector) (net.Listener, error) { 83 if t.tls != nil && (len(t.tls.Certificates) == 0 || t.tls.GetCertificate == nil) { 84 return nil, ErrInvalidTLSConfig 85 } 86 l, err := ListenConfig.Listen(x, n, s) 87 if err != nil { 88 return nil, err 89 } 90 if t.tls == nil { 91 return l, nil 92 } 93 return tls.NewListener(l, t.tls), nil 94 }