Subject: Re: nncp-bundle, nncp-caller, and .seen not working?

From: Sergey Matveev <[email-masked]>
Date: Wed, 6 Jan 2021 20:15:39 +0300

*** John Goerzen [2020-12-31 23:39]:
>> We can avoid it by using hash trees, Merkle trees. Changing of that
>
>I think I'm following here :-)

Well, I tried to get rid of temporary files and make different checksum
calculation. I tried own Merkle tree implementation, but did not finish
with it. I decided to use just hash(hash(header) || hash(body)), where
body is hashed when written on the disk, and at the end, when we
overwrite the header, we just calculate two more hashes. I tried BLAKE3
and it was twice as fast, without any parallelization, on my hardware --
just was curious about it.

But I failed. All of that can be done with single encrypted packet. But
when you want to send via some other nodes, then all that wrapped
encrypted packets are created *on the fly* simultaneously. Overwriting
headers requires seeking ability inside that *unaligned* encrypted
streams. So hardly can be done.

Moreover, I have started to refactor nncp-exec (to be able to use
temporary files at least). And I remembered why it was so simple and
even kept everything in memory. If nncp-exec transfers very big volume
of data, then it should be chunked (depending on configuration of
course) as an ordinary nncp-file. That means creation of multiple NNCP
packets, that can be reordered during the transfer. You can not run
any command when not the whole data is ready. Moreover all the data is
inside multiple encrypted packets.

So there must be some complicated code that somehow must find the .meta
packet containing information about all other chunks. Then it must find
that chunks somehow. It differs from current nncp-file/toss operations,
because they decrypt packets and store them on the filesystem. Ok, let's
just decrypt nncp-exec's chunks too and store on the filesystem and
do literally something like "nncp-reass -stdout nncp-exec's.meta |".

So either we have very complex code trying to find chunks *inside*
encrypted packets (obviously by parsing them again and again, or by
having some additional state anywhere), or we just have an ordinary
nncp-file-like transmission.

But current nncp-reass has options for being able to keep fragments on
the disk even after reassembling. It is able to feed them and delete at
once, not requiring to have double disk space (for chunks and whole
reassembled file). If it will be feeding the file to some external
command -- what kind of behaviour should it have? Delete all files if
that external command fails? Keep them? Possibly it is better to
reassemble them on dedup-ed ZFS dataset and pass that reassembled file
as an argument? I just simply can not tell any of those questions at all.

So I remembered why nncp-exec is so simple. If you want to pass big
volumes of data -- then pass them using nncp-file, and then nncp-exec
commands passing them that filename. Remote side's exec configuration
will work with incoming files anyhow user wants. nncp-exec packet can
reach destination much earlier than nncp-file's data itself. It can just
fail and fail every time nncp-toss met nncp-exec packet, until nncp-file
will come and (probably) be reassembled). I will prefer to use some kind
of cron-ed daemon that will check new files in some special directory
with reassembled files, that are treated like tasks to some command.

It is the most flexible way, without huge code complications and many
hard-to-answer questions/decisions. As I remember, FidoNet had similar
kind of things, where big binary files were transferred with "attached"
additional packet, referencing that binary file.

That is why nncp-exec packets can not be chunked, can not be big and no
temporary files are made, because anyway those -exec packets are
relatively small (well, actually there could be multimegabyte email
messages, but I assume that NNCP is running on computers with multiple
hundreds MB of RAM). Their "nature" is to be streamed inside some
command, then tossed, repeated again if it fail. If they are big, then
nncp-file must be used for data transfer itself (chunked, reassembled,
and so on).

-- 
Sergey Matveev (http://www.stargrave.org/)
OpenPGP: CF60 E89A 5923 1E76 E263  6422 AE1A 8109 E498 57EF