第1章:IRC入門
はじめに
IRC(Internet Relay Chat)は、1988年に誕生したリアルタイムテキスト通信プロトコルです。ft_ircでは、RFC 1459に準拠したIRCサーバーをC++で実装します。
---
1. IRCの歴史
1.1 Jarkko Oikarinenの発明
1988年夏、フィンランド:
Jarkko Oikarinen(通称WiZ)は、
フィンランドのオウル大学で働いていました。
彼は既存のMUTプログラム(チャットシステム)の
代替を開発することにしました。
最初のIRCサーバー:
- ホスト: tolsun.oulu.fi
- ポート: 6667(今日でも標準)
- 1988年8月運用開始
1.2 IRCの発展
年表:
1988: 最初のIRCサーバー(フィンランド)
1989: IRCが世界に広がり始める
1991: 湾岸戦争中、IRCでリアルタイムニュース
1993: EFnet(最初の大規模IRCネットワーク)分裂
1996: RFC 1459「Internet Relay Chat Protocol」
2000: RFC 2810-2813(IRCプロトコルの更新)
2003: IRCピーク時(100万以上の同時接続)
現在:
- Liberaチャット(Freenodeの後継)
- OFTCなどのオープンソースコミュニティ
1.3 IRCの特徴
IRCの設計思想:
1. 分散型: 複数サーバーがネットワークを形成
2. テキストベース: シンプルなプロトコル
3. リアルタイム: 低遅延通信
4. チャンネル: グループ会話
5. プライベートメッセージ: 1対1通信
+--------+ +--------+
|Server A|-----|Server B|
+--------+ +--------+
/ \ |
+---+ +---+ +---+
|C1 | |C2 | |C3 |
+---+ +---+ +---+
Clients
---
2. IRCの基本概念
2.1 ネットワーク構造
IRCネットワーク:
+--------+ +--------+
|Server 1|-----------|Server 2|
+--------+ +--------+
| |
+--------+ +--------+
|Server 3| |Server 4|
+--------+ +--------+
サーバー間:
- スパニングツリー構造
- ループなし(1つのパス)
ft_ircでは:
- 単一サーバーのみ実装
- サーバー間通信は不要
2.2 ユーザー識別
ニックネーム(Nickname):
- ユーザーの表示名
- ネットワーク全体で一意
- 変更可能
ユーザー名(Username):
- 接続時に設定
- 変更不可
ホストマスク:
nick!user@host
例: Alice!alice@192.168.1.100
完全識別:
:Alice!alice@192.168.1.100 PRIVMSG #channel :Hello
2.3 チャンネル
チャンネルの種類:
#channel - 通常チャンネル(最も一般的)
&channel - ローカルチャンネル(サーバー内のみ)
チャンネル名:
- #で始まる
- 大文字小文字を区別しない
- スペース、カンマ、^G(ASCII 7)を含まない
- 最大200文字
例:
#general
#42tokyo
#programming-help
---
3. プロジェクト概要
3.1 必須要件
ft_ircの要件:
1. C++98で実装
2. poll()(または同等)を使用
3. 非ブロッキングI/O
4. 1つのpoll()で全I/Oを処理
5. fork()禁止
対応すべきコマンド:
- PASS(パスワード認証)
- NICK(ニックネーム設定)
- USER(ユーザー登録)
- JOIN(チャンネル参加)
- PART(チャンネル退出)
- PRIVMSG(メッセージ送信)
- KICK(ユーザー追放)
- INVITE(招待)
- TOPIC(トピック設定)
- MODE(モード設定)
3.2 クラス設計
+----------+
| Server |
+----------+
|
+---> std::map<int, Client*> clients
|
+---> std::map<std::string, Channel*> channels
|
+---> poll() loop
+----------+ +----------+
| Client |-------->| Channel |
+----------+ +----------+
- fd - name
- nickname - topic
- username - members
- hostname - operators
- registered - modes
- sendBuffer - inviteList
- recvBuffer
3.3 ディレクトリ構造
ft_irc/
├── Makefile
├── includes/
│ ├── Server.hpp
│ ├── Client.hpp
│ ├── Channel.hpp
│ ├── Command.hpp
│ └── Utils.hpp
├── srcs/
│ ├── main.cpp
│ ├── Server.cpp
│ ├── Client.cpp
│ ├── Channel.cpp
│ ├── commands/
│ │ ├── Pass.cpp
│ │ ├── Nick.cpp
│ │ ├── User.cpp
│ │ ├── Join.cpp
│ │ ├── Part.cpp
│ │ ├── Privmsg.cpp
│ │ ├── Kick.cpp
│ │ ├── Invite.cpp
│ │ ├── Topic.cpp
│ │ └── Mode.cpp
│ └── Utils.cpp
└── conf/
└── default.conf(オプション)
---
4. 起動とテスト
4.1 起動方法
# コンパイル
make
# 起動
./ircserv <port> <password>
./ircserv 6667 secretpass
# ポート: 1024-65535
# パスワード: 接続時に必要
4.2 テスト用IRCクライアント
# ncでテスト
nc localhost 6667
# 手動でコマンド送信
PASS secretpass
NICK Alice
USER alice 0 * :Alice Smith
JOIN #test
# irssi(CLI IRCクライアント)
irssi
/connect localhost 6667 secretpass
# WeeChat
weechat
/server add local localhost/6667 -password=secretpass
/connect local
# HexChat(GUI)
- サーバー設定でlocalhost:6667を追加
4.3 デバッグ方法
# 接続状態の確認
netstat -an | grep 6667
lsof -i :6667
# 通信内容の確認(別ターミナル)
tcpdump -i lo0 port 6667 -A
# Wiresharkでパケットキャプチャ
# IRCプロトコルのフィルタ: irc
---
5. プロトコルの基本
5.1 メッセージ形式
IRCメッセージ:
[:<prefix>] <command> [<params>...] [:<trailing>]\r\n
例:
PASS secretpass\r\n
NICK Alice\r\n
USER alice 0 * :Alice Smith\r\n
:Alice!alice@host PRIVMSG #channel :Hello, World!\r\n
:irc.server.net 001 Alice :Welcome to IRC\r\n
最大長: 512バイト(\r\n含む)
5.2 数値リプライ
成功/情報:
001 RPL_WELCOME - 接続成功
002 RPL_YOURHOST - サーバー情報
003 RPL_CREATED - サーバー作成日
331 RPL_NOTOPIC - トピックなし
332 RPL_TOPIC - トピック
353 RPL_NAMREPLY - チャンネルメンバー
366 RPL_ENDOFNAMES - メンバーリスト終了
エラー:
401 ERR_NOSUCHNICK - ニックが存在しない
403 ERR_NOSUCHCHANNEL - チャンネルが存在しない
433 ERR_NICKNAMEINUSE - ニックネーム使用中
461 ERR_NEEDMOREPARAMS - パラメータ不足
464 ERR_PASSWDMISMATCH - パスワード不一致
---
6. 実装の流れ
6.1 ステップバイステップ
Phase 1: 基盤
├── サーバーソケット作成
├── poll()によるイベントループ
├── クライアント接続/切断処理
└── 基本的なメッセージ受信
Phase 2: 認証
├── PASS コマンド
├── NICK コマンド
├── USER コマンド
└── 接続完了処理
Phase 3: チャンネル基本
├── JOIN コマンド
├── PART コマンド
├── PRIVMSG コマンド(チャンネル向け)
└── PRIVMSG コマンド(プライベート)
Phase 4: チャンネル管理
├── KICK コマンド
├── INVITE コマンド
├── TOPIC コマンド
└── MODE コマンド
Phase 5: 仕上げ
├── エラーハンドリング
├── 切断処理
└── テスト
6.2 参照クライアント
推奨クライアント:
1. irssi(軽量、CLIベース)
2. WeeChat(高機能、CLIベース)
3. HexChat(GUIベース)
テスト手順:
1. クライアントで接続
2. ニックネーム/ユーザー名設定
3. チャンネル参加
4. メッセージ送受信
5. オペレータコマンドテスト
---
まとめ
本章で学んだこと:
- IRCの歴史: Jarkko Oikarinenの発明
- 基本概念: ネットワーク、ユーザー、チャンネル
- プロジェクト構造: クラス設計、ディレクトリ
- 起動方法: 引数、テストクライアント
- プロトコル基礎: メッセージ形式、リプライコード
- 実装の流れ: フェーズごとの進め方
次章では、IRCプロトコルの詳細を学びます。