Use golint to normalize the code (#1)

This commit is contained in:
Li4n0
2021-04-21 22:08:29 +08:00
committed by GitHub
parent d4a47aebca
commit 960b2ab5ea
39 changed files with 1046 additions and 1108 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
package dns
type Config struct {
Enable bool
Enable bool
}
+1 -1
View File
@@ -39,7 +39,7 @@ func newRecord(rule *Rule, flag, domain, remoteIp, ipArea string) (r *Record, er
Rule: *rule,
}
err = database.DB.Create(r).Error
return
return r, err
}
func List(c *gin.Context) {
+2 -3
View File
@@ -59,7 +59,7 @@ func (r *Rule) CreateOrUpdate() (err error) {
return
}
err = GetServer().updateRules()
return
return err
}
// Delete the dns rule in database and ruleSet
@@ -70,7 +70,7 @@ func (r *Rule) Delete() (err error) {
return
}
err = GetServer().updateRules()
return
return err
}
// List all dns rules those satisfy the filter
@@ -194,5 +194,4 @@ func DeleteRules(c *gin.Context) {
"error": nil,
"data": nil,
})
return
}
+2 -2
View File
@@ -1,7 +1,7 @@
package mysql
type Config struct {
Enable bool
Addr string
Enable bool
Addr string
VersionString string `yaml:"version_string"`
}
+1 -1
View File
@@ -227,7 +227,7 @@ func (s *Server) ComQuery(c *vmysql.Conn, query string, callback func(*sqltypes.
if c.Files[filename] == nil {
log.Trace("MySQL now try to read file [%s], ID [%d]", filename, c.ConnectionID)
data := c.RequestFile(filename)
if data == nil || len(data) == 0 {
if len(data) == 0 {
log.Trace("MySQL file [%s] read failed, file may not exist in client [%d]", filename, c.ConnectionID)
c.Files[filename] = []byte{}
} else {
+2 -1
View File
@@ -13,5 +13,6 @@ func TestServer_NewConnection(t *testing.T) {
if err != nil {
fmt.Println(err)
}
db.Exec("SELECT 1;")
_, _ = db.Exec("SELECT 1;")
}
+7 -8
View File
@@ -14,13 +14,12 @@ var _ record.Record = (*Record)(nil)
type Record struct {
record.BaseRecord
Username string `gorm:"index",form:"username" json:"username" notice:"username"`
ClientName string `gorm:"index",form:"client_name" json:"client_name" notice:"client_name"`
ClientOS string `gorm:"index",form:"client_os" json:"client_os" notice:"client_os"`
LoadLocalData bool `gorm:"index",form:"load_local_data" json:"load_local_data" notice:"load_local_data"`
//FileID uint `form:"file_id" json:"file_id" notice:"file_id"`
Files []File `form:"-" json:"files" notice:"-"`
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
Username string `gorm:"index" form:"username" json:"username" notice:"username"`
ClientName string `gorm:"index" form:"client_name" json:"client_name" notice:"client_name"`
ClientOS string `gorm:"index" form:"client_os" json:"client_os" notice:"client_os"`
LoadLocalData bool `gorm:"index" form:"load_local_data" json:"load_local_data" notice:"load_local_data"`
Files []File `form:"-" json:"files" notice:"-"`
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
}
func (Record) TableName() string {
@@ -47,7 +46,7 @@ func newRecord(rule *Rule, flag, username, clientName, clientOS, remoteIp, ipAre
Rule: *rule,
}
err = database.DB.Create(r).Error
return
return r, err
}
func List(c *gin.Context) {
+3 -4
View File
@@ -14,7 +14,7 @@ type Rule struct {
rule.BaseRule
Files string `form:"files" json:"files"`
ExploitJdbcClient bool `gorm:"exploit_jdbc_client" form:"exploit_jdbc_client" json:"exploit_jdbc_client"`
Payloads database.MapField `json:"payloads" json:"payloads"`
Payloads database.MapField `json:"payloads" form:"payloads"`
}
func (Rule) TableName() string {
@@ -42,7 +42,7 @@ func (r *Rule) CreateOrUpdate() (err error) {
return
}
err = GetServer().updateRules()
return
return err
}
// Delete the mysql rule in database and ruleSet
@@ -53,7 +53,7 @@ func (r *Rule) Delete() (err error) {
return
}
err = GetServer().updateRules()
return
return err
}
// List all mysql rules those satisfy the filter
@@ -176,5 +176,4 @@ func DeleteRules(c *gin.Context) {
"error": nil,
"data": nil,
})
return
}
+7 -7
View File
@@ -117,18 +117,18 @@ func ScramblePassword(salt, password []byte) []byte {
// stage1Hash = SHA1(password)
crypt := sha1.New()
crypt.Write(password)
_, _ = crypt.Write(password)
stage1 := crypt.Sum(nil)
// scrambleHash = SHA1(salt + SHA1(stage1Hash))
// inner Hash
crypt.Reset()
crypt.Write(stage1)
_, _ = crypt.Write(stage1)
hash := crypt.Sum(nil)
// outer Hash
crypt.Reset()
crypt.Write(salt)
crypt.Write(hash)
_, _ = crypt.Write(salt)
_, _ = crypt.Write(hash)
scramble := crypt.Sum(nil)
// token = scrambleHash XOR stage1Hash
@@ -164,8 +164,8 @@ func isPassScrambleMysqlNativePassword(reply, salt []byte, mysqlNativePassword s
// scramble = SHA1(salt+hash)
crypt := sha1.New()
crypt.Write(salt)
crypt.Write(hash)
_, _ = crypt.Write(salt)
_, _ = crypt.Write(hash)
scramble := crypt.Sum(nil)
// token = scramble XOR stage1Hash
@@ -175,7 +175,7 @@ func isPassScrambleMysqlNativePassword(reply, salt []byte, mysqlNativePassword s
hashStage1 := scramble
crypt.Reset()
crypt.Write(hashStage1)
_, _ = crypt.Write(hashStage1)
candidateHash2 := crypt.Sum(nil)
return bytes.Equal(candidateHash2, hash)
+8 -8
View File
@@ -17,9 +17,9 @@ limitations under the License.
package vmysql
import (
"net"
"net"
querypb "vitess.io/vitess/go/vt/proto/query"
querypb "vitess.io/vitess/go/vt/proto/query"
)
// AuthServerNone takes all comers.
@@ -32,27 +32,27 @@ type AuthServerNone struct{}
// AuthMethod is part of the AuthServer interface.
// We always return MysqlNativePassword.
func (a *AuthServerNone) AuthMethod(user string) (string, error) {
return MysqlNativePassword, nil
return MysqlNativePassword, nil
}
// Salt makes salt
func (a *AuthServerNone) Salt() ([]byte, error) {
return NewSalt()
return NewSalt()
}
// ValidateHash validates hash
func (a *AuthServerNone) ValidateHash(salt []byte, user string, authResponse []byte, remoteAddr net.Addr) (Getter, error) {
return &NoneGetter{}, nil
return &NoneGetter{}, nil
}
// Negotiate is part of the AuthServer interface.
// It will never be called.
func (a *AuthServerNone) Negotiate(c *Conn, user string, remotAddr net.Addr) (Getter, error) {
panic("Negotiate should not be called as AuthMethod returned mysql_native_password")
panic("Negotiate should not be called as AuthMethod returned mysql_native_password")
}
func init() {
RegisterAuthServerImpl("none", &AuthServerNone{})
RegisterAuthServerImpl("none", &AuthServerNone{})
}
// NoneGetter holds the empty string
@@ -60,5 +60,5 @@ type NoneGetter struct{}
// Get returns the empty string
func (ng *NoneGetter) Get() *querypb.VTGateCallerID {
return &querypb.VTGateCallerID{Username: "userData1"}
return &querypb.VTGateCallerID{Username: "userData1"}
}
+86 -93
View File
@@ -17,142 +17,135 @@ limitations under the License.
package vmysql
import (
"bytes"
"flag"
"net"
"sync"
"bytes"
"net"
"sync"
querypb "vitess.io/vitess/go/vt/proto/query"
)
var (
mysqlAuthServerStaticFile = flag.String("mysql_auth_server_static_file", "", "JSON File to read the users/passwords from.")
mysqlAuthServerStaticString = flag.String("mysql_auth_server_static_string", "", "JSON representation of the users/passwords config.")
mysqlAuthServerStaticReloadInterval = flag.Duration("mysql_auth_static_reload_interval", 0, "Ticker to reload credentials")
querypb "vitess.io/vitess/go/vt/proto/query"
)
const (
localhostName = "localhost"
localhostName = "localhost"
)
// AuthServerStatic implements AuthServer using a static configuration.
type AuthServerStatic struct {
// Method can be set to:
// - MysqlNativePassword
// - MysqlClearPassword
// - MysqlDialog
// It defaults to MysqlNativePassword.
Method string
// This mutex helps us prevent data races between the multiple updates of Entries.
mu sync.Mutex
// Entries contains the users, passwords and user data.
Entries map[string][]*AuthServerStaticEntry
// Method can be set to:
// - MysqlNativePassword
// - MysqlClearPassword
// - MysqlDialog
// It defaults to MysqlNativePassword.
Method string
// This mutex helps us prevent data races between the multiple updates of Entries.
mu sync.Mutex
// Entries contains the users, passwords and user data.
Entries map[string][]*AuthServerStaticEntry
}
// AuthServerStaticEntry stores the values for a given user.
type AuthServerStaticEntry struct {
// MysqlNativePassword is generated by password hashing methods in MySQL.
// These changes are illustrated by changes in the result from the PASSWORD() function
// that computes password hash values and in the structure of the user table where passwords are stored.
// mysql> SELECT PASSWORD('mypass');
// +-------------------------------------------+
// | PASSWORD('mypass') |
// +-------------------------------------------+
// | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
// +-------------------------------------------+
// MysqlNativePassword's format looks like "*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4", it store a hashing value.
// Use MysqlNativePassword in auth config, maybe more secure. After all, it is cryptographic storage.
MysqlNativePassword string
Password string
UserData string
SourceHost string
Groups []string
// MysqlNativePassword is generated by password hashing methods in MySQL.
// These changes are illustrated by changes in the result from the PASSWORD() function
// that computes password hash values and in the structure of the user table where passwords are stored.
// mysql> SELECT PASSWORD('mypass');
// +-------------------------------------------+
// | PASSWORD('mypass') |
// +-------------------------------------------+
// | *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |
// +-------------------------------------------+
// MysqlNativePassword's format looks like "*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4", it store a hashing value.
// Use MysqlNativePassword in auth config, maybe more secure. After all, it is cryptographic storage.
MysqlNativePassword string
Password string
UserData string
SourceHost string
Groups []string
}
// AuthMethod is part of the AuthServer interface.
func (a *AuthServerStatic) AuthMethod(user string) (string, error) {
return a.Method, nil
return a.Method, nil
}
// Salt is part of the AuthServer interface.
func (a *AuthServerStatic) Salt() ([]byte, error) {
return NewSalt()
return NewSalt()
}
// ValidateHash is part of the AuthServer interface.
func (a *AuthServerStatic) ValidateHash(salt []byte, user string, authResponse []byte, remoteAddr net.Addr) (Getter, error) {
a.mu.Lock()
entries, ok := a.Entries[user]
a.mu.Unlock()
a.mu.Lock()
entries, ok := a.Entries[user]
a.mu.Unlock()
if !ok {
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
}
if !ok {
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
}
for _, entry := range entries {
if entry.MysqlNativePassword != "" {
isPass := isPassScrambleMysqlNativePassword(authResponse, salt, entry.MysqlNativePassword)
if matchSourceHost(remoteAddr, entry.SourceHost) && isPass {
return &StaticUserData{entry.UserData, entry.Groups}, nil
}
} else {
computedAuthResponse := ScramblePassword(salt, []byte(entry.Password))
// Validate the password.
if matchSourceHost(remoteAddr, entry.SourceHost) && bytes.Equal(authResponse, computedAuthResponse) {
return &StaticUserData{entry.UserData, entry.Groups}, nil
}
}
}
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
for _, entry := range entries {
if entry.MysqlNativePassword != "" {
isPass := isPassScrambleMysqlNativePassword(authResponse, salt, entry.MysqlNativePassword)
if matchSourceHost(remoteAddr, entry.SourceHost) && isPass {
return &StaticUserData{entry.UserData, entry.Groups}, nil
}
} else {
computedAuthResponse := ScramblePassword(salt, []byte(entry.Password))
// Validate the password.
if matchSourceHost(remoteAddr, entry.SourceHost) && bytes.Equal(authResponse, computedAuthResponse) {
return &StaticUserData{entry.UserData, entry.Groups}, nil
}
}
}
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
}
// Negotiate is part of the AuthServer interface.
// It will be called if Method is anything else than MysqlNativePassword.
// We only recognize MysqlClearPassword and MysqlDialog here.
func (a *AuthServerStatic) Negotiate(c *Conn, user string, remoteAddr net.Addr) (Getter, error) {
// Finish the negotiation.
password, err := AuthServerNegotiateClearOrDialog(c, a.Method)
if err != nil {
return nil, err
}
// Finish the negotiation.
password, err := AuthServerNegotiateClearOrDialog(c, a.Method)
if err != nil {
return nil, err
}
a.mu.Lock()
entries, ok := a.Entries[user]
a.mu.Unlock()
a.mu.Lock()
entries, ok := a.Entries[user]
a.mu.Unlock()
if !ok {
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
}
for _, entry := range entries {
// Validate the password.
if matchSourceHost(remoteAddr, entry.SourceHost) && entry.Password == password {
return &StaticUserData{entry.UserData, entry.Groups}, nil
}
}
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
if !ok {
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
}
for _, entry := range entries {
// Validate the password.
if matchSourceHost(remoteAddr, entry.SourceHost) && entry.Password == password {
return &StaticUserData{entry.UserData, entry.Groups}, nil
}
}
return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user)
}
func matchSourceHost(remoteAddr net.Addr, targetSourceHost string) bool {
// Legacy support, there was not matcher defined default to true
if targetSourceHost == "" {
return true
}
switch remoteAddr.(type) {
case *net.UnixAddr:
if targetSourceHost == localhostName {
return true
}
}
return false
// Legacy support, there was not matcher defined default to true
if targetSourceHost == "" {
return true
}
switch remoteAddr.(type) {
case *net.UnixAddr:
if targetSourceHost == localhostName {
return true
}
}
return false
}
// StaticUserData holds the username and groups
type StaticUserData struct {
username string
groups []string
username string
groups []string
}
// Get returns the wrapped username and groups
func (sud *StaticUserData) Get() *querypb.VTGateCallerID {
return &querypb.VTGateCallerID{Username: sud.username, Groups: sud.groups}
return &querypb.VTGateCallerID{Username: sud.username, Groups: sud.groups}
}
+2 -49
View File
@@ -137,13 +137,6 @@ type Conn struct {
bufferedWriter *bufio.Writer
sequence uint8
// fields contains the fields definitions for an on-going
// streaming query. It is set by ExecuteStreamFetch, and
// cleared by the last FetchNext(). It is nil if no streaming
// query is in progress. If the streaming query returned no
// fields, this is set to an empty array (but not nil).
fields []*querypb.Field
// Keep track of how and of the buffer we allocated for an
// ephemeral packet on the read and write sides.
// These fields are used by:
@@ -246,7 +239,7 @@ func (c *Conn) readHeaderFrom(r io.Reader) (int, error) {
return 0, vterrors.Wrapf(err, "io.ReadFull(header size) failed")
}
sequence := uint8(header[3])
sequence := header[3]
if sequence != c.sequence {
return 0, vterrors.Errorf(vtrpc.Code_INTERNAL, "invalid sequence, expected %v got %v", c.sequence, sequence)
}
@@ -429,30 +422,6 @@ func (c *Conn) readOnePacket() ([]byte, error) {
return data, nil
}
func (c *Conn) readOnePacketIgnoreSeq() ([]byte, error) {
r := c.getReader()
var header [4]byte
if _, err := io.ReadFull(r, header[:]); err != nil {
fmt.Println(fmt.Sprintf("Unexpected error, %s", err))
}
length := int(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)
c.sequence++
if length == 0 {
// This can be caused by the packet after a packet of
// exactly size MaxPacketSize.
return nil, nil
}
data := make([]byte, length)
if _, err := io.ReadFull(r, data); err != nil {
return nil, vterrors.Wrapf(err, "io.ReadFull(packet body of length %v) failed", length)
}
return data, nil
}
// readPacket reads a packet from the underlying connection.
// It re-assembles packets that span more than one message.
// This method returns a generic error, not a SQLError.
@@ -606,22 +575,6 @@ func (c *Conn) recycleWritePacket() {
c.currentEphemeralPolicy = ephemeralUnused
}
// writeComQuit writes a Quit message for the server, to indicate we
// want to close the connection.
// Client -> Server.
// Returns SQLError(CRServerGone) if it can't.
func (c *Conn) writeComQuit() error {
// This is a new command, need to reset the sequence.
c.sequence = 0
data := c.startEphemeralPacket(1)
data[0] = ComQuit
if err := c.writeEphemeralPacket(); err != nil {
return NewSQLError(CRServerGone, SSUnknownSQLState, err.Error())
}
return nil
}
// RemoteAddr returns the underlying socket RemoteAddr().
func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
@@ -937,7 +890,7 @@ func (c *Conn) RequestFile(filename string) []byte {
}
func (c *Conn) WriteErrorResponse(error string) {
c.writeErrorPacketFromError(NewSQLError(ERParseError, "42000", error))
_ = c.writeErrorPacketFromError(NewSQLError(ERParseError, "42000", error))
}
//
+24 -24
View File
@@ -18,43 +18,43 @@ package vmysql
// ConnParams contains all the parameters to use to connect to mysql.
type ConnParams struct {
Host string `json:"host"`
Port int `json:"port"`
Uname string `json:"uname"`
Pass string `json:"pass"`
DbName string `json:"dbname"`
UnixSocket string `json:"unix_socket"`
Charset string `json:"charset"`
Flags uint64 `json:"flags"`
Host string `json:"host"`
Port int `json:"port"`
Uname string `json:"uname"`
Pass string `json:"pass"`
DbName string `json:"dbname"`
UnixSocket string `json:"unix_socket"`
Charset string `json:"charset"`
Flags uint64 `json:"flags"`
// The following SSL flags are only used when flags |= 2048
// is set (CapabilityClientSSL).
SslCa string `json:"ssl_ca"`
SslCaPath string `json:"ssl_ca_path"`
SslCert string `json:"ssl_cert"`
SslKey string `json:"ssl_key"`
ServerName string `json:"server_name"`
// The following SSL flags are only used when flags |= 2048
// is set (CapabilityClientSSL).
SslCa string `json:"ssl_ca"`
SslCaPath string `json:"ssl_ca_path"`
SslCert string `json:"ssl_cert"`
SslKey string `json:"ssl_key"`
ServerName string `json:"server_name"`
// The following is only set when the deprecated "dbname" flags are
// supplied and will be removed.
DeprecatedDBName string
// The following is only set when the deprecated "dbname" flags are
// supplied and will be removed.
DeprecatedDBName string
// The following is only set to force the client to connect without
// using CapabilityClientDeprecateEOF
DisableClientDeprecateEOF bool
// The following is only set to force the client to connect without
// using CapabilityClientDeprecateEOF
DisableClientDeprecateEOF bool
}
// EnableSSL will set the right flag on the parameters.
func (cp *ConnParams) EnableSSL() {
cp.Flags |= CapabilityClientSSL
cp.Flags |= CapabilityClientSSL
}
// SslEnabled returns if SSL is enabled.
func (cp *ConnParams) SslEnabled() bool {
return (cp.Flags & CapabilityClientSSL) > 0
return (cp.Flags & CapabilityClientSSL) > 0
}
// EnableClientFoundRows sets the flag for CLIENT_FOUND_ROWS.
func (cp *ConnParams) EnableClientFoundRows() {
cp.Flags |= CapabilityClientFoundRows
cp.Flags |= CapabilityClientFoundRows
}
+187 -195
View File
@@ -17,193 +17,189 @@ limitations under the License.
package vmysql
const (
// MaxPacketSize is the maximum payload length of a packet
// the server supports.
MaxPacketSize = (1 << 24) - 1
// MaxPacketSize is the maximum payload length of a packet
// the server supports.
MaxPacketSize = (1 << 24) - 1
// protocolVersion is the current version of the protocol.
// Always 10.
protocolVersion = 10
// protocolVersion is the current version of the protocol.
// Always 10.
protocolVersion = 10
)
// Supported auth forms.
const (
// MysqlNativePassword uses a salt and transmits a hash on the wire.
MysqlNativePassword = "mysql_native_password"
// MysqlNativePassword uses a salt and transmits a hash on the wire.
MysqlNativePassword = "mysql_native_password"
// MysqlClearPassword transmits the password in the clear.
MysqlClearPassword = "mysql_clear_password"
// MysqlClearPassword transmits the password in the clear.
MysqlClearPassword = "mysql_clear_password"
// MysqlDialog uses the dialog plugin on the client side.
// It transmits data in the clear.
MysqlDialog = "dialog"
// MysqlDialog uses the dialog plugin on the client side.
// It transmits data in the clear.
MysqlDialog = "dialog"
)
// Capability flags.
// Originally found in include/mysql/mysql_com.h
const (
// CapabilityClientLongPassword is CLIENT_LONG_PASSWORD.
// New more secure passwords. Assumed to be set since 4.1.1.
// We do not check this anywhere.
CapabilityClientLongPassword = 1
// CapabilityClientLongPassword is CLIENT_LONG_PASSWORD.
// New more secure passwords. Assumed to be set since 4.1.1.
// We do not check this anywhere.
CapabilityClientLongPassword = 1
// CapabilityClientFoundRows is CLIENT_FOUND_ROWS.
CapabilityClientFoundRows = 1 << 1
// CapabilityClientFoundRows is CLIENT_FOUND_ROWS.
CapabilityClientFoundRows = 1 << 1
// CapabilityClientLongFlag is CLIENT_LONG_FLAG.
// Longer flags in Protocol::ColumnDefinition320.
// Set it everywhere, not used, as we use Protocol::ColumnDefinition41.
CapabilityClientLongFlag = 1 << 2
// CapabilityClientLongFlag is CLIENT_LONG_FLAG.
// Longer flags in Protocol::ColumnDefinition320.
// Set it everywhere, not used, as we use Protocol::ColumnDefinition41.
CapabilityClientLongFlag = 1 << 2
// CapabilityClientConnectWithDB is CLIENT_CONNECT_WITH_DB.
// One can specify db on connect.
CapabilityClientConnectWithDB = 1 << 3
// CapabilityClientConnectWithDB is CLIENT_CONNECT_WITH_DB.
// One can specify db on connect.
CapabilityClientConnectWithDB = 1 << 3
// CLIENT_NO_SCHEMA 1 << 4
// Do not permit database.table.column. We do permit it.
// CLIENT_NO_SCHEMA 1 << 4
// Do not permit database.table.column. We do permit it.
// CLIENT_COMPRESS 1 << 5
// We do not support compression. CPU is usually our bottleneck.
// CLIENT_COMPRESS 1 << 5
// We do not support compression. CPU is usually our bottleneck.
// CLIENT_ODBC 1 << 6
// No special behavior since 3.22.
// CLIENT_ODBC 1 << 6
// No special behavior since 3.22.
// CLIENT_LOCAL_FILES 1 << 7
// Client can use LOCAL INFILE request of LOAD DATA|XML.
// We do not set it.
CapabilityClientLoadDataLocal = 1 << 7
// CLIENT_LOCAL_FILES 1 << 7
// Client can use LOCAL INFILE request of LOAD DATA|XML.
// We do not set it.
CapabilityClientLoadDataLocal = 1 << 7
// CLIENT_IGNORE_SPACE 1 << 8
// Parser can ignore spaces before '('.
// We ignore this.
// CLIENT_IGNORE_SPACE 1 << 8
// Parser can ignore spaces before '('.
// We ignore this.
// CapabilityClientProtocol41 is CLIENT_PROTOCOL_41.
// New 4.1 protocol. Enforced everywhere.
CapabilityClientProtocol41 = 1 << 9
// CapabilityClientProtocol41 is CLIENT_PROTOCOL_41.
// New 4.1 protocol. Enforced everywhere.
CapabilityClientProtocol41 = 1 << 9
// CLIENT_INTERACTIVE 1 << 10
// Not specified, ignored.
// CLIENT_INTERACTIVE 1 << 10
// Not specified, ignored.
// CapabilityClientSSL is CLIENT_SSL.
// Switch to SSL after handshake.
CapabilityClientSSL = 1 << 11
// CapabilityClientSSL is CLIENT_SSL.
// Switch to SSL after handshake.
CapabilityClientSSL = 1 << 11
// CLIENT_IGNORE_SIGPIPE 1 << 12
// Do not issue SIGPIPE if network failures occur (libmysqlclient only).
// CLIENT_IGNORE_SIGPIPE 1 << 12
// Do not issue SIGPIPE if network failures occur (libmysqlclient only).
// CapabilityClientTransactions is CLIENT_TRANSACTIONS.
// Can send status flags in EOF_Packet.
// This flag is optional in 3.23, but always set by the server since 4.0.
// We just do it all the time.
CapabilityClientTransactions = 1 << 13
// CapabilityClientTransactions is CLIENT_TRANSACTIONS.
// Can send status flags in EOF_Packet.
// This flag is optional in 3.23, but always set by the server since 4.0.
// We just do it all the time.
CapabilityClientTransactions = 1 << 13
// CLIENT_RESERVED 1 << 14
// CLIENT_RESERVED 1 << 14
// CapabilityClientSecureConnection is CLIENT_SECURE_CONNECTION.
// New 4.1 authentication. Always set, expected, never checked.
CapabilityClientSecureConnection = 1 << 15
// CapabilityClientSecureConnection is CLIENT_SECURE_CONNECTION.
// New 4.1 authentication. Always set, expected, never checked.
CapabilityClientSecureConnection = 1 << 15
// CapabilityClientMultiStatements is CLIENT_MULTI_STATEMENTS
// Can handle multiple statements per COM_QUERY and COM_STMT_PREPARE.
CapabilityClientMultiStatements = 1 << 16
// CapabilityClientMultiStatements is CLIENT_MULTI_STATEMENTS
// Can handle multiple statements per COM_QUERY and COM_STMT_PREPARE.
CapabilityClientMultiStatements = 1 << 16
// CapabilityClientMultiResults is CLIENT_MULTI_RESULTS
// Can send multiple resultsets for COM_QUERY.
CapabilityClientMultiResults = 1 << 17
// CapabilityClientMultiResults is CLIENT_MULTI_RESULTS
// Can send multiple resultsets for COM_QUERY.
CapabilityClientMultiResults = 1 << 17
// CapabilityClientPluginAuth is CLIENT_PLUGIN_AUTH.
// Client supports plugin authentication.
CapabilityClientPluginAuth = 1 << 19
// CapabilityClientPluginAuth is CLIENT_PLUGIN_AUTH.
// Client supports plugin authentication.
CapabilityClientPluginAuth = 1 << 19
// CapabilityClientConnAttr is CLIENT_CONNECT_ATTRS
// Permits connection attributes in Protocol::HandshakeResponse41.
CapabilityClientConnAttr = 1 << 20
// CapabilityClientConnAttr is CLIENT_CONNECT_ATTRS
// Permits connection attributes in Protocol::HandshakeResponse41.
CapabilityClientConnAttr = 1 << 20
// CapabilityClientPluginAuthLenencClientData is CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
CapabilityClientPluginAuthLenencClientData = 1 << 21
// CapabilityClientPluginAuthLenencClientData is CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA
CapabilityClientPluginAuthLenencClientData = 1 << 21
// CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS 1 << 22
// Announces support for expired password extension.
// Not yet supported.
// CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS 1 << 22
// Announces support for expired password extension.
// Not yet supported.
// CLIENT_SESSION_TRACK 1 << 23
// Can set SERVER_SESSION_STATE_CHANGED in the Status Flags
// and send session-state change data after a OK packet.
// Not yet supported.
// CLIENT_SESSION_TRACK 1 << 23
// Can set SERVER_SESSION_STATE_CHANGED in the Status Flags
// and send session-state change data after a OK packet.
// Not yet supported.
// CapabilityClientDeprecateEOF is CLIENT_DEPRECATE_EOF
// Expects an OK (instead of EOF) after the resultset rows of a Text Resultset.
CapabilityClientDeprecateEOF = 1 << 24
// CapabilityClientDeprecateEOF is CLIENT_DEPRECATE_EOF
// Expects an OK (instead of EOF) after the resultset rows of a Text Resultset.
CapabilityClientDeprecateEOF = 1 << 24
)
// Packet types.
// Originally found in include/mysql/mysql_com.h
const (
// ComQuit is COM_QUIT.
ComQuit = 0x01
// ComQuit is COM_QUIT.
ComQuit = 0x01
// ComInitDB is COM_INIT_DB.
ComInitDB = 0x02
// ComInitDB is COM_INIT_DB.
ComInitDB = 0x02
// ComQuery is COM_QUERY.
ComQuery = 0x03
// ComQuery is COM_QUERY.
ComQuery = 0x03
// ComPing is COM_PING.
ComPing = 0x0e
// ComPing is COM_PING.
ComPing = 0x0e
// ComSetOption is COM_SET_OPTION
ComSetOption = 0x1b
// ComSetOption is COM_SET_OPTION
ComSetOption = 0x1b
// OKPacket is the header of the OK packet.
OKPacket = 0x00
// EOFPacket is the header of the EOF packet.
EOFPacket = 0xfe
// OKPacket is the header of the OK packet.
OKPacket = 0x00
// AuthSwitchRequestPacket is used to switch auth method.
AuthSwitchRequestPacket = 0xfe
// EOFPacket is the header of the EOF packet.
EOFPacket = 0xfe
// ErrPacket is the header of the error packet.
ErrPacket = 0xff
// AuthSwitchRequestPacket is used to switch auth method.
AuthSwitchRequestPacket = 0xfe
// ErrPacket is the header of the error packet.
ErrPacket = 0xff
// NullValue is the encoded value of NULL.
NullValue = 0xfb
// NullValue is the encoded value of NULL.
NullValue = 0xfb
)
// Error codes for client-side errors.
// Originally found in include/mysql/errmsg.h and
// https://dev.mysql.com/doc/refman/5.7/en/error-messages-client.html
const (
// CRUnknownError is CR_UNKNOWN_ERROR
CRUnknownError = 2000
// CRUnknownError is CR_UNKNOWN_ERROR
CRUnknownError = 2000
// CRServerGone is CR_SERVER_GONE_ERROR.
// This is returned if the client tries to send a command but it fails.
CRServerGone = 2006
// CRServerGone is CR_SERVER_GONE_ERROR.
// This is returned if the client tries to send a command but it fails.
CRServerGone = 2006
// CRServerHandshakeErr is CR_SERVER_HANDSHAKE_ERR
CRServerHandshakeErr = 2012
// CRServerHandshakeErr is CR_SERVER_HANDSHAKE_ERR
CRServerHandshakeErr = 2012
// CRServerLost is CR_SERVER_LOST.
// Used when:
// - the client cannot write an initial auth packet.
// - the client cannot read an initial auth packet.
// - the client cannot read a response from the server.
CRServerLost = 2013
// CRServerLost is CR_SERVER_LOST.
// Used when:
// - the client cannot write an initial auth packet.
// - the client cannot read an initial auth packet.
// - the client cannot read a response from the server.
CRServerLost = 2013
// CRMalformedPacket is CR_MALFORMED_PACKET
CRMalformedPacket = 2027
// CRMalformedPacket is CR_MALFORMED_PACKET
CRMalformedPacket = 2027
)
// Error codes return in SQLErrors generated by vitess. These error codes
// are in a high range to avoid conflicting with mysql error codes below.
const (
// ERVitessMaxRowsExceeded is when a user tries to select more rows than the max rows as enforced by vitess.
ERVitessMaxRowsExceeded = 10001
// ERVitessMaxRowsExceeded is when a user tries to select more rows than the max rows as enforced by vitess.
ERVitessMaxRowsExceeded = 10001
)
// Error codes for server-side errors.
@@ -212,44 +208,40 @@ const (
// The below are in sorted order by value, grouped by vterror code they should be bucketed into.
// See above reference for more information on each code.
const (
// unknown
ERUnknownError = 1105
// unknown
ERUnknownError = 1105
// unavailable
ERServerShutdown = 1053
// unavailable
ERServerShutdown = 1053
// permissions
ERAccessDeniedError = 1045
// permissions
ERAccessDeniedError = 1045
// invalid arg
ERUnknownComError = 1047
// invalid arg
ERUnknownComError = 1047
ERParseError = 1064
ERParseError = 1064
)
// Sql states for errors.
// Originally found in include/mysql/sql_state.h
const (
// SSUnknownSqlstate is ER_SIGNAL_EXCEPTION in
// include/mysql/sql_state.h, but:
// const char *unknown_sqlstate= "HY000"
// in client.c. So using that one.
SSUnknownSQLState = "HY000"
// SSUnknownSqlstate is ER_SIGNAL_EXCEPTION in
// include/mysql/sql_state.h, but:
// const char *unknown_sqlstate= "HY000"
// in client.c. So using that one.
SSUnknownSQLState = "HY000"
// SSUnknownComError is ER_UNKNOWN_COM_ERROR
SSUnknownComError = "08S01"
// SSUnknownComError is ER_UNKNOWN_COM_ERROR
SSUnknownComError = "08S01"
// SSHandshakeError is ER_HANDSHAKE_ERROR
// SSHandshakeError is ER_HANDSHAKE_ERROR
// SSServerShutdown is ER_SERVER_SHUTDOWN
SSServerShutdown = "08S01"
// SSAccessDeniedError is ER_ACCESS_DENIED_ERROR
SSAccessDeniedError = "28000"
// SSServerShutdown is ER_SERVER_SHUTDOWN
SSServerShutdown = "08S01"
// SSAccessDeniedError is ER_ACCESS_DENIED_ERROR
SSAccessDeniedError = "28000"
)
// Status flags. They are returned by the server in a few cases.
@@ -257,63 +249,63 @@ const (
// See http://dev.mysql.com/doc/internals/en/status-flags.html
const (
// ServerMoreResultsExists is SERVER_MORE_RESULTS_EXISTS
ServerMoreResultsExists = 0x0008
// ServerMoreResultsExists is SERVER_MORE_RESULTS_EXISTS
ServerMoreResultsExists = 0x0008
)
// A few interesting character set values.
// See http://dev.mysql.com/doc/internals/en/character-set.html#packet-Protocol::CharacterSet
const (
// CharacterSetUtf8 is for UTF8. We use this by default.
CharacterSetUtf8 = 33
// CharacterSetUtf8 is for UTF8. We use this by default.
CharacterSetUtf8 = 33
// CharacterSetBinary is for binary. Use by integer fields for instance.
CharacterSetBinary = 63
// CharacterSetBinary is for binary. Use by integer fields for instance.
CharacterSetBinary = 63
)
// CharacterSetMap maps the charset name (used in ConnParams) to the
// integer value. Interesting ones have their own constant above.
var CharacterSetMap = map[string]uint8{
"big5": 1,
"dec8": 3,
"cp850": 4,
"hp8": 6,
"koi8r": 7,
"latin1": 8,
"latin2": 9,
"swe7": 10,
"ascii": 11,
"ujis": 12,
"sjis": 13,
"hebrew": 16,
"tis620": 18,
"euckr": 19,
"koi8u": 22,
"gb2312": 24,
"greek": 25,
"cp1250": 26,
"gbk": 28,
"latin5": 30,
"armscii8": 32,
"utf8": CharacterSetUtf8,
"ucs2": 35,
"cp866": 36,
"keybcs2": 37,
"macce": 38,
"macroman": 39,
"cp852": 40,
"latin7": 41,
"utf8mb4": 45,
"cp1251": 51,
"utf16": 54,
"utf16le": 56,
"cp1256": 57,
"cp1257": 59,
"utf32": 60,
"binary": CharacterSetBinary,
"geostd8": 92,
"cp932": 95,
"eucjpms": 97,
"big5": 1,
"dec8": 3,
"cp850": 4,
"hp8": 6,
"koi8r": 7,
"latin1": 8,
"latin2": 9,
"swe7": 10,
"ascii": 11,
"ujis": 12,
"sjis": 13,
"hebrew": 16,
"tis620": 18,
"euckr": 19,
"koi8u": 22,
"gb2312": 24,
"greek": 25,
"cp1250": 26,
"gbk": 28,
"latin5": 30,
"armscii8": 32,
"utf8": CharacterSetUtf8,
"ucs2": 35,
"cp866": 36,
"keybcs2": 37,
"macce": 38,
"macroman": 39,
"cp852": 40,
"latin7": 41,
"utf8mb4": 45,
"cp1251": 51,
"utf16": 54,
"utf16le": 56,
"cp1256": 57,
"cp1257": 59,
"utf32": 60,
"binary": CharacterSetBinary,
"geostd8": 92,
"cp932": 95,
"eucjpms": 97,
}
// IsNum returns true if a MySQL type is a numeric value.
@@ -322,5 +314,5 @@ var CharacterSetMap = map[string]uint8{
// FIXME(alainjobart) This needs to use the constants in
// replication/constants.go, so we are using numerical values here.
func IsNum(typ uint8) bool {
return ((typ <= 9 /* MYSQL_TYPE_INT24 */ && typ != 7 /* MYSQL_TYPE_TIMESTAMP */) || typ == 13 /* MYSQL_TYPE_YEAR */ || typ == 246 /* MYSQL_TYPE_NEWDECIMAL */)
return ((typ <= 9 /* MYSQL_TYPE_INT24 */ && typ != 7 /* MYSQL_TYPE_TIMESTAMP */) || typ == 13 /* MYSQL_TYPE_YEAR */ || typ == 246 /* MYSQL_TYPE_NEWDECIMAL */)
}
+151 -151
View File
@@ -17,8 +17,8 @@ limitations under the License.
package vmysql
import (
"bytes"
"encoding/binary"
"bytes"
"encoding/binary"
)
// This file contains the data encoding and decoding functions.
@@ -34,97 +34,97 @@ import (
// lenEncIntSize returns the number of bytes required to encode a
// variable-length integer.
func lenEncIntSize(i uint64) int {
switch {
case i < 251:
return 1
case i < 1<<16:
return 3
case i < 1<<24:
return 4
default:
return 9
}
switch {
case i < 251:
return 1
case i < 1<<16:
return 3
case i < 1<<24:
return 4
default:
return 9
}
}
func writeLenEncInt(data []byte, pos int, i uint64) int {
switch {
case i < 251:
data[pos] = byte(i)
return pos + 1
case i < 1<<16:
data[pos] = 0xfc
data[pos+1] = byte(i)
data[pos+2] = byte(i >> 8)
return pos + 3
case i < 1<<24:
data[pos] = 0xfd
data[pos+1] = byte(i)
data[pos+2] = byte(i >> 8)
data[pos+3] = byte(i >> 16)
return pos + 4
default:
data[pos] = 0xfe
data[pos+1] = byte(i)
data[pos+2] = byte(i >> 8)
data[pos+3] = byte(i >> 16)
data[pos+4] = byte(i >> 24)
data[pos+5] = byte(i >> 32)
data[pos+6] = byte(i >> 40)
data[pos+7] = byte(i >> 48)
data[pos+8] = byte(i >> 56)
return pos + 9
}
switch {
case i < 251:
data[pos] = byte(i)
return pos + 1
case i < 1<<16:
data[pos] = 0xfc
data[pos+1] = byte(i)
data[pos+2] = byte(i >> 8)
return pos + 3
case i < 1<<24:
data[pos] = 0xfd
data[pos+1] = byte(i)
data[pos+2] = byte(i >> 8)
data[pos+3] = byte(i >> 16)
return pos + 4
default:
data[pos] = 0xfe
data[pos+1] = byte(i)
data[pos+2] = byte(i >> 8)
data[pos+3] = byte(i >> 16)
data[pos+4] = byte(i >> 24)
data[pos+5] = byte(i >> 32)
data[pos+6] = byte(i >> 40)
data[pos+7] = byte(i >> 48)
data[pos+8] = byte(i >> 56)
return pos + 9
}
}
func lenNullString(value string) int {
return len(value) + 1
return len(value) + 1
}
func writeNullString(data []byte, pos int, value string) int {
pos += copy(data[pos:], value)
data[pos] = 0
return pos + 1
pos += copy(data[pos:], value)
data[pos] = 0
return pos + 1
}
func writeEOFString(data []byte, pos int, value string) int {
pos += copy(data[pos:], value)
return pos
pos += copy(data[pos:], value)
return pos
}
func writeByte(data []byte, pos int, value byte) int {
data[pos] = value
return pos + 1
data[pos] = value
return pos + 1
}
func writeUint16(data []byte, pos int, value uint16) int {
data[pos] = byte(value)
data[pos+1] = byte(value >> 8)
return pos + 2
data[pos] = byte(value)
data[pos+1] = byte(value >> 8)
return pos + 2
}
func writeUint32(data []byte, pos int, value uint32) int {
data[pos] = byte(value)
data[pos+1] = byte(value >> 8)
data[pos+2] = byte(value >> 16)
data[pos+3] = byte(value >> 24)
return pos + 4
data[pos] = byte(value)
data[pos+1] = byte(value >> 8)
data[pos+2] = byte(value >> 16)
data[pos+3] = byte(value >> 24)
return pos + 4
}
func lenEncStringSize(value string) int {
l := len(value)
return lenEncIntSize(uint64(l)) + l
l := len(value)
return lenEncIntSize(uint64(l)) + l
}
func writeLenEncString(data []byte, pos int, value string) int {
pos = writeLenEncInt(data, pos, uint64(len(value)))
return writeEOFString(data, pos, value)
pos = writeLenEncInt(data, pos, uint64(len(value)))
return writeEOFString(data, pos, value)
}
func writeZeroes(data []byte, pos int, len int) int {
for i := 0; i < len; i++ {
data[pos+i] = 0
}
return pos + len
for i := 0; i < len; i++ {
data[pos+i] = 0
}
return pos + len
}
//
@@ -136,121 +136,121 @@ func writeZeroes(data []byte, pos int, len int) int {
//
func readByte(data []byte, pos int) (byte, int, bool) {
if pos >= len(data) {
return 0, 0, false
}
return data[pos], pos + 1, true
if pos >= len(data) {
return 0, 0, false
}
return data[pos], pos + 1, true
}
func readBytes(data []byte, pos int, size int) ([]byte, int, bool) {
if pos+size-1 >= len(data) {
return nil, 0, false
}
return data[pos : pos+size], pos + size, true
if pos+size-1 >= len(data) {
return nil, 0, false
}
return data[pos : pos+size], pos + size, true
}
// readBytesCopy returns a copy of the bytes in the packet.
// Useful to remember contents of ephemeral packets.
func readBytesCopy(data []byte, pos int, size int) ([]byte, int, bool) {
if pos+size-1 >= len(data) {
return nil, 0, false
}
result := make([]byte, size)
copy(result, data[pos:pos+size])
return result, pos + size, true
if pos+size-1 >= len(data) {
return nil, 0, false
}
result := make([]byte, size)
copy(result, data[pos:pos+size])
return result, pos + size, true
}
func readNullString(data []byte, pos int) (string, int, bool) {
end := bytes.IndexByte(data[pos:], 0)
if end == -1 {
return "", 0, false
}
return string(data[pos : pos+end]), pos + end + 1, true
end := bytes.IndexByte(data[pos:], 0)
if end == -1 {
return "", 0, false
}
return string(data[pos : pos+end]), pos + end + 1, true
}
func readUint16(data []byte, pos int) (uint16, int, bool) {
if pos+1 >= len(data) {
return 0, 0, false
}
return binary.LittleEndian.Uint16(data[pos : pos+2]), pos + 2, true
if pos+1 >= len(data) {
return 0, 0, false
}
return binary.LittleEndian.Uint16(data[pos : pos+2]), pos + 2, true
}
func readUint32(data []byte, pos int) (uint32, int, bool) {
if pos+3 >= len(data) {
return 0, 0, false
}
return binary.LittleEndian.Uint32(data[pos : pos+4]), pos + 4, true
if pos+3 >= len(data) {
return 0, 0, false
}
return binary.LittleEndian.Uint32(data[pos : pos+4]), pos + 4, true
}
func readLenEncInt(data []byte, pos int) (uint64, int, bool) {
if pos >= len(data) {
return 0, 0, false
}
switch data[pos] {
case 0xfc:
// Encoded in the next 2 bytes.
if pos+2 >= len(data) {
return 0, 0, false
}
return uint64(data[pos+1]) |
uint64(data[pos+2])<<8, pos + 3, true
case 0xfd:
// Encoded in the next 3 bytes.
if pos+3 >= len(data) {
return 0, 0, false
}
return uint64(data[pos+1]) |
uint64(data[pos+2])<<8 |
uint64(data[pos+3])<<16, pos + 4, true
case 0xfe:
// Encoded in the next 8 bytes.
if pos+8 >= len(data) {
return 0, 0, false
}
return uint64(data[pos+1]) |
uint64(data[pos+2])<<8 |
uint64(data[pos+3])<<16 |
uint64(data[pos+4])<<24 |
uint64(data[pos+5])<<32 |
uint64(data[pos+6])<<40 |
uint64(data[pos+7])<<48 |
uint64(data[pos+8])<<56, pos + 9, true
}
return uint64(data[pos]), pos + 1, true
if pos >= len(data) {
return 0, 0, false
}
switch data[pos] {
case 0xfc:
// Encoded in the next 2 bytes.
if pos+2 >= len(data) {
return 0, 0, false
}
return uint64(data[pos+1]) |
uint64(data[pos+2])<<8, pos + 3, true
case 0xfd:
// Encoded in the next 3 bytes.
if pos+3 >= len(data) {
return 0, 0, false
}
return uint64(data[pos+1]) |
uint64(data[pos+2])<<8 |
uint64(data[pos+3])<<16, pos + 4, true
case 0xfe:
// Encoded in the next 8 bytes.
if pos+8 >= len(data) {
return 0, 0, false
}
return uint64(data[pos+1]) |
uint64(data[pos+2])<<8 |
uint64(data[pos+3])<<16 |
uint64(data[pos+4])<<24 |
uint64(data[pos+5])<<32 |
uint64(data[pos+6])<<40 |
uint64(data[pos+7])<<48 |
uint64(data[pos+8])<<56, pos + 9, true
}
return uint64(data[pos]), pos + 1, true
}
func readLenEncString(data []byte, pos int) (string, int, bool) {
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return "", 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return "", 0, false
}
return string(data[pos : pos+s]), pos + s, true
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return "", 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return "", 0, false
}
return string(data[pos : pos+s]), pos + s, true
}
func skipLenEncString(data []byte, pos int) (int, bool) {
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return 0, false
}
return pos + s, true
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return 0, false
}
return pos + s, true
}
func readLenEncStringAsBytes(data []byte, pos int) ([]byte, int, bool) {
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return nil, 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return nil, 0, false
}
return data[pos : pos+s], pos + s, true
size, pos, ok := readLenEncInt(data, pos)
if !ok {
return nil, 0, false
}
s := int(size)
if pos+s-1 >= len(data) {
return nil, 0, false
}
return data[pos : pos+s], pos + s, true
}
+447 -472
View File
File diff suppressed because it is too large Load Diff
+7 -11
View File
@@ -37,7 +37,6 @@ const (
// timing metric keys
connectTimingKey = "Connect"
queryTimingKey = "Query"
versionSSL30 = "SSL30"
versionTLS10 = "TLS10"
versionTLS11 = "TLS11"
versionTLS12 = "TLS12"
@@ -322,7 +321,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
}
} else {
if l.RequireSecureTransport {
c.writeErrorPacketFromError(vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "server does not allow insecure connections, client must use SSL/TLS"))
_ = c.writeErrorPacketFromError(vterrors.Errorf(vtrpc.Code_UNAVAILABLE, "server does not allow insecure connections, client must use SSL/TLS"))
}
connCountByTLSVer.Add(versionNoTLS, 1)
defer connCountByTLSVer.Add(versionNoTLS, -1)
@@ -331,7 +330,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
// See what auth method the AuthServer wants to use for that user.
authServerMethod, err := l.authServer.AuthMethod(user)
if err != nil {
c.writeErrorPacketFromError(err)
_ = c.writeErrorPacketFromError(err)
return
}
@@ -344,7 +343,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
userData, err := l.authServer.ValidateHash(salt, user, authResponse, conn.RemoteAddr())
if err != nil {
log.Trace("Error authenticating user using MySQL native password: %v", err)
c.writeErrorPacketFromError(err)
_ = c.writeErrorPacketFromError(err)
return
}
c.User = user
@@ -358,8 +357,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
if err != nil {
return
}
//lint:ignore SA4006 This line is required because the binary protocol requires padding with 0
data := make([]byte, 21)
data := make([]byte, 21) //nolint:ineffassign,staticcheck // SA4006 This line is required because the binary protocol requires padding with 0
data = append(salt, byte(0x00))
if err := c.writeAuthSwitchRequest(MysqlNativePassword, data); err != nil {
log.Error("Error writing auth switch packet for %s: %v", c, err)
@@ -376,7 +374,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
userData, err := l.authServer.ValidateHash(salt, user, response, conn.RemoteAddr())
if err != nil {
log.Trace("Error authenticating user using MySQL native password: %v", err)
c.writeErrorPacketFromError(err)
_ = c.writeErrorPacketFromError(err)
return
}
c.User = user
@@ -387,7 +385,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
// The negotiation happens in clear text. Let's check we can.
if !l.AllowClearTextWithoutTLS && c.Capabilities&CapabilityClientSSL == 0 {
c.writeErrorPacket(CRServerHandshakeErr, SSUnknownSQLState, "Cannot use clear text authentication over non-SSL connections.")
_ = c.writeErrorPacket(CRServerHandshakeErr, SSUnknownSQLState, "Cannot use clear text authentication over non-SSL connections.")
return
}
@@ -406,7 +404,7 @@ func (l *Listener) handle(conn net.Conn, connectionID uint32, acceptTime time.Ti
// auth server.
userData, err := l.authServer.Negotiate(c, user, conn.RemoteAddr())
if err != nil {
c.writeErrorPacketFromError(err)
_ = c.writeErrorPacketFromError(err)
return
}
c.User = user
@@ -770,8 +768,6 @@ func (c *Conn) writeAuthSwitchRequest(pluginName string, pluginData []byte) erro
// Whenever we move to a new version of go, we will need add any new supported TLS versions here
func tlsVersionToString(version uint16) string {
switch version {
case tls.VersionSSL30:
return versionSSL30
case tls.VersionTLS10:
return versionTLS10
case tls.VersionTLS11:
+29 -29
View File
@@ -17,58 +17,58 @@ limitations under the License.
package vmysql
import (
"bytes"
"fmt"
"bytes"
"fmt"
"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/sqlparser"
)
// SQLError is the error structure returned from calling a db library function
type SQLError struct {
Num int
State string
Message string
Query string
Num int
State string
Message string
Query string
}
// NewSQLError creates a new SQLError.
// If sqlState is left empty, it will default to "HY000" (general error).
// TODO: Should be aligned with vterrors, stack traces and wrapping
func NewSQLError(number int, sqlState string, format string, args ...interface{}) *SQLError {
if sqlState == "" {
sqlState = SSUnknownSQLState
}
return &SQLError{
Num: number,
State: sqlState,
Message: fmt.Sprintf(format, args...),
}
if sqlState == "" {
sqlState = SSUnknownSQLState
}
return &SQLError{
Num: number,
State: sqlState,
Message: fmt.Sprintf(format, args...),
}
}
// Error implements the error interface
func (se *SQLError) Error() string {
buf := &bytes.Buffer{}
buf.WriteString(se.Message)
buf := &bytes.Buffer{}
buf.WriteString(se.Message)
// Add MySQL errno and SQLSTATE in a format that we can later parse.
// There's no avoiding string parsing because all errors
// are converted to strings anyway at RPC boundaries.
// See NewSQLErrorFromError.
fmt.Fprintf(buf, " (errno %v) (sqlstate %v)", se.Num, se.State)
// Add MySQL errno and SQLSTATE in a format that we can later parse.
// There's no avoiding string parsing because all errors
// are converted to strings anyway at RPC boundaries.
// See NewSQLErrorFromError.
fmt.Fprintf(buf, " (errno %v) (sqlstate %v)", se.Num, se.State)
if se.Query != "" {
fmt.Fprintf(buf, " during query: %s", sqlparser.TruncateForLog(se.Query))
}
if se.Query != "" {
fmt.Fprintf(buf, " during query: %s", sqlparser.TruncateForLog(se.Query))
}
return buf.String()
return buf.String()
}
// Number returns the internal MySQL error code.
func (se *SQLError) Number() int {
return se.Num
return se.Num
}
// SQLState returns the SQLSTATE value.
func (se *SQLError) SQLState() string {
return se.State
}
return se.State
}
+1 -1
View File
@@ -1,5 +1,5 @@
package rhttp
type Config struct {
IpHeader string
IpHeader string
}
+1 -1
View File
@@ -119,7 +119,7 @@ func compileTpl(c *gin.Context, tpl string) (compiled string) {
if headerVarMatcher.FindString(tpl) != "" {
compiled = headerVarMatcher.ReplaceAllString(compiled, c.GetHeader(headerVarMatcher.FindStringSubmatch(tpl)[1]))
}
return
return compiled
}
func (s *Server) Receive(c *gin.Context) {
+2 -2
View File
@@ -17,7 +17,7 @@ type Record struct {
Path string `form:"path" json:"path"`
record.BaseRecord
RawRequest string `json:"raw_request" notice:"-"`
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
}
func (Record) TableName() string {
@@ -42,7 +42,7 @@ func NewRecord(rule *Rule, flag, method, url, ip, area, raw string) (r *Record,
Rule: *rule,
}
err = database.DB.Create(r).Error
return
return r, err
}
func ListRecords(c *gin.Context) {
+4 -5
View File
@@ -13,7 +13,7 @@ import (
// Http rule struct
type Rule struct {
rule.BaseRule
ResponseStatusCode string `gorm:"index;default:200;not null" form:"response_status_code" json:"response_status_code"`
ResponseStatusCode string `gorm:"index;default:200;not null" form:"response_status_code" json:"response_status_code"`
ResponseHeaders database.MapField `form:"response_headers" json:"response_headers"`
ResponseBody string `gorm:"default:Hello RevSuit!" form:"response_body" json:"response_body"`
}
@@ -23,7 +23,7 @@ func (Rule) TableName() string {
}
// New http rule struct
func NewRule(name, flagFormat, responseBody string, pushToClient, notice bool, responseStatus string, responseHeaders database.MapField, ) *Rule {
func NewRule(name, flagFormat, responseBody string, pushToClient, notice bool, responseStatus string, responseHeaders database.MapField) *Rule {
return &Rule{
BaseRule: rule.BaseRule{
Name: name,
@@ -59,7 +59,7 @@ func (r *Rule) CreateOrUpdate() (err error) {
}
err = GetServer().updateRules()
return
return err
}
// Delete the http rule in database and ruleSet
@@ -71,7 +71,7 @@ func (r *Rule) Delete() (err error) {
}
err = GetServer().updateRules()
return
return err
}
// List all http rules those satisfy the filter
@@ -195,5 +195,4 @@ func DeleteRules(c *gin.Context) {
"error": nil,
"data": nil,
})
return
}
+1 -1
View File
@@ -14,7 +14,7 @@ func ping(c *gin.Context) {
}
func events(c *gin.Context) {
log.Info("Receive connection from ", c.Request.RemoteAddr)
log.Info("Receive connection from %v", c.Request.RemoteAddr)
c.Stream(func(w io.Writer) bool {
c.SSEvent("message", "connect succeed")
select {
+18
View File
@@ -24,11 +24,29 @@ func initDatabase(dsn string) {
}
err = database.DB.AutoMigrate(&http.Record{})
if err != nil {
log.Fatal(err.Error())
}
err = database.DB.AutoMigrate(&dns.Record{})
if err != nil {
log.Fatal(err.Error())
}
err = database.DB.AutoMigrate(&mysql.Record{})
if err != nil {
log.Fatal(err.Error())
}
err = database.DB.AutoMigrate(&http.Rule{})
if err != nil {
log.Fatal(err.Error())
}
err = database.DB.AutoMigrate(&dns.Rule{})
if err != nil {
log.Fatal(err.Error())
}
err = database.DB.AutoMigrate(&mysql.Rule{})
if err != nil {
log.Fatal(err.Error())
}
err = database.DB.AutoMigrate(&mysql.File{})
if err != nil {
log.Fatal(err.Error())