You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix long message handling with dynamic buffer growth (#158)
* Fix long message handling with dynamic buffer growth
The socket transport plugin used a fixed 64KB buffer size
which caused messages surpassing that size to be truncated
For UDP/Unix datagram sockets, this resulted in parsing errors
like "unexpected end of input"
This change allows the buffer to grow (up to a limit depending on the
protocol) to accommodate larger messages.
* Create helper functions for TCP connection handling
* Add helper sendUDPSocketMessage
* Update TestUnixSocketTransport large message test
This test verifies the dynamic buffer growth by sending
three messages
In each iteration the buffer grows from the initial size
of 65535 bytes to 3 times the initial size.
Also verifies the content of the received message
Closes: OSPRH-23826
@@ -165,10 +178,13 @@ func (s *Socket) WriteTCPMsg(w transport.WriteFn, msgBuffer []byte, n int) (int6
165
178
returnpos, nil
166
179
}
167
180
168
-
func (s*Socket) ReceiveData(maxBuffSizeint64, donechanbool, pc net.Conn, w transport.WriteFn) {
181
+
func (s*Socket) ReceiveData(initialBuffSizeint64, donechanbool, pc net.Conn, w transport.WriteFn) {
169
182
deferpc.Close()
170
-
msgBuffer:=make([]byte, maxBuffSize)
183
+
currentBuffSize:=initialBuffSize
184
+
maxBuffSize:=s.getMaxBufferSize()
185
+
msgBuffer:=make([]byte, currentBuffSize)
171
186
varremainingMsg []byte
187
+
172
188
for {
173
189
n, err:=pc.Read(msgBuffer)
174
190
iferr!=nil||n<1 {
@@ -180,17 +196,40 @@ func (s *Socket) ReceiveData(maxBuffSize int64, done chan bool, pc net.Conn, w t
180
196
}
181
197
return
182
198
}
183
-
msgBuffer=append(remainingMsg, msgBuffer...)
184
199
185
-
// whole buffer was used, so we are potentially handling larger message
186
-
ifn==len(msgBuffer) {
187
-
s.logger.Warnf("full read buffer used")
200
+
// Combine remaining data from previous iteration with newly read data
201
+
vardata []byte
202
+
iflen(remainingMsg) >0 {
203
+
data=make([]byte, len(remainingMsg)+n)
204
+
copy(data, remainingMsg)
205
+
copy(data[len(remainingMsg):], msgBuffer[:n])
206
+
} else {
207
+
data=msgBuffer[:n]
208
+
}
209
+
totalSize:=len(data)
210
+
211
+
// Check if buffer was completely filled - message may have been truncated
212
+
ifn==int(currentBuffSize) {
213
+
ifs.conf.Type==tcp {
214
+
s.logger.Debugf("full read buffer used (%d bytes), TCP will handle continuation if needed", n)
215
+
} else {
216
+
// For UDP/Unix sockets, buffer being full means message was likely truncated
217
+
ifcurrentBuffSize<maxBuffSize {
218
+
newSize:=currentBuffSize*2
219
+
ifnewSize>maxBuffSize {
220
+
newSize=maxBuffSize
221
+
}
222
+
s.logger.Warnf("message may have been truncated (buffer filled with %d bytes), growing buffer from %d to %d bytes for next message", currentBuffSize, currentBuffSize, newSize)
223
+
currentBuffSize=newSize
224
+
msgBuffer=make([]byte, currentBuffSize)
225
+
} else {
226
+
s.logger.Errorf(nil, "message truncated: buffer size (%d bytes) exceeded for %s socket and already at maximum buffer size (%d bytes)", currentBuffSize, s.conf.Type, maxBuffSize)
227
+
}
228
+
}
188
229
}
189
-
190
-
n+=len(remainingMsg)
191
230
192
231
ifs.conf.DumpMessages.Enabled {
193
-
_, err:=s.dumpBuf.Write(msgBuffer[:n])
232
+
_, err:=s.dumpBuf.Write(data)
194
233
iferr!=nil {
195
234
s.logger.Errorf(err, "writing to dump buffer")
196
235
}
@@ -202,16 +241,17 @@ func (s *Socket) ReceiveData(maxBuffSize int64, done chan bool, pc net.Conn, w t
202
241
}
203
242
204
243
ifs.conf.Type==tcp {
205
-
parsed, err:=s.WriteTCPMsg(w, msgBuffer, n)
244
+
parsed, err:=s.WriteTCPMsg(w, data, totalSize)
206
245
iferr!=nil {
207
246
s.logger.Errorf(err, "error, while parsing messages")
0 commit comments