NNTP and TLS progress

Richard <legalize-aS9lmoZGLiVWk0Htik3J/[email protected]> Wed, 12 Apr 2023 10:00:04 -0600
Newsgroups gmane.network.trn.general
Organization multi-cellular, biological
Message-ID <[email protected]>
Hi Team,

Currently the NNTP support in trn is broken on Windows.  (I am not
sure if it ever worked as written on MS-DOS, I'm not going to
resurrect a 25 yr old development environment to find out.)  How is it
broken?  Well, the existing code assumes that you can get a file
descriptor number from the socket and then do things like dup(),
read() and write() on that file descriptor.  This is an assumption
from Berkeley sockets where such things are perfectly valid, but the
assumption fails on WinSock.

To prepare for my talk this evening on using boost.asio with TCP/IP, I
hacked up some code to talk to news servers and switch to TLS after
the initial connection with the STARTTLS command, should the
capabilities report it.  The code is here:
<https://github.com/LegalizeAdulthood/asio-tcp-ip>

This is only meant to serve as an example for my talk, but will
probably serve as the basis for an asio-based library for NNTP that
will replace the existing manual socket code in trn to allow for
asynchronous communication with multiple NNTP servers as well as add
TLS support.

For testing purposes, I think I'm going to hack up a synchronous
get/put line function using boost.asio into trn and add the ability to
dump the NNTP conversation to a log file.  Then during testing I can
play back the log file into trn to validate that the conversation is
handled properly by any changes I make.

I thought about fixing the assumed read/write calls on the file
descriptor using recv/send on the socket file descriptor using
WinSock, but just like the directory enumeration it seems better to
move forward to a modern approach rather than trying to back fill a
procedural C-style approach onto the existing code.

A real NNTP client library using asio would need the following:
- Understanding of which commands can generate which status codes
- A state machine approach to the conversation
- Asynchronous operation, probably delegate all I/O to a distinct
  thread so as to not impose too much "inversion of control" onto the
  existing application's structure
- Handle timeouts from servers
- Deliver "line at a time" of data blocks to the client of the
  library.  In other words, don't force article parsing or data block
  parsing of complex command responses on the library.  Just handle
  the transport.  A library layer on top of transport could handle
  these details
- Support pipelined commands

As near as I can tell, the existing trn code does not:
- Support multiple simultaneous connections to servers
- Support command pipelining

There does appear to be some sort of "background processing" support,
e.g. trying to get ahead of the user in article/server processing
while the user is reading an article, but it's done in a manner that
is currently opaque to me.  I simply haven't studied the code in more
detail to see what's actually going on.

So my next efforts are going to be on an NNTP library as discussed
above that I can plug into trn.  That library will probably be kept as
a separate repository and just pulled into trn via a git submodule or
vcpkg dependency.  I'll try to keep the library agnostic of boost;
I've noticed that many people using asio as a base support boost.asio,
"regular asio" or the C++ networking technical specification (TS).

So things are progressing...

-- Richard

-- 
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
             The Terminals Wiki <http://terminals-wiki.org>
     The Computer Graphics Museum <http://ComputerGraphicsMuseum.org>
  Legalize Adulthood! (my blog) <http://LegalizeAdulthood.wordpress.com>