github.com/TeaOSLab/EdgeNode@v1.3.8/internal/nodes/origin_utils.go (about) 1 package nodes 2 3 import ( 4 "crypto/tls" 5 "errors" 6 "github.com/TeaOSLab/EdgeCommon/pkg/configutils" 7 "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" 8 "github.com/TeaOSLab/EdgeNode/internal/remotelogs" 9 "github.com/iwind/TeaGo/types" 10 "net" 11 "strconv" 12 ) 13 14 // OriginConnect 连接源站 15 func OriginConnect(origin *serverconfigs.OriginConfig, serverPort int, remoteAddr string, tlsHost string) (originConn net.Conn, originAddr string, err error) { 16 if origin.Addr == nil { 17 return nil, "", errors.New("origin server address should not be empty") 18 } 19 20 // 支持TOA的连接 21 // 这个条件很重要,如果没有传递remoteAddr,表示不使用TOA 22 if len(remoteAddr) > 0 { 23 var toaConfig = sharedTOAManager.Config() 24 if toaConfig != nil && toaConfig.IsOn { 25 var retries = 3 26 for i := 1; i <= retries; i++ { 27 var port = int(toaConfig.RandLocalPort()) 28 err = sharedTOAManager.SendMsg("add:" + strconv.Itoa(port) + ":" + remoteAddr) 29 if err != nil { 30 remotelogs.Error("TOA", "add failed: "+err.Error()) 31 } else { 32 var dialer = net.Dialer{ 33 Timeout: origin.ConnTimeoutDuration(), 34 LocalAddr: &net.TCPAddr{ 35 Port: port, 36 }, 37 } 38 originAddr = origin.Addr.PickAddress() 39 40 // 端口跟随 41 if origin.FollowPort && serverPort > 0 { 42 originAddr = configutils.QuoteIP(origin.Addr.Host) + ":" + types.String(serverPort) 43 } 44 45 var conn net.Conn 46 switch origin.Addr.Protocol { 47 case "", serverconfigs.ProtocolTCP, serverconfigs.ProtocolHTTP: 48 // TODO 支持TCP4/TCP6 49 // TODO 支持指定特定网卡 50 conn, err = dialer.Dial("tcp", originAddr) 51 case serverconfigs.ProtocolTLS, serverconfigs.ProtocolHTTPS: 52 // TODO 支持TCP4/TCP6 53 // TODO 支持指定特定网卡 54 55 var tlsConfig = &tls.Config{ 56 InsecureSkipVerify: true, 57 } 58 if origin.Cert != nil { 59 var obj = origin.Cert.CertObject() 60 if obj != nil { 61 tlsConfig.InsecureSkipVerify = false 62 tlsConfig.Certificates = []tls.Certificate{*obj} 63 if len(origin.Cert.ServerName) > 0 { 64 tlsConfig.ServerName = origin.Cert.ServerName 65 } 66 } 67 } 68 if len(tlsHost) > 0 { 69 tlsConfig.ServerName = tlsHost 70 } 71 72 conn, err = tls.DialWithDialer(&dialer, "tcp", originAddr, tlsConfig) 73 } 74 75 // TODO 需要在合适的时机删除TOA记录 76 if err == nil || i == retries { 77 return conn, originAddr, err 78 } 79 } 80 } 81 } 82 } 83 84 originAddr = origin.Addr.PickAddress() 85 86 // 端口跟随 87 if origin.FollowPort && serverPort > 0 { 88 originAddr = configutils.QuoteIP(origin.Addr.Host) + ":" + types.String(serverPort) 89 } 90 91 switch origin.Addr.Protocol { 92 case "", serverconfigs.ProtocolTCP, serverconfigs.ProtocolHTTP: 93 // TODO 支持TCP4/TCP6 94 // TODO 支持指定特定网卡 95 originConn, err = net.DialTimeout("tcp", originAddr, origin.ConnTimeoutDuration()) 96 return originConn, originAddr, err 97 case serverconfigs.ProtocolTLS, serverconfigs.ProtocolHTTPS: 98 // TODO 支持TCP4/TCP6 99 // TODO 支持指定特定网卡 100 101 var tlsConfig = &tls.Config{ 102 InsecureSkipVerify: true, 103 } 104 if origin.Cert != nil { 105 var obj = origin.Cert.CertObject() 106 if obj != nil { 107 tlsConfig.InsecureSkipVerify = false 108 tlsConfig.Certificates = []tls.Certificate{*obj} 109 if len(origin.Cert.ServerName) > 0 { 110 tlsConfig.ServerName = origin.Cert.ServerName 111 } 112 } 113 } 114 if len(tlsHost) > 0 { 115 tlsConfig.ServerName = tlsHost 116 } 117 118 originConn, err = tls.Dial("tcp", originAddr, tlsConfig) 119 return originConn, originAddr, err 120 case serverconfigs.ProtocolUDP: 121 addr, err := net.ResolveUDPAddr("udp", originAddr) 122 if err != nil { 123 return nil, originAddr, err 124 } 125 originConn, err = net.DialUDP("udp", nil, addr) 126 return originConn, originAddr, err 127 } 128 129 // TODO 支持从Unix、Pipe、HTTP、HTTPS中读取数据 130 131 return nil, originAddr, errors.New("invalid origin scheme '" + origin.Addr.Protocol.String() + "'") 132 }