github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/core/cs/client/client.go (about) 1 package client 2 3 import ( 4 "crypto/tls" 5 "crypto/x509" 6 "encoding/pem" 7 "errors" 8 "fmt" 9 "net" 10 "strconv" 11 "strings" 12 "time" 13 14 "github.com/AntonOrnatskyi/goproxy/core/dst" 15 "github.com/AntonOrnatskyi/goproxy/core/lib/kcpcfg" 16 compressconn "github.com/AntonOrnatskyi/goproxy/core/lib/transport" 17 encryptconn "github.com/AntonOrnatskyi/goproxy/core/lib/transport/encrypt" 18 kcp "github.com/xtaci/kcp-go" 19 ) 20 21 func TlsConnectHost(host string, timeout int, certBytes, keyBytes, caCertBytes []byte) (conn tls.Conn, err error) { 22 h := strings.Split(host, ":") 23 port, _ := strconv.Atoi(h[1]) 24 return TlsConnect(h[0], port, timeout, certBytes, keyBytes, caCertBytes) 25 } 26 27 func TlsConnect(host string, port, timeout int, certBytes, keyBytes, caCertBytes []byte) (conn tls.Conn, err error) { 28 conf, err := getRequestTlsConfig(certBytes, keyBytes, caCertBytes) 29 if err != nil { 30 return 31 } 32 _conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", host, port), time.Duration(timeout)*time.Millisecond) 33 if err != nil { 34 return 35 } 36 return *tls.Client(_conn, conf), err 37 } 38 func TlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) { 39 return getRequestTlsConfig(certBytes, keyBytes, caCertBytes) 40 } 41 func getRequestTlsConfig(certBytes, keyBytes, caCertBytes []byte) (conf *tls.Config, err error) { 42 43 var cert tls.Certificate 44 cert, err = tls.X509KeyPair(certBytes, keyBytes) 45 if err != nil { 46 return 47 } 48 serverCertPool := x509.NewCertPool() 49 caBytes := certBytes 50 if caCertBytes != nil { 51 caBytes = caCertBytes 52 53 } 54 ok := serverCertPool.AppendCertsFromPEM(caBytes) 55 if !ok { 56 err = errors.New("failed to parse root certificate") 57 } 58 block, _ := pem.Decode(caBytes) 59 if block == nil { 60 panic("failed to parse certificate PEM") 61 } 62 x509Cert, _ := x509.ParseCertificate(block.Bytes) 63 if x509Cert == nil { 64 panic("failed to parse block") 65 } 66 conf = &tls.Config{ 67 RootCAs: serverCertPool, 68 Certificates: []tls.Certificate{cert}, 69 InsecureSkipVerify: true, 70 ServerName: x509Cert.Subject.CommonName, 71 VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 72 opts := x509.VerifyOptions{ 73 Roots: serverCertPool, 74 } 75 for _, rawCert := range rawCerts { 76 cert, _ := x509.ParseCertificate(rawCert) 77 _, err := cert.Verify(opts) 78 if err != nil { 79 return err 80 } 81 } 82 return nil 83 }, 84 } 85 return 86 } 87 88 func TCPConnectHost(hostAndPort string, timeout int) (conn net.Conn, err error) { 89 conn, err = net.DialTimeout("tcp", hostAndPort, time.Duration(timeout)*time.Millisecond) 90 return 91 } 92 93 func TCPSConnectHost(hostAndPort string, method, password string, compress bool, timeout int) (conn net.Conn, err error) { 94 conn, err = net.DialTimeout("tcp", hostAndPort, time.Duration(timeout)*time.Millisecond) 95 if err != nil { 96 return 97 } 98 if compress { 99 conn = compressconn.NewCompConn(conn) 100 } 101 conn, err = encryptconn.NewConn(conn, method, password) 102 return 103 } 104 105 func TOUConnectHost(hostAndPort string, method, password string, compress bool, timeout int) (conn net.Conn, err error) { 106 udpConn, err := net.ListenUDP("udp", &net.UDPAddr{}) 107 if err != nil { 108 panic(err) 109 } 110 // Create a DST mux around the packet connection with the default max 111 // packet size. 112 mux := dst.NewMux(udpConn, 0) 113 conn, err = mux.Dial("dst", hostAndPort) 114 if compress { 115 conn = compressconn.NewCompConn(conn) 116 } 117 conn, err = encryptconn.NewConn(conn, method, password) 118 return 119 } 120 func KCPConnectHost(hostAndPort string, config kcpcfg.KCPConfigArgs) (conn net.Conn, err error) { 121 kcpconn, err := kcp.DialWithOptions(hostAndPort, config.Block, *config.DataShard, *config.ParityShard) 122 if err != nil { 123 return 124 } 125 kcpconn.SetStreamMode(true) 126 kcpconn.SetWriteDelay(true) 127 kcpconn.SetNoDelay(*config.NoDelay, *config.Interval, *config.Resend, *config.NoCongestion) 128 kcpconn.SetMtu(*config.MTU) 129 kcpconn.SetWindowSize(*config.SndWnd, *config.RcvWnd) 130 kcpconn.SetACKNoDelay(*config.AckNodelay) 131 if *config.NoComp { 132 return kcpconn, err 133 } 134 return compressconn.NewCompStream(kcpconn), err 135 }