Sie sind auf Seite 1von 5

Litepipe Design Document

Berkin Ilbeyi (client and library) and Shrutarshi Basu (server)

1. Litepipe Design Document


a. Thread architecture
b. Protocol support
i. Functional
1. Time
2. Information
3. HTML
ii. Implementation
1. Data packets
2. File/Time
c. Communications library design
d. Server design
e. Client design

Litepipe is a simple data server and corresponding client. It is multithreaded and supports multiple protocols.
The server is written in C using standard UNIX system calls. The graphical client is written in C++ using the Qt
toolkit.

Thread architecture
All thread creation is handled by the Communication library (communicator.c and communicator.h). All network
sends and receives are also handled by the Communication library. The server and client is responsible for
creating and binding sockets and establishing connections.

Litepipe is extensively multithreaded on the server side. Each protocol is served by a separate thread (hence
three server threads -- one for each protocol). Each server then creates a separate thread for each client that

connects to it. But all requests from a specific client on a specific protocol are served by a single thread.

Protocol support
Litepipe supports three separate functional protocols:

• Functional
o Time
o Information
o HTML / file transfer
• Implementation
o Data packets
o File/Time

Functional

Time

Using the time protocol Litepipe behaves as a simple server. Once a connection is established by a client, an
initiator message from the client (which can be any text string) causes the server to start sending the standard
UNIX time every second. To stop this, the client must break the connection.
Information

The information protocol allows clients to request for some specific system information from the Litepipe server.
This is basic system information that will not compromise system safety by being exposed to anonymous clients.
All the information is gathered by reading the corresponding files from the /proc filesystem.

A request on the information protocol can be one of the following strings terminated by a newline:

HELP -- "help"

VERSION -- "version"

UPTIME -- "uptime"

FILESYSTEMS -- "filesystems"

CPUINFO -- "cpuinfo"

PARTITIONS -- "partitions"

The responses are text strings which contain the relevant information. The repsonse to unrecognized requests is
the same as for the "help" request.

HTML

The client can request files from the server by specifying the file name. The server simply takes the file (if it
exists) and returns it or else sends back an error message. The server only serves files if they are in the server's
current working directory. It prevents attempts to access files above the current directory.

Implementation

Data packets

The lowest level of the communication protocol (that is above TCP/IP) is solely managed by the communication
library. Any send requests to the connected remote computer takes the arguments of the data pointer and data
size. The data packet sent consists of four bytes of the size of the data contents, and the data content itself. By
specifying the data size a priori to the connected computer, that computer would only have to construct such
sized buffer, simplifying the transaction as well as reducing the memory overhead, as we do not have to guess the
data size any more. It also makes sure to merge the data if it had to be split up because the kernel recv stack was
not big enough. It would basically ask for more data and use only the specified number of bytes to read. It also
eliminates the problem where two packets are sent in a close time so that the recv call returns a merged buffer of
both packets. That would not be an issue with this design as it will only request the necessary number of bytes
from the recv call.
File/Time

Both the HTML and Information protocols actually serve files. Because of the requirement of embedding images,
client has to request image resources. A page might contain more than one image, so it is crucial to be able to
know exactly what is being received, i.e., its file name. So, for the file transfer, the data segment first includes a
null-terminated string to indicate the file name. The actual contents of the data start right after the null
character. The client requests for any file is simply just requested the file name as the data segment. The server
response file name has also the requirement of having have to exactly match the client file name string, because
that is how the client keeps track of the requests it had sent and the responses it is receiving.

Time is served just as an integer it terms of seconds since the last epoch. The request can be any string. Client
request for time will initialize the server time service, which will send the server the time every second.

Communications library design


The common communications library is used by both server and client. It mainly incorporates the threading and
socket communication utilities.

It implements a callback mechanism to the applications using this library using a functor named handle(). The
handle() functor installed would be called on any important event, such as the connection to a new client/server,
and incoming message, the loss of connection or an error. This callback mechanism helps the library to be easily
pluggable to different server or client code.

For the server, the library creates threads for each client. It also receives messages from the clients and raises
appropriate events for the server to deal with. It also provides a function that wraps around sending data to the
client.

Server design
The server is designed to be multithreaded and modular. Each protocol/port is handled by a protocol server
running on a separate thread. For each connection on a port the server spins off a separate thread for that client.

