Alliance Technical Overview
Introduction
Alliance is a firend-to-friend network.
It is written in Java 5.0 using Swing and asynchronous IO (java.nio package). The current
implementation uses TCP/IP.
Alliance has file-swarming capabilities like BitTorrent.
Unlike BitTorrent it has extensive build-in search, is completely decentralized
and designed to be secure.
Alliance uses tiger hashes to identify
files. All files that a user shares are automatically hashed and indexed in the
background.
Encryption is a vital part of Alliance. Although encryption has been implemented
it is currently unstable. Encryption uses the SSL package in Java 5.0 (SSLEngine
class).
The user interface is designed with ease-of-use in mind. The
goal for the UI is to be extremely simple and concise – everyone that can use Windows
XP should be able to use Alliance. Naturally there are many advanced features –
but they are hidden by default.
Basic Definitions
Node
A node in the Alliance network.
Friend
A node that is trusted. The Alliance application knows the
IP number, port number and public encryption key of every Friend it has. This
is not called friend in the UI – friends are called “Connections”.
Subsystems
Alliance is made up of two subsystems:
UI handles the graphical interface. Core handles everything
else: network communication, file management, node management, search index and
much more. The two subsystems are independent. Core can be run standalone. In
fact, when starting Alliance in background mode only the Core subsystem is
started (UI is started on demand by the user).
All code in both subsystems may not use any static
fields. This is vital because several instances of the each subsystem can
run side-by-side in the same Java VM. This is used extensively when testing Alliance
(see Testsuite).
System Overview
Subsystem Core
The main entry class to Alliance is CoreSubsystem. This, in turn, contains entry
points to several other central parts: FriendManager,
FileManager,
NetworkManager
and InvitationManager.
Comm
The current implementation of the network code is in TCPNIONetworkLayer.
Network packets are received here, converted to Alliance
Packets, and then sent to various Connection
classes. Once a network packet is converted to an Alliance packet it is
independent of the network layer implementation. Encryption will be handled at
this level.
Alliance listens on a single TCP/IP port. This port is
randomly selected the first time Alliance starts. Every connection to that port
is initially handled by a HandshakeConnection.
The HandshakeConnection authenticates the remote computer and creates the
appropriate AuthenticatedConnection
implementation (for example FriendConnection,
DownloadConnection,
…).
FriendConnection and RPCs
The FriendConnection is the main communication link between
friends. For each active connection to a friend there is a FriendConnection. RPCs
are sent over FriendConnections. RPCs are classes extending RPC.
They can be send over the network to other friends and contain logic for what
to do when they’re received.
For example, to send a search for the keyword “alliance” in
the “Document” file type to a certain friend:
Friend
friend = core.getFriendManager().getFriend(friendGUID);
if (friend.isConnected()) {
friend.getFriendConnection().send(new Search(“alliance”, FileType.DOCUMENT.id();
}
That’s all there’s to it. The RPC will be automatically
serialized and sent over the network. Once the RPC is received on the other end
Alliance will execute Search.execute(…). That’s where the logic to handle a
search request resides.
File management
Tiger hashes are used to identify files in Alliance. Every
file is split into 1 Mb blocks and each block is hashed individually. There is
also a root hash created for each file. The hash information and other
meta-data are contained in FileDescriptors.
Incomplete files are stored in a BlockStorage.
The block storage takes care of keeping track what is saved for what file and
can defragment files when they’re completed.
File transfers
Files are downloaded block by block, in a random fashion. It
would be preferable to a rarest-first algorithm here, just like BitTorrent.
Lets say node X wants to download a file. X sends a GetBlockMask
to all its friends. This RPC contains the root hash of the file download. All
friends that have the file (complete or incomplete) reply with a BlockMaskResult.
A block mask is a bitset that
describes what blocks of the file a friend has. After this X opens DownloadConnections
to the friends it wants to download blocks from.
[More information will be
available here in the future]
Subsystem UI
No information here yet. We are not planning on making any
significant changes in the UI subsystem anyway. It works well as is.
[More information will be
available here in the future]
Threading model
The threading model of Alliance is pretty straightforward.
This is a strength of Alliance. Alliance uses asynchronous non-blocking I/O.
Because of that only one thread is needed to handle all communication.
In fact, this one thread handles all code execution in the entire Core
subsystem.
The other thread is the AWT event thread. It takes care of
all Swing code and all code execution in the UI subsystem.
It is extremely important to make sure that no UI code runs
in the Core thread and vice versa. To run UI code from the Core thread SwingUtilities.invokeLater()
is used. To run Core code from the UI thread CoreSubsystem.invokeLater()
is used.
There are a few other threads that run in the background.
Examples of such threads are: The regular UI update thread, the ShareScanner
and the FriendConnector.
Launchers
Launchers are entry points into the Alliance code.
UI
The UI Launcher is the standard entry point. It starts the
Core subsystem and shows the tray icon. Depending on command line parameters it
might or might not start the UI subsystem.
The Testsuite is used by developers for testing. It can
automatically generate setting files for a (large) group of fictional Alliance
users. All these users are connected to each other in a tree that reassembles a
real network (they all connect and listen on different ports on localhost).
When launching the Testsuite all these Alliance instances
are started in one Java VM. Only the Core subsystem is started for each node.
There’s a small UI in the Testsuite allowing launching of
the UI subsystem for a given instance of Core. This way a developer can for
example launch 30 Alliances nodes connected to each other and selectively launch
the UI for certain nodes.
The Testsuite makes for an excellent test bed when
developing Alliance.
Third party libraries
Below is a list of all third party libraries. All binaries (.jar files) for these libraries are checked into the version control system (SVN) under lib/.
Synthetica
A nice look’n’feel for Swing. Based on the Synth l’n’f. Currently
we are using the BlackStar theme of the Synthetica l’n’f.
http://www.javasoft.de/jsf/public/products/synthetica
JDIC
JDesktop Integration Components. Used for the tray icon.
https://jdic.dev.java.net/
Infonode 1.4
Infonode is used for its docking windows
UI (the tabs in Alliance).
http://www.infonode.net/index.html?idw
JUnit
JUnit is a testing framework. It is used very scarcely in Alliance
right now. The plan is to create more JUnit tests for Alliance in the future.
http://www.junit.org
XUI, StendahlsUI, NIF, StendahlsTheme
Third party libraries developed by Maciek Drejak. XUI lays
out Swing GUIs using XML. StendahlsTheme is a special theme used with Infonode
to create the shaded tabs used in Alliance. NIF and StendahlsUI contain a mixed
bag of convenient java tools.
Maciek Drejak created these libraries for his employer and
they are the property of that company. These libraries are currently closed source.
|