Commit Graph

483 Commits

Author SHA1 Message Date
Alexis Sellier d249937a61
Update dependencies
* radicle-surf
* radicle-git-ext
* amplify
2023-05-10 15:56:21 +02:00
Alexis Sellier 1d9ee81b6d
node: Rename `reactor` module to `io`
The name was always confusing and didn't mean much in the contetx of the
service.
2023-05-08 19:31:20 +02:00
Fintan Halpenny 8508eab8fa
radicle: update radicle-git-ext
This change updates to the latest radicle-git-ext, which required a
few changes within the radicle family of crates.

One set of changes is that the radicle-git-ext crate subsumes
git-commit, git-trailers, and git-ref-format -- so all those imports
go through radicle-git-ext.

The commit code requires that parent `Oid`s point to commits, which
made some tests fail. One of the reasons for these failures is that
the patch tests used fabricated `Oid`s and so the verification would
fail. This is fixed by allowing the test context code to create
`PatchRequest`s that create valid commits.
The other reason for failure was that the identity `Action` passed an
`Oid` that pointed to a blob. This is fixed by removing that code and
making a note of it in documentation.

The final major change was moving the Refspec type into git-ref-format
and removing the AsRefspecs trait. The trait was not required and
could its usage could be replaced by simpler code.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-05-08 10:36:15 +01:00
Alexis Sellier 0349699200
node: Don't connect to recently attempted peers 2023-05-05 17:23:52 +02:00
Alexis Sellier ca0abc4356
node: Keep track of connection attempts
When attempting to connect to a peer, and when succeeding, write the timestamp
to the database.

This will allow us to better select addresses and not retry peers to
soon.
2023-05-05 17:23:52 +02:00
Alexis Sellier c20421b0c6
node: Fix superfluous fetch error on macOS
On macOS, shutting down a socket returns an error if the socket is
already closed. We don't consider that a problem, as it just returns
`Ok(())` on Linux.
2023-05-03 17:20:32 +02:00
Alexis Sellier 0886ab0a3c
node: Get the failing fetch tests passing
We fix the failing fetch tests by:

1. Not verifying our own refs, unless we're cloning, since we're
   otherwise not fetching our own refs.
2. Always force-fetching `sigrefs` from remotes into the staging copy.
3. Making sure that sigref updates are fast-forward before transfering
   the remote into the production copy.
2023-05-03 16:16:34 +02:00
Alexis Sellier 1326774d4f
node: Add failing test for sigrefs fetch
Fetching sigrefs fails if the remote ref is an ancestor of the local ref.
2023-05-03 16:16:34 +02:00
Alexis Sellier 448ef67833
node: Add `Disconnect` command
This is useful especially in tests to disconnect two nodes. We also
expose `command` on the handle type (but not the trait).
2023-05-03 16:16:34 +02:00
Fintan Halpenny 3bfea69642
node: validate production in debug mode
Ensure that the production repository is validated after fetching and
performing deletions. This is to highlight any inconsistencies that
may show up between fetching and deleting references.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-04-28 14:26:47 +02:00
Fintan Halpenny 024218014b
node: test case for outdated refs
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-04-28 14:26:47 +02:00
Fintan Halpenny 694bd345d9
node: use ls-remote when in fetching mode
Given the scenario of 3 peers, A, B, and C each having a project R. If
peer A has B's fork, but C does not, then when peer A attempts to
fetch from C the fetch will be rejected since Git will fail when a
refspec that is asked for does not exist on the remote side.

To avoid this, the fetch logic is changed so that the client first calls
ls-remote to the remote side, which results in the references that the
remote has which the client is interested in. The follow-up fetch then
uses these refs as the refspecs -- which should succeed unless there
was a race for a deletion on the remote side.

The rest of the verification logic stays the same, so the storage
should still be in a working state before transferring from the staged
repository to the production repository.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-04-28 14:26:47 +02:00
Fintan Halpenny 5a48cdf507
node: ensure that we can fetch with a non-existent tracked node
Ensure that non-existent tracking relationships do not affect
fetching.

This is tested by first performing a clone, by `bob` from `alice`,
after `bob` tracks a remote that does not exist. `alice` creates an
issue which is then fetched by `bob` -- to ensure the fetching
scenario is also tested.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-04-28 14:26:47 +02:00
xphoniex ac12a4deee
cli: Implement `rad node start` with support for deamonizing
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2023-04-28 14:19:20 +02:00
Alexis Sellier 83547f9c8a
node: Close worker streams on disconnect
This is in an attempt to fix the worker pool from being backed up.
2023-04-27 11:42:33 +02:00
Alexis Sellier df25e9a2a5
radicle: Fix unverified `Remote::new` constructor
We were allowing remotes to be constructed via a function that didn't
check its inputs.

This is now fixed by moving the public key into the `SignedRefs` struct.
2023-04-26 10:57:26 +02:00
Alexis Sellier ccbfe5b6fa
node: Add warning if workers are all busy 2023-04-26 09:59:19 +02:00
Alexis Sellier 10fe2ae299
node: Add worker channel timeouts
It's currently possible for a channel to be blocked forever while
waiting for data, if the remote peer keeps the connection alive.
This can occupy a worker indefinitely.

With these timeouts, we ensure that workers exit if there is no
activity after a certain amount of time.
2023-04-26 09:59:19 +02:00
Alexis Sellier 5428420f27
node: Rework peer map to not panic
In the wire protocol, we often panic in case a peer is not found.
With this change, we instead log an error.
2023-04-26 09:59:19 +02:00
Alexis Sellier 045d201916
node: Fix log pluralization 2023-04-25 12:47:36 +02:00
Alexis Sellier 671c169244
node: Implement `rad sync` command
This command announces refs to peers and waits for them to be
in sync.

