fix(connection): Make bytes up and down a signed 64-bit integer

This fixes a theoretical issue with database interaction. Because the
fields in the database are signed 64-bit integers, it's theoretically
possible to overflow them if we're using unsigned 64-bit integers in the
application code.
pull/2575/head
Hugo Vieira 3 years ago
parent c81398cbf3
commit d206635d74

@ -6,7 +6,7 @@ type Connection struct {
ClientTcpPort uint32 `json:"client_tcp_port,omitempty"`
EndpointTcpAddress string `json:"endpoint_tcp_address,omitempty"`
EndpointTcpPort uint32 `json:"endpoint_tcp_port,omitempty"`
BytesUp uint64 `json:"bytes_up,string,omitempty"`
BytesDown uint64 `json:"bytes_down,string,omitempty"`
BytesUp int64 `json:"bytes_up,string,omitempty"`
BytesDown int64 `json:"bytes_down,string,omitempty"`
ClosedReason string `json:"closed_reason,omitempty"`
}

@ -834,9 +834,9 @@ var inputStructs = []*structInfo{
inProto: &sessions.Connection{},
outFile: "sessions/connection.gen.go",
fieldOverrides: []fieldInfo{
// uint64 fields get marshalled by protobuf as strings, so we have
// int64 fields get marshalled by protobuf as strings, so we have
// to tell the json parser that their json representation is a
// string but they go into Go uint64 types.
// string but they go into Go int64 types.
{Name: "BytesUp", JsonTags: []string{"string"}},
{Name: "BytesDown", JsonTags: []string{"string"}},
},

@ -12,22 +12,22 @@ import (
type countingConn struct {
net.Conn
bytesRead uint64
bytesWritten uint64
bytesRead int64
bytesWritten int64
// Use mutex for counters as net.Conn methods may be called concurrently
// https://github.com/golang/go/issues/27203#issuecomment-415854958
mu sync.Mutex
}
// BytesRead reports the number of bytes read so far
func (c *countingConn) BytesRead() uint64 {
func (c *countingConn) BytesRead() int64 {
c.mu.Lock()
defer c.mu.Unlock()
return c.bytesRead
}
// BytesWritten reports the number of bytes written so far
func (c *countingConn) BytesWritten() uint64 {
func (c *countingConn) BytesWritten() int64 {
c.mu.Lock()
defer c.mu.Unlock()
return c.bytesWritten
@ -38,7 +38,7 @@ func (c *countingConn) BytesWritten() uint64 {
func (c *countingConn) Read(in []byte) (int, error) {
n, err := c.Conn.Read(in)
c.mu.Lock()
c.bytesRead += uint64(n)
c.bytesRead += int64(n)
c.mu.Unlock()
return n, err
}
@ -48,7 +48,7 @@ func (c *countingConn) Read(in []byte) (int, error) {
func (c *countingConn) Write(in []byte) (int, error) {
n, err := c.Conn.Write(in)
c.mu.Lock()
c.bytesWritten += uint64(n)
c.bytesWritten += int64(n)
c.mu.Unlock()
return n, err
}

@ -31,9 +31,9 @@ type ConnInfo struct {
connCtxCancelFunc context.CancelFunc
// The number of bytes uploaded from the client.
BytesUp func() uint64
BytesUp func() int64
// The number of bytes downloaded to the client.
BytesDown func() uint64
BytesDown func() int64
// The time the controller has successfully reported that this connection is
// closed.
@ -44,8 +44,8 @@ type ConnInfo struct {
// RPC to the controller.
type ConnectionCloseData struct {
SessionId string
BytesUp uint64
BytesDown uint64
BytesUp int64
BytesDown int64
}
// Session is the local representation of a session. After initial loading
@ -103,7 +103,7 @@ type Session interface {
// down callbacks to the provided functions. Both functions must be safe for
// concurrent use. If there is no connection with the provided id, an error
// is returned.
ApplyConnectionCounterCallbacks(connId string, bytesUp func() uint64, bytesDown func() uint64) error
ApplyConnectionCounterCallbacks(connId string, bytesUp func() int64, bytesDown func() int64) error
// RequestAuthorizeConnection sends an AuthorizeConnection request to
// the controller.
@ -314,8 +314,8 @@ func (s *sess) RequestAuthorizeConnection(ctx context.Context, workerId string,
// Install safe callbacks before connection has been established. These
// should be replaced when `ApplyConnectionCounterCallbacks` gets called on
// the `sess` object.
ci.BytesUp = func() uint64 { return 0 }
ci.BytesDown = func() uint64 { return 0 }
ci.BytesUp = func() int64 { return 0 }
ci.BytesDown = func() int64 { return 0 }
s.lock.Lock()
defer s.lock.Unlock()
@ -390,7 +390,7 @@ func (s *sess) CancelAllLocalConnections() []string {
// down callbacks to the provided functions. Both functions must be safe for
// concurrent use. If there is no connection with the provided id, an error
// is returned.
func (s *sess) ApplyConnectionCounterCallbacks(connId string, bytesUp func() uint64, bytesDown func() uint64) error {
func (s *sess) ApplyConnectionCounterCallbacks(connId string, bytesUp func() int64, bytesDown func() int64) error {
s.lock.Lock()
defer s.lock.Unlock()

@ -272,8 +272,8 @@ func TestApplyConnectionCounterCallbacks(t *testing.T) {
s := &sess{connInfoMap: make(map[string]*ConnInfo)}
connId := "conn1"
bytesUpFn := func() uint64 { return 10 }
bytesDnFn := func() uint64 { return 20 }
bytesUpFn := func() int64 { return 10 }
bytesDnFn := func() int64 { return 20 }
err := s.ApplyConnectionCounterCallbacks(connId, bytesUpFn, bytesDnFn)
require.EqualError(t, err, "failed to find connection info for connection id \"conn1\"")

@ -345,7 +345,7 @@ func (w *Worker) cleanupConnections(cancelCtx context.Context, ignoreSessionStat
closedIds := s.CancelAllLocalConnections()
localConns := s.GetLocalConnections()
for _, connId := range closedIds {
var bytesUp, bytesDown uint64
var bytesUp, bytesDown int64
connInfo, ok := localConns[connId]
if ok {
bytesUp = connInfo.BytesUp()

@ -5070,12 +5070,12 @@
},
"bytes_up": {
"type": "string",
"format": "uint64",
"format": "int64",
"title": "bytes_up of the connection"
},
"bytes_down": {
"type": "string",
"format": "uint64",
"format": "int64",
"title": "bytes_down of the connection"
},
"closed_reason": {

@ -278,8 +278,8 @@ type Connection struct {
ConnectionId string `protobuf:"bytes,1,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" class:"public"` // @gotags: `class:"public"`
Status CONNECTIONSTATUS `protobuf:"varint,2,opt,name=status,proto3,enum=controller.servers.services.v1.CONNECTIONSTATUS" json:"status,omitempty"`
BytesUp uint64 `protobuf:"varint,3,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
BytesDown uint64 `protobuf:"varint,4,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
BytesUp int64 `protobuf:"varint,3,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
BytesDown int64 `protobuf:"varint,4,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
}
func (x *Connection) Reset() {
@ -328,14 +328,14 @@ func (x *Connection) GetStatus() CONNECTIONSTATUS {
return CONNECTIONSTATUS_CONNECTIONSTATUS_UNSPECIFIED
}
func (x *Connection) GetBytesUp() uint64 {
func (x *Connection) GetBytesUp() int64 {
if x != nil {
return x.BytesUp
}
return 0
}
func (x *Connection) GetBytesDown() uint64 {
func (x *Connection) GetBytesDown() int64 {
if x != nil {
return x.BytesDown
}
@ -950,9 +950,9 @@ var file_controller_servers_services_v1_server_coordination_service_proto_rawDes
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x4f, 0x4e,
0x4e, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x52, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x75,
0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x79, 0x74, 0x65, 0x73, 0x55, 0x70,
0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x62, 0x79, 0x74, 0x65, 0x73, 0x55, 0x70,
0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x04,
0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x22,
0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x22,
0xc4, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x49, 0x6e,
0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49,

@ -713,8 +713,8 @@ type CloseConnectionRequestData struct {
unknownFields protoimpl.UnknownFields
ConnectionId string `protobuf:"bytes,10,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" class:"public"` // @gotags: `class:"public"`
BytesUp uint64 `protobuf:"varint,20,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
BytesDown uint64 `protobuf:"varint,30,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
BytesUp int64 `protobuf:"varint,20,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
BytesDown int64 `protobuf:"varint,30,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
Reason string `protobuf:"bytes,40,opt,name=reason,proto3" json:"reason,omitempty" class:"public"` // @gotags: `class:"public"`
}
@ -757,14 +757,14 @@ func (x *CloseConnectionRequestData) GetConnectionId() string {
return ""
}
func (x *CloseConnectionRequestData) GetBytesUp() uint64 {
func (x *CloseConnectionRequestData) GetBytesUp() int64 {
if x != nil {
return x.BytesUp
}
return 0
}
func (x *CloseConnectionRequestData) GetBytesDown() uint64 {
func (x *CloseConnectionRequestData) GetBytesDown() int64 {
if x != nil {
return x.BytesDown
}
@ -1070,9 +1070,9 @@ var file_controller_servers_services_v1_session_service_proto_rawDesc = []byte{
0x74, 0x61, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73,
0x5f, 0x75, 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62, 0x79, 0x74, 0x65, 0x73,
0x5f, 0x75, 0x70, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x62, 0x79, 0x74, 0x65, 0x73,
0x55, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x64, 0x6f, 0x77, 0x6e,
0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x44, 0x6f, 0x77,
0x18, 0x1e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x44, 0x6f, 0x77,
0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x28, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x82, 0x01, 0x0a, 0x16, 0x43, 0x6c,
0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,

@ -33,10 +33,10 @@ message Connection {
uint32 endpoint_tcp_port = 6; // @gotags: `class:"public"`
// bytes_up of the connection
uint64 bytes_up = 7; // @gotags: `class:"public"`
int64 bytes_up = 7; // @gotags: `class:"public"`
// bytes_down of the connection
uint64 bytes_down = 8; // @gotags: `class:"public"`
int64 bytes_down = 8; // @gotags: `class:"public"`
// closed_reason of the connection
string closed_reason = 9; // @gotags: `class:"public"`

@ -26,8 +26,8 @@ enum CONNECTIONSTATUS {
message Connection {
string connection_id = 1; // @gotags: `class:"public"`
CONNECTIONSTATUS status = 2;
uint64 bytes_up = 3; // @gotags: `class:"public"`
uint64 bytes_down = 4; // @gotags: `class:"public"`
int64 bytes_up = 3; // @gotags: `class:"public"`
int64 bytes_down = 4; // @gotags: `class:"public"`
}
enum SESSIONSTATUS {

@ -109,8 +109,8 @@ message ConnectConnectionResponse {
message CloseConnectionRequestData {
string connection_id = 10; // @gotags: `class:"public"`
uint64 bytes_up = 20; // @gotags: `class:"public"`
uint64 bytes_down = 30; // @gotags: `class:"public"`
int64 bytes_up = 20; // @gotags: `class:"public"`
int64 bytes_down = 30; // @gotags: `class:"public"`
string reason = 40; // @gotags: `class:"public"`
}

@ -30,9 +30,9 @@ type Connection struct {
// EndpointTcpPort of the connection
EndpointTcpPort uint32 `json:"endpoint_tcp_port,omitempty" gorm:"default:null"`
// BytesUp of the connection
BytesUp uint64 `json:"bytes_up,omitempty" gorm:"default:null"`
BytesUp int64 `json:"bytes_up,omitempty" gorm:"default:null"`
// BytesDown of the connection
BytesDown uint64 `json:"bytes_down,omitempty" gorm:"default:null"`
BytesDown int64 `json:"bytes_down,omitempty" gorm:"default:null"`
// ClosedReason of the connection
ClosedReason string `json:"closed_reason,omitempty" gorm:"default:null"`
// CreateTime from the RDBMS

@ -8,8 +8,8 @@ import (
// worker closes a connection between the client and the endpoint.
type CloseWith struct {
ConnectionId string
BytesUp uint64
BytesDown uint64
BytesUp int64
BytesDown int64
ClosedReason ClosedReason
}

@ -15,8 +15,8 @@ func TestClosedWith_validate(t *testing.T) {
sessionConnection := TestConnection(t, conn, session.PublicId, "127.0.0.1", 22, "127.0.0.1", 2222, "127.0.0.1")
type fields struct {
ConnectionId string
BytesUp uint64
BytesDown uint64
BytesUp int64
BytesDown int64
ClosedReason ClosedReason
}
tests := []struct {

@ -548,8 +548,8 @@ func TestUpdateBytesUpDown(t *testing.T) {
conns := make([]*Connection, 0, connCount)
for i := 0; i < connCount; i++ {
c := TestConnection(t, conn, s.PublicId, "127.0.0.1", 22, "127.0.0.1", 2222, "127.0.0.1")
c.BytesUp = uint64(rand.Int63())
c.BytesDown = uint64(rand.Int63())
c.BytesUp = rand.Int63()
c.BytesDown = rand.Int63()
conns = append(conns, c)
}
@ -594,8 +594,8 @@ func TestUpdateBytesUpDown(t *testing.T) {
conns2 := make([]*Connection, len(conns))
for i := 0; i < len(conns); i++ {
conns2[i] = conns[i].Clone().(*Connection)
conns2[i].BytesUp = uint64(rand.Int63())
conns2[i].BytesDown = uint64(rand.Int63())
conns2[i].BytesUp = rand.Int63()
conns2[i].BytesDown = rand.Int63()
}
require.NoError(t, connRepo.updateBytesUpBytesDown(ctx, conns2...))

@ -103,9 +103,9 @@ type Connection struct {
// endpoint_tcp_port of the connection
EndpointTcpPort uint32 `protobuf:"varint,6,opt,name=endpoint_tcp_port,json=endpointTcpPort,proto3" json:"endpoint_tcp_port,omitempty" class:"public"` // @gotags: `class:"public"`
// bytes_up of the connection
BytesUp uint64 `protobuf:"varint,7,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
BytesUp int64 `protobuf:"varint,7,opt,name=bytes_up,json=bytesUp,proto3" json:"bytes_up,omitempty" class:"public"` // @gotags: `class:"public"`
// bytes_down of the connection
BytesDown uint64 `protobuf:"varint,8,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
BytesDown int64 `protobuf:"varint,8,opt,name=bytes_down,json=bytesDown,proto3" json:"bytes_down,omitempty" class:"public"` // @gotags: `class:"public"`
// closed_reason of the connection
ClosedReason string `protobuf:"bytes,9,opt,name=closed_reason,json=closedReason,proto3" json:"closed_reason,omitempty" class:"public"` // @gotags: `class:"public"`
}
@ -170,14 +170,14 @@ func (x *Connection) GetEndpointTcpPort() uint32 {
return 0
}
func (x *Connection) GetBytesUp() uint64 {
func (x *Connection) GetBytesUp() int64 {
if x != nil {
return x.BytesUp
}
return 0
}
func (x *Connection) GetBytesDown() uint64 {
func (x *Connection) GetBytesDown() int64 {
if x != nil {
return x.BytesDown
}
@ -447,9 +447,9 @@ var file_controller_api_resources_sessions_v1_session_proto_rawDesc = []byte{
0x2a, 0x0a, 0x11, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x74, 0x63, 0x70, 0x5f,
0x70, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x65, 0x6e, 0x64, 0x70,
0x6f, 0x69, 0x6e, 0x74, 0x54, 0x63, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x62,
0x79, 0x74, 0x65, 0x73, 0x5f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x62,
0x79, 0x74, 0x65, 0x73, 0x5f, 0x75, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x62,
0x79, 0x74, 0x65, 0x73, 0x55, 0x70, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f,
0x64, 0x6f, 0x77, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65,
0x64, 0x6f, 0x77, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65,
0x73, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x5f,
0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6c,
0x6f, 0x73, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xf5, 0x06, 0x0a, 0x07, 0x53,

Loading…
Cancel
Save