From 66886d3ef9de6ebb2fca665789cc92c3bee8a01b Mon Sep 17 00:00:00 2001 From: Garet Halliday <me@garet.holiday> Date: Thu, 24 Aug 2023 14:54:46 -0500 Subject: [PATCH] sizes --- lib/bouncer/backends/v0/accept.go | 13 ++++++++---- lib/bouncer/backends/v0/cancel.go | 2 +- lib/zap/packet.go | 20 +++++++++++++++++-- .../packets/v3.0/authenticationcleartext.go | 2 +- lib/zap/packets/v3.0/authenticationmd5.go | 2 +- lib/zap/packets/v3.0/authenticationok.go | 2 +- .../packets/v3.0/authenticationresponse.go | 2 +- lib/zap/packets/v3.0/authenticationsasl.go | 8 +++++++- .../v3.0/authenticationsaslcontinue.go | 2 +- .../packets/v3.0/authenticationsaslfinal.go | 2 +- lib/zap/packets/v3.0/backendkeydata.go | 2 +- lib/zap/packets/v3.0/bind.go | 14 ++++++++++++- lib/zap/packets/v3.0/close.go | 2 +- lib/zap/packets/v3.0/copyfail.go | 2 +- lib/zap/packets/v3.0/describe.go | 2 +- lib/zap/packets/v3.0/errorresponse.go | 10 +++++++++- lib/zap/packets/v3.0/execute.go | 2 +- .../packets/v3.0/negotiateprotocolversion.go | 7 ++++++- lib/zap/packets/v3.0/parameterstatus.go | 2 +- lib/zap/packets/v3.0/parse.go | 2 +- lib/zap/packets/v3.0/passwordmessage.go | 2 +- lib/zap/packets/v3.0/query.go | 2 +- lib/zap/packets/v3.0/readyforquery.go | 2 +- lib/zap/packets/v3.0/saslinitialresponse.go | 2 +- 24 files changed, 80 insertions(+), 28 deletions(-) diff --git a/lib/bouncer/backends/v0/accept.go b/lib/bouncer/backends/v0/accept.go index 7e13419e..2ea282d9 100644 --- a/lib/bouncer/backends/v0/accept.go +++ b/lib/bouncer/backends/v0/accept.go @@ -231,7 +231,7 @@ func startup1(conn *bouncer.Conn) (done bool, err error) { } func enableSSL(server zap.ReadWriter, config *tls.Config) (bool, error) { - packet := zap.NewPacket(0) + packet := zap.NewPacket(0, 4) packet = packet.AppendUint16(1234) packet = packet.AppendUint16(5679) if err := server.WritePacket(packet); err != nil { @@ -280,8 +280,13 @@ func Accept(server zap.ReadWriter, options AcceptOptions) (bouncer.Conn, error) } } - // we can re-use the memory for this pkt most of the way down because we don't pass this anywhere - packet := zap.NewPacket(0) + size := 4 + len("user") + 1 + len(username) + 1 + len("database") + 1 + len(options.Database) + 1 + for key, value := range options.StartupParameters { + size += len(key.String()) + len(value) + 2 + } + size += 1 + + packet := zap.NewPacket(0, size) packet = packet.AppendUint16(3) packet = packet.AppendUint16(0) packet = packet.AppendString("user") @@ -292,7 +297,7 @@ func Accept(server zap.ReadWriter, options AcceptOptions) (bouncer.Conn, error) packet = packet.AppendString(key.String()) packet = packet.AppendString(value) } - packet = packet.AppendString("") + packet = packet.AppendUint8(0) err := server.WritePacket(packet) if err != nil { diff --git a/lib/bouncer/backends/v0/cancel.go b/lib/bouncer/backends/v0/cancel.go index 06f73845..e5659b2b 100644 --- a/lib/bouncer/backends/v0/cancel.go +++ b/lib/bouncer/backends/v0/cancel.go @@ -3,7 +3,7 @@ package backends import "pggat2/lib/zap" func Cancel(server zap.ReadWriter, key [8]byte) error { - packet := zap.NewPacket(0) + packet := zap.NewPacket(0, 12) packet = packet.AppendUint16(1234) packet = packet.AppendUint16(5678) packet = packet.AppendBytes(key[:]) diff --git a/lib/zap/packet.go b/lib/zap/packet.go index 88e275dc..73d12d39 100644 --- a/lib/zap/packet.go +++ b/lib/zap/packet.go @@ -7,8 +7,14 @@ import ( type Packet []byte -func NewPacket(typ Type) Packet { - return []byte{byte(typ), 0, 0, 0, 4} +func NewPacket(typ Type, size ...int) Packet { + if len(size) > 0 { + packet := make([]byte, 5, 5+size[0]) + packet[0] = byte(typ) + return packet + } else { + return []byte{byte(typ), 0, 0, 0, 0} + } } func (T Packet) Payload() PacketFragment { @@ -39,6 +45,16 @@ func (T Packet) Grow(n int) Packet { return p } +func (T Packet) Reserve(n int) Packet { + if len(T)+n > cap(T) { + p := make([]byte, len(T), len(T)+n) + copy(p, T) + return p + } + + return T +} + func (T Packet) Type() Type { return Type(T[0]) } diff --git a/lib/zap/packets/v3.0/authenticationcleartext.go b/lib/zap/packets/v3.0/authenticationcleartext.go index 9985942a..027e24e0 100644 --- a/lib/zap/packets/v3.0/authenticationcleartext.go +++ b/lib/zap/packets/v3.0/authenticationcleartext.go @@ -17,7 +17,7 @@ func (T *AuthenticationCleartext) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationCleartext) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthentication) + packet := zap.NewPacket(TypeAuthentication, 4) packet = packet.AppendUint32(3) return packet } diff --git a/lib/zap/packets/v3.0/authenticationmd5.go b/lib/zap/packets/v3.0/authenticationmd5.go index fd480670..8f7ad4e9 100644 --- a/lib/zap/packets/v3.0/authenticationmd5.go +++ b/lib/zap/packets/v3.0/authenticationmd5.go @@ -20,7 +20,7 @@ func (T *AuthenticationMD5) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationMD5) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthentication) + packet := zap.NewPacket(TypeAuthentication, 8) packet = packet.AppendUint32(5) packet = packet.AppendBytes(T.Salt[:]) return packet diff --git a/lib/zap/packets/v3.0/authenticationok.go b/lib/zap/packets/v3.0/authenticationok.go index e73fc9fa..73e4ac45 100644 --- a/lib/zap/packets/v3.0/authenticationok.go +++ b/lib/zap/packets/v3.0/authenticationok.go @@ -17,7 +17,7 @@ func (T *AuthenticationOk) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationOk) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthentication) + packet := zap.NewPacket(TypeAuthentication, 4) packet = packet.AppendUint32(0) return packet } diff --git a/lib/zap/packets/v3.0/authenticationresponse.go b/lib/zap/packets/v3.0/authenticationresponse.go index 260be177..98ab5164 100644 --- a/lib/zap/packets/v3.0/authenticationresponse.go +++ b/lib/zap/packets/v3.0/authenticationresponse.go @@ -17,6 +17,6 @@ func (T *AuthenticationResponse) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationResponse) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthenticationResponse) + packet := zap.NewPacket(TypeAuthenticationResponse, len(*T)) return packet.AppendBytes(*T) } diff --git a/lib/zap/packets/v3.0/authenticationsasl.go b/lib/zap/packets/v3.0/authenticationsasl.go index 983306ff..3f60b9b7 100644 --- a/lib/zap/packets/v3.0/authenticationsasl.go +++ b/lib/zap/packets/v3.0/authenticationsasl.go @@ -28,7 +28,13 @@ func (T *AuthenticationSASL) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationSASL) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthentication) + size := 5 + for _, mechanism := range T.Mechanisms { + size += len(mechanism) + 1 + } + + packet := zap.NewPacket(TypeAuthentication, size) + packet = packet.AppendInt32(10) for _, mechanism := range T.Mechanisms { packet = packet.AppendString(mechanism) diff --git a/lib/zap/packets/v3.0/authenticationsaslcontinue.go b/lib/zap/packets/v3.0/authenticationsaslcontinue.go index 4e5b1d79..99f616e1 100644 --- a/lib/zap/packets/v3.0/authenticationsaslcontinue.go +++ b/lib/zap/packets/v3.0/authenticationsaslcontinue.go @@ -22,7 +22,7 @@ func (T *AuthenticationSASLContinue) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationSASLContinue) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthentication) + packet := zap.NewPacket(TypeAuthentication, 4+len(*T)) packet = packet.AppendUint32(11) packet = packet.AppendBytes(*T) return packet diff --git a/lib/zap/packets/v3.0/authenticationsaslfinal.go b/lib/zap/packets/v3.0/authenticationsaslfinal.go index 23b7df2e..e6ba0b9a 100644 --- a/lib/zap/packets/v3.0/authenticationsaslfinal.go +++ b/lib/zap/packets/v3.0/authenticationsaslfinal.go @@ -22,7 +22,7 @@ func (T *AuthenticationSASLFinal) ReadFromPacket(packet zap.Packet) bool { } func (T *AuthenticationSASLFinal) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthentication) + packet := zap.NewPacket(TypeAuthentication, 4+len(*T)) packet = packet.AppendUint32(12) packet = packet.AppendBytes(*T) return packet diff --git a/lib/zap/packets/v3.0/backendkeydata.go b/lib/zap/packets/v3.0/backendkeydata.go index a14cea1f..a77b8f2b 100644 --- a/lib/zap/packets/v3.0/backendkeydata.go +++ b/lib/zap/packets/v3.0/backendkeydata.go @@ -15,7 +15,7 @@ func (T *BackendKeyData) ReadFromPacket(packet zap.Packet) bool { } func (T *BackendKeyData) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeBackendKeyData) + packet := zap.NewPacket(TypeBackendKeyData, 8) packet = packet.AppendBytes(T.CancellationKey[:]) return packet } diff --git a/lib/zap/packets/v3.0/bind.go b/lib/zap/packets/v3.0/bind.go index 7eff7ff6..c3eec8aa 100644 --- a/lib/zap/packets/v3.0/bind.go +++ b/lib/zap/packets/v3.0/bind.go @@ -52,7 +52,19 @@ func (T *Bind) ReadFromPacket(packet zap.Packet) bool { } func (T *Bind) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeBind) + size := 0 + size += len(T.Destination) + 1 + size += len(T.Source) + 1 + size += 2 + size += len(T.ParameterFormatCodes) * 2 + size += 2 + for _, v := range T.ParameterValues { + size += 4 + len(v) + } + size += 2 + size += len(T.ResultFormatCodes) * 2 + + packet := zap.NewPacket(TypeBind, size) packet = packet.AppendString(T.Destination) packet = packet.AppendString(T.Source) packet = packet.AppendUint16(uint16(len(T.ParameterFormatCodes))) diff --git a/lib/zap/packets/v3.0/close.go b/lib/zap/packets/v3.0/close.go index b8e25a00..66df9786 100644 --- a/lib/zap/packets/v3.0/close.go +++ b/lib/zap/packets/v3.0/close.go @@ -17,7 +17,7 @@ func (T *Close) ReadFromPacket(packet zap.Packet) bool { } func (T *Close) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeClose) + packet := zap.NewPacket(TypeClose, 2+len(T.Target)) packet = packet.AppendUint8(T.Which) packet = packet.AppendString(T.Target) return packet diff --git a/lib/zap/packets/v3.0/copyfail.go b/lib/zap/packets/v3.0/copyfail.go index 74eab124..7ed87ee5 100644 --- a/lib/zap/packets/v3.0/copyfail.go +++ b/lib/zap/packets/v3.0/copyfail.go @@ -15,7 +15,7 @@ func (T *CopyFail) ReadFromPacket(packet zap.Packet) bool { } func (T *CopyFail) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeCopyFail) + packet := zap.NewPacket(TypeCopyFail, len(T.Reason)+1) packet = packet.AppendString(T.Reason) return packet } diff --git a/lib/zap/packets/v3.0/describe.go b/lib/zap/packets/v3.0/describe.go index 4035d8c0..d9276626 100644 --- a/lib/zap/packets/v3.0/describe.go +++ b/lib/zap/packets/v3.0/describe.go @@ -17,7 +17,7 @@ func (T *Describe) ReadFromPacket(packet zap.Packet) bool { } func (T *Describe) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeDescribe) + packet := zap.NewPacket(TypeDescribe, len(T.Target)+2) packet = packet.AppendUint8(T.Which) packet = packet.AppendString(T.Target) return packet diff --git a/lib/zap/packets/v3.0/errorresponse.go b/lib/zap/packets/v3.0/errorresponse.go index 6c6a97a6..b707b783 100644 --- a/lib/zap/packets/v3.0/errorresponse.go +++ b/lib/zap/packets/v3.0/errorresponse.go @@ -57,7 +57,15 @@ func (T *ErrorResponse) ReadFromPacket(packet zap.Packet) bool { } func (T *ErrorResponse) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeErrorResponse) + size := 1 + size += len(T.Error.Severity()) + 2 + size += len(T.Error.Code()) + 2 + size += len(T.Error.Message()) + 2 + for _, field := range T.Error.Extra() { + size += len(field.Value) + 2 + } + + packet := zap.NewPacket(TypeErrorResponse, size) packet = packet.AppendUint8('S') packet = packet.AppendString(string(T.Error.Severity())) diff --git a/lib/zap/packets/v3.0/execute.go b/lib/zap/packets/v3.0/execute.go index db0525e6..8150bcfe 100644 --- a/lib/zap/packets/v3.0/execute.go +++ b/lib/zap/packets/v3.0/execute.go @@ -17,7 +17,7 @@ func (T *Execute) ReadFromPacket(packet zap.Packet) bool { } func (T *Execute) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeExecute) + packet := zap.NewPacket(TypeExecute, len(T.Target)+5) packet = packet.AppendString(T.Target) packet = packet.AppendInt32(T.MaxRows) return packet diff --git a/lib/zap/packets/v3.0/negotiateprotocolversion.go b/lib/zap/packets/v3.0/negotiateprotocolversion.go index 120c23a7..88388b49 100644 --- a/lib/zap/packets/v3.0/negotiateprotocolversion.go +++ b/lib/zap/packets/v3.0/negotiateprotocolversion.go @@ -28,7 +28,12 @@ func (T *NegotiateProtocolVersion) ReadFromPacket(packet zap.Packet) bool { } func (T *NegotiateProtocolVersion) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeNegotiateProtocolVersion) + size := 8 + for _, v := range T.UnrecognizedOptions { + size += len(v) + 1 + } + + packet := zap.NewPacket(TypeNegotiateProtocolVersion, size) packet = packet.AppendInt32(T.MinorProtocolVersion) packet = packet.AppendInt32(int32(len(T.UnrecognizedOptions))) for _, v := range T.UnrecognizedOptions { diff --git a/lib/zap/packets/v3.0/parameterstatus.go b/lib/zap/packets/v3.0/parameterstatus.go index 800790fd..f6dff350 100644 --- a/lib/zap/packets/v3.0/parameterstatus.go +++ b/lib/zap/packets/v3.0/parameterstatus.go @@ -17,7 +17,7 @@ func (T *ParameterStatus) ReadFromPacket(packet zap.Packet) bool { } func (T *ParameterStatus) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeParameterStatus) + packet := zap.NewPacket(TypeParameterStatus, len(T.Key)+len(T.Value)+2) packet = packet.AppendString(T.Key) packet = packet.AppendString(T.Value) return packet diff --git a/lib/zap/packets/v3.0/parse.go b/lib/zap/packets/v3.0/parse.go index 4461d6b5..d58c4ea7 100644 --- a/lib/zap/packets/v3.0/parse.go +++ b/lib/zap/packets/v3.0/parse.go @@ -27,7 +27,7 @@ func (T *Parse) ReadFromPacket(packet zap.Packet) bool { } func (T *Parse) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeParse) + packet := zap.NewPacket(TypeParse, len(T.Destination)+len(T.Query)+4+len(T.ParameterDataTypes)*4) packet = packet.AppendString(T.Destination) packet = packet.AppendString(T.Query) packet = packet.AppendInt16(int16(len(T.ParameterDataTypes))) diff --git a/lib/zap/packets/v3.0/passwordmessage.go b/lib/zap/packets/v3.0/passwordmessage.go index e6af2d58..087f1959 100644 --- a/lib/zap/packets/v3.0/passwordmessage.go +++ b/lib/zap/packets/v3.0/passwordmessage.go @@ -17,7 +17,7 @@ func (T *PasswordMessage) ReadFromPacket(packet zap.Packet) bool { } func (T *PasswordMessage) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthenticationResponse) + packet := zap.NewPacket(TypeAuthenticationResponse, len(T.Password)+1) packet = packet.AppendString(T.Password) return packet } diff --git a/lib/zap/packets/v3.0/query.go b/lib/zap/packets/v3.0/query.go index 8e2ff67d..6cad7ca5 100644 --- a/lib/zap/packets/v3.0/query.go +++ b/lib/zap/packets/v3.0/query.go @@ -13,7 +13,7 @@ func (T *Query) ReadFromPacket(packet zap.Packet) bool { } func (T *Query) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeQuery) + packet := zap.NewPacket(TypeQuery, len(*T)+1) packet = packet.AppendString(string(*T)) return packet } diff --git a/lib/zap/packets/v3.0/readyforquery.go b/lib/zap/packets/v3.0/readyforquery.go index a40055cf..102e675f 100644 --- a/lib/zap/packets/v3.0/readyforquery.go +++ b/lib/zap/packets/v3.0/readyforquery.go @@ -15,7 +15,7 @@ func (T *ReadyForQuery) ReadFromPacket(packet zap.Packet) bool { } func (T *ReadyForQuery) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeReadyForQuery) + packet := zap.NewPacket(TypeReadyForQuery, 1) packet = packet.AppendUint8(byte(*T)) return packet } diff --git a/lib/zap/packets/v3.0/saslinitialresponse.go b/lib/zap/packets/v3.0/saslinitialresponse.go index f73eab53..c3f816f3 100644 --- a/lib/zap/packets/v3.0/saslinitialresponse.go +++ b/lib/zap/packets/v3.0/saslinitialresponse.go @@ -27,7 +27,7 @@ func (T *SASLInitialResponse) ReadFromPacket(packet zap.Packet) bool { } func (T *SASLInitialResponse) IntoPacket() zap.Packet { - packet := zap.NewPacket(TypeAuthenticationResponse) + packet := zap.NewPacket(TypeAuthenticationResponse, len(T.Mechanism)+5+len(T.InitialResponse)) packet = packet.AppendString(T.Mechanism) packet = packet.AppendInt32(int32(len(T.InitialResponse))) packet = packet.AppendBytes(T.InitialResponse) -- GitLab