Adds a subscribe method to `Handle` so that we can get the events
from the seed to allow us to confirm that the configured seeds fetched
from us.
2023-04-24 11:39:37 +02:00
Alexis Sellier fd3a6583d0
node: Improve framing code
Thanks to @fintohaps for these suggestions.
2023-04-23 15:10:42 +02:00
Alexis Sellier bf8653b6c2
node: Fix keep-alive delta
By having the keep-alive delta be the same as the ping timeout,
we essentially disconnected peers right after we sent them our
first ping.

This fixes that issue by setting the ping timeout to double the
keep-alive delta.
2023-04-21 16:54:03 +02:00
Alexis Sellier a16be24517
node: Fix log output in `--help`
The logs were being output in the help text.
2023-04-20 16:32:41 +02:00
Alexis Sellier 26ee6d26dc
node: Reduce log messages when sending messages 2023-04-20 16:32:41 +02:00
Alexis Sellier 9120db4ddb
node: Reduce log verbosity when receiving messages 2023-04-20 16:32:41 +02:00
Alexis Sellier 189eb3f201
node: Cleanup logging 2023-04-20 16:32:41 +02:00
Alexis Sellier b51d491ad9
node: Preserve tracking policy on startup
We were needlessly overwriting the policy if it was set to "trusted".
2023-04-20 16:29:55 +02:00
Alexis Sellier 2598886018
node: Delete unsigned refs on fetch 2023-04-19 11:32:46 +02:00
Alexis Sellier 0d98b84861
node: Skip trusted peers that aren't local 2023-04-18 14:49:13 +02:00
Alexis Sellier 94bef61944
node: Return only remotes that were fetched from
Instead of returning the namespaces that we fetched with,
we return the remotes that were actually fetched from.

This can differ if some trusted peers were not available
on the remote node.

Previously, if that was the case, it would cause errors
since the remotes were looked up and that lookup failed.
2023-04-17 18:58:56 +02:00
Alexis Sellier bb07e25571
node: Emit event when refs are synced
This will help us give the user feedback when he pushes.
2023-04-17 16:18:34 +02:00
Alexis Sellier 4b2bc365ef
node: Better differentiate fetch results
We use an enum to separate initiator vs. responder results.
2023-04-17 16:18:34 +02:00
Alexis Sellier 51b372ecad
node: Share channel type between modules
Shares the `Channels` type between the `wire::protocol` and
`worker` modules.
2023-04-17 15:56:24 +02:00
Alexis Sellier d0e24bd0ce
node: Simplify worker data piping 2023-04-17 15:55:31 +02:00
Alexis Sellier c99497eb21
Update `netservices` to 0.2.2
This includes a small change in how the EOF is sent as well.
2023-04-17 15:53:31 +02:00
Alexis Sellier a8f0329391
node: Downgrade some logs to `trace` level
These logs were a bit noisy and don't help much.
2023-04-17 11:21:22 +02:00
Alexis Sellier 0e7ffcc916
node: Properly validate signed refs on fetch
With this change, we not only verify the signed refs before
the repository "transfer", but also validate that all refs in the
repo are signed and there is no discrepancy with the signed refs
file.
2023-04-15 00:17:17 +02:00
Alexis Sellier 56e41fadd9
node: Update `netservices` and `io-reactor`
This fixes hanging issues we were experiencing.
2023-04-14 23:30:18 +02:00
Alexis Sellier 9729a23559
node: Use `StagedRepository` to know what to do
To know whether or not we're cloning, use `StagedRepository` instead
of checking manually.
2023-04-14 13:56:52 +02:00
Alexis Sellier 3e05939d14
node: Don't fail fetch for existing repositories
If `git-fetch` returns a non-zero code on exit, we keep going in the
case of an existing repository.

The reason is that `git-fetch` will return an error code if any ref
is rejected during the fetch. But this can happen if someone
pushes conflicting `rad/sigrefs` branches for example, and the node
already has a copy of that branch.
2023-04-14 13:56:16 +02:00
Alexis Sellier 18616a16bd
node: Match error by value
There wasn't a good reason to use a reference. This also allows us
to explicitly drop the session.
2023-04-14 13:55:47 +02:00
Alexis Sellier 17651e259d
node: Don't panic if peer disconnected 2023-04-14 13:55:32 +02:00
Alexis Sellier 8c92282578
node: Fix some error messages
A "block" policy doesn't necessarily mean an active block.
2023-04-14 13:55:22 +02:00
Alexis Sellier bda5d6f080
node: Tunnel git data without parsing packet-lines
Instead of parsing the worker requests and responses, which was causing issues
around packfile transmission, we use threads and pass the bytes
transparently.
2023-04-14 13:16:32 +02:00
Alexis Sellier a05de1fbf3
node: Test fetch with large repository
This is for stress-testing the replication.
2023-04-14 13:15:52 +02:00
Alexis Sellier ac3a03fea6
node: Set git-daemon keep-alive
Send a keep-alive packet every 3 seconds to make sure the client doesn't
timeout during pack building.
2023-04-14 13:15:52 +02:00
Alexis Sellier 273ce2744a
node: Add more information to worker result log 2023-04-14 13:15:52 +02:00
Alexis Sellier f4257eb953
node: Add setting for limiting fetch concurrency
Can be passed via `--limit-fetch-concurrency <num>`.
2023-04-14 13:15:52 +02:00
Alexis Sellier ea4294c79f
node: More realistic concurrent fetch test
This implements a test which can optionally use a lot more data by
setting `RAD_TEST_SCALE` to a higher value.
2023-04-14 13:15:52 +02:00
Alexis Sellier 8205f8ad4e
Update `fastrand` dependency to 1.9.0 2023-04-14 13:15:52 +02:00
Alexis Sellier 31647521fa
node: Properly close worker channels
We need to send a 'close' event to the worker channel for it to exit
without an error.

