Skip to content

mixsung/ircserv-modern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ircserv-modern

A modern C++17 IRC server, refactored from the 42 Seoul ft_irc project (originally written in C++98). Built with RAII, smart pointers, non‑blocking I/O, and a single poll() event loop.
Reference IRC client: irssi – the server is tested and works reliably with irssi.

Features

  • IRC protocol (RFC 1459 / 2812): PASS, NICK, USER, JOIN, PART, TOPIC, INVITE, KICK, MODE (+i/+t/+k/+l/+o), PRIVMSG, PING, QUIT
  • Non‑blocking I/O with a single poll() event loop
  • TCP Keep‑Alive and server‑side PING/PONG for dead connection detection
  • TCP_NODELAY for low‑latency messaging
  • Nickname index map for O(1) client lookup
  • Clean shutdown via MarkForClose + cleanup loop
  • Modern C++17: std::unique_ptr, final, noexcept, constexpr, enum class, std::string_view
Server Rules & Limits

Nickname rules:

  • Length: 1–9 characters
  • First character must be a letter
  • Allowed characters: letters, digits, and []{}_|\
  • Nickname must not already be in use on the server

Channel rules:

  • Channel names must start with # or &
  • Channel names are case‑insensitive
  • Maximum members per channel: limited by +l mode (if set)

Message rules:

  • IRC message maximum length: 512 characters (excluding \r\n)

Supported channel modes:

Mode Description
+i Invite‑only channel
+t Only operators can change the topic
+k Channel key (password) required to join
+l User limit (e.g., +l 10)
+o Give/take operator privileges

Connection limits:

  • Maximum simultaneous clients: 128
Known Limitations

This server is built to satisfy the mandatory requirements of the 42 Seoul ft_irc project.
The following features are intentionally not implemented:

  • Multiple channel targets in a single commandJOIN #a,#b, PART #a,#b, INVITE nick #a,#b, KICK #a,#b nick are not supported. Use one command per channel.
  • Server‑to‑server communication – not in scope (explicitly forbidden by the subject).
  • File transfer (DCC) – a bonus feature that was not implemented.
  • User mode changesMODE <nick> <flags> is not supported; only channel modes (i, t, k, o, l) are implemented.
  • Extended channel modes+b (ban mask), +e (exception), +I (invite exception) are not supported.
  • WHO command – irssi may send WHO queries, but the server does not respond to them.

These limitations are deliberate and reflect the scope of the original project.

Quick Start (Docker)

Docker is the recommended way to run the server – it guarantees a consistent environment across all platforms and requires no manual dependency setup. If you prefer to build natively, see the Build from Source section below.

  1. Build the image

    docker build -t my-irc-server .
  2. Run the server (background)

    docker run -d -p 6667:6667 --name irc-server my-irc-server

    NOTE: The default password is mypassword. To change it, either edit the CMD line in the Dockerfile (see the last line: CMD ["ircserv", "6667", "mypassword"]) or override it at runtime.

    docker run -d -p 6667:6667 --name irc-server my-irc-server ircserv 6667 yourpassword
  3. Check logs

    docker logs -f irc-server
  4. Now connect with any IRC client (irssi recommended):

    irssi -c 127.0.0.1 -p 6667 -w <password> -n <nickname>
    Replace <password> and <nickname> with the values you set (or the default mypassword).

We strongly recommend using irssi – this server was implemented with irssi as the reference client, so all commands and edge cases have been verified against it. Other clients may work, but irssi is guaranteed to behave as expected.

Build from Source

Requirements:

  • C++17 compiler (gcc, clang)
  • CMake 3.16+
  • POSIX system (macOS, Linux)
  1. Configure the build – generates build files for a Release (optimised)

    cmake -B build -DCMAKE_BUILD_TYPE=Release
  2. Compile the project – builds the ircserv executable inside the build/ directory.

    cmake --build build
  3. Start the server – replace and with your own values.

    ./build/ircserv <port> <password>

Usage

Recommended Client: irssi

irssi is the reference client used throughout development – all commands and edge cases have been verified against it, so we strongly recommend using irssi for the best experience.

Install irssi on your platform, then connect to the server:

macOS (Homebrew):

brew install irssi

Linux (Debian/Ubuntu):

sudo apt-get update && sudo apt-get install irssi

Windows (WSL)

# Install WSL and Ubuntu (one-time setup)
wsl --install

# Inside the Ubuntu terminal
sudo apt-get update && sudo apt-get install irssi

After installation, run irssi from the WSL terminal.

For other platforms or manual compilation, see the irssi downloads page.

Connect to the server:

irssi -c 127.0.0.1 -p 6667 -w <password> -n <nickname>

NOTE:
Nickname rules
- Length: 1–9 characters
- First character must be a letter
- Allowed characters: letters, digits, and []{}_|\
- Nickname must not already be in use on the server

Inside irssi:

/join #test
Hello, world!          # sends PRIVMSG to the channel
/msg othernick hello   # sends private message
/quit                  # graceful quit

netcat (for quick testing)

# macOS (CRLF translation)
nc -c 127.0.0.1 6667

# Linux
nc -C 127.0.0.1 6667

Type IRC commands manually:

PASS mypassword
NICK mynick
USER myuser 0 * :My Real Name
JOIN #hello
PRIVMSG #hello :hi
QUIT

Project Structure

include/         # Header files
source/          # Main server, client, channel, command parser
source/commands/ # Individual IRC command handlers
CMakeLists.txt   # Build configuration
Dockerfile       # Docker image definition

Configuration

All compile-time constants are defined in include/Constants.h:

namespace irc
{
    constexpr std::size_t MAX_CLIENTS = 128;
    constexpr std::size_t BUF_SIZE   = 1024;
    constexpr std::size_t MAX_TOKENS = 5;
    constexpr int         BACKLOG    = 128;
}

Testing

A minimal manual test session:

# Terminal 1: start server (Docker or native)
./build/ircserv 6667 mypass

# Terminal 2: irssi as Shiv
irssi -c 127.0.0.1 -p 6667 -w mypass -n Shiv
/join #chat

# Terminal 3: netcat as Roman
nc -c 127.0.0.1 6667
PASS mypass
NICK Roman
USER Roman 0 * :Roman
JOIN #chat
PRIVMSG #chat :Hello Shiv!

Roman's message should appear in Shiv's irssi window.

About

Modern IRC Server

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors