この文章にはInternet communityのためのExperimental Protocolを定義し、改善のための意見と提案が寄せられています。 このプロトコルと標準化の状況については"IAB Official Protocol Standards"の最新版を参照して下さい。 この文章の配布は自由に行ってかまいません。
<訳者注:>これは原文の取り扱いです。日本語訳についてはセクション13.2 「日本語訳について」に準じます。 また、IRCプロトコルの定義はあくまで原文であることを断っておきます。
最初にBBS上のユーザ間のチャットの方法として使われ初めてから4年間以上にわたって、IRCプロトコルは開発が進められています。 現在、このプロトコルはサーバ/クライアント方式で世界中のネットワークをカバーしています。そして、ネットワークの成長に伴って、プロトコルも改善されてきています。 過去2年間、主要なIRCネットワークを利用するユーザの数は10倍にも膨れ上がっています。 IRCプロトコルはテキストベースのプロトコルで、クライアントはサーバとソケットでつなぐシンプルなプログラムです。
IRC(=Internet Relay Chat)プロトコルはテキストベースで会話をするプロトコルとして、何年もに渡ってその設計が改良されてきています。 このドキュメントには現在のIRCプロトコルが述べられています。
IRCプロトコルはTCP/IPネットワークプロトコルを使用したシステム上で開発されましたが、これは必要条件ではなく、この動作はTCP/IPプロトコルの範囲に限定するものではありません。
IRCは遠隔的会話システムです。そして、これは(クライアント/サーバモデルのため)多くの機種で動作します。 典型的な構成としては、クライアント(や他のサーバ)の接続点の中心として一つのプロセス(サーバ)を配置します。必要なメッセージの配信、多重送信等の機能をサーバが提供します。
サーバがIRCのバックボーンを形成しています。サーバは、クライアントが互いに接続して会話をしたり、他のサーバとの接続して会話をする接続点を提供し、IRCネットワークを形成しています。 IRCサーバのとりうるネットワーク形態は伸縮自在な木構造のみです。(Fig.1を見よ)あるサーバから見て、それ以外のネットワークの中心ノードとして働くように、各々のサーバを配置します。
[Server 15] [Server 13] [Server 14] | | | [Server 11]----[Server 1]-| [Server 12]---------| | | | |---------[Server 2] |--[Server 3]---------| | | | [Server 5] |-[Server 4]-| [Server 6] | | | | [Server 7]--| [Server 8] |--[Server 9] [Server 10] : [etc.][Fig.1 IRCネットワークの形式]
一つのサーバに接続しているクライアントは他のサーバに接続してはなりません。 各クライアントは他のクライアントから最長9文字のニックネームによって認識されます。 ニックネームにどの文字が使えてどの文字が使えないかはプロトコルの文法規約を参照して下さい。
ニックネームに加えて次に挙げる全クライアントの情報を、すべてのサーバは保持していなくてはなりません:
適切な状態にIRCネットワークを保つため、クライアントの特別な形態であるIRCオペレータ(IRC operator)にネットワーク上で高レベルな保守機能を使用することを許可しています。 オペレータに与えられた権限が「危険と」考えることもできますが、それでもなおIRCオペレータは必要とされます。 長期間に渡って粗悪なネットワークルーティング(network routing)が使われることを防ぐために、必要に応じて接続を切ったり、つなぎ直したりするネットワークの根幹にかかわる操作をIRCオペレータは行うことができます。 プロトコルでは、この必要性を認めているので、IRCオペレータのみにこのような機能を使用する権限を認めています。
セクション4.1.7(SQUITメッセージ)及びセクション4.3.5(CONNECTメッセージ)を参照のこと
まだ多くの議論の余地があるIRCオペレータの権限に、「強制的に」ネットワーク接続からクライアントを排除する能力が挙げられます。オペレータはどんなクライアント-サーバ間の接続でも閉じることができます。 乱用すると破壊的になり、悩みのタネになってしまうので、この問題に対する正当な理由はデリケートです。(IRCオペレータはこのような一般クライアントを追放することができます。) このような行動のより詳細については、セクション4.6.1(KILLメッセージ)を参照のこと
チャンネルとは、一つ以上のクライアントから構成された、ある名付けられたグループをいいます。その「チャンネル」に宛られた全てのメッセージはそれを構成するクライアントに送信されます。 チャンネルは最初のクライアントがJOIN(参加)したときに暗黙のうちに作り出され、そして最後のクライアントが抜けた時に消滅します。 チャンネルが存在する間、クライアントはチャンネルの名前を使って、チャンネルを参照することができます。
チャンネルの名前は最長200文字までの文字列です。(これは'&'または'#'の文字で始まります) 先頭の文字が'&'か'#'であることが必要な条件であることを除くと、 スペース(' ')、C-g(^G ASCIIコードで7)とコンマ(',' これはリストのアイテムのセパレータとしてプロトコルが使用します)を含まないということだけが、チャンネル名に対する制約となります。
2種類のチャンネルがこのプロトコルで認められています。 一つは'#'ではじまるチャンネルでIRCネットワークに接続するすべてのサーバに対して公開されているチャンネルです。 この種のチャンネルの第一の特徴ははチャンネルにJOINしているサーバ上のクライアントが一つでもあれば、IRCネットワーク上に存在するということです。 これらは'&'の文字で始まるものとは区別されます。 これら2種類のチャンネル上で利用できる種々のチャンネルモードで個々のチャンネルの性質を変更することができます。 <訳者注:>&ではじまるチャンネルはサーバにローカルなチャンネルです。(つまり同じサーバにつないでるクライアントからしか見えない)
このメッセージの詳細はセクション 4.2.3(MODEメッセージ)を参照のこと
新しいチャンネルを作るもしくは現存のチャンネルに加わるには、クライアントはチャンネルにJOINすることが必要です。 もしチャンネルにJOINするよりも前にチャンネルが存在していなければ、チャンネルが作られ、そして作ったクライアントがチャンネルオペレータになります。 チャンネルがすでに存在していた場合、そのチャンネルにJOINする要求が認められるかどうかは、その時のチャンネルのチャンネルモードによります。 例えば、チャンネルモードが"invite-only"(mode +i)ならば、"INVITE(招待)"されている時だけJOINできます。
クライアントは同時に複数のチャンネルに参加できます。しかし、初心者からベテランまで十分な数として、10チャンネルまでに制限されています。
この点のより詳細はセクション8.13を参照のこと。
2つのサーバ間が分断され、IRCネットワークの接続が切れた場合、双方が、まだ接続されているサーバ内でチャンネルを再構成します。ひょっとすると分断されたどちらか一方の側では消滅するかもしれません。 分断が回復したとき、接続したサーバは互いに、それぞれのチャンネルとそのチャンネルモードをアナウンスします。 チャンネルが双方で存在していた場合、JOINとMODEは新たに接続した双方のチャンネルにどのクライアントがいてどのようなモードなのか整合するように包括的な方法で解決されます。
権限を与えられたチャンネル上のチャンネルオペレータ("chop"や"chanop"とも呼ばれています。※日本では「なると持ち」と呼ばれています)がそのチャンネルを「所有」するとみなされます。 チャンネルオペレータのこの地位を認めて、チャンネルの管理と健全性を保つための権限をチャンネルオペレータは持っています。 チャンネルオペレータは、チャンネルの所有者なので、チャンネルオペレータに行動の理由を問うことはできません。もし仮にチャンネルオペレータの行動が一般社会常識に反したり、口汚くてもです。この時はIRCオペレータに仲裁するように頼むか、あるいはユーザが直ちに去り、問題のチャンネルオペレータの所有しているチャンネルから他の場所へ行き、自分自身でチャンネルを作るのがよいでしょう。
チャンネルオペレータのみが使用できるメッセージは以下のものです:
KICK - クライアントをチャンネルから追放します MODE - チャンネルモードを変更します INVITE - "invite-only"(mode +i)のチャンネルにクライアントを招待します TOPIC - (mode +t)のときにチャンネルを変更します
チャンネルに参加しているときに(NAMES,WHO,WHOISメッセージのリプライとして表示される)ニックネームのそばの'@'記号でチャンネルオペレータは識別できます。 (※'@'記号がラーメンなどに浮いている「なると」に似ている事が、日本ではチャンネルオペレータの事を「なると持ち」という由来です。)
ここに記述されているプロトコルはサーバ-サーバ間、クライアント-サーバ間の接続の両方共で使用されています。 しかし、サーバの接続に対する制限よりクライアントの接続に対する制限の方が厳しくなっています。クライアントの接続は信頼性がないとみなさているからです。
具体的な文字セットの仕様は定められていません。 1オクテット(=8 bit)のコードのセットをプロトコルではベースとしています。 このオクテットをいくつかまとめたものから、各メッセージは成り立っています。オクテットの値のうちいくつかはデリミタとして働くコントロールコードに使われています。
8ビットプロトコルであることは問題になりません。デリミタとキーワードは大抵のUSASCIIターミナルやtelnet接続のプロトコルのようなものだからです。 スカンジナビア語がIRCの起源なので、文字'{}|'はそれぞれ文字'[]\'の小文字に当たるものとみなされます。 これは2つのニックネームが同じのものであることを確定するときに重要な問題となります。
サーバとクライアントは互いにメッセージを送信し合います。これらのうちには、リプライするものもしないものもあります。 メッセージが正しいコマンドを含んでいた場合、後のセクションで述べますが、クライアントは仕様通りのリプライを期待しています。しかしこれはリプライを永久に待たねばならないことを意味しているわけではありません。クライアント-サーバ間、サーバ-サーバ間の通信は基本的に非同期です。
どのIRCメッセージも最大3つの主な部分から成り立っています:
プレフィックス、コマンド、全コマンドパラメータは1つ以上のASCIIコードのスペース文字(0x20)によって分けられます。
先頭に付いてるコロン(':',0x3b)一文字によって、プレフィックスの存在が表現されます。そしてこれはメッセージ自体の先頭の文字となります。 コロンとプレフィックスの間には飛び(空白文字)があってはいけません。 プレフィックスはメッセージの送信元を表すために、サーバが使用します。 プレフィックスがメッセージから抜け落ちていた場合、送信してきた接続先が送信者であると仮定します。 クライアントはメッセージを送信するときにプレフィックスを使用すべきではありません。クライアントがプレフィックスを使用するとすれば、唯一の妥当なプレフィックスはそのクライアントと関連付けて登録されているニックネームのみです。 プレフィックスによって識別された送信者がサーバの持っているデータベースで見つからない、または、メッセージの来た接続先とは異なった接続のものとしてその送信者が登録されている場合、サーバは黙ってそのメッセージを無視します。
コマンドは正しいIRCコマンドまたはASCIIテキストを表された3桁の10進数のどちらかでなくてはいけません。
IRCメッセージはいつもCR-LF(Carriage Return- Line Feed)で終わる文字の列です。そして、これらのメッセージは512文字を超えた長さにはできません。全文字数に末尾のCR-LFは含まれます。 従って、最大510文字がコマンドとそのパラメータに使用できます。 連続したメッセージ行のための規定はありません。
この事のより詳細についてはセクション7を参照のこと。
プロトコルのメッセージを連続したオクテットのストリームから抽出しなくてはいけません。 現在の解決策はメッセージの区切りとして、2文字(CRとLF)を使用することです。 空のメッセージは黙って無視されます。特別な問題が無ければメッセージの間にCR-LFシーケンスを使用できます。
抽出されたメッセージは<prefix>,<command>,<list of parameters>の成分に構文解析され、さらに、<list of parameters>は<middle>または<tailing>成分にマッチします。
このためのBNF表現は以下にあげるようなものになります。
<message> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf> <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ] <command> ::= <letter> { <letter> } | <number> <number> <number> <SPACE> ::= ' ' { ' ' } <params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ] <middle> ::= <先頭が':'ではなく,SPACE,NUL,CR,CFを含まない、空でないオクテットの列> <trailing> ::= <SPACE,NUL,CR,CFを含まないオクテットの列(空のオクッテトの列も可)> <crlf> ::= CR LF
ほとんどのプロトコルメッセージはリスト中の位置からパラメータ文字列を抽出するにあたり追加の意味と構文を定義しています。 例えば、多くのサーバコマンドはコマンドの後の最初のパラメータが送信先のリストであることを仮定するでしょう。
それは以下のように表現することができます:
<target> ::= <to> [ "," <target> ] <to> ::= <channel> | <user> '@' <servername> | <nick> | <mask> <channel> ::= ('#' | '&') <chstring> <servername> ::= <host> <host> ::=※ホスト名についての詳細はRFC 952 [DNS:4] を参照 <nick> ::= <letter> { <letter> | <number> | <special> } <mask> ::= ('#' | '$') <chstring> <chstring> ::= <8bitコード(SPACE, BELL, NUL, CR, LF, ','を除く)>
他のパラメータの構文は
<user> ::= <nonwhite> { <nonwhite> } <letter> ::= 'a' ... 'z' | 'A' ... 'Z' <number> ::= '0' ... '9' <special> ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}' <nonwhite> ::= <8bitコード(SPACE(0x20),NUL(0x0),CR(0xd),LF(0xa)を除く)
サーバに送信された大抵のメッセージが、なんらかのリプライを生成します。 もっとも一般的なリプライはニュメリックリプライ(numeric reply)です。これはエラーにも通常のリプライにも使用されます。
ニュメリックリプライは送信者のプレフィックスと3桁の数字、そしてリプライの送信先から成り立っています。 クライアントはニュメリックリプライを送信することは認められていません。どんなメッセージでもサーバは受け取りますが黙って落とされます。 これ以外の点おいては、ニュメリックリプライが普通の文字列より短い3桁の数字からキーワードから成り立っていることを除いて、普通のメッセージとまったく同じように扱われます。 種々のリプライのリストがセクション6にあります。
このセクションではIRCプロトコルの構成の背景にあるコンセプトと、現在、いろいろな異なる形態のメッセージの送信がどのように実装されているかを述べていきます。
1--A--2 D--4 | | | | 3--B------C------E サーバ :A,B,C,D,E クライアント:1,2,3,4[Fig.2. 小規模なIRCネットワークの例]
ほとんどのサーバ-サーバ間のトラフィックは互いのサーバの通信結果だけでは済まないので、1対1の通信は通常、クライアントだけが行います。 クライアントが互いに会話をする機能を安全な方法で提供するには、全サーバがどのクライアントにもたどり着けるように、正確に木構造のネットワークに沿って、単一の方向にメッセージを配信できるようになっていなくてはなりません。 送信されるメッセージの経路は木構造のネットワーク上の2点間の最も短い経路になります。
以下の例はFig.2のに沿って述べられています。
IRCの主な目的は簡単で効果的なコンファレンス(一対多の会話)が可能なフォーラムを提供することです。 IRCはこれを達成するため複数の方法を提供しています。それぞれの使用目的によってそれぞれの送信方法があります。
一対多の会話の最も効率の悪いスタイルはクライアントがクライアントのリストを使用して通信することです。 それがどのようになされるかは、ほとんど自明でしょう。 クライアントはメッセージの送信先のリストを与えてメッセージを送信します。サーバはリストを分解し、それぞれの送信先に送信するため、メッセージをコピーして別々に送信します。 これはグループを使うより効率的ではありません。なぜなら送信先のリストが分解され、各経路で複製が送信されないという信頼性がチェックをすることなく、送信されるからです。
IRCのチャンネルはマルチキャストグループと等価な役割を持ちます。この存在はダイナミックなものです。(人がチャンネルに参加したり、別れていくにつれて、出現したり消滅したりします。)そして、チャンネルでなされた実際の会話はそのチャンネルのクライアントを受け持っているサーバのみに送信されます。 同じチャンネルのクライアントが同一サーバ上に多数いる場合、メッセージテキストはそのサーバにたった一度だけ送信されます。そしてサーバは同じチャンネル上の各クライアントに送信します。 各クライアント-サーバ間の送信は繰り返され、送信されたメッセージは各チャンネルのメンバーに到達します。 Fig 2.に沿って例を挙げていきます。
関係ユーザ、ホスト、サーバへのマスクメッセージを使って配信するためのメカニズムをIRCオペレータは利用することができます。 これらのメッセージはホストやサーバの情報がマスクに一致するクライアントに送信されます。 メッセージはチャンネルと似通った方法でクライアントの所に送信されます。
「1→全体」タイプのメッセージはブロードキャストメッセージと言った方がよいでしょう。全てのクライアントやサーバまたはその両方にメッセージを送信します。 クライアントとサーバからなる巨大なネットワーク上では、一つのメッセージが、全ての送信先に到達する作業のために、ネットワークに大量のトラフィックを生むことになります。
いくつかのメッセージは全サーバへブロードキャストする以外の選択ができません。なぜなら、サーバ間で整合性ある状態情報を、全サーバが保持せねばならないからです。
ある単独のクライアントが他の全クライアントにメッセージが送信するような、メッセージ形態は用意されていません。
大部分の状態情報(チャンネルメンバー,チャンネルモード,ユーザ情報など、)を変化させるコマンドはデフォルトで全サーバに向けて送信せねばなりません。クライアントはこの送信の設定を変更することはできません。
サーバ間のメッセージが全ての「他の」サーバに送信される時は大抵、クライアント、チャンネルあるいはサーバに影響するメッセージの時だけに必要になります。 これはIRCにおいて根幹にかかわる事ですので、サーバから送信されるおおよそ全てのメッセージは接続している他の全サーバへのブロードキャストとなります。
以下ではIRCサーバとクライアントが使用可能な各メッセージについて述べています。 本プロトコルによる全サーバがこのセクションで述べている全てのコマンドを実装しなくてはなりません。 一覧表にあるリプライ"ERR_NOSHUCHSERVER"は<server>パラメータに該当するサーバが見つからないことを意味しています。 このリプライを受けた後は、サーバはそのコマンドのために他のリプライを送信してはいけません。
クライアントと接続しているサーバは完全なメッセージをパースし適切なエラーを返すことが必要です。 サーバがメッセージをパースしているときに致命的なエラーを発見した場合、エラーをクライアントに返信し、パースを終了しなくてはなりません。 不正なコマンド、サーバに不明なホスト(サーバ,ニックネーム,チャンネル名,などこのカテゴリに属するもの)、パラメータの不足、特権違反等が致命的エラーとみなされます。
パラメータが完全にそろっていた場合は、クライアントに返信されてきた応答の正当性と妥当性をチェックしなくてはなりません。 コンマを項目のセパレータとするメッセージの場合、リプライは各項目にたいして送信する必要があります。
この下の例では、いくつかのメッセージはフルフォーマットで使用してます:
:Name COMMAND parameter list
この例はサーバ間で通過する"Name"からのメッセージを表しています。ここで重要な点は、正確な経路を通ってリモートサーバへリプライを返すために、メッセージの最初の送信者の名前が含まれているという点です。
ここで説明されるメッセージはIRCサーバに接続を開始したり、もちろんクライアントやサーバが正常に接続を切ったりすることにも使用します。
PASSコマンドはクライアントやサーバの接続の登録に必須ではありません。しかし行うならば、SERVERメッセージや、すぐ後で説明するNICK/USERメッセージに先だって行わなければなりません。 サーバ間の接続に関しては実際の接続で一定のセキュリティの水準を保つために、パスワードを設定することを強く推奨します。 クライアントが登録を行う場合、以下に述べる順にメッセージを送ることを推奨します:
PASSメッセージは接続パスワードを送信するために使います。 パスワードは接続を開始しようとする前に送信することが可能ですし、送信しなくてはなりません。 現在クライアントは、NICK/USERの関連付けを送信する前にPASSメッセージを送信すること、サーバはSERVERメッセージを送信する前に必ずPASSメッセージを送信せねばならないとが、定められています。 送信されたパスワードはC/N行(サーバ)またはI行(クライアント)にマッチしなくてはなりません。 接続が登録される前に何度PASSメッセージを送信してもかまいませんが、最後に送信したものだけが認証には使用されます。接続が一度登録されたら変更することはできません。
NICKメッセージはクライアントにニックネームを与えたり、前のものから変更したりするために使用します。 <hopcount>のパラメータはニックネームのホームサーバからどのくらい離れているか示すためにサーバだけが使用します。 ローカルな接続のhopcountは0です。 クライアントが送った場合は、hopcountは無視すべきです。
サーバが受信したNICKメッセージが他のクライアントのすでに使用しているニックネームと同一であることが判明した場合、ニックネームの衝突が発生します。 ニックネームの衝突のがおこると、ニックネームに関する全ての情報がサーバのデータベースから取り除かれます。そして他の全サーバのデータベースからこのニックネームを取り除くために、KILLメッセージが送信されます。 衝突を引き起こしたNICKメッセージがニックネームの変更ならば、そのときは元の(古い)ニックネームもまた削除されます。
サーバがデータベースにあるのと同一のニックネームを指定するNICKメッセージを直接接続してきたローカルなクライアントから受け取った場合は、そのローカルなクライアントに対してERR_NICKCOLLISIONを発行し、NICKメッセージをドロップします。そしてニックネームは生成されず、KILLも行われません。
USERメッセージは接続の最初に新しいクライアントのユーザ名、ホスト名、サーバ名、本名を指定するために使います。 これは2つのサーバ間での通信でもIRC上の新しいクライアントの到着を示すのに使用します。USERとNICKの両方を受け取った後にサーバはユーザを登録するからです。
サーバ間ではUSERメッセージはクライアントのニックネームのプレフィックスが必要です。 USERメッセージは直接接続したクライアントから来た時、<hostname>と<servername>をIRCサーバは(安全のために)無視することに注意してください。しかし、これらはサーバ-サーバ通信では使用されます。 新しいユーザを残りのネットワークに紹介する時、USERコマンドで情報を送信する前にNICKメッセージを送信せねばならないことを意味します。
<realneme>のパラメータは最後のパラメータであることに注意してください。これはこのパラメータはスペース文字を含むかもしれないからです。このようにスペースを認識させるためにコロン(':')のプレフィックスを付けねばなりません。
<username>の取得はUSERメッセージにのみ依存しているので、クライアントは偽ることが容易です。そこでサーバには"Indentity Server"の使用が推奨されています。(訳者注:RFC1413を参照) クライアントの接続しているホストが"Identity Server"を使用可能ならば<username>は"Identity Server"からのリプライに従って設定されます。
SERVERメッセージは新しく接続した端点はサーバであることを伝えるのに使用します。 このメッセージは全ネットワークにサーバのデータを伝えるためにも使われます。 新しいサーバがネットワークに接続したとき、このサーバについての情報はネットワーク全体にブロードキャストされます。 <hopcount>はそのサーバからどのくらい離れているかという内部情報を全てのサーバに渡すのに使われます。 完全なサーバリストを漬かって、全体のサーバツリーのマップを構築することが可能となっています。しかし、ホストマスクがこれを行うのに邪魔になります。
SERVERメッセージは以下のどちらかの場合の時しか受け付けてはなりません:
(b)の場合、新しいサーバはSERVERメッセージを使って既存の接続先のSERVERメッセージの受信時に起こるほとんどのエラーは受信先のホスト(ターゲットSERVER)が接続を拒否した結果です。 エラーリプライは通常、ニュメリックリプライよりむしろ"ERROR"メッセージを使って送信されます。これは、この場合には有益な性質を持っているためです。
SERVERメッセージが解析された結果、すでに接続されているサーバへの登録が試みられた場合、サーバへの2重の経路が形成され、非循環的なIRCツリーが壊されるので、そのメッセージによる接続は(正しい手続きの後に)閉じなくてはなりません。
OPERメッセージは一般クライアントがIRCオペレータの権限を得るために使用します。 <user>と<password>の組み合わせがIRCオペレータの権限を得るために必要です。
OPERメッセージを送信したクライアントがそのユーザに割り当てられた正しいパスワードを送った場合、サーバはクライアントのニックネームに対して"MODE +o"を送信することによって新しいオペレータを残りのネットワークに知らせます
OPERメッセージはクライアント-サーバ間のみで使用されます。
クライアントのセッションを<quit message>と共に終了します。 サーバはQUITメッセージを送信したクライアントとの接続を閉じなくてはなりません。 <quit message>が与えられた場合、これはデフォルトメッセージのニックネームの代わりに送信されます。
ネットスプリット(2つのサーバ間の接続の切断)が発生したとき、<quit message>はネットスプリットに巻き込まれた2つのサーバの名前をスペースで区切ったものとなります。 1番目の名前はまだ接続しているサーバのもので、2番目の名前は接続が切断されたサーバの名前です。 他の何らかの理由で、クライアントがQUITメッセージを発行することなしにクライアントの接続が閉じたられた場合(例えばクライアントが死んで、ソケット上にEOFが発生した時)、サーバは、終了の原因を反映するような終了メッセージを代わりに使用することが必要となります。
SQUITメッセージはサーバが終了または死ぬことを送信するために使用されます。 サーバがあるサーバとの接続を破棄したい場合、サーバは他のサーバにSQUITメッセージを送らねばなりません。その時、<server>パラメータには送り先のサーバの名前を使用します。すると送り先のサーバは終了しようとしているサーバとの接続を閉じます。 このメッセージはIRCオペレータがIRCサーバの適切なネットワークを維持するために使用されます。 IRCオペレータはリモートサーバの接続に対するSQUITメッセージを発行することも可能です。 この場合以下に述べるように、SQUITはIRCオペレータとリモートサーバの間にはさまれる各サーバによって構文解析され、各サーバが保持するネットワークの形状が更新されます。
IRCオペレータは、リモートサーバ(これは現在オペレータのいるサーバ サーバもまた<comment>にエラーやそれに類似したメッセージを置いてゆきます。
ネットワークの閉じる接続の向こう側に広がる全サーバのために、閉じる接続の両端のサーバはSQUITメッセージを(そのサーバに接続している他の全てのサーバに)送信することが要求されます。
同様に、切りはなされる方のネットワークに接続している全クライアント分のQUITメッセージを送信せねばなりません。 これに加えて、分断によってそのチャンネルのメンバーを失う全チャンネルのメンバーはQUITメッセージを送信せねばなりません。
サーバとの接続が突然切れた場合(例えば、接続先のサーバが死んだ場合)、この接続の切断を検知したサーバは接続が閉じられた残りのネットワークに、何らかの妥当なコメントをコメントフィールドに記載して知らせることが必要です。
このメッセージ群はチャンネルの操作、チャンネルの性質(チャンネルモード),そしてチャンネルの(特にクライアントの)内容と関係があります。 ネットワークで2つのクライアントが最終的に衝突するメッセージを送信した時、これに対する反応には必然的にいく種類かの状態が存在します。 いつでも<nickname>が指定できることを保証するためにサーバがニックネームのヒストリーを保持することもまた必要です。ニックネームが変更された場合、サーバはこのヒストリをチェックします。
JOINメッセージはクライアントが実際にチャンネルに接続しはじめるのに使います。 クライアントがそのチャンネルにJOINできるかどうかは、クライアントが接続しているサーバがチェックします。そのサーバがメッセージを受領した場合、他のサーバは自動的にクライアントをチャンネルに加えます。
以下のような事が影響します:
より詳細な記述はMODEメッセージの解説のところにあります。 (詳細はセクション4.2.3を参照のこと。)
まず、クライアントがチャンネルにJOINすると、クライアントにはサーバが受け取ったチャンネルに影響する全てのメッセージについてのNOTICEメッセージが送信されてきます。 PRIVMSG/NOTICEメッセージはもちろん,MODE,KICK,PART,QUITメッセージなどが含まれます。 JOINメッセージは各サーバがチャンネル上のクライアントがどこにいるか知らなくてはいけないので、全てのサーバへのブロードキャストが必要です。 これによって、チャンネルへのPRIVMSG/NOTICEメッセージの送信が最適化されます。
JOINが成功した場合、クライアントにはチャンネルのトピック(RPL_TOPICが使用されます)、そしてチャンネル上のクライアントのリスト(RPL_NAMREPLYが使用されます)が送られてきます。リストにはJOINしたクライアントも含まれます。
PARTメッセージは<channel>パラメータにリストで指定した全チャンネルからクライアントが抜けるときに使用されます。<channel>パラメータにリストされた全チャンネルのユーザリストからそのクライアントを取り除きます。
MODEメッセージはIRCでは2つの目的を持つメッセージです。 これはユーザ名とチャンネルの両方をモード変更の対象としています。 この理論的根拠は、将来ニックネームが使用されなくなったときにそれに等価なものがチャンネルになるからです。
ODEメッセージを構文解析する時、最初にメッセージ全体を解析することが推奨されます。そしてモードを変更する際はその解析結果をもとにします。
MODEメッセージはチャンネルオペレータが「彼らの」チャンネルの特徴を変更するために提供されています。 チャンネルオペレータがモードを変更できるように、サーバも変更することができる必要があります。
チャンネルで利用できる各種のモードは以下の通りです:
o | - チャンネルオペレータの特権(channeloperator privileges)を授与/剥奪します。 |
p | - プライベートチャンネル(Private channel)属性を設定/解除します。 |
s | - シークレットチャンネル(Secret channel)属性を設定/解除します。 |
i | - インバイトオンリー(Invite-only)属性を設定/解除します。 |
t | - トピックの変更権(Topic settable)をチャンネルオペレータのみに設定/解除します。 |
n | - チャンネル外のクライアントのメッセージ(No message)の受信を許可/不許可します。 |
m | - モデレートチャンネル(Moderated channel:司会つきチャンネル)属性を設定/解除します。 |
l | - チャンネルに参加するクライアントの数を制限(user limit)する。 |
b | - クライアントの侵入を拒むBANマスク(Ban mask)を設定/解除します。 |
v | - モデレートチャンネル属性のついているチャンネルでの発言権を授与/剥奪します。 |
k | - チャンネルキー(channelkey)(=password)を設定/解除します。 |
'o'と'b'のオプションを使用した時、全部で3つの事がMODEメッセージでは必要とされます。 これは、'o'や...と関連づけられた...
<訳者注:>原文も途中で終わっています。ここは「これは、'o'に関連付けられるニックネームや'b'に関連付けられるバンマスクです。」ではないかと思われます。
ユーザモードは大抵、クライアントが他の人からの見え方やクライアントに送られてくる「余分な」メッセージに影響します。 メッセージの送信者とパラメータとして与えられたニックネームの両方が同一の時に、ユーザMODEメッセージは受領されます。
以下に述べるものがモードとして使用可能です:
i | - クライアントを不可視(Invisible)とします。 |
s | - サーバのNOTICE(Server notice)メッセージを受信します。 |
w | - クライアントはWALLOPSメッセージを受信します |
o | - IRCオペレータフラグ(Operator flag)を立てます。 |
後ほど追加のモードが利用できるようになるかもしれません。
ライアントが自分自身を"+o"フラグを使ってIRCオペレータに任命しようとした場合、その試みは無視されます。 しかしながら、自分自身を"-o"を使うことでIRCオペレータをやめること(deopping)することにはなんの制約もありません。
TOPICメッセージはチャンネルのトピックを見たり変更したりするために使用します。 もし、<topic>がなかった場合、<channel>で指定されたチャンネルのトピックが返されます。 <topic>のパラメータが送られた場合、チャンネルモードのパーミッションが許せばチャンネルのトピックが変更されます。
NAMESメッセージを使うことによって、クライアントはそのクライアントが可視なチャンネル上のニックネームを全て一覧することができます。 可視なチャンネルとはprivate(+p)やsecret(+s)などが設定されていない、実際にだれかいるチャンネルを言います。 その指定が妥当なものなら、<channel>パラメータは情報を返すチャンネルを指定します。 間違ったチャンネル名に対するエラーリプライはありません。
<channel>パラメータが与えられなかった場合は、全てのチャンネルとその参加者のリストが帰ってきます。 このリストの最後には、クライアントのいるチャンネル上もしくは可視なチャンネル上にいない可視なクライアントのリストが、「チャンネル」"*"として一覧表示されます。
LISTメッセージはチャンネルとそのチャンネルのトピックを一覧表示するのに使用します。 <channel>パラメータが使われた場合、チャンネルのステータスを表示するだけです。 プライベートチャンネルでは、クライアントがそのプライベートチャンネルにいるのでなければ、チャンネル"Prv"として、(トピックなしで)一覧表示されます。 同様にシークレットチャンネルでは、クライアントが問題のチャンネルメンバーでなければ、全くリストにのりません。
INVITEメッセージはチャンネルにクライアントを招待するために使用します。 パラメータ<nickname>はターゲットのチャンネル<channel>に招かれる人のニックネームです。 ターゲットとなるクライアントが招かれるチャンネルが存在しなくてはならないとか、有効なチャンネルでなければならないといった必要性はありません。 クライアントをinvite-onlyなチャンネル(mode +i)に招くには、INVITEを送信するクライアントがそのチャンネル上でチャンネルオペレータの権限をもっていなくてはなりません。
KICKメッセージは強制的にチャンネルからクライアントを削除するときに使うことができます。 これはチャンネルから「追い出だし(kicks them out)」(強制離脱)ます。 チャンネルオペレータだけがチャンネルの外からきた他のクライアントを追い出すことができます。 チャンネルからキックの犠牲者を削除する前に、KICKメッセージを受け取ったサーバは、これが有効かどうか(送信者が本当にチャンネルオペレータかどうか)チェックします。
KICKメッセージをパラメータを以下のように拡張することも可能です:
<channel>{,<channel>} <user>{,<user>} [<comment>]
サーバに対するクエリーメッセージ群はネットワークに接続しているサーバについての情報を返すように設計されています。 接続している全てのサーバはこれらの要求に正確に応答しなくてはなりません。 どんなものでもその不当な(または不足している)リプライはそのサーバが壊れたサインのと受け取られます。そして、状況が回復するまで、可能な限り速やかにそのサーバと接続を切断または接続を不可能にしなくてはいけません。
これらのクエリーでは、<server>として現れるパラメータの所に、いつでもニックネームまたはサーバまたはいく種類かのワイルドカードを使った名前がくる事を意味します。 しかしながら、それぞれパラメータについても、たった一つのクエリーとリプライのセットが生成されます。
VERSIONメッセージはサーバプログラムのバージョンを要求するために使用します。 オプショナルなパラメータ<server>はクライアントが直接接続していないサーバプログラムのバージョンを請求する時に使用します。
STATSメッセージはある特定のサーバの統計を要求するのに使用します。 <server>パラメータが書かれていなかった場合、単にRPL_ENDOFSTATSが送信されてきます。 サーバは下記の(ような)クエリーを供給できなくてはならないのですが、このメッセージの実装はサーバに高く依存します。
送信先のサーバ(パラメータ<server>で指定できます)に対して、クエリーとして1文字を指定します。中継するサーバはこれを無視し変更せずに転送します。 以下に述べる要求は現在のIRCで実装されているもので、サーバのセットアップ情報の大部分が供給されます。 これらはバージョンによって同じようにはサポートされていないかもしれません。クエリーの目的と現在使用されているリプライのフォーマットに矛盾しない、正しいリプライをサーバはSTATSメッセージに対してリプライしなくてはなりません。
LINKSメッセージによって、サーバが要求に答えることで知ることのできる全サーバをクライアントは一覧表示する事ができます。 返されるサーバのリストはマスクにマッチするもののリストかマスクが指定されていなければ完全なリストです。
<server mask>に加えて<remote server>が指定されていた場合、LINKSメッセージはその<remote server>にマッチした最初のサーバへ転送されます。そして、そのサーバが要求に対して応答をします。
TIMEメッセージは指定したサーバのローカルタイム(地方時間)を要求するのに使用されます。 <server>パラメータが指定されなかった場合、メッセージを扱うサーバが要求に対して応答を返します。
CONNECTメッセージは直ちに他のサーバとの新しい接続の確立を試る事をサーバに強制する時に使用します。 CONNECTメッセージを実行する権限はIRCオペレータのみに与えられています。 リモートサーバを指定した場合、サーバはCONNECTメッセージを<target server>の<port>に対して試みます。
TRACEメッセージは指定されたサーバへの経路を探すのに使用されます。 このメッセージを処理する各サーバはそのサーバの経路リンクを通過した事を示すリプライメッセージをTRACEメッセージの送信者に送信しなくてはいけません。こうして、経路追跡を使うことで得られる結果に似た一連のリプライが構成されます。 リプライを送信した後、指定したサーバに到達するまでは、次のサーバにTRACEメッセージ送信しなくてはなりません。 <server>パラメータが書き落とされていた場合、TRACEコマンドに対して、現在のサーバが直接接続しているサーバを示すメッセージを送信者に送り返さなくてはいけません。
パラメータ<server>によって指定されたサーバが実在する場合、そのサーバは自分に接続された全サーバ、及びクライアントをレポートすることが求められていますが、現在のクライアントについてはIRCオペレータのみ見ることが出来ます。 パラメータ<server>によって指定された受信先がニックネームの場合、単にニックネームがリプライとして割り当てられます。
ADMINメッセージは、指定したサーバまたは<server>が省略された場合は現在のサーバの管理者の名前を見つけるためにつかいます。 各サーバはADMINメッセージを他のサーバに転送できなければなりません。
INFOメッセージはサーバについての以下のような情報を返すために使用します:
IRCプロトコルの主な目的はクライアントが互いに通信する基礎を提供することです。 PRIVMSGとNOTICEだけが、あるクライアントから他のクライアントへテキストメッセージを実際に送信可能なメッセージです。残りは信頼性や順序を保証したりすることを可能とするために使用されます。
PRIVMSGはクライアント間のプライベートメッセージを送信するのに使われます <receiver>はメッセージを受け取る人のニックネームです。 <receiver>はコンマで区切ることでニックネームやチャンネルのリストにすることもできます。
<receiver>パラメータはホストマスク(#mask)やサーバマスク($mask)を使用することもできます。 どちらの場合も、サーバはマスクにマッチするサーバやホストにPRVMSGメッセージを配信するだけです。 マスクは最低1つの"."を含んでいなくてはなりません。そして最後の"."の後にワイルドカードがあってはいけません。 この制限は誰かがメッセージを"#*"や"$*"へ送信することを防ぐために存在します。これは、全てのクライアントに対するブロードキャストになってしまいます。経験的にこれらは正しく意図的に使用されることよりも誤用されることが多いからです。 ワイルドカードは'*'と'?'の文字が使用できます。 このPRIVMSGメッセージへの拡張はIRCオペレータのみが使用できます。
NOTICEメッセージはPRIVMSGと同じように使用します。 NOTICEとPRIVMSGの間で異なる点は、 NOTICEメッセージを受け取った場合、それに対してなにも反応して送信してはいけません。 この規定はサーバに対しても適用されます。NOTICEメッセージを受け取ったクライアントにエラーリプライすら返信する必要してはいけません。 この規定の目的は、メッセージに対して自動的になにかを送信するクライアントとの間のループを避けることです。 これは典型的なオートマトン(クライアントはAIまたは人間が操作する会話的なプログラムです)によって使用されます。すなわち、他のオートマトンとのリプライのループが切りたいオートマトンが使用します。
リプライの詳細と例はPRIVMSGを参照のこと
ユーザ情報の要求は特にクライアントやクライアントのグループ(チャンネル)について詳細を調べる関係したメッセージ群です。 これらのメッセージにおいてワイルドカードを使用したとき、ワイルドカードがマッチした場合、「見える(visible)」クライアントの情報を返すだけです。 クライアントの可視性はユーザモードと同一のチャンネルにいるかどうかという事の組み合わせに従って決定されます。
WHOメッセージはクライアントが<name>パラメータにマッチしたクライアントの情報のリストを返すクエリーを生成するために使用されます。 <name>パラメータが欠如していた場合、全ての可視なクライアント(不可視(user mode +i)になっていないクライアントで、かつ、クエリーを送信したクライアントと共通のチャンネルにいないクライアント)のリストを表示します。 "0"という<name>を使うか、全てのエントリに完全にマッチするワイルドカードを使うことで同じ結果を得ることができます。
WHOメッセージに渡された<name>は、channel<name>にマッチしない場合、クライアントのhost<name>,server<name>,real<name>,nick<name>に対してマッチします。
"o"パラメータが与えられた場合、与えられたネームマスクによる結果のうちIRCオペレータだけを返します。
このWHOISメッセージはクライアント個別の情報を要求するために使用されます。 <nickmask>にマッチする(見る資格を持っている)各クライアントの状態の違いを示すニュメリックリプライによってこのメッセージに回答します。 <nickmask>にワイルドカードが使われていない場合、可視なニックネームについての情報が表示されます。 コンマ','でニックネームのリストを区切ることで複数指定することができます。
別の使い方では指定したサーバにクエリーを送信できます。 他の情報は全体に行き渡っているのですが、問題のユーザがどのくらいidle状態にあるかといったローカルサーバ(すなわち、ユーザが直接に接続しているサーバ)にしか分からないことを知りたい場合に便利です。
WHOWASメッセージはもう存在していない<nickname>の情報を問い合わせます。 これはニックネームが変更されたり、IRCから去ったりした場合に使用します。 このクエリーに対するリプライは、サーバがニックネームヒストリを使って<nickname>に該当する見出しのエントリを探索します。(ここではワイルドカードマッチを使用しません。) ヒストリは後方検索され、最初に見つかったエントリを最初に返します。 複数のエントリがあった場合、<count>個までのリプライが返されます。(<count>パラメータを指定しなかった場合は見つかるだけ全て返します。) <count>として非正数が渡された場合、見つかるだけ全てを返します。
このカテゴリのメッセージはどのカテゴリにも属さないものですが、プロトコルの一部であり必要なものです。
KILLメッセージはクライアント-サーバ間の接続を直接接続しているサーバが閉じるときに使われます。 サーバが、正確なニックネームリストでだぶったエントリに遭遇したときに、この2つのエントリをKILLメッセージを使って削除します。 これはIRCオペレータも使用することができます。
単に接続を短時間切断するだけのことなので、事実上自動的に再接続するアルゴリズムを持っているクライアントにはこのメッセージに利用価値はありません。 クライアントは生成されたKILLメッセージを拒否することが出来ないので、問題の箇所に目星をつけてデータの流れを中断させ、大きな被害になることを食い止めるのに使うことができます。
ニックネームはいつでも世界中でユニークな事が要求されます。「二重性」が検知された時は(すなわち、2つのクライアントが同一のニックネームを登録しようとした時)いかなる時でも両者が消えるか、片方だけ再び出現することを期待して送信されます。
<comment>はKILLメッセージに対する実際の理由を反映していなくてはいけません。 サーバが生成するKILLメッセージのコメントは2つの衝突したニックネームの所在に関する詳細な情報で構成されます。
これを見た他のユーザが満足できる十分な理由をユーザが提供することは、それぞれにまかされています。 偽のKILLメッセージの送信者が自分自身の情報を隠すのを防ぐために、このコマンドを通過させるサーバは仁の名前を'kill-path'と呼ばれるものを後ろに付け加えて、これを<comment>に含めます。
KILLメッセージを使って他のクライアントをKILLする事はオペレータのみに許可されています。 理想的にはIRCオペレータすらこれを行う必要はありません。これを使用するものとしてはサーバだけが残ります。
PINGメッセージはコネクションの他端のアクティブなクライアントの状態をテストするために使われます。 他端の接続からアクティブなものが検知できない場合、PINGメッセージが一定間隔をおいて送信されます。 接続が規定時間以内にPINGメッセージに対して反応しなかった場合、その接続は閉じられます。
PINGメッセージを受け取ったクライアントは、まだ接続が生きていることを示すために、<server1>に対してできる限り速やかに適切なPONGメッセージを返信しなくてはいけません。 サーバはPINGメッセージに対して返信はしません。しかし、PINGに対するリプライから他端の接続からの接続が生きている事を信用します。 <server2>パラメータが指定された場合、PINGメッセージはそこに転送されます。
PONGメッセージはPINGメッセージに対するリプライです。 パラメータ<daemon2>が指定された場合、このメッセージは指定のデーモンに転送されます。 <daemon>パラメータはPINGメッセージに対してこのPONGメッセージを生成して返信を行うデーモンの名前です。
ERRORメッセージはIRCオペレータに、深刻なまたは致命的なエラーを報告するために、サーバが使用します。 あるサーバから別のサーバに対して送信することもできます。しかし、通常、他端のクライアントからのものは受領されません。
ERRORメッセージはサーバ-サーバ間の接続で発生したエラーを報告するためだけに使用されます。 ERRORメッセージは全サーバ(これは、直接接続しているオペレータ全員にERRORメッセージを伝えます)と直接接続している全オペレータに対して送信されます。 あるサーバからERRORメッセージが届いた場合、サーバはERRORメッセージを他のサーバに転送しません。
サーバがIRCオペレータに受信したERRORメッセージを送信するときは、クライアントがこのエラーに対して反応しないように指示するために、<error message>をNOTICEメッセージにします。
このセクションではOPTIONALメッセージについて述べてゆきます。 サーバはここのプロトコルで述べる実装をする必要はありません。 このオプションがないときは、エラーリプライメッセージを生成するか、さもなければ、不明なメッセージのエラーとします。 他のサーバがそのメッセージにリプライを送信するいる場合があるので、これを通過させなくてはいけません。(従って、要素を解析をする必要があります。) これらのリプライに割り当てられた番号はメッセージの説明の後に並べてあります。
AWAY(チャンネルに対して送信されたものではなく)そのクライアントに直接配信されたPRIVMSGメッセージに対して自動的にリプライメッセージを返信するようにクライアントは指定することができます。 クライアントに配信されたPRIVMSGメッセージに対してサーバが自動リプライを送信します。 リプライをするサーバは送信したクライアントがつながっているサーバだけです。 パラメータを1つ指定した時(AWAYメッセージを設定する)とパラメータなしの時(AWAYメッセージを解除する)の両方の場合で使用できます。
REHASHメッセージは強制的にサーバに設定ファイルを読み込ませるためにIRCオペレータが使用します。
RESTARTメッセージは強制的にサーバを再起動するためにIRCオペレータが使用します。 IRCオペレータとしてサーバに接続しているひとが、なにかの間違いでRESTARTメッセージを送信するリスクがあるので、このメッセージはオプションあつかいになっています。このメッセージは(最低でも)IRCサービスの中断を引き起こします。
RESTARTメッセージはいつでも、送信したクライアントが接続しているサーバに作用します。接続している他のサーバに転送されることはありません。
SUMMONメッセージはIRCサーバの走っているホストのユーザにIRCに参加するように呼びかけるメッセージを与えるために使用します。 以下のような条件を満たす場合のみメッセージは送信されます:
<server>パラメータが指定されなかった場合、クライアントがつないでいるサーバを送信先サーバと仮定して、<user>をSUMMON(召喚)することを試みます。
そのサーバでSUMMON(召喚)できなかった場合、ニュメリックリプライERR_SUMMONDISABLEDが返され、SUMMONメッセージは失敗します。
USERSメッセージはそのサーバのユーザログインリストを、who(1)やrusers(1)、finger(1)のような形式で返します。 セキュリティに関係する理由で、接続しているサーバ上でこのメッセージが使えない人がいる事もあります。 使えない場合、この事を示すため、正しいニュメリックリプライを返さなくてはいけません。
現在オンライン中の全IRCオペレータに対してメッセージを送信します。 ユーザメッセージとしてWALLOPSの実装をすると、(WALLとよく似た)多くの人にメッセージを送信する方法としてよく悪用されます。 このため現在は、以下の例のように、WALLOPSの送信者としてはサーバのみを認めるようにWALLOPSを実装しなくてはなりません。
USERHOSTメッセージは最大5つのニックネームをスペース文字で区切ったリストをパラメータとしてとることができます。各ニックネームについて見つかった情報を返します。 各リプライはスペースで区切ったリストとして返されます。
ISONメッセージはすばやく効果的にニックネームが現在IRC上にいるかどうかを得る方法を提供するために実装されていました。 ISONはたった1つのパラメータをとります。それはスペースで区切られたニックネームのリストです。 このリストにある各ニックネームがいた場合、サーバはリプライ文字列にそのニックネームを加えます。 従って、空文字列(指定されたニックネームがいない時)から、パラメータ文字列の完全なコピー(全ていた時)まで、パラメータで指定したニックネームの部分集合がリプライの文字列として返されます。 チェックできるニックネームの数の制限は文字列の長さできまります。長すぎる場合はパラメータの文字列は512文字以内になるようにサーバが切り落とします。
ISONはローカルサーバがメッセージを発送したクライアントに対して実行します。遠方の他のサーバには転送しません。
以下は、メッセージに応じて生成されるニュメリックリプライのリストです。 各々のニュメリックリプライにはその番号と名前とリプライ文字列が割り当てられています。
<reply> ::= <nick>['*'] '=' <'+'|'-'><hostname>クライアントがIRCオペレータとして登録されているかどうかを'*'は示します。 クライアントのAWAYメッセージが設定/解除されているか、それぞれ'-'/'+'で表しています。
必要なパラメータがきちんと指定されていた場合、回答するサーバは 上記のニュメリックリプライの中からリプライを組み立るか、エラーリプライを返すかしなくてはなりません。 RPL_WHOISUSERの中の'*'はリテラルな文字です。ワイルドカードではありません。 各リプライのセットの内で、RPL_WHOISCHANNELSだけは複数回現れます。 チャンネル名の後に続く'@'と'+'の文字はそれぞれクライアントがチャンネルオペレータまたはmoderated channel(mode +m)での発言権が与えられていることを示します。 RPL_ENDOFWHOISリプライはWHOISメッセージを実行した後にその印として使われます。
以下のようなカテゴリに含まれるので、これらの番号は今まで記述されていません。
クライアントとサーバ双方は同じ認証レベルに属しています。 いずれの場合も、サーバとの接続を形成するために、ホスト名に対するIPアドレスの調査(およびこの反対のチェック)が行われます。 (もしパスワードがその接続に対して設定されていた場合)どちらの接続もパスワード認証に属しています。 パスワードチェックは一般的にサーバにだけ使用されますが、パスワードチェックは全ての接続で可能です。
これに加えて、接続の認証をユーザ名を使用して行う方法が一般的になってきています。 接続の他端のユーザ名を得る事は典型的なRFC1413で述べられているIDENTによるサーバ認証によって接続することを意味します。
パスワードを指定することなしに、ネットワーク接続の他の端点の信頼性を簡単に決定することはできません。IDENTの使用などの手段に加えて、パスワードの使用をサーバ間接続に関して強く推奨します。
このプロトコルで述べる実装は"IRC server,version 2.8"現在のものです。 これ以前のバージョンでは、多くのニュメリックリプライの代わりに、NOTICEメッセージを使って一部または全てのメッセージが実装されています。 残念ながら、上位互換のために実装がこの公開されている文書と異なる実装がなされています。
主な相違点は:
このセクションの残は、大部分のサーバを実装しようとした場合の重要な問題を扱います。そしてクライアントにも同様にそのまま適用できる部分もあります。
TCPが提供する信頼性あるネットワークプロトコルが会議の規模によく適しているので、IRCはTCPの上に実装されています。 マルチキャストIPに置き換えられていきます。しかし、これはまだ幅広く利用できず、現時点ではサポートされていません。
UNIXのソケットではlisten/connectの操作が利用できます。現在の実装では、クライアントとサーバ両方の、UNIXのソケット上での接続でlistenとacceptするように構築されています。 これらは'/'で始まるホスト名のところのソケットとして認識されます。
UNIXのソケットの接続についての情報が提供されたとき、実際のソケットの名前が特に指定されなければ、サーバはpathnameの中の実際のホスト名に置き換えられます。
クライアントとサーバに便利な「バッファリングのない(non-buffered)」ネットワークI/Oが提供されています。各接続にはそれぞれにプライベートな、最も新しく読み込み、パースの結果を保持している「入力バッファ(input buffer)」が割り当てられます。 512バイトの大きさのバッファが1つの完全なメッセージを保持するために使われます。これは通常複数のメッセージを含んでいます。 読み込みが行われた後、プライベートバッファは正しいメッセージかパースされます。 そのバッファで一つのクライアントからの複数のメッセージを処理する場合、クライアントが消滅するかもしれないので気を付けなくてはなりません。
送信先のホストにデータが送信できない時や飽和したネットワークリンクが見つかる事はよくあることです。 UNIXでは大抵これをTCP windowとその内部バッファを通して扱いますが、サーバは多くの場合、膨大な量の送信すべきデータを抱えています。(特に新しいサーバ-サーバリンクが形成された時です)そして、カーネルの提供する小さなバッファは、流入量に対して十分ではありません。 この問題を軽減するため、「送信キュー(send queue)」が送信データのFIFOとして使われます。 新しいサーバが接続する場合、低速なネットワーク接続の巨大なIRCネットワーク上では、よく送信キューが200Kbもの大きさに膨れることあります。 接続の調査をする時、サーバはまず読み込み、全入力データをパースし、送信された各データはキューに格納されます。 利用可能な全入力に対して実行されたら、キューにあったデータは吐き出されます。 これはwrite()システムコールの使用を減少させ、TCPがより大きなパケットを生成するのを助けます。
接続が死んだり反応がなくなったりしたことが検知された場合、このような指定した一定時間に反応がなかった接続に対してサーバはPINGをしなくてはなりません。
接続が時間内に反応を返さなかった場合、この接続は適切な手順で閉じられます。 サーバプロセスをブロックするよりも、低速な接続を閉じた方がよいので、送信キューが最大値を超えた場合、接続が落ちます。
IRCサーバとの接続をする場合、クライアントに(LUSERメッセージの通りの)現在のユーザ/サーバカウントだけではなく、(存在するならば)MOTDを送信します。 適切な導入メッセージだけではなく、名前、バージョンをクライアントに明確なメッセージで指定しなくてはいけません。
これを処理してから、サーバは新しいクライアントのニックネームやそれについての情報を送信しなくてはなりません(USERメッセージによる)。それからサーバとして認識されます。(DNS認証サービスによる) サーバはUSERに続いてまずNICKの情報を送信します。
問題が発生する可能性のある場所が多いので(最悪の場合競合状態が起こります)、サーバ-サーバ間の接続の確立する過程には危険がともないます。 サーバが正しく認識されたPASS/SERVERの組に続いて接続が受け付けられた後、全状態情報(後述)と共に、その接続に関するPASS/SERVERの情報をリプライします。
サーバとの接続を受け付ける(accept)前に、初期化中の場合はPASS/SERVERの組を受信して、サーバの応答が正しく認証できるかもチェックします。
サーバ間で交換される状態情報のオーダーは必要不可欠なものです。
そのオーダーは以下に述べるようになります:
サーバに関する情報は 特別なSERVERメッセージを経由して送信されます。ユーザ情報は各NICK/USER/MODE/JOINメッセージで、チャンネル情報はMODEメッセージで送信されます。
TOPICメッセージは古いトピック情報を上書きするだけですので、チャンネルトピックはここでは交換されません。接続の両端でトピックが交換されるだけです。
まず、サーバについての状態情報が転送されると、ニックネームの衝突が発生する前に、すでに存在しているサーバとの衝突が起こります。 IRCネットワークは非循環的なグラフとして存在しているため、ネットワークが既に別の所で再結合されているかもしれません。 この時、衝突の起こったところがネットを分断すべき場所になります。
クライアントの接続が閉じられた時、クライアントとの接続を閉じるサーバが、クライアントのために、QUITメッセージが生成します。 これ以外のメッセージが生成/使用されることはありません。
サーバ-サーバ間の接続が、間接的にSQUITを用いて閉じられるか、「自然に」閉じてしまった場合、残りのIRCネットワークは閉鎖が検知されたサーバについての情報を更新しなくてはなりません。。 サーバは(その接続の背後に広がっていた各サーバそれぞれに対応した)SQUITメッセージのリストと、(その接続の背後に広がっていた各クライアントに対応した)QUITメッセージのリストを送信します。
全IRCサーバは最新のニックネームの変更のヒストリを保持しなくてはなりません。 これはメッセージの操作によってニックネーム変更の競合状態が発生した時に接触を保つチャンスをサーバに与えるために必要です。
ニックネームの変更を追跡しなくてはならないメッセージは:
その他のメッセージはニックネームの変更をチェックする必要はありません。
上記のような場合、サーバはまず最初にニックネームが存在するかどうか、そして(あるならば)誰のものかチェックしなくてはなりません。 これで競合状態の危険性が減少しますが、それでもなお不適切なクライアントの影響でサーバで競合状態が発生することがあります。 上記のメッセージに対して変更の追跡が行われた時、時間の範囲を設けて古すぎるエントリを無視するようにする事を推奨します。
正常なヒストリでは、サーバは以前のニックネームを保持することができます。これは全てのクライアントについて変更されたかどうかを知るためです。 このサイズの制限は(例えばメモリのような)他の原因によります。
IRCサーバ間で接続する大きなネットワークでは、ネットワークに接続している単一のクライアントが非常に簡単に絶え間のないメッセージを送信することができてしまいます。その結果、ネットワークで洪水が発生するだけでなく、他のクライアントに提供されるサービスの水準が低下します。 洪水の「被害者」の保護をすることより、洪水を防ぐようにサーバは書かれています。そしてサーバ以外の全てのクライアントに対してこれが適用されます。
現在のアルゴリズムは以下のようになっています:
そしてクライアントに対してメッセージ1つに対して2秒のペナルティーを課します。 このようにして本質的な意味では不利な影響は及ぼさずに、クライアントは2秒毎に1メッセージを出すことができます。
リアルタイム環境では、全てのクライアントが公平にサービスを受けることができるようにサーバプロセスの待ち時間をできるだけ短くする事が基本です。 明らかにこれは全ネットワークのread/writeの操作についてノンブロックキングI/Oでなされる必要があります。 通常のサーバ接続では、これは難しいことではありません。しかし、ブロックしなくてはならないサポート操作(例えばディスクの読み書き)も他にあります。 可能な限り、このような操作は短い時間で実行しなくてはいけません。
バークレーの標準ライブラリを使用はタイムアウトのリプライが起きた場合、大きな遅延が起きます。
これを避けるため、DNSルーチンのセットを分けて、段階毎にノンブロックキングI/O操作を行い、サーバのメインI/Oループの中で調査するように書かれています。
他のプログラムに組み込んで使用できるいくつかのIDENTライブラリがありますが、これらは同期方法に影響しいくつかの問題が起こります。そしてその結果、周期的な遅延が発生します。 解決策は、ノンブロッキングI/Oとして使えるようサーバの残りと協調する形で書くことです。
柔軟性のあるセットアップの方法とサーバの運用を提供するため、設定ファイルに以下に述べるサーバへの指示項目が含まれる事が推奨されます。
ホスト名を指定では、ドメイン名と点'.'(dot)を使った表記法(例えば127.0.0.1)両方が受け付けられるようにすべきです。 全ての送信/受信の接続の使用/受け付けに対してパスワードを指定することを可能にしなくてはいけません。(ただし、送信用の接続は他のサーバがこれを行います)
上記のリストはサーバが他のサーバと接続するためのに最小限必要なことです。
その他、役に立つかもしれない事項は:
サーバは「アクセスコントロールリスト(access control list)」のようなものを使用すべきでしょう。それは起動時に読み込まれ、どのホスト、クライアントがそのサーバとの接続を利用できるか決定するために使用されます。 「拒否(deny)」と「許可(allow)」の両方がホストアクセスコントロールの柔軟性を提供するために実装されるべきです。
破壊的な人物にオペレータの権限を許可することは、その与えた力によって、全IRCネットワークの安寧に悲惨な結果をもたらすことになるでしょう。 それ故、このような権限の取得はあまり簡単にすべきではありません。 現在、それら一方は簡単に推測できますが、2つのpasswordsが必要です。 設定ファイル内のOPER passwordのストアは、簡単に盗みとられないようにcryptフォーマット(すなわちUNIXのcrypt(3)を使用します)で暗号化してハードコーディングする事が望ましいでしょう。
サーバ間の接続 不正な接続はIRCの有用性に大きな衝撃を与えます。 それゆえ、各サーバは、相手が自分の接続を許可していて、自分も相手の接続を許可しているサーバのリストを保持しているべきです。 サーバが気まぐれなホストがサーバとして接続することを許すような状況を作ってはいけません。 サーバが接続できるかできないということに加えて、設定ファイルにはpasswordや、そのリンクの他の特性などもストアすべきでしょう。
ADMINメッセージ(セクション 4.3.7を参照のこと)に対する綿密で正確なリプライを提供できるように、サーバが設定の中で詳細な事項を取得できるようにしなくてはなりません。
現在のサーバではローカルクライアントは最大10の違うチャンネルにJOINを登録できます。 ローカルでないユーザの接続には制約をかすことはないので、サーバは(もちろん)全てのチャンネルの基本的なメンバーとして恒常的に加わっています。(つまりはサーバは全てのチャンネルのメンバーです。)
このプロトコルにはいくつかの問題が認識されています。ncigt h evr#Iイプロトコkοテキ全て解決されることを願っています。 現在、これらの解決策を探す作業が進行中です。
大きなエリアで使った時、このプロトコルは十分に釣り合いがとれていない事が幅広く認識されています。 主な問題点は、他のサーバ、クライアント、そして、これらの変更時に更新するための情報を全サーバが知っていなくてはならないという事です。 パスの長さが各2点間で最小になるようにサーバの数をできるだけ減らし、また、、できるだけ強い枝からなる伸縮自在な木になるようにするため、いくつかのサーバの下で管理することが望ましいでしょう。
現在IRCプロトコルは3タイプのラベルがあります: ニックネーム,channel name,server nameです 各3タイプはそれぞれの別々の領域(名前空間)に属しており、同じ領域で重複することはありません。
現在、クライアントは3タイプのラベルどれでも選択して使用するすことが可能です。そしてこのために衝突が発生する可能性があります。 循環的なな木構造を許すさないのはもちろん、チャンネルやニックネームが衝突しないしないようなユニークな名前をつけるプランで再構築する必要があることが広く認識されています。
IRC上のニックネームのアイデアは、非常にクライアントがチャンネルの外の人と話すときに、非常に便利なものです。ニックネーム空間には数の限りがあります。しかし、同じニックネームを使用したい人が複数いることは珍しいことではありません。 このプロトコルで2人の人が同一のニックネームを選んだ場合、一方が成功しないか、両方がKILLメッセージ(セクション4.6.1参照)によって削除されます。
現在チャンネルレイアウトでは全サーバが全チャンネルと、チャンネルにいる人、チャンネルの性質を知らなくてはなりません。 大きさと同時にプライバシーにも問題があります。 ニックネームの衝突を解決したときのように排他的に解決されるのではなく、チャンネルの衝突は包括的な方法で解決します。(新たにチャンネルを作った人、両方ともが同じチャンネルのメンバーであるとみなします。)
サーバの数は通常、クライアントやチャンネルの数くらべて相対的に少ないですが、現在、サーバは2つの方法で全体のなかから指定できます。それぞれ個別に指定するか、マスクでくるんで指定する方法です。
サーバのコードの中の複数箇所で、(例えば、クライアントのセットのリストからチャンネルをチェックするような所で)O(N^2)のアルゴリズムを使用することを避けることができません。
現在のサーバのバージョンでは、各サーバは隣接しているサーバが正常であることを想定していて、堅牢にチェックされたデータベースがありません。 接続したサーバがバグを持っていたり、実在するネットワークと矛盾することを紹介しようとした場合、このことは大きな問題につながります。
現在、内部と外部のラベルのユニークさの欠如から、競合状態が多数存在してます。 これら競合状態は一般的に、メッセージが転送され、IRCネットワークに波及するのにかかる時間が原因で生じます ユニークなラベルの変更でさえ、チャンネル関係のメッセージが分裂する問題があります。
セキュリティについては、セクション 4.1, 4.1.1, 4.1.3, 5.5, 7で述べられています。
Jarkko Oikarinen Tuirantie 17 as 9 90500 OULU FINLAND Email: jto@tolsun.oulu.fi Darren Reed 4 Pateman Street Watsonia, Victoria 3087 Australia Email: avalon@coombs.anu.edu.au
日本語訳にあたって、できる限り自然な日本語になるようつとめました。 一部訳しにくい(もしくは訳者の英語力の不足のため理解ができない)文章はかなり意訳してあるところもあります。不明瞭な所は適宜RFC1459原文の該当箇所を参照して下さい。 意味の通じないところ、訂正すべき箇所、適切な訳案がございましたら、E-mailにてご連絡くだされば幸いです。
早稲田大学理工学部電子通信学科 野々垣直浩
Email:g95g0819@mn.waseda.ac.jp
重ねてみなさまのご協力、よろしくお願いいたします。
田村健人が行いました。