Also updated and improved a bunch of the logs.
2023-04-14 13:15:52 +02:00
Alexis Sellier 267aba5901
node: Announce inventory only if it changed
Previously we were announcing inventories all the time, due to
relying on the timestamp changing on insertion.

We change this to only announce our inventory when it actually changes.
2023-04-14 13:15:52 +02:00
Alexis Sellier 7cbfde1e9b
node: Don't needlessly fetch or announce
* We shouldn't announce if no refs were updated.
* We shouldn't blindly fetch if we don't know if we have an item in
  storage.
2023-04-14 13:15:52 +02:00
Alexis Sellier f3d513783c
node: Don't fetch owned refs unless cloning
We shouldn't be fetching our own refs unless we are creating a clone.
2023-04-12 16:40:53 +02:00
Alexis Sellier c8e548fb1d
node: Make sure we have all refs in staging copy
Previous to this change, we just created a clone, which was missing
all the refs.
2023-04-12 11:43:43 +02:00
Alexis Sellier 097b5b4ca4
node: Improve worker code logging and errors 2023-04-12 11:28:12 +02:00
Alexis Sellier eeec2008e8
node: Allow most refs to be force-updated
Previously, during the "transfer" stage of a fetch, we used `force:
false`, which didn't allow refs to be force-updated.

This change makes it possible to fetch force-updated refs, but ensures
that the sigrefs branch is never force-updated.
2023-04-12 11:09:05 +02:00
Alexis Sellier 89b9eb53b7
node: Implement protocol multiplexing
To improve the reliability and flexibility of the protocol, we introduce
multiplexing over peer connections. This involves a new `Frame` type
that carries a stream-id and payload.

Three stream types are made available:

1. Control
2. Gossip
3. Git

This change brings the following improvements:

* Removed need to queue fetch requests
* Removed need to queue gossip messages
* Removed need for `Fetch` and `FetchOk` messages
* Service doesn't need to know about inbound fetches
* Removed one round-trip for fetch negotiation
* Removed special `done` git packet
* Removed session logic and state around Git/Fetch protocols
* Removed code around upgrading/downgrading transport
* Worker in responder mode is able to process any number of fetches
* Connections support any number of concurrent fetches

We had to introduce a few extra things however to make it all work:

* A `VarInt` type for variable-length integers, since we want the frames
  to be lightweight.
* A custom "tunnel" implementation, since we couldn't use the existing
  one anymore.

Overall the change removes more complexity than it adds, while improving
the protocol along the way.
2023-04-10 14:41:55 +02:00
Alexis Sellier ed4c266a51
node: Don't prune owned refs
Owned refs were being pruned on fetch.
2023-04-03 22:09:41 +02:00
Alexis Sellier c3e14c346b
node: Add `--force` option to start node
Forces the node to start even in the presence of an existing socket
file.
2023-03-31 17:30:55 +02:00
Slack Coder 6417a71e08
node: systemd file
Support users with systemd integration by providing a systemd service
file.  The file includes basic instructions for how to adapt to the
users context.

There are two scenarios it would be run in, as a system service, or as a
user service.  The scenario as a user service is problematic.
`radicle-node` relies on ssh-agent or a clear text RAD_PASSPHRASE.
2023-03-31 15:48:32 +02:00
Alexis Sellier 3f389f37ea
node: Make sure we retry on lock contention
This fixes an issue that came up in tests where we would be reading
and writing to the database at the same time, and it would fail with
an error due to the lock being contended on.
2023-03-31 14:07:45 +02:00
Fintan Halpenny c618c3e443
node: remove Namespaces::One
The One variant caused many paint points for fetching logic, where it
was not necessary. It was only constructed in one place, which could
be replaced by using the variant that holds a set of keys.

Remove the Namespaces::One variant and rename Namespaces::Many to
Namespaces::Trusted.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-31 12:23:32 +01:00
Fintan Halpenny adf6312a55
node: fetch trusted peers on clone
When a repository does not yet exist during a fetch, i.e. a clone,
then only delegates are being fetched.

Augment Namespaces::Many to hold the trusted and optional delegate peers
separately. Doing so allows the construction of the variant without
the repository existing, but tracking relationships existing.

This variant can then be used to build refspecs for both the trusted
peers and delegates when doing a cloning fetch.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-31 12:23:31 +01:00
Fintan Halpenny f78e010c55
node: e2e test simulating a peer migrating their key
Previously, if a peer created a project which was replicated and then
moved to another setup, ultimately deleting that project, then they
would not be able to fetch it again since their remote namespace would
be excluded from the fetch.

This test confirms that a peer can remove their project and clone it
again from a peer that has replicated the project. This is simulated
by directly removing the project directory in the test and fetching
the project from the other peer.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-31 12:19:37 +01:00
Fintan Halpenny 6e08f0be59
node: enable test_fetch_trusted_remotes
With the latest fetch updates, the test for fetching trusted remotes
can be enabled.

The caveat is that its expected behaviour is to fetch the delegate
upon a clone and fetch all trusted peers on a subsequent
fetch. Fetching all trusted peers is left as a follow-up task.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-31 12:19:36 +01:00
Fintan Halpenny db0ceddf6b
node: multistep fetching logic
The previous fetching logic had some pitfalls regarding its logic:

* Fetched 'rad' references could end up not being verifiable and leaving
  the storage in a corrupt state
* Forced pushes would be prohibited, since they would be rejected by
  the client side due to the refspecs being used.

The new approach is to stage a fetch in 2 steps. The first step is to
fetch the relevant `rad/id` and `rad/sigrefs` for verification. For
all remotes that are verified, fetch all references listed in their
respective `rad/sigrefs`, using the `+` marker in the refspec,
allowing to update for any force pushes -- note that this becomes a
safe operation since the `sigrefs` are signed by the remote that
created them.

