Reliable Datagram / Stream behaviour of NT Pipes

Luke Kenneth Casson Leighton lkcl at lkcl.net
Fri Jan 30 11:22:26 CST 2009


folks, hi,
if you recall, i implemented nt named pipes in samba tng, and also
implemented the use of nt named pipes as a transport in freedce, for
when i ported freedce to win32.  so i have quite a bit of experience
when it comes to nt named pipes.
i've encountered some bugs (thanks to python again :) ) in the wine
implementation of nt named pipes, and have raised it as a bug
http://bugs.winehq.org/show_bug.cgi?id=17195 but it started getting
complicated so i thought i'd best raise it here.
the behaviour of nt named pipes is a cross between datagrams and
streams - it's the best of both worlds:
* absolute inviolate message sizes (datagrams)
* absolute inviolate message order (streams).
the issue with the implementation of nt named pipes on top of _just_
streams (unix sockets) is this: two packets sent get blatted into one
read.

you _cannot_ allow this to happen - it screws applications up
_royally_, as applications _critically_ depend on the number of reads
and writes being interleaved, thanks to the characteristics of
NamedPipes.  standard unix applications / protocols (SMTP, etc) have
no choice but to do manual synchronisation built-in to the protocol,
because standard unix streams don't _have_ this "free feature".

so, in samba tng, the emulated-implementation of nt named pipes (on
top of unix sockets) i was forced to send a (32-bit) length field
actually _in_ the data stream, just like is done in NetBIOS.  the
NetBIOS protocol (which was implemented by IBM, not microsoft) sends a
16-bit length field followed by that exact number of bytes.  again,
NetBIOS implements a "reliable datagram-stream" protocol on top of
standard unix streams (tcp stream, this time)

inexplicably, unix simply... is ... entirely... missing this concept.
so, i'm sorry to have to tell you this, but you are absolutely forced
to emulate it (by sending length, data, length data), just like
everyone else ever has.

so, send (write) is simple: write out the length field, write out the
data.  done.  dead simple.

read is... tricky.  you _may_ have to keep track of having read the
length, already.  or, of how _much_ has been read already, of the
"current packet being read".  .... *walks through source code a
bit...*

... i'm veery tempted to say "can i have a go at implementing this?"
but... i know it'll be ... how-to-say... eeenteresting :)

should i try?

would an extra server message need to be added (for read), so that the
server can keep track of how much data has been read back (of the
current datagram)?

l.



More information about the wine-devel mailing list