\section{Implementation}
\label{sec:implementation}

As stated in the previous sections, and as Figure \ref{fig:arch} points out,
the whole implementation of the SWIFT protocol resides as a kernel module.
From the user's perspective, an application only has to use the generic socket
interface. It's implementation is described in Section \ref{subsec:sock}.
Based on the scenario, the application can act as file content distributor, or
receiver, (or perhaps both). Each behavior is largely presented in Section
\ref{subsec:psender} and \ref{subsec:preceiver}.

\subsection{P2PKP Socket Interface}
\label{subsec:sock}
This module advertises a new family socket in order to be used from user space
applications. Listing \ref{lst:protocol} presents the necessary registered
structures in order to create a new protocol in UNIX. There are three steps
that must be followed:

\renewcommand{\figurename}{Listing}
\begin{figure}[h!]
	\begin{minipage}[h]{.5\linewidth}
		\lstset{language=C,captionpos=b,label=snip:familyops}
		\begin{lstlisting}

static struct proto p2pkp_proto = {
	.name		= P2PKP_PROTO_NAME,
	.owner		= THIS_MODULE,
	.obj_size	= sizeof(struct p2pkp_sock),
};
		\end{lstlisting}
		\subcaption{Protocol Specification}\label{subfig1}
	\end{minipage} \\
	\begin{minipage}[h]{.5\linewidth}
		\lstset{language=C,captionpos=b,label=snip:familyops}
		\begin{lstlisting}
	
static const struct net_proto_family p2pkp_family_ops = {
	.family		= PF_P2PKP,
	.create		= p2pkp_create,
	.owner		= THIS_MODULE,
};	
		\end{lstlisting}
		\subcaption{Protocol Family}\label{subfig2}
	\end{minipage} \\
	\begin{minipage}[h]{.5\linewidth}
		\lstset{language=C,captionpos=b,label=snip:familyops}
		\begin{lstlisting}

static const struct proto_ops p2pkp_ops = {
	.family		= PF_P2PKP,
	.owner		= THIS_MODULE,
	.release	= p2pkp_release,
	.bind		= p2pkp_bind,
	.connect	= p2pkp_connect,
	.sendmsg	= p2pkp_sendmsg,
	.recvmsg	= p2pkp_recvmsg,
	...
};
		\end{lstlisting}
		\subcaption{Protocol Operations}\label{subfig3}
	\end{minipage}
	\caption{Protocol specification}
	\label{lst:protocol}
\end{figure}

\begin{itemize}
	\item Register the protocol - the structure needed to register a protocol
	is presented in Listing \ref{subfig1}. It specifies the
	protocol as it is seen in \\
		\texttt{/proc/net/protocols}
	\item Register a new protocol family - Listing \ref{subfig2} is presenting
	the structure needed to register a new protocol family. The
	\texttt{p2pkp\_create} function initializes the kernel socket structures
	when the \texttt{socket} system call is called.
	\item Specify the protocol operations - the structure from Listing
	\ref{subfig3} advertises the functions called by the Linux socket
	interface from the \texttt{write}, \texttt{read}, \texttt{bind}, etc.
	wrappers. Their implementation will be largely presented in the next
	sections.
\end{itemize}

In order to use the protocol provided by this module, all senders and
receivers have to open a socket. Then, based on their profile, they must
implement one of the following scenarios.

\subsection{P2PKP Sender}
\label{subsec:psender}
As already described in Section \ref{subsec:sender}, after opening the socket,
the user space application has to specify all of the peers that wants to
distribute the file content to. Therefore it calls multiple times the
\texttt{connect} function, which is translated by the Linux socket interface
to the \texttt{p2pkp\_connect} function call. This function only links the
destination to a specific list attached to each socket. As this protocol is
built over UDP, there is no need of establishing a real connection to the
other peer.

The next step the user space application has to do is to call the
\texttt{write} system call with the desired filename for distribution. This
system call maps to the \texttt{p2pkp\_sendmsg} function, and has the behavior
described in Listing \ref{lst:sender}. This is the main logic of the
multiparty sender. After some parameters checks are
performed, the input files are iterated and opened using the VFS \texttt{open}
call. If no files exist, the function exits with a \texttt{ENOENT}
\texttt{errno} set. Then, the content of the file is sent to each peer
previously connected. This is done using the Linux NET layer, using the
\texttt{kernel\_sendmsg} function. If the function succeeds, the total number
of files distributed is returned to the application. Otherwise, if one of the
Linux VFS or NET layer fail, the proper error is returned.

The file's data is not read all at once in a single chunk, but rather
iteratively in chunks of 8192 bytes. After loading the data in buffer, it is
directly transmitted to all peers using the Linux NET layer. Therefore any
latency caused by the network, or hard disks are not to be assigned to the P2PKP
module, as it is a simple user of these mechanisms.

After sending all the files to all the peers, the file is closed and the
structures are cleaned up. At this point, the user might start sending some
different files, or close the socket, using \texttt{close}. In this case, the
\texttt{p2pkp\_release} function is called that frees all the allocated data,
closes the UDP socket and cleans up the kernel structures.

\addtocounter{lstlisting}{2}
\lstset{language=C,captionpos=b,label=lst:sender,caption={\texttt{p2pkp\_sendmsg}
		pseudo code},tabsize=4,morekeywords={foreach}}
\begin{lstlisting}
foreach file
	f = open(file, O_RDONLY)
	do
		read(f, buffer, chunk_size)
		foreach peer
			send(peer, buffer, chunk_size)
	while f has more data
	close(f)

\end{lstlisting}

\subsection{P2PKP Receiver}
\label{subsec:preceiver}
In order to receive files using the P2PKP module, a receiver application has
to bind a socket to an interface. As in any other protocol, this is done using
the \texttt{bind} system call, which is translated to \texttt{p2pkp\_bind}
function. In this function we create a new UDP socket, and we bind it to the
specified interface.

Next, the application has to call the \texttt{read} function in order to
receive a file. The pseudo code of this function is presented in Listing
\ref{lst:receiver}. Basically, this function reads data from network and dumps
them into a file. First, a new file is opened for writing this time. If the
file exists, it is truncated to 0, otherwise it is created.

Then the module enters in a loop, where it waits for data coming from the
peers through the Linux NET layer. Similar to the sender's behavior data is
received in chunks of 8192 each. After the transfer is completed, the cleanup
is done similarly to the receiver from the previous section.

\lstset{language=C,captionpos=b,label=lst:receiver,caption={\texttt{p2pkp\_recvmsg}
		pseudo code},tabsize=4,morekeywords={foreach}}
\begin{lstlisting}
f = open(file, O_WRONLY|O_CREAT|O_TRUNC);
while more data on socket
	recv(sock, buffer, chunk_size)
	write(f, buffer, chunk_size)
close(f)

\end{lstlisting}

Having presented the internal implementation of our module, we will proceed to
describing the testing scenarios we have performed in order to test our module
efficiency.
