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  }