Kirill Isakov [Sun, 24 Apr 2022 19:38:50 +0000 (01:38 +0600)]
Improve proxy server support
- fix authentication with socks5 proxies
- fix crash in forked process with exec proxy and empty node name
- refactor byte fiddling into structs
- add unit and integration tests
Guus Sliepen [Sat, 23 Apr 2022 09:39:09 +0000 (11:39 +0200)]
Reoder the README and add a quickstart guide.
The README didn't really present the most relevant information to new
users at the start, it read more like a release notes file. This makes
it a more proper introduction to tinc.
Also add a quickstart guide as a Markdown file in the root of the source
tree, this will make it nicer on GitHub and GitLab, and might help users
that don't want to read the manual.
Kirill Isakov [Fri, 22 Apr 2022 12:33:52 +0000 (18:33 +0600)]
Wipe (some) secrets from memory after use
to lessen the amount of sensitive information ending up in swap, core
dumps, or in the hands of any remote attackers.
While there still remaings a lot interesting data in configuration trees,
connection_t structs, etc, this is considered a good practice nevertheless.
Some bedtime reading:
- http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html
- http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html
- https://github.com/jedisct1/libsodium/blob/
be58b2e6664389d9c7993b55291402934b43b3ca/src/libsodium/sodium/utils.c#L78:L101
Kirill Isakov [Wed, 20 Apr 2022 10:29:23 +0000 (16:29 +0600)]
CI: add libgcrypt to sanitizer run
Also disable check for unsigned integer overflow.
I couldn't find a way to reliably disable it for a single function:
https://github.com/google/sanitizers/issues/765
and warnings it produces do not seem to be of enough importance to
introduce ugly hacks like resetting the most significant byte here:
size_t result = 0;
// ...
for(; len; --len) {
result = (size_t)(result << 8);
// ^^^^
Kirill Isakov [Fri, 22 Apr 2022 19:53:37 +0000 (01:53 +0600)]
Add link to building docs to the top of README.md
plus a few minor improvements to INSTALL.md
Kirill Isakov [Fri, 22 Apr 2022 06:50:49 +0000 (12:50 +0600)]
CI: run all test flavors even on failure
Kirill Isakov [Fri, 22 Apr 2022 06:00:44 +0000 (12:00 +0600)]
CI package jobs: workaround for git security fix
https://github.blog/2022-04-12-git-security-vulnerability-announced/
We could chown the build directory to our own user, but that's
relatively slow. Since we fully control the environment (relatively
speaking, we're still running on other's machines), the vulnerability
doesn't affect this particular use case.
Kirill Isakov [Fri, 22 Apr 2022 04:08:04 +0000 (10:08 +0600)]
CI: ignore package job failures
Guus Sliepen [Thu, 21 Apr 2022 18:43:16 +0000 (20:43 +0200)]
Add __pycache__ directories to .gitignore.
Kirill Isakov [Thu, 21 Apr 2022 08:11:16 +0000 (14:11 +0600)]
connection_t: remove unused compression_level field
Kirill Isakov [Thu, 21 Apr 2022 07:12:47 +0000 (13:12 +0600)]
connection_t: split compression_level/log_level into two fields
compression_level is reused as a place to store log_level when piping
logs to tincctl. Since it was being compared directly with a log level,
it felt like a wrong field is being used by mistake.
Wrap it in union to avoid wasting additional memory.
Kirill Isakov [Thu, 21 Apr 2022 05:39:36 +0000 (11:39 +0600)]
Minor type improvements in legacy protocol code
Kirill Isakov [Thu, 14 Apr 2022 15:44:49 +0000 (21:44 +0600)]
connection_t: allocate legacy context on first use
Since the new protocol is preferred if available, if both sides of the
connection are running modern versions of tinc, the old protocol may not
be used at all.
Kirill Isakov [Thu, 21 Apr 2022 12:22:32 +0000 (18:22 +0600)]
Use actual port in tincd logs / tinc get Port / invitations
If Port 0 option is used (which makes tincd bind to a port chosen
by the operating system), tinc and tincd used to print that value as
it is instead of whatever port was actually allocated.
https://github.com/gsliepen/tinc/issues/363
Kirill Isakov [Sat, 16 Apr 2022 10:28:27 +0000 (16:28 +0600)]
cmd_config: replace action magic numbers with enum
Kirill Isakov [Tue, 12 Apr 2022 16:20:58 +0000 (22:20 +0600)]
Refactor crypto RNG; add getrandom() support
/dev/urandom and /dev/random are ubiquitous, but take an open
file descriptor, and may not actually be present inside badly
configured containers.
Kirill Isakov [Mon, 11 Apr 2022 18:41:29 +0000 (00:41 +0600)]
Reduce duplication in request handler tables
Request handlers and request names are now grouped together so there's
less chance of messing up the order (however unlikely it may have been).
Kirill Isakov [Sun, 10 Apr 2022 10:28:28 +0000 (16:28 +0600)]
CI: fix creation of Windows installer
After moving to meson, we've been using separate build directories
for each test flavor instead of running `git clean -dfx`, and the .nsi
used to create a Windows installer for the development release wasn't
updated to reflect this.
Kirill Isakov [Sun, 10 Apr 2022 07:53:25 +0000 (13:53 +0600)]
Rewrite integration test suite in Python
While the previous test suite ran fine in practice, it relied on
subtle differences in behavior of many UNIX tools, and thus needed GNU
Coreutils on many operating systems to work properly, and didn't work on
"pure" Windows at all.
A simple example would be how different versions of tail handle SIGPIPE
if you pipe its output into another process: GNU tail exits on SIGPIPE
since about 2017 (too lazy to look up the exact version, but this
changed recently), while most other tails continue reading the file and
piping the output into god knows where.
Since we need Python to run the new build system (meson) anyway, let's
use it for the test suite, and get rid of all other test dependencies.
It (currently) requires only the standard library of Python 3.6 or newer.
Unlike the original test suite, this one assigns node names and port
numbers randomly to support `meson test --repeat` (because meson can run
the same test multiple times in parallel, and this breaks with the old
approach).
Also remove old integration tests based on shell scripts.
Kirill Isakov [Sun, 3 Apr 2022 11:14:55 +0000 (17:14 +0600)]
Update old Python code
- reformat old Python scripts with black
- fix pylint warnings
- fix mypy warnings
- wrap all linters in lint.py
- replace reformat.py with lint.py --fix
- add new linting command: `ninja -C build lint`
Kirill Isakov [Thu, 31 Mar 2022 15:19:59 +0000 (21:19 +0600)]
Adjust CI to new integration tests
Kirill Isakov [Sat, 2 Apr 2022 11:41:50 +0000 (17:41 +0600)]
Correct close() function when building with MSVC
The original close() was throwing assertion errors from inside the
Windows libraries because we were trying to close OS handles as file
descriptors.
Kirill Isakov [Fri, 1 Apr 2022 18:26:51 +0000 (00:26 +0600)]
Allow building sptps_{test,keypair} with MSVC
Guus Sliepen [Mon, 4 Apr 2022 19:53:47 +0000 (21:53 +0200)]
Run shfmt as part of the reformat target.
Add a reformat.py script and call it from the reformat target. It will run
astyle and shfmt from the source directory.
Guus Sliepen [Sat, 2 Apr 2022 13:39:08 +0000 (15:39 +0200)]
Improve handling invitation read errors.
Fix a file descriptor leak when something goes wrong while reading an
invitation file. Also check that we read it in full before committing.
Found by cppcheck.
Guus Sliepen [Fri, 1 Apr 2022 14:00:09 +0000 (16:00 +0200)]
Speed up the authentication protocol security tests.
The security test took 70 seconds, mainly because it consisted of
several subtests that each had to wait for a timeout to pass. Split it
into three tests; two for testing a MITM splicing connections between
tinc daemons using the legacy and SPTPS protocols, the remaining tests
are in a single shell script but now run in parallel.
Guus Sliepen [Fri, 1 Apr 2022 13:16:40 +0000 (15:16 +0200)]
Reduce log level of SPTPS errors.
SPTPS error messages should not always be logged, they are mostly
low-level details, and serious errors like failing to connect to a node
due to SPTPS issues will be logged by higher layers anyway, so move it
down to log level 3.
Fixes #298 on GitHub.
Guus Sliepen [Fri, 1 Apr 2022 12:28:45 +0000 (14:28 +0200)]
Prevent underflow when sending UDP probes.
Make sure send_udp_probe_packet() never tries to send a packet smaller
than MIN_PROBE_SIZE, otherwise length calculation could potentially wrap.
Fixes #351 on GitHub.
Guus Sliepen [Fri, 1 Apr 2022 10:46:11 +0000 (12:46 +0200)]
Make sure version.py runs succesfully even if git is not installed.
Kirill Isakov [Thu, 31 Mar 2022 05:32:56 +0000 (11:32 +0600)]
Fall back to VERSION file if .git is not present
https://github.com/gsliepen/tinc/issues/358
Kirill Isakov [Mon, 28 Mar 2022 15:38:31 +0000 (21:38 +0600)]
Disable function attributes on unsupported compilers
Kirill Isakov [Mon, 28 Mar 2022 07:46:46 +0000 (13:46 +0600)]
Add __packed__ attribute on drop-in structs
Kirill Isakov [Mon, 28 Mar 2022 07:09:07 +0000 (13:09 +0600)]
Add check for __Static_assert() and asserts on struct sizes
Kirill Isakov [Sun, 27 Mar 2022 19:55:23 +0000 (01:55 +0600)]
meson: use Python script for version detection
Kirill Isakov [Fri, 25 Mar 2022 17:29:07 +0000 (23:29 +0600)]
Replace MinGW with Windows to avoid ambiguities
Kirill Isakov [Fri, 25 Mar 2022 14:09:36 +0000 (20:09 +0600)]
Add support for building tinc with MSVC
Tests are not supported because of their strong dependence on running
under Unix-like environment.
Kirill Isakov [Fri, 25 Mar 2022 12:16:17 +0000 (18:16 +0600)]
GitHub CI: add MSVC jobs
Kirill Isakov [Fri, 25 Mar 2022 12:44:39 +0000 (18:44 +0600)]
Mention Windows SDK compat in installation docs
Kirill Isakov [Fri, 25 Mar 2022 05:56:51 +0000 (22:56 -0700)]
Add dirent.h
readdir() / closedir() / etc for Windows by Toni Rönkkö.
Copied from https://github.com/tronkko/dirent
Guus Sliepen [Sun, 27 Mar 2022 18:58:44 +0000 (20:58 +0200)]
Don't put the --recursive option in .astylerc.
When calling astyle manually without wildcards in the filename(s),
astyle will refuse to work if the --recursive option is used. Remove it
from .astylerc and add the option to the command line when the "reformat"
build target is used.
Guus Sliepen [Sun, 27 Mar 2022 18:56:48 +0000 (20:56 +0200)]
Fix compiler warning.
Quash a compiler warning by checking the result of snprintf() and
handling truncation.
Kirill Isakov [Sun, 27 Mar 2022 18:08:35 +0000 (00:08 +0600)]
Fix building tinc and running tests on Solaris
Kirill Isakov [Wed, 23 Mar 2022 11:41:31 +0000 (17:41 +0600)]
Add unit tests suite using cmocka library
Kirill Isakov [Wed, 23 Mar 2022 06:49:09 +0000 (12:49 +0600)]
Move integration tests into a subdirectory
Kirill Isakov [Wed, 23 Mar 2022 06:45:11 +0000 (12:45 +0600)]
Add cmocka packages to CI jobs
Kirill Isakov [Wed, 23 Mar 2022 09:22:05 +0000 (15:22 +0600)]
Rearrange conflicting tincd globals
Kirill Isakov [Wed, 23 Mar 2022 05:52:51 +0000 (11:52 +0600)]
Add support for meson build system
Kirill Isakov [Fri, 18 Mar 2022 17:19:38 +0000 (23:19 +0600)]
GitHub CI: change build system to meson
Kirill Isakov [Thu, 17 Mar 2022 19:26:20 +0000 (01:26 +0600)]
sourcehut CI: change build system to meson
Kirill Isakov [Mon, 21 Mar 2022 09:41:26 +0000 (15:41 +0600)]
Update docs with instructions on building with meson
Kirill Isakov [Sun, 20 Mar 2022 19:13:06 +0000 (01:13 +0600)]
Move sys/mman.h into have.h
Kirill Isakov [Mon, 21 Mar 2022 06:47:02 +0000 (12:47 +0600)]
Remove vendored LZ4
Kirill Isakov [Sun, 20 Mar 2022 19:13:41 +0000 (01:13 +0600)]
Remove autotools configs
Kirill Isakov [Fri, 18 Mar 2022 13:39:28 +0000 (19:39 +0600)]
Extract common logic in OpenSSL-specific code
Kirill Isakov [Thu, 17 Mar 2022 14:49:29 +0000 (20:49 +0600)]
Add support for OpenSSL 3.0+
Also use centralized logging for OpenSSL errors.
https://github.com/gsliepen/tinc/issues/347
Kirill Isakov [Wed, 16 Mar 2022 13:34:17 +0000 (19:34 +0600)]
CI: add tests with OpenSSL 3.0
Guus Sliepen [Tue, 15 Mar 2022 07:39:35 +0000 (08:39 +0100)]
Remove unnecessary status bitfield conversions.
Kirill Isakov [Tue, 15 Mar 2022 04:40:19 +0000 (10:40 +0600)]
Replace uint32_t bitfields with bool
This fixes a bunch of bugprone-narrowing-conversions from clang-tidy 12
or newer.
Kirill Isakov [Mon, 14 Mar 2022 17:01:57 +0000 (23:01 +0600)]
CI: fix running clang-tidy on full sources
Kirill Isakov [Sat, 12 Mar 2022 10:34:40 +0000 (16:34 +0600)]
CI: run `make distcheck` instead of `make check`
Kirill Isakov [Sat, 12 Mar 2022 06:32:01 +0000 (12:32 +0600)]
Fix `make distcheck`
`make distcheck` builds and then calls both tinc and tincd with two options:
--version
--help
tincd behavior was changed by
28b7a53b6 to print usage information to
stderr, but automake expects to see a non-empty output from stdout, and
fails distcheck if it's empty.
Guus Sliepen [Mon, 24 Jan 2022 13:32:45 +0000 (14:32 +0100)]
Move -lssp to LIBS.
Append -lssp to LIBS to ensure the correct order of linking.
Guus Sliepen [Sun, 23 Jan 2022 22:49:24 +0000 (23:49 +0100)]
CI: Ignore gcrypt sources when running clang-tidy.
Guus Sliepen [Sat, 22 Jan 2022 22:26:50 +0000 (23:26 +0100)]
CI: Fix missing dependencies for macOS and Windows.
Clang-tidy doesn't like the latest OpenSSL libraries available in Brew,
so disable the clang-tidy test on macOS for now.
Guus Sliepen [Sat, 22 Jan 2022 21:56:55 +0000 (22:56 +0100)]
Enable hardening flags at the end of the configure script.
Unfortunately some of the autoconf checks themselver trigger compiler
warnings when hardening is enabled and if -Werror is also enabled. Avoid
this by only enabling the hardening flags at the end of the configure
script.
Guus Sliepen [Sat, 22 Jan 2022 21:31:16 +0000 (22:31 +0100)]
CI: Install netcat-openbsd on Debian.
Guus Sliepen [Sun, 16 Jan 2022 22:02:09 +0000 (23:02 +0100)]
Enable and fix many extra warnings supported by GCC and Clang.
This enables many extra warning options when hardening is enabled, and
fixes the definition of _FORTITY_SOURCE. -Wshadow is not (yet) enabled,
as this generates quite some warnings that are less trivial to fix.
Guus Sliepen [Sun, 16 Jan 2022 19:45:41 +0000 (20:45 +0100)]
Fix potential crash during failing PMTU discovery.
If we get PACKET_TOO_BIG responses when sending UDP packets, we lower the
maximum MTU we will probe accordingly. However, after enough of those
responses, maxmtu could drop below zero and wrap. Guard against that by
never dropping maxmtu below the minimum required MTU for UDP communication.
Guus Sliepen [Mon, 23 Aug 2021 16:42:09 +0000 (18:42 +0200)]
Suppress UBSan warnings in the xoshiro implementation.
Xoshiro relies on the well defined overflow behavior of unsigned
integer, but UBSan complains about it unless we force it to ignore it.
Guus Sliepen [Mon, 16 Aug 2021 21:26:24 +0000 (23:26 +0200)]
Use xoshiro256** to generate pseudo-random numbers.
Also seed it using /dev/random or whatever equivalent is available.
Kirill Isakov [Mon, 23 Aug 2021 07:00:44 +0000 (13:00 +0600)]
CI: fix archive name for sanitizer results.
Kirill Isakov [Thu, 19 Aug 2021 08:36:02 +0000 (14:36 +0600)]
CI: improve sanitizer runs; minor cleanups.
- sanitizers now do the full test run, as in every other job.
- run all test flavors even if one of them fails.
- change big-endian cross build to little-endian MIPS.
Kirill Isakov [Wed, 18 Aug 2021 08:51:10 +0000 (14:51 +0600)]
Restore libgcrypt support.
Kirill Isakov [Tue, 17 Aug 2021 18:36:30 +0000 (00:36 +0600)]
Move repeating MIN/MAX macros into dropin.h.
Kirill Isakov [Tue, 17 Aug 2021 18:30:01 +0000 (00:30 +0600)]
Rename base64 funcs to show they're not RFC-compliant.
Kirill Isakov [Mon, 16 Aug 2021 13:24:13 +0000 (19:24 +0600)]
CI: run tests with libgcrypt.
Guus Sliepen [Tue, 17 Aug 2021 21:33:33 +0000 (23:33 +0200)]
Fix memcmp() reading out of bounds in the tinc info command.
Mathew Heard [Mon, 16 Aug 2021 02:04:19 +0000 (12:04 +1000)]
Use epoll() if available.
Kirill Isakov [Tue, 17 Aug 2021 10:35:22 +0000 (16:35 +0600)]
Fix UBSAN warnings in linux/device.c.
linux/device.c:149:11: runtime error: implicit conversion from type 'ssize_t' (aka 'long') of value -1 (64-bit, signed) to type 'size_t' (aka 'unsigned long') changed the value to
18446744073709551615 (64-bit, unsigned)
#0 0x55e3cb851f84 in read_packet /home/runner/work/tinc/tinc/src/linux/device.c:149:11
#1 0x55e3cb7bb7fe in handle_device_data /home/runner/work/tinc/tinc/src/net_packet.c:1906:5
#2 0x55e3cb78e6e0 in event_loop /home/runner/work/tinc/tinc/src/event.c:353:5
#3 0x55e3cb7a6a90 in main_loop /home/runner/work/tinc/tinc/src/net.c:505:6
#4 0x55e3cb83d241 in main /home/runner/work/tinc/tinc/src/tincd.c:614:11
#5 0x7fec881950b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#6 0x55e3cb757dcd in _start (/home/runner/work/tinc/tinc/src/tincd+0x9adcd)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/device.c:149:11 in
linux/device.c:163:23: runtime error: unsigned integer overflow:
18446744073709551615 + 10 cannot be represented in type 'unsigned long'
#0 0x55e3cb852253 in read_packet /home/runner/work/tinc/tinc/src/linux/device.c:163:23
#1 0x55e3cb7bb7fe in handle_device_data /home/runner/work/tinc/tinc/src/net_packet.c:1906:5
#2 0x55e3cb78e6e0 in event_loop /home/runner/work/tinc/tinc/src/event.c:353:5
#3 0x55e3cb7a6a90 in main_loop /home/runner/work/tinc/tinc/src/net.c:505:6
#4 0x55e3cb83d241 in main /home/runner/work/tinc/tinc/src/tincd.c:614:11
#5 0x7fec881950b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#6 0x55e3cb757dcd in _start (/home/runner/work/tinc/tinc/src/tincd+0x9adcd)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior linux/device.c:163:23 in
Kirill Isakov [Tue, 17 Aug 2021 08:04:19 +0000 (14:04 +0600)]
Fix invalid logger() calls in Solaris device code.
Kirill Isakov [Mon, 16 Aug 2021 18:01:51 +0000 (00:01 +0600)]
Fix more memory leaks and invalid free() in invitation.c.
Kirill Isakov [Sun, 15 Aug 2021 18:57:05 +0000 (00:57 +0600)]
Replace pointers to cipher_t/digest_t in connection_t with structs.
Part of #294.
Kirill Isakov [Sun, 15 Aug 2021 18:56:58 +0000 (00:56 +0600)]
CI: downgrade cross-compilation jobs to debian:buster
Mathew Heard [Sun, 15 Aug 2021 05:46:04 +0000 (15:46 +1000)]
Simplify signal handling.
Use an array instead of a splay tree.
Kirill Isakov [Sun, 15 Aug 2021 17:25:04 +0000 (23:25 +0600)]
Fix UBSAN warnings about conversions and overflows.
Guus Sliepen [Sun, 15 Aug 2021 18:05:24 +0000 (20:05 +0200)]
CI: use explicit Debian release names.
Currently debian:stable fails because the image on Docker Hub is still
buster, but bullseye is the new stable, and the sources.list URLs are
wrong.
Kirill Isakov [Sun, 15 Aug 2021 12:43:14 +0000 (18:43 +0600)]
tincd on Windows: call srand() after main2()
On Windows, rand() was returning the same sequence on every service
execution, because srand() was initializing its state only for the
short-lived process.
Kirill Isakov [Sat, 14 Aug 2021 19:08:53 +0000 (01:08 +0600)]
FreeBSD CI: unbreak clang-tidy.
compiledb does not like the BSD make when running the -j flag.
-n (for some weird reason) also produces an empty file list.
Kirill Isakov [Sat, 14 Aug 2021 18:58:55 +0000 (00:58 +0600)]
Improve failure detection in the test suite.
Mathew Heard [Sat, 14 Aug 2021 15:14:41 +0000 (01:14 +1000)]
hash table fix
Guus Sliepen [Fri, 13 Aug 2021 19:53:13 +0000 (21:53 +0200)]
Bump the timeout for the sanitizer tests.
Guus Sliepen [Fri, 13 Aug 2021 19:13:09 +0000 (21:13 +0200)]
Avoid warnings from -fsanitize=integer in the hash functions.
Hash functions rely heavily on unsigned integer overflow behavior, but
the sanitizer complains about them. Instead of disabling the sanitizer
(which might prevent us from getting warnings from real errors), silence
it by explicitly upcasting values to 64-bit integers before applying
operations, then explicitly downcasting to 32-bit again. The compiler
will optimize this out.
Mathew Heard [Tue, 29 Jun 2021 01:27:24 +0000 (11:27 +1000)]
Subnet Cache hashtable improvements
- inline & staticly allocated hash table
- increased hashtable size (32bit: 1024, 64bit: 65536)
- re-arrange subnet members
- Add key type
- reduce clearing of hash table
- cleanup key pointer operations
- removed unused hash_search_or_insert
- add open addressing to hash table
- type specific hash functions & hash seeding
- no collisions for 32bit os
- implement cache flush by SUBNET_MAC
Kirill Isakov [Wed, 11 Aug 2021 14:56:21 +0000 (20:56 +0600)]
Use splay trees inside node_t directly.
Kirill Isakov [Wed, 11 Aug 2021 14:17:12 +0000 (20:17 +0600)]
Replace pointers to global splay trees with structs.
re #294
Kirill Isakov [Wed, 11 Aug 2021 04:31:11 +0000 (10:31 +0600)]
Make apt stop asking questions when building deb package.
Fufu Fang [Tue, 10 Aug 2021 00:53:00 +0000 (01:53 +0100)]
Reduce pointer indirection for global list_t variables
Converted cmdline_conf, connection_list, outgoing_list from
pointer-to-structs to structs.
Created list_empty_list for these structs. This is necessary,
because list_delete_list frees the supplied list_t pointer.
Part of https://github.com/gsliepen/tinc/issues/294
Fufu Fang [Mon, 9 Aug 2021 23:34:29 +0000 (00:34 +0100)]
Fix -Wsign-compare error in keys.c
Part of https://github.com/gsliepen/tinc/issues/288
Guus Sliepen [Tue, 10 Aug 2021 18:10:29 +0000 (20:10 +0200)]
Symlink README to README.md when running make dist.
Since Markdown is perfectly human readable, just create a symlink from
README to README.md when make dist wants it. Also add it to .gitignore.
Kirill Isakov [Tue, 10 Aug 2021 06:00:09 +0000 (12:00 +0600)]
Rename README to make software forges properly render Markdown.