Tairent is a minimalistic BitTorrent client for Linux servers. It means that it has no GUI, TUI or CLI. Instead it provides effective way for serving large files using BitTorrent protocol. Because Tairent uses Tairon library for networking (and other stuff) it can handle very large number of idling connections at the moment. Other key feature is that Tairent tries to minimize data copying in memory by using mmap for mapping large files into the memory and then sending them directly to the peer.
Tairent is divided into modules (each is located in its own directory under src/). This document is brief introduction to how Tairent internally works.
This isn't module in the sense that it could be loaded at runtime. It's built into executable program's binary and initializes all the necessary components (i.e. managers from the Tairon library). Core module also creates thread for networking (runs Tairon::Net::Loop) and implements common data structures: BEncode and bitfield.
Main module is the heart of the application. It implements all program logic (and thus the BitTorrent client itself). The module creates managers (for different tracker methods, torrents and one for limiting bandwidth; the last one is implemented in the Tairon library) and two program threads (main that is already created and one for hash checking). When all modules are loaded this module tells torrent manager that it can start serving torrents and executes main program loop.
Tracker manager (Tairent::Main::TrackerManager class) keeps list of registered protocols for trackers (official BitTorrent specification uses just HTTP) and can create clients for those protocols.
Torrent manager (Tairent::Main::TorrentManager class) keeps information about served torrents. It means that it loads these informations from torrents.xml file stored in the directory configurable by torrents-directory option. For each served torrent it loads its metainfo file and possible creates storage engine for this torrent if fast-resume data is present. Torrent manager also creates client for each served torrent.
Every minute Torrent manager asks all clients to save their state into the torrents.xml file and thus it allows resuming of unfinished torrents. This is done by connecting save() method to a timer with 60 seconds timeout.
Client for one torrent is represented by Tairent::Main::TorrentClient class. It has lists of connected peers and connections that hasn't been fully established. Client controls connection logic by receiving specific protocol's commands and relaying them to the storage engine or doing specific actions with peers (choking, closing and opening new connections, requesting new pieces etc).
Tairent::Main::Connection handles BitTorrent protocol at the network level: connection initialization by sending, receiving and verifying handshake sequence and then by reading and sending messages over the connection. This class communicates with client that owns this connection and possibly with client's storage engine. Connection handles lists commands that should be sent to the peer, peer's requests and other connection's state (which side of the connection is choked/interested, list of peer's pieces, etc).
This engine (implemented in Tairent::Main::Storage class) is one of the most critical part. It loads information about torrent's file(s) from its metainfo and prepares internal structures for effective handling. Storage also chooses what piece should be requested, maintains list of requested and already received pieces and creates objects for reading and writing them.
This is one module that implements support for trackers communicating over HTTP protocol. The module implements factory (Tairent::TrackerClient::HTTPTrackerClientFactory class) for creating clients for these trackers and the client itself represented by Tairent::TrackerClient::HTTPTrackerClient. Client requests list of peers from the torrent's trackers and relays this list to the client.