To prevent unverifiable 'rad' references from polluting storage, all
fetch negotiations are done in a staging repository set up in a
temporary directory. All successful fetches are then transferred,
using the 'file://' protocol, from the temporary directory into the
radicle storage.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-31 12:19:36 +01:00
Alexis Sellier 973f618cd3
node: Fix routing table update on refs
The announcer is always the one who must have the refs, not the relayer.
This was changed in a recent patch.
2023-03-30 10:24:09 +02:00
Alexis Sellier 7c41c5edff
node: Replace most sleeps with events
With the new event system, we can replace the thread sleeps by
waiting for events. This should speed tests up a lot and
be more reliable.
2023-03-30 10:24:06 +02:00
Fintan Halpenny a629f91b1e
node: set identity head after fetch
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-27 10:13:03 +01:00
Han Xu b030e9ea80
node: Only fetch from tracked nodes
The tracked nodes include nodes marked tracked in the db, and
the delegates and `Namespaces::All` if it is a new repo.

Signed-off-by: Han Xu <keepsimple@gmail.com>
2023-03-25 12:27:29 +01:00
Alexis Sellier da9d63b284
node: Fix fetch requests code
We were not correctly deleting the fetch request, since only one
was kept per RID.
2023-03-24 13:25:40 +01:00
Alexis Sellier fe8953ab8b
node: Don't penalize peer for protocol mismatch
Instead of returning a non-transient disconnect reason, return
a transient one, since protocol mismatches can happen.
2023-03-24 13:23:43 +01:00
Alexis Sellier d3f4189324
node: Fix reconnection logic
First, we make sure to always attempt reconnection to persistent peers,
no matter the reason.

Second, we don't re-attempt connections when an inbound peer
disconnects. This minimizes the chance of connections crossing.

Third, we clean up `session::Error`, and don't use it to signal a
missing session, since it doesn't really belong there.
2023-03-24 13:20:34 +01:00
Alexis Sellier 4438a10498
node: Change ping interval to 1 minute
30 seconds is too chatty.
2023-03-24 13:19:36 +01:00
Alexis Sellier bfea229850
node: Relax `Service` storage trait bound 2023-03-23 18:08:06 +01:00
Alexis Sellier c427f41379
node: Fix periodic inventory announcement
1. We were announcing inventory every 30 seconds. This is now changed
   to 1 hour.
2. We were using a variable to track whether our inventory has been
   announced to the network, but this var was set based on what we
   tracked, not the inventory we had. This var has been removed.
2023-03-22 22:03:59 +01:00
Alexis Sellier dd97ac8384
node: Improve worker error handling
Better handle case where the connection to the daemon fails, in the
responder scenario.

Instead of trying to read the `done` packet once, we loop until we've
read it. This handles a scenario where the uploader fails before the
git protocol is initiated, and the fetcher is still sending git packets.
2023-03-22 12:22:44 +01:00
Alexis Sellier a9d1a71f7a
node: Add timestamp to test logger 2023-03-22 12:22:44 +01:00
Adam Szkoda 1455810d57
node: Add commit SHA-1 to log 2023-03-22 08:52:52 +01:00
Han Xu 241c41a632
node: Queue pending fetches in Session
Pending fetches are drained one at a time after the previous fetch is
completed.

Signed-off-by: Han Xu <keepsimple@gmail.com>
2023-03-22 08:46:27 +01:00
Alexis Sellier ed1120f3eb
node: Don't relay redundant gossip messages
This change ensures that on `Subscribe`, we only relay the latest
announcement of each node, per announcement category.

Previously, we would relay all announcement, while only the last one
was relevant.
2023-03-17 17:10:10 +01:00
xphoniex a49eec9892
node: Add eventing system to `Handler` and `Service`
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2023-03-16 22:26:57 +01:00
Alexis Sellier ebfd445034
node: Use correct scope when getting namespaces
We were using the default scope instead of the entry scope.
2023-03-16 15:38:05 +01:00
Alexis Sellier 88c545bfdd
node: Make sure to only read packet-line header
If there is an unexpected error, eg. `BrokenPipe` in the upload process
process of the worker, we may have more than four bytes to read from the
remote socket. This change ensures that we don't attempt to read more
into a buffer of size `4`.
2023-03-16 15:26:16 +01:00
Alexis Sellier c46bc0cc82
node: Start periodic tasks
This change ensures that we start the periodic tasks "loop" by
scheduling the first wakeup during initialization.
2023-03-16 15:26:13 +01:00
Alexis Sellier fdfe1d508b
node: Use deserializer when decoding messages
For whatever reason, we weren't using the deserializer for message
decoding. This meant that if a message came in two pieces, it would
cause decoding problems, since the first piece would be discarded.
2023-03-16 15:26:13 +01:00
Alexis Sellier 17e3c975fb
node: Better error message when protocol mismatch 2023-03-16 15:26:13 +01:00
Alexis Sellier c4a66c20d0
node: Fix potential protocol mismatch on fetch
It's possible that the daemon or stream closes the git connection
without reading the final `done` packet. If this is the case, we
try to read it after either of the connections is closed.

This may potentially mitigate the issue where the node then receives
the `done` packet while in gossip mode, and disconnects the remote
for misbehavior.
2023-03-16 15:26:13 +01:00
Alexis Sellier 98ee9c46a9
node: Fix state mismatch between service and wire
Due to never removing peers from the peer map in the wire
protocol module, it was possible for there to be multiple
connected peers with the same Node ID. Some might be in a
"connected" state, while others might be "disconnected".

This caused a bug where a peer, although connected would
be considered disconnected by the wire module, because
when searching for a peer with that Node ID, the disconnected
one would return first.