The server starts by creating a separate thread for each port (using the common library). Each server thread then
sits and listens for incoming connection. When a client attempts to connect, the server accepts the connection
and then creates a separate thread (again using the library) to communicate with the client. A client thread is
destroyed when the client disconnects. The server threads persist until the server as a whole is shut down.
The server source code is composed of 2 C files: server.c which handles generic server functions and protocol.c
which handles functionality for the separate protocols.

Each server thread runs a loop that waits for client connections (serve_thd function). Once a client connection
has been wrapped in it's own thread, the server_handler() function gets called to handle events that occur (such
as receiving new data from the client). This function then calls the protocol specific functions in protocol.c

The serve_time() function handles the time protocol. It simply sends the current UNIX over the open client
connection. It blocks for a second every time so as not to completely use up the CPU.

The serve_info() function parses the information request and then calls serve_proc() with the appropriate
filename in the /proc filesystem. Due the nature of the files in /proc, the information is copied to a temporary file
which is then served the serve_file() function.

serve_html() checks that the file exists and is within the current working directory and subdirectory. It then calls
the serve_file() function to serve the appropriate file or else sends back an error message.

There are two interrupt handlers: the SIGPIPE (raised when there is a socket error) handler simply kills the
current thread which is no longer needed as its client is unavailable. The SIGINT handler prints a shutdown
message and then exits the program. It does not attempt to close open connections or notify clients.

The client has been written in a functional style: information is passed from one function to the next with
minimal shared state (especially between threads). This helps avoid some of the programs common to thread-
based concurrent programming.

Client design
Client part is written in C++ and uses Qt 4 toolkit for the GUI functionality. It exploits the pluggable nature of
the communication library. The HTML parsing and displaying is done using QTextEdit. This component has the
ability to directly display rich text if HTML is supplied for its source. The underlying display engine of QTextEdit,
QDocument, has an internal cache of a HTML files and other resources such as images, CSS files etc. So for any
embedded resource encountered in the HTML, if it is not already in its cache, it would issue a resource request
which can be overriden and caught. At this stage, the name of the requested resource could be extracted, and
simply that resource would be requested using the underlying file transferring layer. The requests for resources
would be put to a set, so that once the requested files start arriving in, they could be matched and supplied
directly to the QTextEdit through resource's byte array. This eliminates the need for any temporary files for
HTML and embedded content.

New data and communication establishment and break events are received through the pluggable handle
interface of the communications library. Before the call to initialize a client communication thread is done, a
pointer to a static function in the client, handleCommunicationEvent, is passed as the handler. When this functor
is called, the call would be the client network thread, not the GUI thread. Like many GUI toolkits, Qt is not
thread-safe and requires any call to modify the GUI to be in the main GUI thread. To transfer the control to the
GUI thread, we used Qt's signal-slot mechanism, so that the static functor would emit a signal, which is
configured to trigger a slot in the GUI thread's event queue. This process ensures the control is properly
delivered.

connect(this, SIGNAL(handleCommunicationEventSignal(int, void*)), this,


SLOT(handleCommunicationEventSlot(int, void*)));

...

public:

static void handleCommunicationEvent(int status, void *data);

signals:

void handleCommunicationEventSignal(int status, void *data);

private slots:

void handleCommunicationEventSlot(int status, void *data);

Apart from these issues, there were no diversion from regular simple GUI programming, as bulk of the low levels
are abstracted thanks to the communication library and the HTML display by Qt.

Outstanding issues
Though Litepipe meets the functional requirements, there are a few outstanding issues:

1. The HELP file is an HTML document that must be served from the server's current working directory. If
the server's directory is changed, the HELP file can be lost as well as the information functionality.
2. The source code naming conventions are inconsistent, especially between the server (written in C,
following C conventions) and the client (written in C++ with C++ naming conventions). This could be
fixed by refactoring the code with testing to make sure that functionality is not broken.
3. IPv6 support is inconsistent. The server is agnostic, but the shared library is IPv4 only. A substantial
rewrite would be necessary.

Tools used

1. GCC, GDB and GNU Make for compiling and debugging C and C++ source code
2. Git for version control and merging client/server code bases
3. Google Docs for documentation and presentation
4. Emacs and KDevelop for editing support
5. Qt Toolkit for graphics and HTML rendering

Das könnte Ihnen auch gefallen