Skip to content

yoavnach/NetworksProject

Repository files navigation

NetworksProject

Overview

This project implements a custom networking environment that demonstrates how several core networking protocols work together in one complete system.

The project includes:

  • A DNS server with local cache and manual domain registration
  • A DHCP server that dynamically assigns IP addresses and network settings
  • An application server that serves content over HTTP/TCP and Reliable UDP (RUDP)
  • A GUI client built with PyQt6 + Qt WebEngine

The project is designed for learning and demonstration. It shows how a client can receive network configuration, resolve a domain name, connect to an application server, and load application content.


System Architecture

The components can work together like this:

  1. The DNS server translates domain names such as my-app.home into IP addresses.
  2. The DHCP server can provide the client with an IP address, DNS server address, and lease information.
  3. The application server serves pages and media over TCP and RUDP.
  4. The GUI client connects to the server and displays the application.

High-level flow:

GUI Client
   |
   | HTTP / RUDP
   v
Application Server
   |
   | registers domain in DNS
   v
DNS Server
   |
   | if not in cache
   v
External DNS (Google 8.8.8.8)

Main Components

1. DNS Server

The DNS server resolves domain names to IP addresses.

What it does

  • Listens for DNS queries on UDP port 53
  • Maintains a local cache named DNS_RECORDS
  • If a domain exists in the cache, returns the cached IP address
  • If a domain does not exist in the cache, forwards the query to Google DNS (8.8.8.8)
  • Stores external results in the cache for a limited time
  • Supports manual registration of domain names through an admin UDP port (5354)

How the DNS server works in this project

The DNS server code contains these main parts:

  • encode_dns_name(domain) converts a regular domain string into DNS wire format
  • decode_dns_name(data, offset) decodes a domain name from a DNS packet
  • build_dns_query(domain) builds a DNS query packet for an external DNS server
  • get_ip(response) extracts the first IPv4 address from a DNS response
  • query_external_dns(domain) asks Google DNS for a domain if it is not cached locally
  • build_dns_response(data, ip, domain) creates a DNS response packet to send back to the client
  • handle_client(sock, data, addr) processes one incoming DNS request
  • admin_listener_thread() listens for manual registration commands

Manual domain registration

The DNS server supports admin commands over UDP on port 5354.

Supported command:

REGISTER <domain> <ip>

Example:

REGISTER my-app.home 192.168.1.50

This adds a permanent entry to the local DNS cache.

Important note about host binding

The DNS server supports a --host argument:

python dns.py --host 127.0.0.1

or:

python dns.py --host 0.0.0.0
  • 127.0.0.1 means the DNS server is only accessible from the same computer
  • 0.0.0.0 means the DNS server listens on all local network interfaces

2. DHCP Server

The DHCP server dynamically assigns IP addresses and network settings to clients.

What it does

  • Allocates an IP from a configured address pool
  • Sends the DNS server address to the client
  • Sends lease duration information
  • Tracks used and available addresses

Why it exists in this project

It demonstrates how a client can receive automatic network configuration instead of hardcoding IP settings manually.


3. Application Server

The application server provides the actual web application content.

Features

  • HTTP communication over TCP
  • Reliable UDP communication over RUDP
  • Controller-based routing
  • Automatic DNS registration using the DNS admin port
  • Serving of HTML, CSS, JavaScript, and media files

Controllers used by the server

Examples:

  • HomeController
  • WatchController
  • MediaController
  • JsController
  • CssController

What happens when the server starts

When the application server starts:

  1. It optionally registers its domain in the DNS server
  2. It starts the TCP server
  3. It starts the RUDP server
  4. It waits for client connections

4. Reliable UDP (RUDP)

UDP alone does not guarantee delivery, order, or retransmission.

RUDP adds reliability on top of UDP.

Features implemented in the project

  • Handshake
  • Acknowledgements (ACK)
  • Retransmissions on timeout
  • Sliding window
  • Basic congestion-style control with window_size and ssthresh
  • Segmentation of large responses into smaller packets

This allows the server to send data more reliably while still using UDP.


5. GUI Client

The client is built with:

  • PyQt6
  • PyQt6-WebEngine

What it does

  • Opens the graphical interface
  • Connects to the application server
  • Displays HTML/CSS/JS content
  • Allows interaction with the project like a mini browser

Why Qt WebEngine is required

Because the GUI needs to render web content inside the desktop application.


Project Structure

A typical structure for the repository looks like this:

NetworksProject/
│
├── server.py
├── dns.py
├── client_dns.py
├── dhcp_server.py
├── start_dhcp.py
├── requirements.txt
│
├── Client/
│   ├── Client_GUI.py
│   ├── client_TCP.py
│   ├── client_rudp.py
│   ├── Client_DHCP.py
│
├── Controller/
│   ├── HomeController.py
│   ├── WatchController.py
│   ├── MediaController.py
│   ├── JsController.py
│   └── CssController.py
│
├── Model/
├── View/
└── RUDP/

