-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Message source is missing for UDP transport based inputs #5293
Labels
Milestone
Comments
bernd
added
bug
blocker
If not finished by release date, the release will be postponed.
labels
Nov 19, 2018
This is most probably also the underlying cause of #5264. |
@dennisoelkers Yes! Thanks for the heads up! |
This also appears broken for TCP syslog inputs in 2.5.1, works fine in 2.4.x; source attribute is blank. reverting to 2.4.6 fixes the problem. |
bernd
added a commit
that referenced
this issue
Jan 15, 2019
This fixes an issue that has been introduced with the big Netty 4.1 update in PR #4397. In Netty 3.x we always passed a "MessageEvent" through the channel pipeline and got the remote address from that object. Since this object doesn't exist anymore in Netty 4.x, we only pass the message payload's "ByteBuf" through the pipeline and rely on the "Channel#getRemoteAddress" method to always return the remote address object. The problem is that this does indeed work for TCP based channels but it doesn't work for UDP based channels. For UDP channels the "#getRemoteAddress()" method always returns "null". This is probably due to the connection-less nature of UDP. For UDP transports Netty only creates a single channel. For TCP transports there is one channel per TCP connection To fix this we need to get our hands on the remote address when we create the "RawMessage" object at the very end of the Netty pipeline. Since we only pass the message payload "ByteBuf" through the Netty pipeline, we could previously reuse several classes for TCP and UDP transports because they were basically the same. For UDP transports we now need to carry the remote address through the pipeline by using a "AddressedEnvelope" (available in Netty) that takes a payload and a sender/receiver object. That means we have to create a few UDP specific - or rather "AddressedEnvelope" specific - pipeline handlers because the shared ones only know how to handle "ByteBuf" messages. This PR moves some shared code out of the "NettyTransport" class up to "AbstractTcpTransport" and "UdpTransport" so we can customize the pipeline for the two different payload types. It also creates new message aggregation handlers for the "AddressedEnvelope" objects. In the future we can probably refactor this to share some more code, but for 3.0 I tried to change as few as possible. The TCP pipeline is basically unchanged apart from the "AbstractTcpTransport" change. Fixes #5264 Fixes #5293
kroepke
pushed a commit
that referenced
this issue
Jan 15, 2019
This fixes an issue that has been introduced with the big Netty 4.1 update in PR #4397. In Netty 3.x we always passed a "MessageEvent" through the channel pipeline and got the remote address from that object. Since this object doesn't exist anymore in Netty 4.x, we only pass the message payload's "ByteBuf" through the pipeline and rely on the "Channel#getRemoteAddress" method to always return the remote address object. The problem is that this does indeed work for TCP based channels but it doesn't work for UDP based channels. For UDP channels the "#getRemoteAddress()" method always returns "null". This is probably due to the connection-less nature of UDP. For UDP transports Netty only creates a single channel. For TCP transports there is one channel per TCP connection To fix this we need to get our hands on the remote address when we create the "RawMessage" object at the very end of the Netty pipeline. Since we only pass the message payload "ByteBuf" through the Netty pipeline, we could previously reuse several classes for TCP and UDP transports because they were basically the same. For UDP transports we now need to carry the remote address through the pipeline by using a "AddressedEnvelope" (available in Netty) that takes a payload and a sender/receiver object. That means we have to create a few UDP specific - or rather "AddressedEnvelope" specific - pipeline handlers because the shared ones only know how to handle "ByteBuf" messages. This PR moves some shared code out of the "NettyTransport" class up to "AbstractTcpTransport" and "UdpTransport" so we can customize the pipeline for the two different payload types. It also creates new message aggregation handlers for the "AddressedEnvelope" objects. In the future we can probably refactor this to share some more code, but for 3.0 I tried to change as few as possible. The TCP pipeline is basically unchanged apart from the "AbstractTcpTransport" change. Fixes #5264 Fixes #5293 **Note:** This needs to be cherry-picked into 3.0
bernd
added a commit
that referenced
this issue
Jan 16, 2019
This fixes an issue that has been introduced with the big Netty 4.1 update in PR #4397. In Netty 3.x we always passed a "MessageEvent" through the channel pipeline and got the remote address from that object. Since this object doesn't exist anymore in Netty 4.x, we only pass the message payload's "ByteBuf" through the pipeline and rely on the "Channel#getRemoteAddress" method to always return the remote address object. The problem is that this does indeed work for TCP based channels but it doesn't work for UDP based channels. For UDP channels the "#getRemoteAddress()" method always returns "null". This is probably due to the connection-less nature of UDP. For UDP transports Netty only creates a single channel. For TCP transports there is one channel per TCP connection To fix this we need to get our hands on the remote address when we create the "RawMessage" object at the very end of the Netty pipeline. Since we only pass the message payload "ByteBuf" through the Netty pipeline, we could previously reuse several classes for TCP and UDP transports because they were basically the same. For UDP transports we now need to carry the remote address through the pipeline by using a "AddressedEnvelope" (available in Netty) that takes a payload and a sender/receiver object. That means we have to create a few UDP specific - or rather "AddressedEnvelope" specific - pipeline handlers because the shared ones only know how to handle "ByteBuf" messages. This PR moves some shared code out of the "NettyTransport" class up to "AbstractTcpTransport" and "UdpTransport" so we can customize the pipeline for the two different payload types. It also creates new message aggregation handlers for the "AddressedEnvelope" objects. In the future we can probably refactor this to share some more code, but for 3.0 I tried to change as few as possible. The TCP pipeline is basically unchanged apart from the "AbstractTcpTransport" change. Fixes #5264 Fixes #5293 **Note:** This needs to be cherry-picked into 3.0 (cherry picked from commit 375e618)
kroepke
pushed a commit
that referenced
this issue
Jan 16, 2019
…5519) This fixes an issue that has been introduced with the big Netty 4.1 update in PR #4397. In Netty 3.x we always passed a "MessageEvent" through the channel pipeline and got the remote address from that object. Since this object doesn't exist anymore in Netty 4.x, we only pass the message payload's "ByteBuf" through the pipeline and rely on the "Channel#getRemoteAddress" method to always return the remote address object. The problem is that this does indeed work for TCP based channels but it doesn't work for UDP based channels. For UDP channels the "#getRemoteAddress()" method always returns "null". This is probably due to the connection-less nature of UDP. For UDP transports Netty only creates a single channel. For TCP transports there is one channel per TCP connection To fix this we need to get our hands on the remote address when we create the "RawMessage" object at the very end of the Netty pipeline. Since we only pass the message payload "ByteBuf" through the Netty pipeline, we could previously reuse several classes for TCP and UDP transports because they were basically the same. For UDP transports we now need to carry the remote address through the pipeline by using a "AddressedEnvelope" (available in Netty) that takes a payload and a sender/receiver object. That means we have to create a few UDP specific - or rather "AddressedEnvelope" specific - pipeline handlers because the shared ones only know how to handle "ByteBuf" messages. This PR moves some shared code out of the "NettyTransport" class up to "AbstractTcpTransport" and "UdpTransport" so we can customize the pipeline for the two different payload types. It also creates new message aggregation handlers for the "AddressedEnvelope" objects. In the future we can probably refactor this to share some more code, but for 3.0 I tried to change as few as possible. The TCP pipeline is basically unchanged apart from the "AbstractTcpTransport" change. Fixes #5264 Fixes #5293 **Note:** This needs to be cherry-picked into 3.0 (cherry picked from commit 375e618)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Expected Behavior
Log messages coming in via UDP transports should have a
source
field.Current Behavior
Since the big netty upgrade from 3 to 4, all messages that arrive via UDP netty transports do not have a source field anymore.
Possible Solution
Our RawMessageHandler is trying to get the remote address from the netty channel. This works for TCP channels but doesn't work for UDP channels. For UDP channels
ctx.channel().remoteAddress()
always returnsnull
.graylog2-server/graylog2-server/src/main/java/org/graylog2/inputs/transports/netty/RawMessageHandler.java
Lines 40 to 45 in 12f456e
The remote address for UDP datagrams can be obtained via DatagramPacket#sender(). The problem is, that our DatagramPacketHandler and NetflowMessageAggregationHandler only pass on the actual payload byte buffer to subsequent netty handlers. That means we cannot get to the datagram packet sender in the RawMessageHandler later.
One possible solution could be to create a small container object that holds the payload byte buffer and the remote address instead of just passing on the payload byte buffer to subsequent netty handlers.
Another option might be to use netty channel attributes to set the remote address when still having access to the datagram packet and then read it in the RawMessageHandler. But that might be problematic because the same netty channel is used for all incoming packets so we might run into race conditions.
Steps to Reproduce (for bugs)
echo udp test | ncat -u 127.0.0.1 5555
Context
This basically breaks all messages that are coming in via UDP and which don't set a custom source!
Your Environment
The text was updated successfully, but these errors were encountered: