Skip to content

abestaev/ft_irc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

53 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ ft_irc - IRC Server Implementation

A fully compliant, non-blocking IRC server built in C++98

42 Project Language Protocol


πŸ“‹ Table of Contents


✨ Features

Core IRC Functionality

  • βœ… Full Authentication - Password-protected server with PASS/NICK/USER registration
  • βœ… Channel Management - Create, join, part channels with operator privileges
  • βœ… Private Messaging - User-to-user and channel messaging (PRIVMSG/NOTICE)
  • βœ… Channel Modes - Invite-only (+i), topic protection (+t), password (+k), user limit (+l), operator (+o)
  • βœ… User Modes - Invisible (+i), wallops (+w), restricted (+r), operator (+o/O)
  • βœ… Moderation Tools - KICK, INVITE, OPER, KILL commands
  • βœ… Discovery - WHO, WHOIS, LIST, NAMES commands

Technical Excellence

  • βœ… Non-blocking I/O - Single poll() call for all operations
  • βœ… RFC Compliant - Follows IRC protocol specifications (RFC 1459/2812)
  • βœ… Robust Parsing - Handles partial data, multiple line endings (CRLF/LF)
  • βœ… Output Buffering - Queued sends with POLLOUT management
  • βœ… Signal Handling - Graceful shutdown on SIGINT/SIGTERM
  • βœ… Colored Logging - ANSI-colored server logs for debugging

πŸ”§ Requirements

  • Compiler: g++ or clang++ with C++98 support
  • OS: Linux (tested on Ubuntu/Debian)
  • Build tool: make
  • Client: Any IRC client (WeeChat, irssi, HexChat, nc)

πŸ“¦ Installation

# Clone the repository
git clone <your-repo-url> ft_irc
cd ft_irc

# Build the project
make

# The binary 'ircserv' will be created in the root directory

Compilation Flags

-Wall -Wextra -Werror -std=c++98 -g3

πŸš€ Usage

Starting the Server

./ircserv <port> <password>

Example:

./ircserv 6667 mySecurePass123

Output:

[INFO] Starting IRC server on port 6667
[INFO] Password required for connection: mySecurePass123
[INFO] Listening on 0.0.0.0:6667
Press Ctrl+C to stop the server

Connecting with a Client

Using netcat (quick test)

nc 127.0.0.1 6667
PASS mySecurePass123
NICK alice
USER alice 0 * :Alice Wonderland
JOIN #general
PRIVMSG #general :Hello everyone!
QUIT :Goodbye

Using WeeChat

weechat
/server add local 127.0.0.1/6667 -password=mySecurePass123
/connect local
/nick alice
/join #general

Using irssi

irssi
/connect 127.0.0.1 6667 mySecurePass123 alice
/join #general

πŸ—οΈ Architecture

Single Poll() Loop

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Main Loop (Server::run)              β”‚
β”‚                                          β”‚
β”‚  while (!signal) {                       β”‚
β”‚      poll(_pfds, _nfds, 100ms);          β”‚ ← ONE poll() call
β”‚                                          β”‚
β”‚      if (POLLIN on listening socket)     β”‚
β”‚          β†’ accept_new_clients()          β”‚ (1 accept/cycle)
β”‚                                          β”‚
β”‚      if (POLLIN on client socket)        β”‚
β”‚          β†’ process_client_messages()     β”‚ (1 read/client)
β”‚                                          β”‚
β”‚      if (POLLOUT on client socket)       β”‚
β”‚          β†’ flush output buffers          β”‚ (1 send/client)
β”‚  }                                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

Client β†’ [recv] β†’ inbuf β†’ [parse] β†’ Command β†’ [process] β†’ outbuf β†’ [send] β†’ Client

Key Design Decisions

  1. Non-blocking I/O: All sockets use fcntl(fd, F_SETFL, O_NONBLOCK)
  2. Input Buffering: Accumulates partial data until complete line (\r\n or \n)
  3. Output Buffering: Queues messages, sends on POLLOUT readiness
  4. Single Poll: Exactly one poll() call per event loop iteration
  5. No errno loops: No EAGAIN checking to trigger re-reads (subject requirement)

πŸ“‘ Supported Commands

Authentication & Registration

Command Description Example
PASS Set connection password PASS mySecurePass123
NICK Set/change nickname NICK alice
USER Set username and realname USER alice 0 * :Alice W.
CAP Capability negotiation CAP LS

Channel Operations

