sunbeam/README.md

106 lines
6.0 KiB
Markdown

# Sunbeam Network Relay v0.3
#### Elizabeth Evelene Amelia Diode
#### June 2019
#### AGPL v3
---
### Oh no, what is it this time?
Sunbeam is a simple and fast multi-endpoint TCP/UDP relay for
for um
we swear we had a perfectly reasonable use in mind, but we honestly can't remember it now.
---
### What it does
Sunbeam is a little tiny server that relays data between clients.
Run at the command line, Sunbeam takes any number of local ports (numbers between 1 and 65535)
and remote addresses (strings like [ip address]:[port]). For each address argument passed,
Sunbeam attempts to connect to that address, and for each port argument, it listens for incoming
connections on that port locally. Whenever it receives data over any connection, that data is
promptly retransmitted to all other connections, with the exception that data is not passed
between clients that connect to Sunbeam on the same port.
For example, Sunbeam can be used as a relay for an audio stream by giving it the address of the
stream server and a local port. Clients connecting to the local port will receive the stream
data, but if one client sends data back to Sunbeam, it will not interfere with other clients'
streams (it will, however, be relayed back to the source).
This behavior can be overridden with "loopback mode" in which Sunbeam always relays data to all
clients and servers except the one which originated the data. Sunbeam automatically goes into
loopback mode if no ports are specified, or if only one port and no addresses are specified. You
can also pass the `-l` or `--loopback` flag to require Sunbeam to run in loopback mode.
If you want Sunbeam to send data back to its source in addition to relaying it, you can also
activate "mirror mode" by passing the `-m` or `--mirror` flag at the command line.
General usage looks like the following:
`sunbeam [flags] [local port]... [remote address]:[port]...`
Sunbeam is capable of using both TCP and UDP for sending and receiving data, and can pass data
between TCP and UDP streams. By default, Sunbeam attempts to use both protocols for every port
and address argument passed to it (e.g. if port 4444 is specified at the command line, it will
bind to both UDP port 4444 and TCP port 4444, and if an address is given, it will connect via TCP
and also begin sending UDP keepalives (packets containing only `\n`) to that address). You can
specify that Sunbeam should only use one protocol or the other by prefixing the argument with a
letter - `t` for TCP or `u` for UDP.
Unless Sunbeam is running in loopback mode, data sent to a given port number over UDP will not be
relayed to clients connecting to the same port number via TCP, nor vice versa - ports with the
same number are treated as the same port.
---
### How to block IP addresses
It's 2019, and a server that can't filter incoming connections is a server that belongs to **The
Enemy**. That's why Sunbeam, minimal as it is, includes this functionality nonetheless.
You can create the file `.nosunbeam` in the directory where Sunbeam runs. Sunbeam will read it,
parse each line as an IP address (v4 or v6 are both fine), and immediately drop any incoming
TCP connections or UDP packets from those addresses.
---
### How to make ports private
In case you want a port only to be accessible locally - e.g. if you're running a streaming server
and don't want anyone else to be able to inject data into the stream - you can mark them private
by suffixing them with the letter `p`, e.g.
`sunbeam 4444p 55555`
Additionaly, ports suffixed with `w` only accept connections from IP addresses listed in the file
`.yesunbeam`, which acts as a whitelist in a similar fashion to the `.nosunbeam` blacklist.
Entries in the blacklist take precedence over entries in the whitelist, so addresses listed in
both places will not be able to connect.
Using `w` with an empty or missing `.yesunbeam` file is nearly equivalent to using `p`, with the
difference being that `p` causes the listener socket to bind to `127.0.0.1` instead of the public
address, while `w` keeps the binding public but checks all incoming connections against a hash
table of allowed addresses and drops them if they are not found. `p` is likely a little bit
faster, but only `w` will print a notification to the console whenever a connection is rejected.
If a port is suffixed with both `w` and `p`, whichever is listed last will take precedence.
Addresses specified on the command line for Sunbeam to contact as a client are not subject to the
blacklist or whitelist, since they are static during runtime and it is assumed that the user will
not attempt to connect to a hostile host.
---
### Why you can't give it domain names
Rust has a minimal standard library. One consequence of this is the fact that there's no way to
resolve a domain name without depending on external crates or writing an entire DNS client from
scratch. We admit we don't really understand how it all works, but it seems we only have two
choices: live without domain name resolution, or pull in some enormous DNS crate with 37 unstable
dependencies. We choose the former. As a result, you'll have to do your DNS resolution some other
way, like by running `dig`at the command line to look up the IP address for the domain you want.
Yes, it's clunky, but the point of this program is to be minimal and simple and reliable, not to
be easier to use at the expense of those things.
---
### Why it's called that
This program is called "Sunbeam" because of a particular plot device that we thought was clever
in the sci-fi novel *The Three Body Problem* by Cixin Liu. A character discovers that, due to a
particular plasma-driven mechanism inside the sun, it's possible to use the sun as a gigantic
radio amplifier at certain frequencies - all you have to do is launch a radio beam into the
photosphere with enough intensity, and it bounces back out with orders of magnitude more power.
That's basically what this program does - you just aim your transmitter at it and start
talking, and it lets you communicate with other receivers that you normally couldn't reach.