Requirements

General requirements

You need:

  • Python 3.10+
  • pip
  • git (optional, but recommended)

Supported operating systems:

  • Windows
  • Linux (Ubuntu / Debian / WSL)

Installation

Windows Installation

1. Install Python

Download Python from:

https://www.python.org/downloads/

During installation, enable:

Add Python to PATH

2. Download the project

Clone the repository:

git clone https://github.com/yoavnach/NetworksProject.git
cd NetworksProject

Or download the project as ZIP and extract it.

3. Create a virtual environment

python -m venv venv

Activate it.

PowerShell:

venv\Scripts\Activate.ps1

CMD:

venv\Scripts\activate

4. Install dependencies

pip install -r requirements.txt

Linux Installation (Ubuntu / Debian / WSL)

1. Install required system packages

sudo apt update
sudo apt install -y \
  python3 python3-venv python3-pip git \
  libnss3 libxkbfile1 libxkbcommon-x11-0 libglu1-mesa libglib2.0-0 \
  libasound2t64 libgtk-3-0 libgbm1 libxss1 libatk-bridge2.0-0 \
  libxcb-cursor0 libxcb-shape0 libxcb-xfixes0 libxcb-icccm4 \
  libxcb-image0 libxcb-keysyms1 libxcb-render-util0 \
  libxcb-xinerama0 libxcb-xinput0

These are mainly required for Qt WebEngine.

2. Create virtual environment

python3 -m venv --copies venv

Activate it:

source venv/bin/activate

3. Install Python dependencies

pip install -r requirements.txt

4. Optional: allow raw/network privileges for DHCP

If your DHCP code uses raw sockets or privileged ports, you may need:

sudo setcap cap_net_raw,cap_net_bind_service+ep ./venv/bin/python3

Verify:

getcap ./venv/bin/python3

Running Modes

The project can run in two main modes.

Mode 1: Localhost Mode

In this mode, all services listen only on the local machine.

Use:

127.0.0.1

Best for

  • Development
  • Debugging
  • Running everything on one computer

Advantage

Very easy to test.

Limitation

Other devices on the network cannot connect.


Mode 2: Network Mode

In this mode, services listen on all available network interfaces.

Use:

0.0.0.0

Best for

  • Testing across multiple devices
  • LAN demonstration
  • Running client and server on different machines

Advantage

Other computers on the same network can connect using the host machine IP address.

Limitation

You may need firewall changes and correct network configuration.


How to Run the Full System

A. Localhost Run (same machine)

This is the easiest way to run the project.

Step 1: Start the DNS server

Windows or Linux:

python dns.py --host 127.0.0.1

Expected output:

DNS Server is running on 127.0.0.1:53...
Waiting for requests...

Step 2: Start the DHCP server (optional)

python DHCP/dhcp_main.py --dns 127.0.0.1

If your DHCP server script is named differently, use that file instead.

Example output:

Server is running on port 6767. Press Ctrl+C to stop.

Step 3: Start the application server

python server.py --host 127.0.0.1 --tcp_port 80 --udp_port 8080 --dns 127.0.0.1 --domain my-app.home

What this does:

  • Starts the TCP server on port 80
  • Starts the RUDP server on port 8080
  • Registers my-app.home in the DNS server at 127.0.0.1

Expected output includes something like:

[server] listening on 127.0.0.1:80
[server] RUDP listening on 127.0.0.1:8080

Step 4: Start the GUI client

Windows:

python -m Client.Client_GUI

Linux:

QT_QPA_PLATFORM=xcb QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu" python3 -m Client.Client_GUI

This opens the graphical client.


B. Network Run (LAN / 0.0.0.0)

Use this mode when the server should accept connections from other machines on the same network.

Step 1: Start the DNS server on all interfaces

python dns.py --host 0.0.0.0

This makes the DNS server listen on all local network interfaces.

Step 2: Start the DHCP server

python DHCP/dhcp_main.py --dns <DNS_SERVER_IP>

Replace <DNS_SERVER_IP> with the real IP of the machine running dns.py.

The DHCP server typically detects the local subnet and prepares a dynamic range.

Step 3: Start the application server in network mode

python server.py --host 0.0.0.0 --tcp_port 80 --udp_port 8080 --dns <DNS_SERVER_IP> --domain my-app.home

Replace <DNS_SERVER_IP> with the real IP of the machine running dns.py.

Example:

python server.py --host 0.0.0.0 --tcp_port 80 --udp_port 8080 --dns 192.168.1.20 --domain my-app.home

