github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/stochastikctx/variable/statusvar.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package variable 15 16 import ( 17 "bytes" 18 "crypto/tls" 19 "sync" 20 21 "github.com/whtcorpsinc/milevadb/soliton" 22 ) 23 24 var statisticsList []Statistics 25 var statisticsListLock sync.RWMutex 26 27 // DefaultStatusVarScopeFlag is the default scope of status variables. 28 var DefaultStatusVarScopeFlag = ScopeGlobal | ScopeStochastik 29 30 // StatusVal is the value of the corresponding status variable. 31 type StatusVal struct { 32 Scope ScopeFlag 33 Value interface{} 34 } 35 36 // Statistics is the interface of statistics. 37 type Statistics interface { 38 // GetScope gets the status variables scope. 39 GetScope(status string) ScopeFlag 40 // Stats returns the statistics status variables. 41 Stats(*StochastikVars) (map[string]interface{}, error) 42 } 43 44 // RegisterStatistics registers statistics. 45 func RegisterStatistics(s Statistics) { 46 statisticsListLock.Lock() 47 statisticsList = append(statisticsList, s) 48 statisticsListLock.Unlock() 49 } 50 51 // GetStatusVars gets registered statistics status variables. 52 // TODO: Refactor this function to avoid repeated memory allocation / dealloc 53 func GetStatusVars(vars *StochastikVars) (map[string]*StatusVal, error) { 54 statusVars := make(map[string]*StatusVal) 55 statisticsListLock.RLock() 56 defer statisticsListLock.RUnlock() 57 58 for _, statistics := range statisticsList { 59 vals, err := statistics.Stats(vars) 60 if err != nil { 61 return nil, err 62 } 63 64 for name, val := range vals { 65 scope := statistics.GetScope(name) 66 statusVars[name] = &StatusVal{Value: val, Scope: scope} 67 } 68 } 69 70 return statusVars, nil 71 } 72 73 // Taken from https://golang.org/pkg/crypto/tls/#pkg-constants . 74 var tlsCiphers = []uint16{ 75 tls.TLS_RSA_WITH_RC4_128_SHA, 76 tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, 77 tls.TLS_RSA_WITH_AES_128_CBC_SHA, 78 tls.TLS_RSA_WITH_AES_256_CBC_SHA, 79 tls.TLS_RSA_WITH_AES_128_CBC_SHA256, 80 tls.TLS_RSA_WITH_AES_128_GCM_SHA256, 81 tls.TLS_RSA_WITH_AES_256_GCM_SHA384, 82 tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 83 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 84 tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 85 tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, 86 tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 87 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 88 tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 89 tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 90 tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 91 tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 92 tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 93 tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 94 tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 95 tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 96 tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 97 tls.TLS_AES_128_GCM_SHA256, 98 tls.TLS_AES_256_GCM_SHA384, 99 tls.TLS_CHACHA20_POLY1305_SHA256, 100 } 101 102 var tlsSupportedCiphers string 103 104 // Taken from https://github.com/openssl/openssl/blob/c784a838e0947fcca761ee62def7d077dc06d37f/include/openssl/ssl.h#L141 . 105 var tlsVersionString = map[uint16]string{ 106 tls.VersionSSL30: "SSLv3", 107 tls.VersionTLS10: "TLSv1", 108 tls.VersionTLS11: "TLSv1.1", 109 tls.VersionTLS12: "TLSv1.2", 110 tls.VersionTLS13: "TLSv1.3", 111 } 112 113 var defaultStatus = map[string]*StatusVal{ 114 "Ssl_cipher": {ScopeGlobal | ScopeStochastik, ""}, 115 "Ssl_cipher_list": {ScopeGlobal | ScopeStochastik, ""}, 116 "Ssl_verify_mode": {ScopeGlobal | ScopeStochastik, 0}, 117 "Ssl_version": {ScopeGlobal | ScopeStochastik, ""}, 118 } 119 120 type defaultStatusStat struct { 121 } 122 123 func (s defaultStatusStat) GetScope(status string) ScopeFlag { 124 return defaultStatus[status].Scope 125 } 126 127 func (s defaultStatusStat) Stats(vars *StochastikVars) (map[string]interface{}, error) { 128 statusVars := make(map[string]interface{}, len(defaultStatus)) 129 130 for name, v := range defaultStatus { 131 statusVars[name] = v.Value 132 } 133 134 // `vars` may be nil in unit tests. 135 if vars != nil && vars.TLSConnectionState != nil { 136 statusVars["Ssl_cipher"] = soliton.TLSCipher2String(vars.TLSConnectionState.CipherSuite) 137 statusVars["Ssl_cipher_list"] = tlsSupportedCiphers 138 // tls.VerifyClientCertIfGiven == SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE 139 statusVars["Ssl_verify_mode"] = 0x01 | 0x04 140 statusVars["Ssl_version"] = tlsVersionString[vars.TLSConnectionState.Version] 141 } 142 143 return statusVars, nil 144 } 145 146 func init() { 147 var ciphersBuffer bytes.Buffer 148 for _, v := range tlsCiphers { 149 ciphersBuffer.WriteString(soliton.TLSCipher2String(v)) 150 ciphersBuffer.WriteString(":") 151 } 152 tlsSupportedCiphers = ciphersBuffer.String() 153 154 var stat defaultStatusStat 155 RegisterStatistics(stat) 156 }