Command Description Example
JOIN Join channel(s) JOIN #general,#random
PART Leave channel(s) PART #general :Goodbye
TOPIC View/set channel topic TOPIC #general :New topic
LIST List all channels LIST
NAMES List channel members NAMES #general

Messaging

Command Description Example
PRIVMSG Send message PRIVMSG #general :Hello!
NOTICE Send notice (no auto-reply) NOTICE alice :Info

Moderation & Admin

Command Description Example
KICK Remove user from channel KICK #general bob :Bad behavior
INVITE Invite user to channel INVITE alice #private
MODE Change channel/user modes MODE #general +it
OPER Gain operator privileges OPER admin pass
KILL Disconnect user (oper only) KILL bob :Abuse

Information

Command Description Example
WHO Get user info WHO #general
WHOIS Detailed user info WHOIS alice
PING Keep-alive check PING token
PONG Response to PING (automatic)

Other

Command Description Example
QUIT Disconnect QUIT :Bye
ERROR Server error message (server-sent)

πŸ§ͺ Testing

Manual Testing Scenarios

1. Basic Connection & Authentication

echo -e "PASS wrong\r\nQUIT\r\n" | nc 127.0.0.1 6667
# Expected: ERROR :Password incorrect

2. Multi-Client Chat

# Terminal 1
nc 127.0.0.1 6667
PASS mySecurePass123
NICK alice
USER alice 0 * :Alice
JOIN #test

# Terminal 2
nc 127.0.0.1 6667
PASS mySecurePass123
NICK bob
USER bob 0 * :Bob
JOIN #test
PRIVMSG #test :Hello alice!

3. Channel Modes

MODE #test +i          # Invite-only
MODE #test +t          # Topic protection
MODE #test +k secret   # Set password
MODE #test +l 10       # Max 10 users
MODE #test +o alice    # Give alice operator

4. Partial Data (Subject Requirement)

# Send command in fragments (simulating slow connection)
(printf "PA"; sleep 0.1; printf "SS pass"; sleep 0.1; printf "123\r\n") | nc 127.0.0.1 6667
# Expected: Server correctly assembles and processes "PASS pass123"

πŸ” Technical Details

Compliance with Subject Requirements

βœ… Non-blocking I/O

  • All sockets use O_NONBLOCK via fcntl(fd, F_SETFL, O_NONBLOCK)
  • No other fcntl() usage (F_GETFL forbidden by subject)

βœ… Single poll()

  • Exactly 1 poll() call in entire codebase (src/Server.cpp:110)
  • No select(), epoll(), or kqueue()
  • Verify with: grep -r "poll(" src/

βœ… poll() before I/O

  • Every accept() preceded by POLLIN check
  • Every read() preceded by POLLIN check
  • Every send() preceded by POLLOUT check
  • No errno checking for EAGAIN to trigger actions (forbidden by subject)

βœ… Partial Data Handling

  • Input buffer accumulates data until complete line
  • Supports both \r\n (CRLF) and \n (LF) line endings
  • Tested with fragmented input (see test_partial_data.sh)

Error Handling

  • Socket errors: Logged and client disconnected
  • Unknown commands: 421 ERR_UNKNOWNCOMMAND
  • Missing parameters: 461 ERR_NEEDMOREPARAMS
  • Privilege errors: 481/482 ERR_NOPRIVILEGES
  • Channel errors: 403/471/473/475 (No such channel, full, invite-only, bad key)

Logging System

Color-coded server logs for debugging:

  • πŸ”΅ [INFO] - Server startup/status (blue)
  • 🟒 [AUTH] - Authentication events (green)
  • 🟑 [CHANNEL] - Channel operations (yellow)
  • πŸ”΄ [ERROR] - Errors (red)
  • 🟣 [CMD] - Commands received (magenta)
  • πŸ”΅ [STATE] - Server state (blue)
  • 🟠 [CONNECT] - New connections (cyan)
  • 🟑 [DISCONNECT] - Client disconnections (yellow)

πŸ“ Project Structure

