The first two repositories contain code that compiles to
executable programs:

tools - Tools are programs that we use for testing and debugging.

daemons - The Daemons repo is used to build the Katzenpost
components such as mix client, mix server and PKI server. This
repository has vendored dependencies, however for development and
testing we generally do not use vendored dependencies.

We do some additional ticket tracking in:

mixnet_uprising - Repository for tracking open tasks for the
Katzenpost mixnet framework.

Our specs and other documents are here:

docs - All our documentation is here with the exception of our
website. This includes our design specifications as well as this
document you are currently reading.

The mix server and directory authority libraries both make use
of our core library:

1. You may choose to NOT use go dependency vendoring. In that case you
can simply check out all our git repos yourself and you can also use
“go get” to retrieve transitive dependencies. Keep in mind you’ll have
to move aside the vendoring directory in the daemons repo if you
intend to build which your local copies of katzenpost dependencies
instead of what is in the vendoring directory.

2. Here’s how to use our dependency vendoring system with a development
workflow:

The Katzenpost server repository has several coding themes which you
should become familiar with before making a contribution. The server
must not have any unbounded resource consumption such as spawning new
go routines for example.

Katzenpost is NOT crash-only software. Everything has a proper
shutdown code path unlike many golang examples on the
Internet. Struct types which act as worker goroutines MUST be a
composite struct type with the Worker type which is defined in our
“core” repository here:

Correctly implementing a composite Worker type means that your
code uses the Worker’s Go method to spawn new goroutines and will
halt it’s runtime loop upon receiving from the channel returned
by the Worker’s HaltCh method. There are plenty of examples of this
in our code.

The extended functionality of these channels is well suited to
building various kinds of computational pipelines. In particular
throughout the code base you will see “infinite buffered channels”
used as a queue connecting the schedulers of pipeline stages.
More discussion on this pipeline model is below in the next section.

The Katzenpost server is essentially a software based router and as
such it utilizes three active queue management algorithms
(AQMs). These queues are called the ingress queue, the mix strategy
queue and the egress queue. We utilize a computational model called
SEDA or Staged Even Driven Architecture where these three queues are
pipelined together.

At each stage of the pipeline there is a thread pool of workers which
perform the computation for that stage. Between each of these stages
is an AQM which can drop work tasks and can have dynamic load shedding
properties so that performance degrades gracefully with respect to
increased work load.

If you’d like to learn more about the SEDA computation model we
recommend reading:

For many circumstances it is easier and more appropriate to perform your
integration testing on a mixnet deployed to a single machine, a remote
server which could be a VM instance. In that case I would compile my katzenpost
binaries locally and upload them to my remote server and then run a bash script
to restart the services.

You will most likely want to turn on debug logging for all the mixnet services.
Checking these debug log can help you determine if the behavior is correct.
Certainly you could do all of this and add extra debug log statements to help
track down a problem that would otherwise be very difficult to detect.

Kimchi does not actually perform any tests per se. However it can be
used to exercise your code in order to determine if it works
correctly. Using Kimchi is supposed to be easier than hand configuring
many instances of the “server”.

Currently Kimchi does not utilize a configuration file. You may need
to make minor code changes to Kimchi in order for it to test your new
code. Kimchi does not run any code in the daemons repo. Instead it
provides alternate main functions which spawns many goroutines to
run each component of the Katzenpost system.

It is a good idea to discuss your code change with us before
investing your time in writing the code.

Write a specification document

If your code change is complex or requires us to change any of our
protocols you will need to first propose a draft specification
document. You can do this by forking our docs repository, creating
a new git branch with your specification document and then
submitting a pull-request.

Document the work task

Open a ticket to document your feature addition or code change using
the repository’s issue tracker.

Testing your code

Your code should have unit tests. However you may wish to gain
extra confidence in your code addition by using our kimchi tool.

Request code review

Finally you can submit a pull-request for your code changes or
additions. We will review your code. There may be several rounds
of code reviews until the code is of sufficient quality to be
merged.