I'm once again doing some stuff with Netty's SCTP support - for a project 
involving thousands of sensors that are read periodically and the data 
collected on a private network, its characteristics are pretty ideal for 
small wads of metrics being shot over the wire.

In stress-testing the code (in ways that are unlikely to appear in real 
life, but still...), I've run into an odd little corner case:

NioSctpChannel does the following to send a message:

        final int writtenBytes = javaChannel().send(nioData, mi);
        return writtenBytes > 0;

while the JDK's SctpChannelImpl, in the send() method that takes a 
ByteBuffer:

                do {
                    n = send(fdVal, buffer, messageInfo);
                } while ((n == IOStatus.INTERRUPTED) && isOpen());



and in the send method that takes a file descriptor:

that winds up calling down into the JDK's 
SctpChannelImpl.sendFromNativeBuffer() to do this:

        int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, 
addr,
                            port, -1 /*121*/, streamNumber, unordered, ppid
);
        if (written > 0)
            bb.position(pos + written);
        return written;



and as best I can tell, send0() does *not* necessarily write all of the 
data.

So the client winds up receiving a truncated (but claiming to be complete) 
SctpMessage.

I've got a few workarounds:

 - Flush on a delay instead of immediately (the test is really artificial 
in that it's slamming the server with messages in a loop)
 - Store the actual number of bytes written via a threadlocal and check it 
(discarded this approach - if you aren't calling from an event loop thread, 
the threadlocal is useless, and the below is more reliable)
 - Subclass NioSctpChannel, and have doWrite() compute its return value 
like this:

        int limit = nioData.limit();
        final int writtenBytes = javaChannel().send(nioData, mi);
        return writtenBytes == limit;


which *does* send garbage across the wire; so have the first bytes of each 
SCTP message contain the length the sender expected to send, and if the 
buffer length doesn't match, simply ignore it (since the sender will know 
the write failed and [?] retry it).

This solves the problem, but it is pretty ugly.

Any less ugly approaches?  Or something dumb that I'm not thinking of that 
would solve the problem?

Thanks,

Tim

-- 
You received this message because you are subscribed to the Google Groups 
"Netty discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/netty/80a0df0f-8e52-415c-9742-a17f8e13978e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to