A high-performance, multi-threaded firewall simulation built in C using the POSIX threads (pthreads) API. This project transforms a serial packet-filtering program into a highly concurrent one, demonstrating advanced parallel programming concepts and synchronization techniques.
The core of the project is a producer-consumer architecture where a single producer thread simulates the arrival of network packets, and a pool of consumer threads processes them in parallel.
- Concurrent Packet Processing: Leverages multi-threading to significantly speed up packet filtering compared to a serial approach.
- Thread-Safe Ring Buffer: Implements a custom circular buffer for efficient, non-blocking communication between the producer and consumer threads.
- Advanced Synchronization: Utilizes
pthreadsynchronization primitives, including mutexes and condition variables, to prevent race conditions and ensure data integrity without resorting to inefficient busy-waiting. - Ordered Logging: A key challenge solved in this project is the generation of a perfectly ordered log file. Despite packets being processed in a non-deterministic order by multiple threads, the final log is written sequentially based on the packet's original timestamp. This is achieved through careful synchronization, ensuring the output reflects the order of packet arrival.
- Packet Production: The main thread acts as the producer. In
producer.c, thepublish_datafunction reads simulated packet data from an input file. It then callsring_buffer_enqueue()to place each packet into the shared ring buffer. Once all packets are published, it callsring_buffer_stop()to signal consumers that no more data will be produced. - Thread-Safe Ring Buffer: The
so_ring_buffer_tstruct inring_buffer.cis the central data structure. Its thread-safety is achieved using a combination of apthread_mutex_tand two POSIX semaphores (sem_t):fill_cnt: Counts the number of items in the buffer. Consumers wait on this semaphore, blocking withsem_wait()until it's greater than zero.empty_cnt: Counts the number of empty slots. The producer waits on this, blocking if the buffer is full.- A
pthread_mutex_tprotects the critical sections where the buffer's internal state (read_pos,write_pos,len) is modified.
- Parallel Consumption: In
consumer.c,create_consumersspawns a pool of consumer threads. Eachconsumer_threadruns an infinite loop callingring_buffer_dequeue(), which blocks until a packet is available. The dequeue function returns a unique, sequential ID for each packet. When the producer signals a stop and the buffer is empty,ring_buffer_dequeue()returns -1, causing the consumer threads to exit their loops and terminate cleanly. - Filtering Logic: After dequeuing a packet, each consumer thread calls
process_packet()to determine the firewall action (PASSorDROP) andpacket_hash()to compute its hash, preparing it for logging. - Synchronized Logging: To ensure logs are written in the correct order despite non-deterministic processing, a sophisticated synchronization mechanism is used in
consumer.c:- A global
atomic_ulong g_next_seq_to_writetracks the sequence number of the next packet that should be logged. - A shared
pthread_mutex_tandpthread_cond_tare used to coordinate the threads. - After processing a packet, a consumer acquires the lock and enters a
whileloop, waiting on the condition variable (pthread_cond_wait) until its packet's sequence number matchesg_next_seq_to_write. - Once it's its turn, the thread writes to the log file, atomically increments
g_next_seq_to_writeusingatomic_fetch_add, and callspthread_cond_broadcast()to wake up other waiting threads so they can re-check the condition. This ensures strict, ordered logging without sacrificing parallel processing.
- A global
To build the serial and parallel firewall binaries, navigate to the src/ directory and run make.
cd src/
makeYou can run the parallel firewall with a specified input file, output file, and the number of consumer threads.
# Example: Run with 4 consumer threads
./firewall <input_file> <output_file> 4This project was originally developed as a university assignment focused on operating systems and concurrent programming. The repository includes the original tests and grading scripts for validation.