Telodendria: The terminal branches of an axon.
Telodendria is a Matrix homeserver implementation written from scratch in ANSI C. It is designed to be lightweight and simple, yet functional. Telodendria differentiates itself from other Matrix homeserver implementations because it:
Telodendria is on Matrix! Check out the official Matrix rooms:
Room | Description |
---|---|
#telodendria-releases:bancino.net
|
Get notified of new releases. |
#telodendria-general:bancino.net
|
General discussion and support for Telodendria. |
#telodendria-issues:bancino.net
|
Report issues with Telodendria. |
#telodendria-patches:bancino.net
|
Submit code patches to the Telodendria project. |
Telodendria is distributed as source tarballs, in true Unix
fashion. If you want, you can verify the checksum of your download,
and check the signature. To check the signature, you'll need
signify
, and the signify public key:
telodendria-signify.pub.
If your operating system has an official package or port of Telodendria, you should prefer to use that instead of manually downloading the source and building it. If your operating system's package or port is too out of date for your tastes, please contact the package's maintainers to notify them, or offer to update the package yourself.
Version | Download | Checksum | Signature |
---|---|---|---|
No downloads here yet. See the Project Status for more information. |
You can check out the change log here.
Telodendria's documentation is distributed with the source
code as man
pages, which contain all of the information
on how to build the source, configure it, as well as contribute to
the project. The man
pages are also available online
for convenience:
Telodendria is designed to be extremely configurable. As such, it has
a fairly extensive configuration file. The configuration file is passed to
the Telodendria binary with the -c
option, and is
typically called /etc/telodendria.conf
. It uses OpenBSD-style
syntax, and consists of the following options.
There are example configuration files in the contrib
folder of
every source tarball, and in the CVS repository.
listen [port]
The port to listen on. Telodendria will bind to all interfaces, but
It is recommended to configure your firewall so that it only listens on
localhost
, and then configure a reverse proxy such as
relayd(8)
in front of it, because Telodendria does
not implement TLS. Note that Telodendria doesn't provide multiple
ports for the various services it offers. All APIs are made available over
the same port.
[port]
should be a decimal port number or a service name.
The listen
directive is entirely optional; if it is omitted,
then Telodendria will listen on localhost
, port
8008
by default.
server-name [name]
Configure the domain name of your homeserver. Note that Matrix servers cannot be migrated to other domains, so once this is set, it should never change, unless you want unexpected things to happen, or you want to start over.
[name]
should be a DNS name that everyone on the network
can resolve. This directive is required.
chroot [directory]
Change the root to the specified directory as soon as possible. Note that
all other paths and files specified in the configuration file must be
accessible from this directory. This only works if Telodendria is
running as root
. If it isn't, then a warning is printed to the
log, and no chroot
call is made. In that case, Telodendria
will still change into the specified directory, so that other paths can be
made relative to this one.
This directive is required. It is expected that the server data and logs will live here.
id [uid] [gid]
The effective UNIX user and group to drop to after binding to the socket and
changing the filesystem root. This only works if Telodendria is running as
root
, and is used as a security mechanism. If Telodendria is
started as a non-privileged user, then a warning is printed to the log if that
user does not match what's specified here.
This directive is required, even if Telodendria is unable to switch to this user. It can be used as a sanity check to make sure the permissions are working properly.
data-dir [directory]
The data directory in which Telodendria will write all user and event information. Telodendria doesn't use a database like other Matrix homeserver implementations; it uses a flat-file directory structure, similar to how an SMTP server uses Maildirs to deliver email.
This directive is required. [directory]
should be a path relative
to the chroot
directory. Don't depend on the chroot
option working, because there are many legitimate cases when Telodendria
will not be started as root
, thus causing the chroot to fail.
federation [true|false]
Whether to enable federation with other Matrix homeservers or not. Matrix by
its very nature is a federated protocol, but if you just want your own internal
chat server with no contact with the outside, then you can use this option to
disable federation. It is highly recommended to set this to true
,
however, if you wish to be able to communicate with users on other Matrix
servers.
This directive is required, though it may be made optional at some point in the future.
registration [true|false]
Whether or not to enable new user registration or not. For security and anti-spam
reasons, you can set this to false
. If you do, you can still add users
via the administrator API.
In an ideal world, everyone would run their own homeserver, so no public
registration would ever be required. But unfortunately, not everyone has the means
to run their own homeserver, especially because of the fact that public IPv4 addresses
are becoming increasingly harder to come by. If you would like to provide a service
for those that are unable to run their own homeserver, you can set this to true
,
which will allow anyone to create an account.
Telodendria should be capable of handling a large amount of users without difficulty or security issues. This directive is required.
log [file|stdout]
The log configuration. Telodendria uses its own logging facility, which can output to either standard output or a file. A number of child directives can be added to this directive to customize the log output:
level [error|warning|task|message|debug]
The level of messages to log at. Each level shows all the levels above it. For
example, setting the level to error
will show only errors, while
setting the level to warning
will show warnings and errors.
task
shows tasks, warnings, and errors, and so on.
timestampFormat [format|none|default]
If you want to custom ize the timestamp format shown in the log, or disable
the timestamp functionality altogether, you do so via this option. Acceptable
values are none
, default
, or a formatter string as
described by your system's strftime()
manual.
color [true|false]
Whether or not to enable colored output on TTYs. Note that ANSI color sequences will not be written to a log file, only a real terminal, so this option only applies if the log is being written to a standard output which is connected to a terminal.
threads [count]
How many worker threads to sping up to handle requests. This should generally be less than the total CPU core count, to prevent overloading the system. The most efficient number of threads ultimately depends on the configuration of the machine running Telodendria, so you may just have to play around with different values here to see which gives the best performance.
Telodendria is a very ambitious project. There's a lot that needs to happen yet before it is usable. At the moment, there's nothing that even remotely ressembles a Matrix homeserver here; I'm still getting off the ground and building a foundation.
But just because there's nothing here yet doesn't mean you should go away! I could always use help, so you are more than welcome to help out if you want things to go quicker. Please see the Contributing section for details on how you can get involved.
The Telodendria roadmap is organized into phases, with each phase representing a new milestone in the project's lifetime.
A new open-source project needs a few basic things before development can begin. This phase covers the pre-development stage of Telodendria.
Matrix homeservers require a few prerequisites. In this phase, we build up all the tools required to properly implement a Matrix homeserver. This includes basic data structures, exchange format parsers, and more. We also build up a command line application, multi-threaded HTTP server, and architect a flat-file database framework.
-c file -Vh
)Canonical JSON
\u
escapesWhen the foundations are laid, we can start implementing a real Matrix homeserver. This phase tracks our current progress in implementing the Matrix specification.
/_matrix/client/versions
The Matrix specification is only a part of what it takes to be a production-ready Matrix homeserver. While the spec details how clients and homeservers interact with each other, we still need a way to administer our homeserver. This phase tracks our progress on getting Telodendria packaged, as well as writing some useful administrative tools. Only when these things are completed can we call Telodendria "production-ready."
This documentation needs just a little work. Here's the things on my list for that:
indent(1)
instead.anoncvs
account is just anoncvs
.make.sh
recipes, and what they domsg-error
div)li
elements.div
s for notes and warnings.I want a lightweight Matrix homeserver designed specifically for OpenBSD and other Unix-like operating systems. I want a homeserver that can be developed and compiled with built-in tools. I want it to function entirely on a base OS install without having to install any extra packages whatsoever. I've found that as far as these goals are concerned, the existing homeserver implementations fall short. This project aims to prove that Matrix homeservers can be lightweight and written in such a way that very few, if any, third-party libraries need to be pulled in.
I also want to learn how Matrix works, and I want to understand the code I'm running on my server, which is why I'm writing every component from scratch, even the HTTP server.
Telodendria is written entirely in portable ANSI C. It depends on no third-party C libraries other than the standard POSIX C library. The only thing you need to run it is a reverse proxy with HTTPS support, such asrelayd(8)
, and a directory that data can be
written to. Everything Telodendria needs to run itself is compiled
into a single static binary, and the source code can be built
anywhere, right out of the box. This makes it suitable for running
in a chroot(8)
environment.
Telodendria doesn't use a database like all the other homeservers.
Instead, it operates more like email: it uses a flat-file data
structure similar to Maildir to store data. The advantage of this is
that it saves server maintainers from also having to maintain a
database. It greatly simplifies the process of getting a Matrix
homeserver up and running, and it makes it highly portable. It also is
extremely easy to back up and restore with base tools; just
tar(1)
up the directory, and you're good to go.
Telodendria is developed and tested on OpenBSD, but you'll find that it should just run on any POSIX operating system without modification.
The goals of this project are generally divided into user goals, and developer goals, depending on who they impact the most. This isn't an exhaustive list, but it is a list of things that I want to prioritize, because other server implementations lack them.
The user goals are as follows:
The developer goals are as follows:
chroot(8)
. You'll even notice that
the documentation is written in HTML directly, not Markdown, to remove
the dependency on a Markdown parser and renderer.
Telodendria is designed to be fairly straightforward, but that
doesn't mean there won't be hiccups along the way. If you are struggling
to get Telodendria up and running, you're more than welcome to
reach out for support. Just join the
#telodendria-general:bancino.net
Matrix channel. Before
you do though, make sure you're running the latest version of
Telodendria and you've thoroughly read through all the
relevant documentation.
Telodendria is an open source project. As such, it welcomes contributions. There are many ways you can contribute, and any way you can is greatly appreciated.
If—after you've reached out to
#telodendria-general:bancino.net
—it has been
determined that there is a problem with Telodendria, it should
be reported to #telodendria-issues:bancino.net
. There it
can be discussed further. The issues room serves as the official
issue tracker of Telodendria; although severe issues may be copied
into a TODO
file in the CVS repository just so they
don't get lost.
The primary language used to write Telodendria code is ANSI C. Other languages you'll find in the Telodendria repository are shell scripts and HTML. If you have any experience at all with any of these languages, your contributions are valuable. Please follow the guidelines in this section to ensure the contribution workflow goes as smoothly as possible.
If you'd like to hack on Telodendria, you'll need the following tools in addition to the tools required to build the source:
cvs
for checking out and updating a local copy
of the source code.indent
for formatting your code before generating
patchespatch
for applying patches to your local copy of the
source code.Note that all of these tools are built into OpenBSD. While you of course don't have to use OpenBSD to develop Telodendria, it may make the process a little easier. In fact, these tools were chosen precisely because they were built into OpenBSD, the operating system I use.
You can download an official release tarball if you would really like, but the preferred way is to check out the source code from CVS. This makes generating patches a lot easier.
If you already checkout out the code previously, make sure you update your local copy before you start developing:
You should now have the latest Telodendria source code. Follow
the Code Style as you make your changes. If
the cvs
command fails with a Connection refused
error message, then try setting the CVS_RSH
environment
variable to ssh
, like this:
Then run the checkout again. Some versions of CVS don't use SSH to checkout
by default, so if yours doesn't, you might want to put that line in your
.bashrc
or other shell init script.
In general, these are the conventions used by the code base. This guide may be slightly outdated or subject to change, however. The source code itself is the absolute source of truth, so as long as you make your code look like the code surrounding it, you should be fine.
CamelCase
. This is preferred to snake_case
because it is more compact.
lowerCamelCase
. This is preferred
to snake_case
because it is more compact.
enum
s and struct
s are always
typedef
-ed to their same name. The typedef
occurs in the public API header, and the actual declaration occurs in
the implementation file.
.c
file that
has a matching header file. The header file should only export public
symbols, everything else in the .c
file should be
static
.
As far as actually formatting the code goes, such as where to put
brackets and whether you use tabs or spaces, use indent(1)
to take care of all of that. The root of the repository has a
.indent.pro
file that should automatically be loaded by
indent(1)
to set the correct rules. If you don't have
access to a working indent(1)
, just indicate in your patch
that I should run indent(1)
on the code after applying it.
I'll likely run my indent(1)
on the code anyway though,
just to make sure the spacing is consistent, if nothing else.
Telodendria aims at remaining as minimal as possible. This doesn't just mean minimal code, it also means a minimal development process, which is why Telodendria doesn't use GitHub, GitLab, or even SourceHut. Instead, the contribution workflow operates on submitting patch files to a public Matrix room, sort of like the OpenBSD project operates on patch files sent to a public mailing list.
If you're not used to manually creating and submitting patches instead of
opening a "pull request," you should be pleased to hear that submitting
patches is fairly easy to do if you've got the CVS sources checked out.
In fact, I find it easier than having to make a GitHub account, forking
a project repository, and then making a pull request for it. Once you
have made your changes in your local copy of the code, and you've
configured your environment using the instructions in
The Build Script, just run the
patch
recipe:
This will automatically generate a patch file for all your changes,
and then open it in your preferred editor.
You can also generate a patch for only certain files and directories.
To do that, set PATCHSET
, like this:
As you'll notice, the top of the patch file should have some email-style headers that look like this:
As much information as possible should be filled out for you, such as
the date. An attempt to fill out the From
header was also
made, but the information there can be made more accurate by setting
MXID
to your Matrix ID, and DISPLAY_NAME
to
your real name in your environment, or the .env
file.
The Subject
should very briefly describe what the patch
is about.
You'll also notice these lines:
This is a checkbox that tells me whether or not you actually have the rights to submit your patch, and that once you submit the patch, your code is bound by the Telodendria license. The full text of the developer certificate of origin is as follows:
After the headers, but before the checkbox, write a more thorough
description of the patch and why it was created. Then, send the
resulting patch file to #telodendria-patches:bancino.net
,
so it can be discussed and reviewed by the community.
Try to keep your patches on topic—make one patch file per feature or bug fix being implemented. It is okay if your patches depend on previous patches, just indicate that in the patch. Note that it may take a while for patches to be committed, and some patches may not be committed at all. In either case, all sent patches are queued from the Matrix room into the public patch directory, so they can be referenced easier in the future. If you want to reference a submitted patch in a Matrix message or email, it might be a good idea to link to it in the public patch directory.
The public patch directory works as follows: when you send your patch to the
Matrix room, it is downloaded by the Telodendria Bot and placed in the
ingress/
directory, named as the message ID. Then, it is
assigned a Telodendria patch ID and copied to the p/
directory as just ${id}.patch
. This is a permanent link that will
always reference your patch. Then, your patch is symlinked to the
queue/
directory. I have a script that automatically ingresses
patches and queues them for me, and I'll use this to review patches.
If your patch is accepted, the queue symlink will be moved to the
accepted/
directory and the patch is committed to the official
CVS repository. If you patch is rejected for some reason, its symlink will
be moved to the rejected/
directory. Regardless of the state
of your patch, it will always remain permalinked in the p/
directory, and when it is accepted or rejected, Telodendria Bot will
send a message.
You're always welcome to inquire about rejected patches, and request they be reviewed again, or you can use them as a starting point for future patches.