What happens here:

  • The TCP server listens on all interfaces
  • The RUDP server listens on all interfaces
  • The application server detects its real local IP and registers that IP in the DNS server

Step 4: Start the GUI client

On the client machine:

Windows:

python -m Client.Client_GUI

Linux:

QT_QPA_PLATFORM=xcb QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu" python3 -m Client.Client_GUI

Make sure the client points to the correct DNS / server settings if they are configurable in your project.


Running Individual Components

Run only the DNS server

Local only:

python dns.py --host 127.0.0.1

LAN:

python dns.py --host 0.0.0.0

What it means

  • 127.0.0.1 → same computer only
  • 0.0.0.0 → all interfaces

Important note about port 53

Port 53 is a privileged / standard DNS port.

  • On Windows, you may need to run as Administrator
  • On Linux, you may need sudo or extra privileges

Example on Linux:

sudo python3 dns.py --host 0.0.0.0

If port 53 is already occupied by another DNS service, stop that service or change the port in code.


Run only the DHCP server

python DHCP/dhcp_main.py

or on Linux:

python3 DHCP/dhcp_main.py

If your OS blocks raw sockets or low ports, run with suitable privileges.


Run only the application server

Localhost:

python server.py --host 127.0.0.1 --tcp_port 80 --udp_port 8080 --dns 127.0.0.1 --domain my-app.home

LAN:

python server.py --host 0.0.0.0 --tcp_port 80 --udp_port 8080 --dns 192.168.1.20 --domain my-app.home

Explanation of arguments

  • --host → which interface to bind to
  • --tcp_port → TCP / HTTP port
  • --udp_port → RUDP port
  • --dns → IP address of the DNS server admin/register target
  • --domain → domain name to register for this server

Run only the GUI client

Windows:

python -m Client.Client_GUI

Linux:

QT_QPA_PLATFORM=xcb QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu" python3 -m Client.Client_GUI

Recommended Startup Order

To run the full environment, use this order:

  1. Start the DNS server
  2. Start the DHCP server (if used)
  3. Start the application server
  4. Start the GUI client

This ensures that DNS and network configuration are already available when the application server and client start.


Example Scenarios

Scenario 1: Everything on one computer

Use:

  • DNS → 127.0.0.1
  • Application server → 127.0.0.1
  • Client → same computer

Commands:

python dns.py --host 127.0.0.1
python DHCP/dhcp_main.py --dns 127.0.0.1
python server.py --host 127.0.0.1 --tcp_port 80 --udp_port 8080 --dns 127.0.0.1 --domain my-app.home
python -m Client.Client_GUI

Scenario 2: Server on one computer, client on another

On server machine:

python dns.py --host 0.0.0.0
python DHCP/dhcp_main.py --dns 192.168.1.20
python server.py --host 0.0.0.0 --tcp_port 80 --udp_port 8080 --dns 192.168.1.20 --domain my-app.home

On client machine:

python -m Client.Client_GUI

Replace 192.168.1.20 with the actual server machine IP.


Troubleshooting

Port already in use

Windows

netstat -ano | findstr :53
netstat -ano | findstr :80

Linux

sudo lsof -i :53
sudo lsof -i :80

If a port is already in use, stop the existing service or change the port in your code.


DNS server permission problems

Port 53 may require elevated permissions.

Windows

Run terminal as Administrator.

Linux

Use sudo if needed:

sudo python3 dns.py --host 0.0.0.0

DHCP permission denied on Linux

If your DHCP implementation uses raw sockets or restricted networking features, run:

sudo setcap cap_net_raw,cap_net_bind_service+ep ./venv/bin/python3

Qt WebEngine problems on Linux

Install the required Qt / XCB dependencies from the installation section.

For debugging missing libraries:

ldd ./venv/lib/python3.12/site-packages/PyQt6/Qt6/plugins/platforms/libqxcb.so | grep "not found"

GPU / rendering issues on Linux

Run the GUI with:

QT_QPA_PLATFORM=xcb QTWEBENGINE_CHROMIUM_FLAGS="--disable-gpu" python3 -m Client.Client_GUI

External DNS resolution fails

If a domain is not in the local cache, the DNS server forwards the request to 8.8.8.8.

If that fails:

  • check internet connection
  • check firewall rules
  • verify that outbound UDP is allowed

Summary

This project demonstrates how several networking components can work together in a realistic environment.

It includes:

  • DNS resolution
  • DHCP configuration
  • TCP-based HTTP serving
  • Reliable UDP transport
  • A GUI application client

The system can run either:

  • locally on one machine using 127.0.0.1
  • across a local network using 0.0.0.0

This makes it useful both for development and for network demonstrations.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors