[JBoss JIRA] (JGRP-1961) TCP_NIO2: message bundling can lead to corruption of msgs sent asynchronously
by Bela Ban (JIRA)
[ https://issues.jboss.org/browse/JGRP-1961?page=com.atlassian.jira.plugin.... ]
Bela Ban updated JGRP-1961:
---------------------------
Description:
When a message is sent with a message bundler (in {{TP}}), the output buffer in {{TP.BaseBundler}} is reused for all messages of a given bundle (say {{m1}} and {{m2}}).
This works for {{TCP}} and {{UDP}} because a write _blocks_ and - when it returns - we're guaranteed that the buffer has been copied into an OS buffer (TCP's send window).
However, this is different with {{TCP_NIO2}}: *an async write always returns immediately, irrespective of whether the data was written completely, partially, or not at all !*
If a write only writes a part of its data, on returning from the write, the message bundler reuses the output buffer and can thus overwrite and corrupt buffers that are in transit, waiting to be written.
A quick check where buffers were copied fixed the problem.
TODO: see where we need to copy data when using a bundler. Possibly only copy if a write didn't write all of the data.
was:
When a message is sent with a message bundler (in {{TP}}), the output buffer in {{TP.BaseBundler}} is reused for all messages of a given bundle (say {{m1}} and {{m2}}).
This works for {{TCP}} because a write _blocks_ and - when it returns - we're guaranteed that the buffer has been copied into an OS buffer (TCP's send window).
However, this is different with {{TCP_NIO2}}: *an async write always returns immediately, irrespective of whether the data was written completely, partially, or not at all !*
If a write only writes a part of its data, on returning from the write, the message bundler reuses the output buffer and can thus overwrite and corrupt buffers that are in transit, waiting to be written.
A quick check where buffers were copied fixed the problem.
TODO: see where we need to copy data when using a bundler. Possibly only copy if a write didn't write all of the data.
> TCP_NIO2: message bundling can lead to corruption of msgs sent asynchronously
> -----------------------------------------------------------------------------
>
> Key: JGRP-1961
> URL: https://issues.jboss.org/browse/JGRP-1961
> Project: JGroups
> Issue Type: Bug
> Affects Versions: 3.6.5
> Reporter: Bela Ban
> Assignee: Bela Ban
> Priority: Critical
> Fix For: 3.6.6
>
>
> When a message is sent with a message bundler (in {{TP}}), the output buffer in {{TP.BaseBundler}} is reused for all messages of a given bundle (say {{m1}} and {{m2}}).
> This works for {{TCP}} and {{UDP}} because a write _blocks_ and - when it returns - we're guaranteed that the buffer has been copied into an OS buffer (TCP's send window).
> However, this is different with {{TCP_NIO2}}: *an async write always returns immediately, irrespective of whether the data was written completely, partially, or not at all !*
> If a write only writes a part of its data, on returning from the write, the message bundler reuses the output buffer and can thus overwrite and corrupt buffers that are in transit, waiting to be written.
> A quick check where buffers were copied fixed the problem.
> TODO: see where we need to copy data when using a bundler. Possibly only copy if a write didn't write all of the data.
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (JGRP-1951) Flexible buffers for scatter/gather
by Bela Ban (JIRA)
[ https://issues.jboss.org/browse/JGRP-1951?page=com.atlassian.jira.plugin.... ]
Bela Ban resolved JGRP-1951.
----------------------------
Resolution: Done
Individual buffers can now be added, removed, and accessed
> Flexible buffers for scatter/gather
> -----------------------------------
>
> Key: JGRP-1951
> URL: https://issues.jboss.org/browse/JGRP-1951
> Project: JGroups
> Issue Type: Feature Request
> Reporter: Bela Ban
> Assignee: Bela Ban
> Fix For: 3.6.7
>
>
> Currently, {{Buffers}} and {{WriteBuffers}} are inflexible in that they always expect a length buffer followed by data ({{Buffers}}), or a sequence of len/data pairs ({{WriteBuffers}}).
> This is bad if we for example want to read a sequence like the one below (for connection establishment in TCP):
> {noformat}
> | cookie | version | len | peer-address |
> (4) (2) (2) (variable)
> {noformat}
> Goals:
> * Have only 1 buffer, for reading *and* writing
> * Allow to define the sequence by adding buffers dynamically, e.g. in the above case, we'd add a 4 and a 2-length buffer and read data into them. If the cookie and version don't match, throw an exception, else *dynamically* add a length buffer (possibly doing a clear() which removes the first 2 buffers), read data into it, then add a new buffer sized to the read length and finally read data into it.
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months
[JBoss JIRA] (JGRP-1951) Flexible buffers for scatter/gather
by Bela Ban (JIRA)
[ https://issues.jboss.org/browse/JGRP-1951?page=com.atlassian.jira.plugin.... ]
Bela Ban commented on JGRP-1951:
--------------------------------
- {{WriteBuffers}} was merged into {{Buffers}}
- Reading into a variable number of buffers is possible by adding (e.g.) 3 buffers, doing a scattering read and reading the individual buffers, see {{BuffersTest.testRead3Buffers()}} for an example
> Flexible buffers for scatter/gather
> -----------------------------------
>
> Key: JGRP-1951
> URL: https://issues.jboss.org/browse/JGRP-1951
> Project: JGroups
> Issue Type: Feature Request
> Reporter: Bela Ban
> Assignee: Bela Ban
> Fix For: 3.6.7
>
>
> Currently, {{Buffers}} and {{WriteBuffers}} are inflexible in that they always expect a length buffer followed by data ({{Buffers}}), or a sequence of len/data pairs ({{WriteBuffers}}).
> This is bad if we for example want to read a sequence like the one below (for connection establishment in TCP):
> {noformat}
> | cookie | version | len | peer-address |
> (4) (2) (2) (variable)
> {noformat}
> Goals:
> * Have only 1 buffer, for reading *and* writing
> * Allow to define the sequence by adding buffers dynamically, e.g. in the above case, we'd add a 4 and a 2-length buffer and read data into them. If the cookie and version don't match, throw an exception, else *dynamically* add a length buffer (possibly doing a clear() which removes the first 2 buffers), read data into it, then add a new buffer sized to the read length and finally read data into it.
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)
8 years, 10 months