To fix this, we make sure to remove peers from the map once
the connection is dropped.
2023-03-15 16:46:27 +01:00
Alexis Sellier 5828b917f9
node: Fail fast when repository can't be read
It's not a good idea to have fallible operations run after `FetchOk`
is received, since there's no easy way to communicate the error
to the remote at that point. What would then happen is that the fetch
just "hangs", since nothing is there to cancel it.

Hence, we compute namespaces earlier in the process, and store the
namespaces in the session. If there is a failure, the fetch is
never initiated.
2023-03-15 16:22:43 +01:00
Alexis Sellier 05d7090326
node: Remove `Handle::inventory` method 2023-03-15 12:59:49 +01:00
Alexis Sellier caaa7581e6
node: Remove `Routing` command
Replaced by direct DB access.
2023-03-15 12:59:49 +01:00
Alexis Sellier 40c58b45ed
node: Move `routing` to `radicle` crate 2023-03-15 12:59:49 +01:00
Alexis Sellier b558c742e6
node: Rename `repo_entries` to `repo_policies`
Do the same thing for `node_entries` etc.
2023-03-15 12:59:49 +01:00
Alexis Sellier 9b6ede8fc5
cli: Use tracking DB access for `node` command 2023-03-15 12:59:49 +01:00
Alexis Sellier cf8113765c
node: Move tracking store to `radicle` crate 2023-03-15 12:59:49 +01:00
Alexis Sellier cf80f246b3
node: Fix bug in seed stats 2023-03-15 12:48:03 +01:00
Alexis Sellier cd12741bf2
node: Prevent redundant [re-]connections
It was possible to trigger multiple connection attempts to the same
peer, since we didn't track connection attempts that hadn't yet
returned to the service via `Service::attempted`.

With this change, we add an extra `Initial` state to sessions, so
that redundant connections are not attempted when one is already under
way.
2023-03-14 13:42:59 +01:00
Alexis Sellier 413238a1e0
node: Implement exponential back-off for reconnect
Instead of immediately attempting reconnection when a persistent
peer disconnects, wait some amount of time, increasing on every
attempt.
2023-03-13 17:43:49 +01:00
Alexis Sellier 94427ee22b
node: Call service on failed connection attempt
Before this change, we were not calling back into the service due
to the missing `NodeId`.
2023-03-13 16:31:00 +01:00
Fintan Halpenny 646376828d
node: add tracking-scope option
The radicle-node was forced into using Scope::Trusted for its default
scope.

Allow the Scope to be specified at the command line using a
`--tracking-scope` option.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-13 12:13:12 +01:00
Alexis Sellier 8e5627d28a
node: Rename `tracked_repo` -> `repo_policies`
I was finding the current naming misleading, as the returned entries
could be for blocked repos/nodes.
2023-03-13 11:41:07 +01:00
Alexis Sellier 4f062ef2c6
node: Fetch missing inventory
Periodically, make sure we try to fetch inventory that is tracked
but missing from local storage.

We decide not to fetch immediately on `TrackRepo`, as this limits
the command's flexibility. For example, when `rad clone` is used,
we want to be able to fetch manually after tracking.
2023-03-13 11:38:33 +01:00
Alexis Sellier 0df724a58f
node: Bind control socket immediately
This avoids race conditions, especially in tests, where we try to
connect to the node right after spawning it, but since the
`Runtime::run` function is often called in a different thread, the
socket is not created in time.
2023-03-09 16:31:49 +01:00
Alexis Sellier db38f2df76
node: Handle `FetchOk` never being received
It's possible for a peer to disconnect before responding with `FetchOk`.
In that case, we make sure to return to any pending fetch request with
an error.
2023-03-08 16:22:42 +01:00
Fintan Halpenny 821a6b6c08
node: test do not fetch from owned refs
To ensure the behaviour of ignoring references that are owned by the
local peer a test case is added.

The case has two peers: alice and bob, where alice creates a new
repository. bob fetches to be up-to-date with alice. alice, in turn,
creates an issue and fetches from bob -- which should be successful.

