@@ -781,6 +781,17 @@ func (a *agent) reportConnectionsLoop(ctx context.Context, aAPI proto.DRPCAgentC
781
781
}
782
782
}
783
783
784
+ const (
785
+ // reportConnectionBufferLimit limits the number of connection reports we
786
+ // buffer to avoid growing the buffer indefinitely. This should not happen
787
+ // unless the agent has lost connection to coderd for a long time or if
788
+ // the agent is being spammed with connections.
789
+ //
790
+ // If we assume ~150 byte per connection report, this would be around 300KB
791
+ // of memory which seems acceptable.
792
+ reportConnectionBufferLimit = 2048
793
+ )
794
+
784
795
func (a * agent ) reportConnection (id uuid.UUID , connectionType proto.Connection_Type , ip string ) (disconnected func (code int , reason string )) {
785
796
// If the experiment hasn't been enabled, we don't report connections.
786
797
if ! a .experimentalConnectionReports {
@@ -797,25 +808,45 @@ func (a *agent) reportConnection(id uuid.UUID, connectionType proto.Connection_T
797
808
798
809
a .reportConnectionsMu .Lock ()
799
810
defer a .reportConnectionsMu .Unlock ()
800
- a .reportConnections = append (a .reportConnections , & proto.ReportConnectionRequest {
801
- Connection : & proto.Connection {
802
- Id : id [:],
803
- Action : proto .Connection_CONNECT ,
804
- Type : connectionType ,
805
- Timestamp : timestamppb .New (time .Now ()),
806
- Ip : ip ,
807
- StatusCode : 0 ,
808
- Reason : nil ,
809
- },
810
- })
811
- select {
812
- case a .reportConnectionsUpdate <- struct {}{}:
813
- default :
811
+
812
+ if len (a .reportConnections ) >= reportConnectionBufferLimit {
813
+ a .logger .Warn (a .hardCtx , "connection report buffer limit reached, dropping connect" ,
814
+ slog .F ("limit" , reportConnectionBufferLimit ),
815
+ slog .F ("connection_id" , id ),
816
+ slog .F ("connection_type" , connectionType ),
817
+ slog .F ("ip" , ip ),
818
+ )
819
+ } else {
820
+ a .reportConnections = append (a .reportConnections , & proto.ReportConnectionRequest {
821
+ Connection : & proto.Connection {
822
+ Id : id [:],
823
+ Action : proto .Connection_CONNECT ,
824
+ Type : connectionType ,
825
+ Timestamp : timestamppb .New (time .Now ()),
826
+ Ip : ip ,
827
+ StatusCode : 0 ,
828
+ Reason : nil ,
829
+ },
830
+ })
831
+ select {
832
+ case a .reportConnectionsUpdate <- struct {}{}:
833
+ default :
834
+ }
814
835
}
815
836
816
837
return func (code int , reason string ) {
817
838
a .reportConnectionsMu .Lock ()
818
839
defer a .reportConnectionsMu .Unlock ()
840
+ if len (a .reportConnections ) >= reportConnectionBufferLimit {
841
+ a .logger .Warn (a .hardCtx , "connection report buffer limit reached, dropping connect" ,
842
+ slog .F ("limit" , reportConnectionBufferLimit ),
843
+ slog .F ("connection_id" , id ),
844
+ slog .F ("connection_type" , connectionType ),
845
+ slog .F ("ip" , ip ),
846
+ )
847
+ return
848
+ }
849
+
819
850
a .reportConnections = append (a .reportConnections , & proto.ReportConnectionRequest {
820
851
Connection : & proto.Connection {
821
852
Id : id [:],
0 commit comments