Graylog2 / Graylog2/graylog2-server
UDP buffer size problems (FreeBSD, maybe generally when OS != Linux)
- Dominant language
- Java
- Stars
- 8.1k
- Forks
- 1.1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 217
Description
## Expected Behavior
When setting a buffer size for UDP inputs, either on the Graylog config file (udp_recvbuffer_sizes parameter), the value should be provided to the setsockopt() call. The operating system should decide whether the value is legal or not.
This should work for a value greater than 65536 bytes.
## Current Behavior
There are two different issues at play here:
1. At least on FreeBSD there seems to be some buffer size cap to 16 bit (65536) which should not exist.
2. Due to a known linuxism there seems to be some confusion with how to check whether the setsockopt() call has been successful.
The behavior on FreeBSD is rather confusing. Moreover I have found a workaround that suggests a potential fix for *any* operating system.
On a FreeBSD system configured with a UDP buffer size of 1048576 bytes (1 MB), Graylog gives the following warning:
`2024-06-14 12:05:08,300 WARN o.g.i.t.UdpTransport [netty-transport-0] receiveBufferSize (SO_RCVBUF) for input RawUDPInput{title=Alertas DNS ML, type=org.graylog2.inputs.raw.udp.RawUDPInput, nodeId=XXXXXX} (channel [id: 0x75163fc7, L:/10.0.0.1:555]) should be >= 262144 but is 65536.
`
And the UDP buffer size is indeed 65536 bytes, checking with netstat -x -p udp (not sure these options work on Linux)
This happens in any of these cases:
- udp_recvbuffer_sizes is commented out. The built in default on Graylog seems to be 262144 bytes.
- udp_recvbuffer_sizes is present, specifying a buffer size greater than 65536 bytes. Of course the complaint is "should be >= specified bytes but is 65536")
- Regardless of what happens with the graylog.conf option, specifying a value greater than 65536 bytes results in the same error.
## Possible Solution
**Workaround on FreeBSD**:
- Set the graylog.conf variable udp_recvbuffer_sizes to 0.
- Make sure not to set the optional buffer size on UDP input definitions.
When doing this, Graylog makes a setsockopt(SO_RCVBUF) with 0 specified as a buffer length. The call will fail, so the actual buffer size set by the system to the default value will not change. Graylog issues a warning but it moves forward.
`2024-06-15 08:32:31,391 WARN i.n.b.Bootstrap [inputs-0] Failed to set channel option 'SO_RCVBUF' with value '0' for channel '[id: 0x30026dd0]'
`
**Suggested fix**:
There is a cap to 65536 bytes somewhere. It may be netty, Graylog or OpenJDK. I don't know.
Anyway in my opinion the sane, foolproof option is to change the default behavior:
- If udp_recvbuffer_sizes is not specified -> Do **not** try a setsockopt(SO_RCVBUF) **unless** a specific buffer size is specified for a UDP input of course.
- Alternatively, if udp_recvbuffer_sizes is 0 then do not issue the setsockopt() call that would fail anyway and document this behavior.
Doing this, Graylog will trust whatever default UDP buffer size has been configured by the system administrator which is probably the best option. I am not sure about other systems but at least on FreeBSD there are two system variables controlling this:
- net.inet.udp.recvspace: UDP receive buffer size
- kern.ipc.maxsockbuf: Maximum socket buffer size
## Steps to Reproduce (for bugs)
1. On FreeBSD, leave udp_recvbuffer_sizes commented out or specify a value greater than 65536.
## Context
This issue is important because the UDP buffer size is critical for high volume UDP packet reception.
## Your Environment
* Graylog Version: 6.0.1
* Java Version: OpenJDK BSD Porting Team 17.0.11 on FreeBSD 14.1-RELEASE
* OpenSearch Version: 2.0.14
* MongoDB Version: 5.0.26
* Operating System: FreeBSD 14.1 (amd64)
Contributor guide
Assessment
This issue has not been assessed yet.