If the refspec:

    ^refs/namespaces/<alice>/*

was not in place, her fetch from bob would fail since the signed
references would not be a fast-forward.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:33:42 +00:00
Fintan Halpenny 7fddc70a57
node: test fetch from trusted
Adds a test for fetching from trusted delegates.

Currently marked as failing. When the fetch is initiated from a client
that does not have the repository then it will fetch all namespaces,
instead of the trusted set.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:33:42 +00:00
Fintan Halpenny 1e8f5b2259
node: determine fetching namespace based on repo policy
To determine the correct Namespaces to use, the repo Policy and Scope
are consulted.

If the policy is Block then this is a failure state and is reported to
the other end.

Otherwise, if the policy is Track, then the scope is checked. For the
Trusted Scope then the Namespaces should consist of all tracked nodes
and delegates for the given repository. However, the repository might
not exist and so it is necessary for the whole repository to be
fetched.

For the All Scope, all Namespaces are fetched.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:33:41 +00:00
Fintan Halpenny e937cdd79a
node: improve fetch
The fetch implementation will potentially fetch the local operator's
remote, which is unnecessary and could result in deleted data.

Fix this by threading the local operator's public key and add an
ignore refspec to the fetch arguments, i.e.

    ^refs/namespaces/<local>/*

The implementation also strictly fetches all or one namespace. This is
improved upon by introducing a new variant for specifying a set of
namespaces.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny 3b015a9325
radicle: accept Scope as track_repo argument
The method `track_repo` only accepted the RID as the argument for
tracking.

Instead, allow passing Scope as an argument for tracking a
repository.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny 546b402467
node: return full tracking policy
Instead of returning tuples for `repo_entry` and `node_entry`, return
the `Repo` and `Node` types, respectively.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny b82584617b
node: store Scope in tracking config
The tracking configuration has no way of consulting for a configured
scope.

This change allows the storing of this scope inside the tracking
`Config` -- currently unused.

The default Scope is chosen as Trusted, so that nodes do not
implicitly track any other node. If this behaviour is desired -- for
example, for seed nodes -- then All should be chosen.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny 5902236d0a
radicle: remove DelegatesOnly scope
The DelegatesOnly scope is very limited and causes more confusion than
it solves.

The Trusted scope subsumes DelegatesOnly since it implies delegates
along with any tracked nodes. This feels more natural to use and so
DelegatesOnly is removed -- leaving only Trusted and All.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny 39be7db1e9
radicle: make alias optional
Previously the alias field was simply a string which could possibly be
empty. Some checks were made to see if this string was empty.

Instead, make the logic more obvious by making the alias field
optional.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny 0302701c98
node: limit number of loops in `routes_to`
The `routes_to` function can loop infinitely during test.

To prevent this from happening a number of tries variable is added. It
checks that the number of tries does not exceed 30, which gives the
function about 3 seconds to complete -- due to the call to
`thread::sleep` using 100ms.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:34 +00:00
Fintan Halpenny d476d35887
radicle: populate MockRepository
The MockStorage holds an inventory of repositories and their
identities but when asking for a MockRepository, none of this
information is transferred.

Add `id` and `doc` fields to MockRepository for defining some of its
functionality.

In addition, add a generator for a nonempty MockStorage to use in
tests that will expect the storage to be populated.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:33 +00:00
Fintan Halpenny e408b0d62c
node: use enum for fetch direction
A fetch is a client-server interaction and so there are two sides to
this interaction. These sides are generally referred to as receive --
the client side -- and upload -- the server side.

The `Fetch` type indicated whether it was doing a receive or upload by
using a field `initiated: bool`. However, this can be confusing when
you pair it with the `namespaces: Namespaces` field, since only the
receive side should be sending what refspecs it wants and the upload
side responds with those matching refspecs.

A better way to represent this is using an enum for which direction
the fetch is being considered, where the receive side contains the
Namespaces. To borrow from Noise, the variant names are 'Initiator'
for the client and 'Responder' for the server.

The resulting code then makes decisions based on what variant of the
enum was passed.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 10:12:54 +00:00
Alexis Sellier c3a5aced07
node: Handle case of crossing fetch requests
It is possible for a pair of nodes to concurrently ask each other
to fetch some repo. These "crossing" requests are problematic,
because the nodes end up waiting for each other to reply, and
the reply never comes.

With this change, the node pair agrees on proceeding with one of
the fetches, while canceling the other.
2023-03-07 16:22:22 +01:00
Alexis Sellier fb635d80c3
node: Gossip once we switch to gossip protocol
Previous to this change, we were attempting to gossip after a successful
fetch, but before the session was switched back to the gossip protocol.
This meant that messages were queued for a short amount of time. With
this change, messages should be sent straight away.
2023-03-07 15:44:10 +01:00
Fintan Halpenny f322305f86
node: wire up connect command
The connect command was unimplemented for both Node and the control
socket.

This wires up the connect functionality in both places.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-07 15:38:41 +01:00
Fintan Halpenny 1f837c6572
node: implement tracking and routing
The routing function for Node was not implemented and there were no
functions for getting any tracking information.

This implements routing, tracked_repos, and tracked_nodes. To
accomplish this it was necessary to add associated types to the
Handler trait so that implementations could differ in the types they
use for returning this data, i.e. the control socket needs to use a
channel while the Node needs to return serializable data.

Currently, the Node uses a `Vec` but it would be more beneficial to
return an Iterator directly to ensure we are not always hitting the
heap.

To allow for the tracking types to be used across radicle-node (the
crate) and in radicle::node (the module), it was necessary to move
the types to the common place, i.e. radicle::node. At the same time,
new structs were added to make it easier to refer to tracked repos vs
tracked nodes.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-07 15:38:41 +01:00
Alexis Sellier 94899f7be2
node: Update `localtime` crate 2023-03-07 10:47:12 +01:00
Alexis Sellier 85df613682
cli: Implement automatic issue announcement 2023-03-07 08:40:20 +01:00
Alexis Sellier a5ee494fda
node: Correctly handle disconnect in wire protocol 2023-03-06 15:39:07 +01:00
Alexis Sellier 54dc34d4b9
node: Minor logging improvements 2023-03-06 15:39:07 +01:00
Alexis Sellier c8c44c884c
cli: Allow `init` without running node 2023-03-06 15:38:42 +01:00
Alexis Sellier e69be6051d
cli: Give more control over `init` announcement
Instead of always announcing the inventory, by default we don't.
Users can run `rad push` to trigger an announcement.
2023-03-06 15:38:42 +01:00
Alexis Sellier 793c085094
node: Don't force use of RAD_PASSPHRASE
If it isn't set, prompt the user.
2023-03-06 10:22:53 +01:00
Alexis Sellier 5f59493c70
cob: Don't require a local fork to exist
Before this change, the identity document would be loaded for the
COB signer. This meant that a fork would be needed for that signer.

After this change, it's no longer necessary, since the identity doc
head is computed from available remotes.

While making those changes, it was also apparent that some of the
identity-related functions had bad names and error types, this
was fixed as well.
2023-03-01 15:40:30 +01:00
Alexis Sellier 411c54a604
node: Use loopback address as git-daemon default
Prevents external connections to it.
2023-03-01 13:03:42 +01:00
Alexis Sellier 207030d2e1
cli: Don't fail clone if we have repo locally 2023-02-27 18:19:02 +01:00
Fintan Halpenny c70dc71b18
node: improve seeds information
Previously, the seeds information would only consist of the connected
NodeIds.

Improve on this by adding any disconnected and fetching seeds as
well. A seed can either be disconnected, connected, or fetching --
where fetching implies connected.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-27 17:48:11 +01:00
Fintan Halpenny c0b92d25fb
radicle: remove FetchResult associated type
The Handle trait defines a FetchResult associated type. This type is
always instantiated to be the FetchResult enum in radicle::node.

Remove the associated type to simplify the trait.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-27 17:17:00 +01:00
Alexis Sellier 11da344e3a
node: Add `--tracking-policy` flag
Sets the default tracking policy.
2023-02-27 13:46:40 +01:00
Dr Maxim Orlovsky 158f1ff7fa Update to fixed `io-reactor` timer 2023-02-22 16:21:25 +01:00
Alexis Sellier 7e1b2b6222
crypto: Cleanup `hash` module
Remove `Digest` type and use `ssh-key` for formatting public ssh key.
2023-02-17 10:51:27 +01:00
Fintan Halpenny 8e26e4c046
radicle: canonicalize home path
If a path was passed to `Home` in non-canonical form it would not use
the right path for any initialisation or use.

The aim is to use the `canonicalize` function for paths. However, this
may return an error if none of the paths exist. To ensure that the
path exists the `new` constructor for `Home` creates the directory and
canonicalizes the path.

Since `new` now initialises the home directory, it would be useful if
it also initialised all the necessary subdirectories -- which removes
the need for the `init` method.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-16 16:35:59 +01:00
Alexis Sellier a7d2fa95cd
node: Remove redundant handshake
With `NoiseXK` handshake implemented, there is no longer a need to
have an `Initialize` message and an extra state in the session.
2023-02-16 15:10:31 +01:00
Alexis Sellier 71561a8e12
node: Move state transition code to session 2023-02-16 15:09:53 +01:00
Alexis Sellier 011923f1df
node: Buffer gossips until fetch is completed
This change ensures that gossip messages are buffered if we try to
send them during a fetch, and sent after the fetch completes.
2023-02-16 15:09:53 +01:00
Alexis Sellier 0f81f8a7aa
node: Take session reference when writing messages
This ensures that we have an existing session when sending messages.
It also will allow us to check the session's state.
2023-02-16 15:09:53 +01:00
Alexis Sellier 950fae209d
Make `ReadStorage` more usable
Previously, we were not able to access a `ReadRepository` instance
through `ReadStorage`. With this change, we are able to.
2023-02-15 22:08:20 +01:00
Alexis Sellier 89fcc6de1c
node: Subscribe on track-repo
We re-subscribe after our tracking policy has been changed so that
peers are informed of our interests.
2023-02-15 22:07:51 +01:00
Alexis Sellier 8cbc3c2403
node: Move to NoiseXK
Move from NoiseNN with a custom authentication protocol, to NoiseXK.
Uses ECDH on the ed25519 curve via the `ec25519` library.
2023-02-15 22:05:04 +01:00
Slack Coder 76d23a3fa9
node: Add more command argument documentation
Document `--git-daemon` and describe the default values.

Signed-off-by: Slack Coder <slackcoder@server.ky>
2023-02-15 15:17:07 +01:00
Alexis Sellier b29ce1a222
node: Fix bug when socket file is deleted
If the socket file is deleted while the node is running, we can no
longer quit with Ctrl-C. This is the "fix".
2023-02-15 10:41:09 +01:00
Alexis Sellier ee513ccf7e
node: Complete the "relay" seed test
These are the final changes to get the "relay" scenario passing.
There are still some issues left, though it's done as far as the
test is concerned.
2023-02-14 20:31:40 +01:00
Alexis Sellier 7919c7ea61
node: Use millisecond precision for timestamps
Previously we used seconds, which could result in false positives
when checking for stale announcements, if things happened too quickly.
2023-02-14 20:31:40 +01:00
Alexis Sellier 72c99b7939
node: Handle `SIGINT` and `SIGTERM` properly
This ensures that the socket file is cleaned up on exit.
2023-02-14 13:28:16 +01:00
Alexis Sellier 3ae826dee2
node: Add clone test with seed acting as relay 2023-02-13 10:30:04 +01:00
Alexis Sellier 3e7761740f
node: Rely on inventory announcement in `rad init` 2023-02-13 09:59:44 +01:00
Alexis Sellier c673f5db68
node: Add some useful test utility functions 2023-02-12 21:03:28 +01:00
Alexis Sellier 7087288cfb
node: Implement inventory sync command 2023-02-12 20:57:33 +01:00
Alexis Sellier 2f1a18470e
node: Fix filter construction and policy code 2023-02-12 17:07:57 +01:00
Alexis Sellier 5f4c6edee4
node: Simulator logging improvements 2023-02-12 16:48:46 +01:00
Alexis Sellier 42b4d95f93
node: Improve output of `Session::fetch` function 2023-02-12 16:22:51 +01:00
Alexis Sellier bd7c5a0daa
node: Add ability to have default tracking policy
When a specific tracking policy isn't found, we allow setting a default.
To preserve existing behavior, the default is `Block`, ie. if a node
isn't tracked explicitly, it is blocked.

However, this change allows for using `Track` as the default, which
is a way to track everything without having to know the entities in
advance.
2023-02-12 16:22:51 +01:00
xphoniex bdc0ab9881
Update `radicle-git` and `radicle-surf`
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2023-02-10 22:14:50 +01:00
Alexis Sellier 488f043226
node: Properly reap git-daemon process 2023-02-10 12:57:04 +01:00
Slack Coder 02c07d7be1
cli: Test rad-clone is deterministic
The last commit of a newly cloned repository should remain untouched by
making `Node::project()` use a repository fixture instead of a randomly
generated one.

Signed-off-by: Slack Coder <slackcoder@server.ky>
2023-02-09 16:49:52 +01:00
Alexis Sellier 69ac8be8fd
node: Update local routing table on announce 2023-02-08 21:28:49 +01:00
Alexis Sellier f01735bef6
cli: Have `init` trigger routing table updates
Before this change, nodes had to be restarted to announce newly
initialized projects.
2023-02-08 16:29:42 +01:00
Alexis Sellier c138cd062c
node: Give each peer its own inbox
Instead of a shared queue, each peer gets its own inbox.
2023-02-08 11:43:39 +01:00
Alexis Sellier 054655d79b
node: Log read buffer if not empty 2023-02-07 21:13:29 +01:00
Alexis Sellier f66ecd4ece
node: Replication fixes
* Read git request line before starting daemon, so that we don't leave
  git data in the socket read buffer in case of an error connecting to
  the daemon.
* Send a response on the fetch channel even if we disconnect the remote.
* Don't send `done` packet if there's an error; it won't be expected.
2023-02-07 21:04:13 +01:00
Alexis Sellier d59c422b9d
node: Send special `done` packet to end protocol 2023-02-07 10:47:35 +01:00
Alexis Sellier f5f36191d9
node: Fix some connection-related logic 2023-02-07 10:47:35 +01:00
Alexis Sellier 7bdedd0ffd
node: Fix bug with persistent peer reconnect
We weren't updating the sessions map when a persistent peer
was re-attempted. It would then panic when `connected` was called,
because the state would be `Disconnected`.
2023-02-07 10:47:35 +01:00
Alexis Sellier 2ceb39553e
node: Remove redundant log 2023-02-07 10:47:35 +01:00
Alexis Sellier 037ff39894
node: Use JSON for control commands 2023-02-07 10:46:12 +01:00
Alexis Sellier 2649e9c6fe
cli: Add `rad-clone` test 2023-02-07 10:46:12 +01:00
Alexis Sellier a8531eff36
node: Implement `seeds` control command 2023-02-07 10:46:12 +01:00
Alexis Sellier b542ddcd6c
node: Create shared test environment
We move and combine some of the test code, so that the CLI tests and
node tests use shared code.
2023-02-07 10:46:12 +01:00
Alexis Sellier 45e31a5192
Communicate fetch results through control socket
This allows a CLI to report to the user what fetch requests were
fulfilled, and which ones failed.
2023-02-07 10:46:12 +01:00
Slack Coder 98f09130bb
node: Elaborate --help message
Signed-off-by: Slack Coder <slackcoder@server.ky>
2023-02-04 20:03:31 +01:00
Fintan Halpenny 3f48c2c516
Rust 1.67
Rust 1.67 was announced[0]. Update the necessary files for running
1.67 and fix the clippy suggestions for string interpolation.

[0]: https://blog.rust-lang.org/2023/01/26/Rust-1.67.0.html

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-04 19:30:29 +01:00
Alexis Sellier 98f7fe1db8
node: Rename `GIT_RESET` env var 2023-01-30 18:23:24 +01:00
Alexis Sellier c1a749e09e
node: Make git-daemon errors more apparent 2023-01-30 14:07:31 +01:00
Alexis Sellier 03b94c81a0
node: Make git daemon listen configurable 2023-01-30 13:47:09 +01:00
Alexis Sellier 498a5c4e4a
node: Handle `fetched` differently if initiated 2023-01-30 13:22:33 +01:00
Alexis Sellier 3aa105afda
node: Return error if remote errors
Instead of simply breaking out of the loop, log and return an error.
2023-01-30 13:15:33 +01:00
Alexis Sellier 0726c553da
node: Run git fetch without any user config 2023-01-30 12:35:08 +01:00
Alexis Sellier a0910f7593
Cleanup old `fetch` code
We only use the old code in the simulator now.
2023-01-30 12:26:29 +01:00
Alexis Sellier be77eebc3d
node: Only try to fetch from connected nodes 2023-01-30 11:20:33 +01:00
Alexis Sellier ac23f45d9b
node: Cleanup working naming 2023-01-29 21:41:16 +01:00
Alexis Sellier 7d5347b74f
node: Document worker a little more 2023-01-29 21:34:40 +01:00
Alexis Sellier b92dc59204
node: Turn off `--atomic` when not supported 2023-01-29 18:22:41 +01:00
Alexis Sellier 33d8c35189
node: Move some code to `Runtime::run` 2023-01-29 17:39:46 +01:00
Alexis Sellier 23cf44f4c7
node: Rename `client` module to `runtime` 2023-01-29 17:33:07 +01:00
Alexis Sellier 02be334144
node: Use `git-daemon` as backend 2023-01-29 17:26:01 +01:00
Alexis Sellier d9e1055067
Improve logging 2023-01-28 23:58:16 +01:00
Alexis Sellier deeb160c2d
node: Improve stderr logging for git process 2023-01-27 17:04:20 +01:00
Alexis Sellier be95222fb5
node: Fix bug in upload-pack
We were not properly exiting one of the threads that was copying
data from the stream to the upload-pack process. This is a fix.
2023-01-27 15:09:17 +01:00
Alexis Sellier 026dfbde5d
node: Improve logging output 2023-01-26 18:15:27 +01:00
Alexis Sellier 405c00b91d
Update all dependencies
Also moves `netservices` to `crates.io`
2023-01-25 20:38:54 +01:00
Alexis Sellier 798485dfb1
Remove "log" feature from netservices 2023-01-25 20:12:13 +01:00
Alexis Sellier 30e9d6103c
Cleanup `clone` code
Remove a bunch of different instances of it.
2023-01-25 17:51:49 +01:00
Alexis Sellier cdc3c8a265
node: Try to cleanup socket file on exit
Signed-off-by: Alexis Sellier <self@cloudhead.io>
2023-01-25 17:51:49 +01:00