Overseer updated draft #1

Merged
JakeHillion merged 7 commits from develop into master 2020-10-21 21:13:57 +01:00

View File

@ -4,15 +4,19 @@
\usepackage{pdfpages} \usepackage{pdfpages}
\usepackage{graphicx} \usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document} \begin{document}
\includepdf{cover.pdf} \includepdf{cover.pdf}
\section*{Introduction and Description of the Work} \section*{Introduction and Description of the Work}
This project aims to provide a method of combining Internet connections without modifying existing devices or infrastructure. Rather, by inserting a Local Server to consolidate multiple, heterogeneous connections and a Remote Server to act as a common connection to the wider network, both speed and resilience improvements may be possible. While there are existing solutions that combine multiple connections, they prioritise one at the expense of the other; this project will attempt to show that this trade-off can be avoided. This project attempts to combine multiple heterogeneous network connections into a single virtual connection, which has both the combined speed and the maximum resilience of the original connections. This will be achieved by inserting a Local Portal and a Remote Portal into the network path, as shown in Figure \ref{fig:sample-network}. While there are existing solutions that combine multiple connections, they prioritise one of resilience or speed over the other; this project will attempt to show that this trade-off can be avoided.
The resilience focus of this software should allow a TCP flow\footnote{Flow is used slightly outside of normal in this document. It describes a channel of communication between two devices that is uninterrupted.} or UDP flow to continue, given all but one of the connections between the Local Server and the Remote Server being lost. As an example, this would allow a SIP call to continue without a redial. The speed focus is achieved by providing a single virtual connection that aggregates the speed of all connections. An example of this is allowing a single flow video stream to exceed the bandwidth available on a single connection. Further, the system is integrated in such a way that the details of the load balancing are hidden from both the applications behind the Local Server and peers on the wider network. The speed focus of this software is achieved by providing a single virtual connection which aggregates the speed of the individual connections. As this single connection is all thats made visible to the client, all applications and protocols can benefit from the speed benefits, as they require no knowledge of how their packets are being split. As an example, a live video stream that only uses one flow will be able to use the full capacity of the virtual connection.
The resilience focus provides similar benefits, in that the virtual connection conceals the failing of any individual network connections from the client and applications. This again means that applications and protocols not built to handle a network failover can benefit from the resilience provided by this solution. An example is a SIP call continuing without a redial.
This system is useful in areas where multiple low bandwidth connections are available, but not a single higher bandwidth connection. This is often the case in rural areas in the UK. It will also be useful in areas with diverse connections of varying reliability, such as a home with both DSL and wireless connections, which may become more common with the advent of 5G and LEO systems such as Starlink. The lack of requirement for vendor support allows for this mixture of connections to be supported. This system is useful in areas where multiple low bandwidth connections are available, but not a single higher bandwidth connection. This is often the case in rural areas in the UK. It will also be useful in areas with diverse connections of varying reliability, such as a home with both DSL and wireless connections, which may become more common with the advent of 5G and LEO systems such as Starlink. The lack of requirement for vendor support allows for this mixture of connections to be supported.
@ -32,33 +36,41 @@ Some existing attempts to solve these problems, and the shortfalls of each solut
\end{itemize} \end{itemize}
By providing congestion control over each interface and therefore being able to share packets without bias between connections, this project should provide a superior solution for load balancing across heterogeneous and volatile network connections. An example of a client using this is shown in Figure \ref{fig:sample-network}. It's worth noting that this solution is highly flexible, allowing the client to be a NAT Router with more devices behind it, or the flows from the Local Server to the Remote Server being tunnelled over a VPN. By providing congestion control over each interface and therefore being able to share packets without bias between connections, this project should provide a superior solution for load balancing across heterogeneous and volatile network connections. An example of a client using this is shown in Figure \ref{fig:sample-network}. This solution is highly flexible, allowing the client to be a NAT Router with more devices behind it, or the flows from the Local Portal to the Remote Portal being tunnelled over a VPN.
\begin{figure} \begin{figure}
\small \centering
\begin{verbatim} \begin{tikzpicture}[
Uncontrolled squarednode/.style={rectangle, draw=black!60, fill=red!5, very thick, minimum size=5mm},
On Premises Off Premises Devices ]
+-------------------------------------------------+ +----------+ +----------+
% Nodes
\node[squarednode] (client) {Client};
\node[squarednode] (localserver) [right=of client] {Local Portal};
\node[squarednode] (modema) [above right=0.5 and 1 of localserver] {Modem A};
\node[squarednode] (modemb) [below right=0.5 and 1 of localserver] {Modem B};
\node[squarednode] (remoteserver) [below right=0.5 and 1 of modema] {Remote Portal};
\node[squarednode] (webserver) [above right=of remoteserver] {Web Server};
\node[squarednode] (voipserver) [right=of remoteserver] {VoIP Server};
\node[squarednode] (vpnserver) [below right=of remoteserver] {Corporate VPN};
% Edges
\draw[->] (client.east) -- (localserver.west);
\draw[->] (localserver.east) -- (modema.west);
\draw[->] (localserver.east) -- (modemb.west);
\draw[->] (modema.east) -- (remoteserver.west);
\draw[->] (modemb.east) -- (remoteserver.west);
\draw[->] (remoteserver.east) -- (webserver.west);
\draw[->] (remoteserver.east) -- (voipserver.west);
\draw[->] (remoteserver.east) -- (vpnserver.west);
\end{tikzpicture}
+----------+
| Web |
+->+ Server |
+----------+ via | | |
+-------------------------------+ | | ISP A | +----------+
| | +-->+ Modem A +--+ |
| +----------+ +----------+ | | | | | +----------+ | +----------+
| | | | Local +----+ +----------+ +---->+ Remote +--+ | VoIP |
| | Client +---->+ Server | | | Server |---->+ Server |
| | | | +----+ +----------+ +---->+ +--+ | |
| +----------+ +----------+ | | | | | +----------+ | +----------+
| | +-->+ Modem B +--+ |
+-------------------------------+ | | via | +----------+
+----------+ ISP B | |Corporate |
+->+ VPN |
| |
+----------+
\end{verbatim}
\caption{A network applying this proxy} \caption{A network applying this proxy}
\label{fig:sample-network} \label{fig:sample-network}
\end{figure} \end{figure}
@ -67,36 +79,18 @@ By providing congestion control over each interface and therefore being able to
I have spent some time looking into the shortfalls and benefits of the available methods for combining multiple Internet connections. The Part IB course \emph{Computer Networking} has provided the background information for this project. I have significant experience with Go, though none with lower level networking. I have no experience with Rust, and my C++ experience is limited to the Part IB course \emph{Programming in C and C++}. I have spent some time looking into the shortfalls and benefits of the available methods for combining multiple Internet connections. The Part IB course \emph{Computer Networking} has provided the background information for this project. I have significant experience with Go, though none with lower level networking. I have no experience with Rust, and my C++ experience is limited to the Part IB course \emph{Programming in C and C++}.
I have some knowledge of the Wireguard project, though as a user instead of a programmer. I intend for this to inspire the interaction between the user and the project, though this will not be in the form of code. While I am not aware of any existing software that accomplishes the task that I propose, Wireguard performs a similar task of tunnelling between a local and remote node, has a well regarded interface, and is a well structured project, providing both inspiration and an initial model for the structure of my project.
\section*{Substance and Structure of the Project} \section*{Substance and Structure of the Project}
The system will involve load balancing multiple congestion controlled flows between the Local Server and the Remote Server. The Local Server will receive packets from the client, and use load balancing and congestion control algorithms to send individual packets along one of the multiple available connections to the Remote Server, which will extract the original packets and forward them along a high bandwidth connection to the wider network. The system will involve load balancing multiple congestion controlled flows between the Local Portal and the Remote Portal. The Local Portal will receive packets from the client, and use load balancing and congestion control algorithms to send individual packets along one of the multiple available connections to the Remote Portal, which will extract the original packets and forward them along a high bandwidth connection to the wider network.
To achieve this congestion control, I will initially use TCP flows, which include congestion control. However, TCP also provides other guarantees, which will not benefit this task. For this reason, the application should be structured in such a way that it can support alternative protocols to TCP. An improved alternative is using UDP datagrams with a custom congestion control protocol, that only guarantees congestion control as opposed to packet delivery. Another alternative solution would be a custom IP packet with modified source and destination addresses and a custom preamble. Having a variety of techniques available would be very useful, as each of these has less overhead than the last, while also being less likely to work with more complicated network setups. To achieve this congestion control, I will initially use TCP flows, which include congestion control. However, TCP also provides other guarantees, which will not benefit this task. For this reason, the application should be structured in such a way that it can support alternative protocols to TCP. An improved alternative is using UDP datagrams with a custom congestion control protocol, that only guarantees congestion control as opposed to packet delivery. Another alternative solution would be a custom IP packet with modified source and destination addresses and a custom preamble. Having a variety of techniques available would be very useful, as each of these has less overhead than the last, while also being less likely to work with more complicated network setups.
When the Local Server has a packet it wishes to send outbound, it will place the packet and some additional security data in a queue. The multiple congestion controlled links will each be consuming from this queue when they are not congested. This will cause greedy load balancing, where each connection takes all that it can get from the packet queue. As congestion control algorithms adapt to the present network conditions, this load balancing will alter the balance between links as the capacity of each link changes. When the Local Portal has a packet it wishes to send outbound, it will place the packet and some additional security data in a queue. The multiple congestion controlled links will each be consuming from this queue when they are not congested. This will cause greedy load balancing, where each connection takes all that it can get from the packet queue. As congestion control algorithms adapt to the present network conditions, this load balancing will alter the balance between links as the capacity of each link changes.
To make integration of this solution as simple as possible, the Local Server will endeavour to provide a DHCP server on the client interface. This will allow the client to automatically configure its IP, as is often the case with an ISP.
Security is an important consideration in this project. Creating a multipath connection and proxies in general can create additional attack vectors, so I will perform a review of some existing security literature for each of these. However, as the tunnel created here transports entire IP packets, any security added by the application or transport layer will be maintained by my solution. Security is an important consideration in this project. Creating a multipath connection and proxies in general can create additional attack vectors, so I will perform a review of some existing security literature for each of these. However, as the tunnel created here transports entire IP packets, any security added by the application or transport layer will be maintained by my solution.
The structure of the Wireguard project is also a good fit for this project. The elements are presented as follows:
\begin{itemize}
\item To manage the tunnel, a C kernel codebase and a Go user space codebase.
\item Existing $ip(8)$ and $ifconfig(8)$ tools for the configuration that they can manage.
\item A $wg(8)$ tool for configuration that can't be handled by existing tools.
\item A $wg-quick(8)$ tool for persistent configuration.
\end{itemize}
Although I only plan to implement a user space codebase as part of this project, I will endeavour to produce the three parts listed above. That is, allowing all configuration that can be handled by the existing tools $ip(8)$ or $ifconfig(8)$ to be completed by them, an additional tool for bespoke configuration elements, and a separate script that uses both of these for persistent configuration.
Examples are provided showing the path of a packet with standard session based load balancing, and with this solution applied: Examples are provided showing the path of a packet with standard session based load balancing, and with this solution applied:
\subsubsection*{Session Based Load Balancing} \subsubsection*{Session Based Load Balancing}
@ -111,30 +105,31 @@ A sample network is provided in Figure \ref{fig:sample-network-session-based}.
\end{enumerate} \end{enumerate}
\begin{figure} \begin{figure}
\small \centering
\begin{verbatim} \begin{tikzpicture}[
Uncontrolled squarednode/.style={rectangle, draw=black!60, fill=red!5, very thick, minimum size=5mm},
On Premises Devices ]
+-------------------------------------------------+ +----------+
% Nodes
\node[squarednode] (client) {Client};
\node[squarednode] (natrouter) [right=of client] {NAT Router};
\node[squarednode] (modema) [above right=0.5 and 1 of natrouter] {Modem A};
\node[squarednode] (modemb) [below right=0.5 and 1 of natrouter] {Modem B};
\node[squarednode] (webserver) [above right=0.25 and 1 of modema] {Web Server};
\node[squarednode] (voipserver) [below right=0.25 and 1 of modema] {VoIP Server};
\node[squarednode] (vpnserver) [below right=1.75 and 1 of modema] {Corporate VPN};
% Edges
\draw[->] (client.east) -- (natrouter.west);
\draw[->] (natrouter.east) -- (modema.west);
\draw[->] (natrouter.east) -- (modemb.west);
\draw[->] (modema.east) -- (webserver.west);
\draw[->] (modema.east) -- (voipserver.west);
\draw[->] (modemb.east) -- (vpnserver.west);
\end{tikzpicture}
+----------+
| Web |
+-->+ Server |
+----------+ | | |
+-------------------------------+ | +--+ +----------+
| | +-->+ Modem A |
| +----------+ +----------+ | | | +--+ +----------+
| | | | NAT +----+ +----------+ | | VoIP |
| | Client +---->+ Router | | +-->+ Server |
| | | | +----+ +----------+ | |
| +----------+ +----------+ | | | | +----------+
| | +-->+ Modem B +--+
+-------------------------------+ | | | +----------+
+----------+ | |Corporate |
+-->+ VPN |
| |
+----------+
\end{verbatim}
\caption{A network with a NAT Router and two modems} \caption{A network with a NAT Router and two modems}
\label{fig:sample-network-session-based} \label{fig:sample-network-session-based}
\end{figure} \end{figure}
@ -143,12 +138,12 @@ A sample network is provided in Figure \ref{fig:sample-network-session-based}.
A sample network is provided in Figure \ref{fig:sample-network}. A sample network is provided in Figure \ref{fig:sample-network}.
\begin{enumerate} \begin{enumerate}
\item Local Server receives the packet from the client. \item Local Portal receives the packet from the client.
\item Local Server wraps the packet with additional information. \item Local Portal wraps the packet with additional information.
\item Local Server sends the wrapped packet along whichever connection has available capacity. \item Local Portal sends the wrapped packet along whichever connection has available capacity.
\item Wrapped packet travels across the Internet to the Remote Server. \item Wrapped packet travels across the Internet to the Remote Portal.
\item Remote Server receives the packet. \item Remote Portal receives the packet.
\item Remote Server dispatches the unwrapped packet via its high speed WAN interface. \item Remote Portal dispatches the unwrapped packet via its high speed WAN interface.
\item Destination receives the packet. \item Destination receives the packet.
\end{enumerate} \end{enumerate}
@ -156,11 +151,11 @@ A sample network is provided in Figure \ref{fig:sample-network}.
\section*{Success Criteria} \section*{Success Criteria}
\begin{enumerate} \begin{enumerate}
\item Allow either a TCP flow or a UDP flow to continue if one or more (but not all) of the connections between the Local Server and the Remote Server are lost. \item Allow either a TCP flow or a UDP flow to continue if one or more (but not all) of the connections between the Local Portal and the Remote Portal are lost.
\item Any and all performance gains stated below should function bidirectionally (inbound/outbound to/from the client). \item Any and all performance gains stated below should function bidirectionally (inbound/outbound to/from the client).
\item Allow the network client behind the main client to treat its IP address on the link to the Local Server as the IP of the Remote Server. \item Allow the network client behind the main client to treat its IP address on the link to the Local Portal as the IP of the Remote Portal.
\item Provide security that is no worse than not using this solution at all. \item Provide security that is no worse than not using this solution at all.
@ -168,7 +163,7 @@ A sample network is provided in Figure \ref{fig:sample-network}.
\item Demonstrate that a flow can be maintained over two connections of equal bandwidth with this solution if one of the connections becomes unavailable. \item Demonstrate that a flow can be maintained over two connections of equal bandwidth with this solution if one of the connections becomes unavailable.
\item Provide full support for both IPv4 and IPv6. This includes reaching the Remote Server over IPv6 but proxying IPv4 packets, and vice versa. \item Provide full support for both IPv4 and IPv6. This includes reaching the Remote Portal over IPv6 but proxying IPv4 packets, and vice versa.
\end{enumerate} \end{enumerate}
@ -183,7 +178,7 @@ A sample network is provided in Figure \ref{fig:sample-network}.
\item Demonstrate that if one of two connections is lost and then regained, the bandwidth available reaches the levels of before the connection was lost. \item Demonstrate that if one of two connections is lost and then regained, the bandwidth available reaches the levels of before the connection was lost.
\item My initial design requires the Remote Server to have two interfaces: one for communicating with the Local Server, and one for communicating with the wider network. This criteria is achieved by supporting both of these actions over one interface. \item My initial design requires the Remote Portal to have two interfaces: one for communicating with the Local Portal, and one for communicating with the wider network. This criteria is achieved by supporting both of these actions over one interface.
\item Support a metric value for connections, such that connections with higher metrics are only used for load balancing if no connection with a lower metric is available. \item Support a metric value for connections, such that connections with higher metrics are only used for load balancing if no connection with a lower metric is available.
@ -198,91 +193,89 @@ A sample network is provided in Figure \ref{fig:sample-network}.
\end{enumerate} \end{enumerate}
Although these tests will be performed predominantly on virtual hardware, I will endeavour to replicate some of them in a non-virtual environment, though this will not be a part of the success criteria.
\pagebreak \pagebreak
\section*{Timetable and Milestones} \section*{Timetable and Milestones}
\subsection*{12/10/2020 - 1/11/2020} \subsection*{12/10/2020 - 1/11/2020 (Weeks 1-3)}
Study Go, Rust and C++'s abilities to read all packets from an interface and place them into some form of concurrent queue. Research the positives and negatives of each language's SPMC and MPSC queues. Study Go, Rust and C++'s abilities to read all packets from an interface and place them into some form of concurrent queue. Research the positives and negatives of each language's SPMC and MPSC queues.
\noindent \\ \noindent \\
Milestone: Example programs in each language that read all packets from a specific interface and place them into a queue, or a reason why this isn't feasible. A decision of which language to use for the rest of the project, based on these code segments and the status of SPMC queues in the language. Milestone: Example programs in each language that read all packets from a specific interface and place them into a queue, or a reason why this isn't feasible. A decision of which language to use for the rest of the project, based on these code segments and the status of SPMC queues in the language.
\subsection*{02/11/2020 - 15/11/2020} \subsection*{02/11/2020 - 15/11/2020 (Weeks 4-5)}
Set up the infrastructure to effectively test any produced work from this point onwards. Set up the infrastructure to effectively test any produced work from this point onwards.
\noindent \\ \noindent \\
Milestone: A virtual router acting as a virtual Internet for these tests. 3 standard VMs below this level for each: the Local Server, the Remote Server and a speed test server to host iPerf3. Behind the Local Server should be another virtual machine, acting as the client to test the speed from. Backups of this setup should also have been made. Milestone: A virtual router acting as a virtual Internet for these tests. 3 standard VMs below this level for each: the Local Portal, the Remote Portal and a speed test server to host iPerf3. Behind the Local Portal should be another virtual machine, acting as the client to test the speed from. Backups of this setup should also have been made.
\subsection*{16/11/2020 - 29/11/2020} \subsection*{16/11/2020 - 29/11/2020 (Weeks 6-7)}
This section should focus on the security of the application. This would include the ability for someone to maliciously use a Remote Server to perform a DoS attack. This section should focus on the security of the application. This would include the ability for someone to maliciously use a Remote Portal to perform a DoS attack. Draft the introduction chapter.
\noindent \\ \noindent \\
Milestone: An analysis of how the security of this solution compares, both with other multipath solutions and a network without any multipath solution applied. Milestone: An analysis of how the security of this solution compares, both with other multipath solutions and a network without any multipath solution applied. A drafted introduction chapter.
\subsection*{30/11/2020 - 20/12/2020} \subsection*{30/11/2020 - 20/12/2020 (Weeks 8-10)}
Implementation of the transport aspect of the Local Server and Remote Server. The first data structure for transport should also be created. This does not include the load sharing between connections - it is for a single connection. To enable testing, this will also require the setup of configuration options for each side. At this stage, it would be reasonable for the Remote Server to require two different IPs - one for server communication, and one as the public IP of the Local Router. The initial implementation should use TCP, but if time is available, UDP with a custom datagram should be explored for reduced overhead. Implementation of the transport aspect of the Local Portal and Remote Portal. The first data structure for transport should also be created. This does not include the load sharing between connections - it is for a single connection. To enable testing, this will also require the setup of configuration options for each side. At this stage, it would be reasonable for the Remote Portal to require two different IPs - one for server communication, and one as the public IP of the Local Router. The initial implementation should use TCP, but if time is available, UDP with a custom datagram should be explored for reduced overhead.
\noindent \\ \noindent \\
Milestone: A piece of software that can act either as the Local Server or Remote Server based on configuration. Any IP packets sent to the Local Server should emerge from the Remote Server. Milestone: A piece of software that can act either as the Local Portal or Remote Portal based on configuration. Any IP packets sent to the Local Portal should emerge from the Remote Portal.
\subsection*{21/12/2020 - 10/01/2021} \subsection*{21/12/2020 - 10/01/2021 (Weeks 11-13)}
Create mock connections for tests that support variable speeds, a list of packet numbers to lose and a number of packets to stop handling packets after. Produce the first draft of the preparation chapter. Create mock connections for tests that support variable speeds, a list of packet numbers to lose and a number of packets to stop handling packets after. Finalise the introduction chapter. Produce the first draft of the preparation chapter.
\noindent \\ \noindent \\
Milestone: Mock connections and tests for the existing single transport. A draft of the preparation chapter. Milestone: Mock connections and tests for the existing single transport. A finalised introduction chapter. A draft of the preparation chapter.
\subsection*{11/01/2021 - 07/01/2021} \subsection*{11/01/2021 - 07/02/2021 (Weeks 14-17)}
Implement the load balancing between multiple connections for both servers. At this point, connection losses should be tested too. Implement the load balancing between multiple connections for both servers. At this point, connection losses should be tested too. The progress report is due soon after this work segment, so that should be completed in here.
The progress report is due soon after this work segment, so that should be completed in here.
\noindent \\ \noindent \\
Milestone: The Local Server and Remote Server are capable of balancing load between multiple connections. They can also suffer a network failure of all but one connection with minimal packet loss. The progress report should be prepared. Milestone: The Local Portal and Remote Portal are capable of balancing load between multiple connections. They can also suffer a network failure of all but one connection with minimal packet loss. The progress report should be prepared.
\subsection*{08/02/2021 - 21/02/2021} \subsection*{08/02/2021 - 21/02/2021 (Weeks 18-19)}
Implementation of a DHCP server for the Local Server. This should create a DHCP pool with a single address, that of the Remote IP. Finalise the drafted preparation chapter. Draft the implementation chapter. Produce a non-exhaustive list of graphs and tests that should be included in the evaluation section.
As well as code in this period, it is important to complete the preparation chapter, and complete a solid draft of the implementation chapter of the dissertation.
\noindent \\ \noindent \\
Milestone: The router behind the Local Server should automatically receive the Public IP of the Remote Server from DHCP. The dissertation should have a completed preparation chapter, and an acceptably drafted implementation chapter. Milestone: Completed preparation chapter. Drafted implementation chapter. A plan of data to gather to back up the evaluation section.
\subsection*{22/02/2021 - 21/03/2021} \subsection*{22/02/2021 - 21/03/2021 (Weeks 20-23)}
Complete dissertation. Finalise the implementation chapter. Gather the data required for graphs. Draft the evaluation chapter. Draft the conclusions chapter.
\noindent \\ \noindent \\
Milestone: Benchmarks and graphs for non-extended success criteria complete and added. Complete dissertation draft handed to DoS and supervisor for feedback. Milestone: Finalised implementation chapter. Benchmarks and graphs for non-extended success criteria complete and added. First complete dissertation draft handed to DoS and supervisor for feedback.
\subsection*{22/03/2021 - 25/04/2021} \subsection*{22/03/2021 - 25/04/2021 (Weeks 24-28)}
Flexible time: divide between re-drafting dissertation and adding additional extended success criteria features, with priority given to re-drafting the dissertation. Flexible time: divide between re-drafting dissertation and adding additional extended success criteria features, with priority given to re-drafting the dissertation.
\noindent \\ \noindent \\
Milestone: A finished dissertation and any extended success criteria that have been completed. Milestone: A finished dissertation and any extended success criteria that have been completed.
\subsection*{26/04/2021 - 09/05/2021} \subsection*{26/04/2021 - 09/05/2021 (Weeks 29-30)}
New additions freeze. Nothing new should be added to either the dissertation or code at this point. New additions freeze. Nothing new should be added to either the dissertation or code at this point.
\noindent \\ \noindent \\
Milestone: Bug fixes and polishing. Milestone: Bug fixes and polishing.
\subsection*{10/05/2021 - 14/05/2021} \subsection*{10/05/2021 - 14/05/2021 (Week 31)}
The project should already be submitted a week clear of the deadline, so this week has no planned activity. The project should already be submitted a week clear of the deadline, so this week has no planned activity.
\section*{Resources Required} \section*{Resources Required}
\begin{itemize} \begin{itemize}
\item Personal Computer (AMD R9 3950X, 16GB RAM) \item Personal Computer (AMD R9 3950X, 32GB RAM)
\item Personal Laptop (AMD i7-8550U, 16GB RAM) \item Personal Laptop (AMD i7-8550U, 16GB RAM)
\end{itemize} \end{itemize}