3.7 KiB
tnet
Purpose
A minimalist and hackable file transfer (and messages) tool for local network
Description
-
Built with python's standard library with no 3rd-party dependencies.
-
Utilizes the sockets and selectors modules for networking.
-
Due to the use of the selectors module the app is async and single-threaded.
-
Requires 2 ports to be opened (can be configured which ones).
-
Does not preserve file attributes when transferring a file.
-
Designed for the local network only, thus no encryption is implemented.
-
Tested with python 3.8, 3.11 and 3.12 on Ubuntu 20.04, Debian 12 and Alpine 3.19
-
Licensed under GPLv3 license
The architecture looks as follows: there are 4 sockets - one for listening incoming TCP connections, one for listening incoming UDP connections (discovery mechanism), the other 2 are UNIX sockets - one for accepting the local commands (send file, send notification, discover who is online, etc.) and the second one is for distributing events like incoming notifications, file transfer progress (both incoming and outcoming), errors, etc. First 2 sockets are mandatory and they are used by a daemon for communication over the local network, the rest is optional and used for communication between cli and daemon on the same machine.
There are only 4 main source files: protocol.py
, daemon.py
, cli.py
and util.py
, their descriptions are in the corresponding files.
Typical workflow:
- daemon is started and listens for the configured TCP and UDP ports, and one local UNIX socket for incoming commands
- a separate cli instance sends the 'discover' command to the UNIX socket to get a list of available machines in the local network
- the daemon in turn gets this command and broadcasts the 'discover' request via UDP
- a daemon on another machine (if any) gets this request on the UDP socket it listens to and replies directly to the requester via TCP with its IPv4 and host name
- the daemon on the first machine gets it and replies to the cli via the same UNIX socket
- then this info can be used via cli to send a file or notification, again the command is sent to the daemon via the UNIX socket
- daemon sends the file or notification via TCP, and optionally can report the progress (or errors) back to ANOTHER UNIX socket
- counterparty daemon processes the incoming data over TCP and also can optionally report the progress on a UNIX socket, called events socket
- once file is received it is moved from
/tmp
to the configured downloads directory, if transfer fails - the file gets removed from/tmp
Configuration
The following env variables can be set for daemon:
+EVENT_SOCKET
, a path to the UNIX socket the events should be reported to, defaults to './run/tnet/events'
+COMMAND_SOKET
, a path to the UNIX socket the commands should be read from, defaults to './run/tnet/commands'
+BROADCAST_PORT
, 'discovery' UDP port each daemon listens to, defaults to 0xC0DE
+RECEIVE_PORT
, main data transfer TCP port, defaults to 0xC00D
+FILE_SAVE_DIR
, a directory the downloaded files will be stored, defaults to 'Downloads'
+REPORT_PROGRESS_IN
, 0 or 1, if a CLI or other app needs to track progress via EVENT_SOCKET of incomming file transfer, defaults to 0
+REPORT_PROGRESS_OUT
, 0 or 1, if a CLI or other app needs to track progress via EVENT_SOCKET of outcoming file transfer defaults to 0
The following env variables can be set for cli:
+EVENT_SOCKET
, a path to the UNIX socket the events can be read from, defaults to './run/tnet/events'
+COMMAND_SOKET
, a path to the UNIX socket the commands should be sent to, defaults to './run/tnet/commands'