ft_irc/
β”œβ”€β”€ inc/                          # Header files
β”‚   β”œβ”€β”€ Channel.hpp              # Channel management
β”‚   β”œβ”€β”€ Client.hpp               # Client structure
β”‚   β”œβ”€β”€ Commands.hpp             # Command handler class
β”‚   β”œβ”€β”€ Message.hpp              # IRC message parser
β”‚   β”œβ”€β”€ Server.hpp               # Main server class
β”‚   β”œβ”€β”€ config.hpp               # Constants (MAX_CLIENTS, BUFFER_SIZE)
β”‚   β”œβ”€β”€ ft_irc.hpp               # Common includes
β”‚   └── utils.hpp                # Utility functions
β”‚
β”œβ”€β”€ src/                          # Source files
β”‚   β”œβ”€β”€ main.cpp                 # Entry point
β”‚   β”œβ”€β”€ Server.cpp               # Server implementation (poll loop)
β”‚   β”œβ”€β”€ Client.cpp               # Client methods
β”‚   β”œβ”€β”€ Channel.cpp              # Channel methods
β”‚   β”œβ”€β”€ Message.cpp              # IRC message parsing
β”‚   β”œβ”€β”€ Commands.cpp             # Command dispatcher
β”‚   β”œβ”€β”€ utils.cpp                # Helper functions
β”‚   β”‚
β”‚   └── commands/                # Individual command handlers
β”‚       β”œβ”€β”€ CAP.cpp              # Capability negotiation
β”‚       β”œβ”€β”€ PASS.cpp             # Password authentication
β”‚       β”œβ”€β”€ NICK.cpp             # Nickname management
β”‚       β”œβ”€β”€ USER.cpp             # User registration
β”‚       β”œβ”€β”€ JOIN.cpp             # Channel joining (multi-channel support)
β”‚       β”œβ”€β”€ PART.cpp             # Channel leaving (multi-channel support)
β”‚       β”œβ”€β”€ TOPIC.cpp            # Topic management
β”‚       β”œβ”€β”€ MODE.cpp             # Mode changes (channel & user)
β”‚       β”œβ”€β”€ PRIVMSG_NOTICE.cpp   # Messaging
β”‚       β”œβ”€β”€ INVITE_KICK.cpp      # Moderation
β”‚       β”œβ”€β”€ OPER.cpp             # Operator authentication
β”‚       β”œβ”€β”€ KILL.cpp             # Force disconnect
β”‚       β”œβ”€β”€ WHO_WHOIS.cpp        # User information
β”‚       β”œβ”€β”€ LIST_NAMES.cpp       # Channel listing
β”‚       β”œβ”€β”€ PING_PONG.cpp        # Keep-alive
β”‚       β”œβ”€β”€ QUIT.cpp             # Disconnect
β”‚       └── ERROR.cpp            # Error handling
β”‚
β”œβ”€β”€ Makefile                      # Build configuration

Key Classes

  • Server: Main event loop, socket management, poll() handling
  • Client: Client state (fd, nick, user, modes, buffers)
  • Channel: Channel state (name, topic, modes, users, operators)
  • Message: IRC message parser (command, params, trailing)
  • Commands: Command dispatcher and handlers

πŸ“Š Configuration

Edit inc/config.hpp to customize:

#define MAX_CLIENTS 100          // Maximum simultaneous clients
#define BUFFER_SIZE 4096         // Read buffer size

πŸ› Known Limitations

Intentional (Subject Constraints)

  • Single server (no server-to-server linking)
  • No SSL/TLS support
  • No services (NickServ, ChanServ)
  • Minimal capability negotiation (CAP)

🎯 Subject Compliance Checklist

Mandatory Part

  • ./ircserv <port> <password> usage
  • Non-blocking I/O on all operations
  • One single poll() (or equivalent)
  • poll() called before each accept/read/recv/write/send
  • No other fcntl() usage
  • No errno checks after I/O operations
  • TCP/IP (v4) sockets
  • Multiple clients without hanging
  • No forking
  • Partial data handling
  • Low bandwidth client support
  • Client-to-client communication
  • Authentication (password, nickname, username)
  • Channel operations (join, send/receive messages)
  • Forward messages to all channel clients
  • Distinguish operators from regular users
  • Operator-only commands implementation

Commands Implemented

  • PASS - Password authentication
  • NICK - Set nickname
  • USER - Set username
  • JOIN - Join channels
  • PART - Leave channels
  • PRIVMSG - Send messages
  • NOTICE - Send notices
  • KICK - Kick user (operator)
  • INVITE - Invite to channel (operator)
  • TOPIC - View/set topic (operator if +t)
  • MODE - Channel/user modes (operator)
  • PING/PONG - Keep-alive

Channel Modes

  • +i - Invite-only channel
  • +t - Topic restriction (operators only)
  • +k - Channel password
  • +o - Operator privileges
  • +l - User limit

πŸ“š Resources


About

Internet Relay Chat (IRC) is a text-based communication protocol on the Internet. It offers real-time messaging that can be either public or private. Users can exchange direct messages and join group channels.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors