// jcol tool lab / RFC から読めない IRC


RFC から読めない IRC

IRC の極意や上級者/開発者向けの高度な情報

元々は, IRC の暗黙の了解, tips などについて個人的にメモしていた文章でした.

そろそろ内容の追加と見直し, 構成の変更やページ分割などをするかもしれません (検討中).

URL 移動中:

[index] は目次に移動します. [here] はその場所自身のアンカーです. このアンカーなどは, 将来的に (近い将来ほぼ確実に?) 変更が入ります (の予定?).

[index] [here]

はじめに

IRC の RFC (RFC1459) には, メッセージに関する厳密な規定が存在していないため, その利用の自由度は極めて高くなっております. それにより, client を作成/利用する側は, 自由に新しいメッセージ仕様を作成し利用することが可能となっています.

ただし, 各ユーザーの client ごとにばらばらな仕様になってしまうと, コミュニケーションの道具として, メリットを失う場合もでてきます. そのため多くの client では, ``規定はないけれども (暗黙の了解として存在する) あいまいな仕様'' に対して合わせようとしています. このページは全体的に, その仕様に対しての憶測を 著者が自分のためのメモ書きとして記述しています.

このページに書かれてある内容に一切の保証はありません. このページが原因で何らかの問題が発生しても一切関与しません. 内容が不正確であるところもありますが, 元が「自分のためのメモの一部を公開」という方針であるため, 原則として「たぶん」「おそらく」という情報の羅列です (でも, たまに正確なところもあります).

なお「RFC から読めない IRC」という言葉は, 「IRC については, RFC から読むことができません」 という主張を意図しているわけではありません. 「IRC については, 全てが RFC に記述されているわけではない, その記述されていない部分について」 とでも, 適当に解釈してください.

[index] [here]

無保証, 免責, 権利, 制限

無保証: 本文書は無保証であり, 正確であることを保証していないことをあらかじめお伝えしておきます. 中には間違い情報があるかもしれません; いや, きっとあるでしょう. 間違い指摘等を元に, 時々修正されているのが現状ですが, 修正する義務はないものとします. 本文書内の情報を鵜呑みにしないでください. 記述されている内容を利用し別の文書として公開する場合は, 他の情報源からも情報を収集し裏を取った上で行うことをお勧めします.

免責: 著者はこの文書の内容が正確であることを保証しません. それに対する関係を問わず, 著者はこの文書の影響により発生するいかなる事柄につきましても, 一切責任を負いません. この文書を読み内容を信用してそのとおりに行動したところ, 何らかの損害が発生したとしましても, 文書の著者に責任はないものとします. その点について納得し, 自分の行動の責任を自分で取れる覚悟のある方のみ, この文書を利用することが可能です. なお文責そのものは著者にあります.

権利, 制限: 著作権はCopyright 表記のとおり保持され放棄されておりません. 文書中の引用, 転載など部分的に埋め込まれた著作物は, その場に記述される Copyright 表記に従います. Copyright 表記が存在する場合, 文書中のどこであっても, その表記部分を不当に削除/変更する行為は認められません.

この文書に記述されている「単純に事実を現すだけの情報」の部分につきましては, 当然のことながら, その部分に関して言えば, 著作権を主張することができるような著作物ではないと判断できます. ただし, ときには 「単純に事実を現すだけの情報」 のように見えて実はそうではない作文も存在しますので, 記述されてる情報を断片的にピックアップし他の場所で公開する場合はご注意ください.

例えば URL などの情報はあきらかに単なる事実を現す情報です. 「A の部分に記述できる文字列の長さは n バイトまでである」, 「B の部分に使用できない文字コードは以下のとおりである」 というような情報も同様です. それらの情報につきまして, 著者は権利を主張することもなく, 読む人は自由に利用し, 他の場所にその情報を記述し公開することができるものとします (いずれにしても, 利用する場合は免責に関して同意しなければなりません). ただし, URLなど事実を現す単純な情報であったとしても, それが記述されている文章そのものは著者独自の文章表現であり, これはあきらかに著作物です. それをそのまま転載, もしくは一部改変し公開する場合は, 権利を尊重する必要があり, 著作権者の許可を得なければなりません. 引用の場合は例外となりますが, 正当なる引用の範囲から外れないようご注意ください.

[index] [here]

警告

(2000年1月末から2月頭での状態において) URL http://www.friend.td.nu/irc-memo.html 文書内の記述を見ると, いくつか本文書からの転載らしき記述が見られます. その中の一部になりますが, 具体例を挙げるため, 以下に引用します.

本文書の記述
00###■###FFFFFF 白
01###■###000000 黒
02###■###000080 暗青
03###■###008000 暗緑
04###■###FF0000 赤
05###■###800000 暗赤
06###■###800080 暗紫
07###■###FF8000 橙
08###■###FFFF00 黄
09###■###00FF00 緑
10###■###008080 暗水
11###■###00FFFF 水
12###■###0000FF 青
13###■###FF00FF 紫
14###■###808080 暗灰
15###■###C0C0C0 灰色
http://www.friend.td.nu/irc-memo.html 内の記述
色文字

^C0hogehoge^C0番目の色FFFFFF白
^C1hogehoge^C1番目の色000000黒
^C2hogehoge^C2番目の色000080暗青
^C3hogehoge^C3番目の色008000暗緑
^C4hogehoge^C4番目の色FF0000赤
^C5hogehoge^C5番目の色800000暗赤
^C6hogehoge^C6番目の色800080暗紫
^C7hogehoge^C7番目の色FF8000橙
^C8hogehoge^C8番目の色FFFF00黄
^C9hogehoge^C9番目の色00FF00緑
^C10hogehoge^C10番目の色008080暗水
^C11hogehoge^C11番目の色00FFFF水
^C12hogehoge^C12番目の色0000FF青
^C13hogehoge^C13番目の色FF00FF紫
^C14hogehoge^C14番目の色808080暗灰
^C15hogehoge^C15番目の色C0C0C0灰色

とりあえず, このような類似記述となっておりました. 16進数6桁による色の表現につきまして, おそらくこのような値となるのではないか, と私が予想した結果がこの数値です. この数値が完全に同一となっています. 漢字による色表記 (暗水, 水,...,暗灰, 灰色) も見事に同一の表現を行っています. 他の色は「色」という文字を付けていないのに 「灰」にだけ「色」を付けてしまったのは, 私の記述ミスだったわけですが, ここまで完全に同一となっています.

この部分を見ますと, まずは私の書いた文書をそのままコピーし, そして一部表の左側あたりの改変を行ったのではないかと予想します. すなわちこれは, 安易なる改変付き無断転載とも言えます. この行為が著作権法に反するかどうかについては, 簡単に判断できず, また判断するつもりもなく, 争うつもりもありません. しかし少なくとも, ここまで安易な複写改変をやられますと, 決して嬉しくはありません. この部分に限らず, 似た感想を持ってしまう記述は他にもありましたが, とりあえずこの部分だけ言及致します.

もし, 転載ページが非常に人気のあるページであり, 本ページが非常にマイナーなページであったとしたら, 読者の中によっては正しくない判断をしてしまうかもしれません. すなわち本サイトの方が無断転載改変を行っているのだ, と判断されてしまうかもしれません. ただでさえ奇妙な転載をされて嬉しくない状態である上に, 逆に転載を行ったと扱われてしまってはたまったものではありません. しかし, それを防ぐ記述はどこにもありませんでした. そのためにも, そしてまた, 今後類似の問題が発生することを防ぐためにも, 改めてこの件をここに記述させていただきます.

免責など著作権者の意思を尊重する限り, 本文書内に含まれる情報は御自由に利用できるものとします. それには他の場所での公開等も含まれます. ただし, 表現そのものに関して, そのような自由はありません. 著作権法に従い, 著作権を尊重し, 一般的な著作物同様の扱いをしていただけるようお願い申し上げます.

 [here]

目次

[index] [here]

LINK

[index] [here]

PICKUP

IRC を始めたばかりの人は, あまりうろうろしていると迷子になりますし, 本ページを読んでも何の役にも立ちませんので, もっと良いページを参考にしてゆっくり IRC に馴染んでください.

| IRC users in Japan Home Page | IRC 普及委員会 | IRC 広告版 |
| murichat | CHOCOA |

他にも良いページは沢山ありますが, 迷子にならないようこれだけならべてみました. さらに多くのページを閲覧したいと考えるなら, 下に並ぶリンク先や, リンク先のリンク先を辿ってみてください.

[index] [here]

RFC1459

まずは, RFC に書かれていることを理解しなければなりません. 以下に並べてある RFC へのリンクを参考に RFC に目を通しましょう. なにしろ, このページは RFC にひととおり目を通して半分ほど分かった人, RFC には全部しっかり目を通した人, これを読者の条件としています.

以下, RFC へのリンク.

他のサイトから RFC を入手したいときは, RFCFIND からお探しください.

[index] [here]

本サイト内の文書

[index] [here]

他サイトへのリンク

[index] [here]

irc server

ircd のソースを読みましょう.

[index] [here]

irc bot

「bot」「ボット」, それは robot (ロボット) です. 「bot」の言葉の定義はいろいろあるでしょうけれども, ここでは「`bot' == `software robot'」とします. robot と言っても, そこに機械的な装置はない, すなわち, hardware としての robot ではありません. 自動運転のために必要とされる機材は, すでにそこに存在している general purpose な物だけです. bot の自動運転のため仕組みは (基本的に) 全て software だけで作成されています. 結局のところは IRC Client です. 基本敵には, 単なる IRC Client です.

ただし, この定義が万能ではないことに注意してください. 人により, また場面や話題により定義は異なるでしょう.

簡単な bot 程度なら自作するとよいでしょう. 多機能が欲しいとき, いろんな bot のソースを見たいときは, いろんな bot を使ってみましょう.

[index] [here]

IRC client for Java

詳細不明. Java を選択するメリットはほとんどないでしょう. 温泉に行きたいという人に入浴剤を与えるようなものです (詳細不明). WWW ブラウザー上で動作すればお手軽という声もありますが, たかが IRC client を動作させるために 巨大な WWW ブラウザーを経由させること自体道を踏み外しています. 電車の中でゲームがしたいからといって小型ゲーム機を欲しがる子供に, ゲーム機に加え電車をプレゼントするようなものです (詳細不明).

[index] [here]

IRC gateway (pirc...)

IRC 常駐支援などを目的とした, IRC 接続の gateway となる soft です. IRC gateway は IRC server に IRC プロトコルに基づいてあらかじめ接続します. そのあとで, IRC client は IRC gateway に (まるで server に接続するように) IRC プロトコルに基づいて接続します. ダイアルアップの切断などにより client と gateway の間が切断されても, gateway と server との間の接続は維持されます.

たとえ client 側の環境が常時接続不可能であったとしても, server への常時接続が可能となる環境に gateway プログラムを置き, そして動作させることで, 擬似的な常時接続を実現することができるようになります. channel 内のログ収集, nick や channel の名称の維持, といった目的/メリットがあります.

[index] [here]

IRC client for misc

他に分類されていない環境で動作する IRC client です.

[index] [here]

IRC client for win32

簡単な client 程度なら自作するとよいでしょう. フリーウェアでいくつか公開されている物を使っても良いでしょう.

[index] [here]

IRC client for Mac

[index] [here]

IRC client for Linux/Unix/X11

Linux 向け, Unix 向け, X11 向けなど, とりあえず Linux 上で動作しそうな IRC client です.

[index] [here]

IRC で利用される日本語 character set (文字集合; 文字コード)

`「いわゆる半角カナ」について' も参照してください.

IRCnet など一般的な IRC server (群) において, 通常日本語を利用する場合, charset (文字集合) として ISO-2022-JP を利用します. charset ISO-2022-JP は, 複数の charset の組合せです.

RFC1468 (ISO-2022-JP) において以下の 4 種類が存在します:

       Esc Seq    Character Set                  ISOREG
       ESC ( B    ASCII                             6
       ESC ( J    JIS X 0201-1976 ("Roman" set)    14
       ESC $ @    JIS X 0208-1978                  42
       ESC $ B    JIS X 0208-1983                  87

RFC2237 (ISO-2022-JP-1) において以下の 5 種類が存在します:

   reg# character set     ESC sequence                  designated to
   6    ASCII             ESC 2/8 4/2                   ESC ( B    G0
   42   JIS X 0208-1978   ESC 2/4 4/0                   ESC $ @    G0
   87   JIS X 0208-1983   ESC 2/4 4/2                   ESC $ B    G0
   14   JIS X 0201-Roman  ESC 2/8 4/10                  ESC ( J    G0
   159  JIS X 0212-1990   ESC 2/4 2/8 4/4               ESC $ ( D  G0

しかし, IRC 上ではこの 4|5 種類のうち 「ASCII (ESC '(' 'B')」 「JIS X0208-1983 (ESC '$' 'B')」 の 2 つだけを使用します. ただし, 一般的であるだけで, 規定はありません.

仕様として IRC server は 8 bit 目の情報も問題なく扱うことができます. また, PRIVMSG などメッセージの中では, 0x00 と 0x0A と 0x0D の 3 つを除き, 文字コード 0 から 255 までの間の全てを利用することができます. そのため Shift_JIS や EUC-JP などお好みの charset で 会話を行うことも可能です. どの charset を採用するかは, その場で会話を行おうとしている人達の間の 合意によって定められることが原則でしょう. それを省略したときのデフォルト値として, 先ほど挙げた ESC(B ESC$B によるレジスター切り替えの方針が存在しています.

[index] [here]

メッセージ内の ASCII 制御コード

IRC のメッセージ内における ASCII Control Character (ASCII 制御文字 0x00-0x1F) の扱いについて記述します. このセクションにおいて, 「メッセージ」は, 「PRIVMSG, NOTICE コマンドの Trail 部分」を表現しています.

CodeComment
^A 0x010x01 で挟むことによりその間の文字列は CTCP とし て扱われます. ほとんどの client はこれを考慮しています.
^B 0x02Bold. ^B が登場するとそこから太い文字となり, 再度登場すると解除となります. 奇数個の登場もありえますので基本的に行末で全て解除と考えます. 多くの client はこの存在を考慮しているでしょう.
^V 0x16Reverce. 反転表示です. Bold 同様の扱いです. CHOCOA など一部 client は反転ではなく斜体文字になるようです.
^_ 0x1FUnderline. 下線です.
^@ 0x00 NUL
^M 0x0D CR
^J 0x0A LF
RFC 規定により Trail 内での使用は禁止されています (RFC1459 sec.2.3.1 line.443)
NUL は全面的に使用禁止です. CR, LF は行 (1つのメッセージ) の終りを現すためだけに使用されます.
^C 0x03 mIRC, CHOCOA など色文字を扱える client は, これによって文字の色が制御されます. 後ろに ASCII 数字文字が 2 byte 続き, その値が色の指定となります.
[index] [here]

mIRC などでの色指定

00###■###FFFFFF 白
01###■###000000 黒
02###■###000080 暗青
03###■###008000 暗緑
04###■###FF0000 赤
05###■###800000 暗赤
06###■###800080 暗紫
07###■###FF8000 橙
08###■###FFFF00 黄
09###■###00FF00 緑
10###■###008080 暗水
11###■###00FFFF 水
12###■###0000FF 青
13###■###FF00FF 紫
14###■###808080 暗灰
15###■###C0C0C0 灰色

試してみたところ, およそこのような感じになりましたので, ここにメモしておきます.

なお, この色コードの仕様とは異なる色コードを扱っている IRC client soft もあるようです.

Color FAQ <http://www.ircle.houseit.com/colorfaq.html> この Ircle Color FAQ によると, Ircle では Ctrl-C の次の 1 byte が色を決めるようです.

[index] [here]

CTCP

CTCP は, メッセージを 0x01 (^A) で挟むという書式となります. ここでの「メッセージ」は, PRIVMSG もしくは NOTICE の Trail の全部, もしくは一部です.

PRIVMSG コマンドを使って送信すると CTCP-query (質問) となり, NOTICE コマンドを使って送信すると CTCP-reply (回答) となります. (この呼び方は, 著者が便宜上そう呼んでいる表現をそのまま記述しているだけであり, 一般的にどう呼ばれるか不明です)

CTCP (Client To Client Protocol) は, server 経由のメッセージを利用しています. PRIVMSG コマンドを利用しているため, server から見れば通常のメッセージと変わりありません. 質問元 client が質問先 client に質問メッセージを送信し, 質問先 client がそのメッセージに応じた回答メッセージを 自動で送信することにより CTCP が実現します. 一般的に, Client-Client 間の Ping チェック (往復にかかる時間を調べること) や, 相手の Version 情報 (使用している client soft の名前やバージョン) や, 相手のローカル時刻 (相手の client コンピューターのシステム時計) 情報などを得るために, CTCP は用いられます.

質問は, 相手の Nick もしくは#channel に対しての PRIVMSG コマンドです. 質問先の種類が nick or #channel のいずれの場合であっても, 回答は, 質問元の Nick に対しての NOTICE コマンドです.

[index] [here]

良くない CTCP への反応

もし, メッセージの中に頭の (CTCP の始まりを示す) 0x01 が存在しているにも関わらず, 後ろ側の (CTCP の終わりを示す) 0x01 が存在しない場合, これを CTCP と扱うかどうかは client soft によって異なるようです. (例えば, CHOCOA では CTCP 扱いしません. 他の client では CTCP 扱いとすることが若干多いと憶測...) 多くの client では, "PRIVMSG target :\x01CTCPcommand\x01\x0D\x0A" というメッセージを CTCP(-query) として発行します. すなわち, PRIVMSG の trail 部分全体を 0x01 で囲みます. 1 つ目の 0x01 より前に何か文字列があった場合や, 2 つ目の 0x01 より後ろに何か文字列があった場合, このような CTCP を受けたときの動作は client によります.

本来の CTCP の方針としては, メッセージの一部だけを CTCP にすることも可能であり, また 1 つのメッセージの中に複数の CTCP を埋め込むことも可能だそうです. よって "PRIVMSG target :\x01A\x01\x01A\x01\x01A\x01...\x0D\x0A" というメッセージも「ありえる」ことになります. IRC の仕様上, 1 メッセージの最大長は CR LF 含めて 512 byte です. ":fromnick!fromuser@fromhost PRIVMSG nick-name :\r\n" という 49 byte を除くと仮定すれば残りは 463 byte であり, そしてその中に "\x01A\x01" という 3 byte を 154 個並べることができます. さて, そのような 150 件を越える CTCP を埋め込まれたメッセージ 1 行を受信したときの動作, これは client によって異なっているのが現状です.

まず, `A' という CTCP を受信したとき, すなわち知らない query を受信したときの扱い方が client によって異なります. ある client は, それを完全に ignore します. ある client は, 「エラーである. 知らない query である」といったメッセージを返します. ある client は, CLIENTINFO を受けたときと同じように扱い, 知っている query を羅列して返します. それら以外の反応を示す client もあるかもしれません.

また, 1 行に複数 CTCP を詰め込んだ query を受信したときの反応も client によって異なっています. まじめに正しく, 全ての CTCP query に反応を示す client もあります. 最初の 1 つだけ CTCP として扱う反応もあります. 全て CTCP として扱わない反応もありますが, そのとき, メッセージ全体をただのメッセージとして画面に表示する方針もあれば, 全て ignore してしまう方針もあるでしょう.

もし, `A' という CTCP にまでしっかり返事を行い, また, 1 行に複数 CTCP を詰め込まれている query を受けたとき全てに反応をするという仕様で, しかも, その 2 つが両立する (排他しない) という仕様ならば, 150 以上の query を詰め込まれたメッセージを受信したあと, おそらくまじめに 150 件の返事を行うことでしょう. 300 sec (5 min) のペナルティーです. flood protection が無ければ, すぐに server から切断されてしまいます (この場合は無い方が幸せ).

さて, どのような仕様が「良い」のでしょうか. これは価値観によって違いが出てくることでしょう. まず複数 query を 1 行に詰め込まれたときの反応ですが, それを CTCP 扱いしないという (CHOCOA のような) 仕様はいただけません. それは手抜きです. ただし, 100 以上あっても全て CTCP 扱いするのも問題であり, 10 個まで, 5 個まで, といった限度は設けるべきでしょう. そして `A' というような unknown query を受けてしまったときの反応ですが, ignore も一つの考えですし, また CLIENTINFO として扱うのも一つの考えです. 反応することに問題はないのですが, 前述の「1 行に詰め込まれた複数 CTCP への反応」 と両立してはいけません. 「知らない query に対して, 私の知っている query はこれだけですよと返事する行為」 を連続で行う必要性を考慮すれば良いでしょう.

[index] [here]

CTCP の応用例

以下, 各種 CTCP の具体的内容について記述します.

[index] [here]

PING

書式例

Q: PING 123123
A: PING 123123

手元の端末から遠隔の端末まで, 情報伝達に必要な時間を知るため, 試験用の小さな情報を往復させ, 往復にかかった時間を調べる手段を一般的に PING と呼びます. IP を実装しているシステムに標準搭載されている ICMP の ECHO を利用した「いわゆる PING」 と同様の目的で使われることでしょう.

IRC CTCP の PING では, 質問元 client のシステム時刻を現す文字列を, 質問元 client から質問先 client に向かって, CTCP-query にて送信します. 数値化の書式は, client の種類などにより異なります. \x01 で挟まれる文字列は, "PING" + 空白 + 数値部分の文字列 となることが一般的のようです. 数値を表す文字列は単純に 10 進数表記の文字列となることが多いようです. 値は time_t そのまま, もしくは time_t の下位一部の桁, もしくはそれに 100 分の 1 秒や 1000 分の 1 秒の値を混合させたデータになるでしょう. CTCP PING のパラメーターをどのような書式にするかは, 質問側 client の自由です. 質問した通りのデータが常に返ってくるとは限りませんし, 質問していないときに回答が返ってこないわけでもありません. あらゆる client は, 突然の, そして予想もしない書式の CTCP PING reply を受信したとき, 正しく処理できなければならないでしょう.

受け取った質問先 client は, そのままのデータを CTCP-reply で回答します. この回答は自動的に即時行われます. CTCP PING の存在価値は, その回答の即時性にあります. 回答を受け取った質問元 client は, 回答を受けた時刻と, 回答に記述されたデータを比較し, 往復に要した時間を得ます. この時間が, 会話における `lag time' (ラグタイム; 遅延時間) となります.

IRC 利用者が, 極めて高速に文字を読み, 極めて高速に文字を入力したとしても, CTCP PING で得られる `lag time' より早い会話の往復を行うことはできません. CTCP PING で判明する `lag time' と, 「(相手および自分という 2 人分の) 利用者の動作に必要な時間」 を加えた値が, 「実際の会話の往復時間」となります.

`lag time' は, ネットワーク事情により (時には激しく) 変動するため, 注意が必要です. 数分前に計測した CTCP PING の結果は, 今現在の事情を現していないかもしれません.

`lag time' というのは, 常に存在するかもしれない, ということに注意してください. 特に (地理的にではなくネットワーク的に) 遠距離となる server 間では長い `lag time' の発生が起きます. 「今までリアルタイムで会話していたのに, 突然返事がなくなった」 というとき 30 分後に返事が返ってくるかもしれません. server A から server B に向かって, もしくは逆方向, もしくは両方向のデータ転送に遅れが出ている状態ということです. 「知人二人が仲良く会話しているのを発見したため, その会話に参加し, いろいろ喋ってみたのだけれど, 反応がない, 無視されている」 という状態のとき, 実際のところ, 1 時間ほど前に行われた二人の会話が, 今ごろになって自分の server に届いていたのだ, というハジカキ逸話もあります.

注意してください: Server PING/PONG は, 質問が "PING" 回答が "PONG" です. CTCP PING は, 質問も回答も "PING" です.

この CTCP PING は, 多くの client soft が対応している CTCP です.

[index] [here]

VERSION

書式例

Q: VERSION
A: VERSION SoftwareName VersionNumber Platform Etc

使用している client soft のバージョン情報 (client soft の名前, バージョン, OS 等プラットフォーム, など) を得るための CTCP です.

(他の CTCP も同様ですが, 特に CTCP VERSION) この回答が正確であるという保証はどこにもありません.

この CTCP VERSION は, 多くの client soft が対応しています.

[index] [here]

TIME

書式例

Q: TIME
A: TIME Sun Jan 01 01:01:01 1991
A: TIME Sun Jan 01 01:01:01 1991 GMT
A: TIME Sun Jan 01 01:01:01 1991 JST
A: TIME Sun Jan 01 01:01:01 1991 +0900

client soft が動作しているシステムのシステムクロック情報をローカル時刻表記で送り出します. 書式は, time_t t=time(0);ctime(&t) が一般的のようです (が, 詳細不明).

相手の時計のずれ (もしくは自分の時計のずれ) を知るために利用可能です. 相手の国・地域を知るため, もしくはその地域の時刻を知るために利用することも可能です. 通常, 相手の地域を知りたいとき, まず hostname に目を向けるでしょう. そのとき, CTCP TIME にも目を向けると良いでしょう.

この CTCP TIME は, 多くの client soft が対応しています.

[index] [here]

CLIENTINFO

書式例

Q: CLIENTINFO
A: CLIENTINFO :DCC PING VERSION CLIENTINFO USERINFO TIME

どのような CTCP を理解するか, について質問します. 受けた側は, 自分が実装している CTCP を羅列して回答します.

この CTCP CLIENTINFO は, 多くの client soft が対応しています.

[index] [here]

FINGER

書式例

Q: FINGER
A: FINGER :username@domain
など

ユーザーのドメイン情報, フルネーム, E-Mail アドレスなど, ユーザーに関する情報を返します. 返答の内容や書式は, client によって異なります. ドメイン名を返す場合は, client 自身が gethostname() などによって理解している自分のホスト + ドメイン名, もしくはユーザー自身が登録した E-Mail アドレスのドメイン名など 回答することが多いようです. IRC server への接続で使用したユーザー名を返すこともあるかもしれません. 逆引きできていない環境で, server 経由では IP-Address しか伝えられない場合でも, CTCP FINGER によりドメイン名を伝えることが可能かもしれません. 逆に伝えたくない場合でもこれにて伝わることがあります.

この CTCP FINGER には, 一部の client soft が回答を返します.

例えば
mIRC の場合: FINGER RealName (Email-Address) Idle nnn seconds
murichat の場合: FINGER UserName@Host.DomainName

[index] [here]

USERINFO

書式例

Q: USERINFO
A: USERINFO helllooohelllooo my web site is http://www.......

ユーザーが出力するように指示した情報 (ユーザーの関する情報) を返します. 自分の WWW サイトの URL, メールアドレス, なにかコメント, その他, 自分の情報について公開したい事項を返すようあらかじめ設定しておきます.

この CTCP USERINFO は, 多くの client soft が対応しています.

[index] [here]

ACTION

書式例

Q: ACTION is away
A: (返答なし)
Q: ACTION will go to dinner
A: (返答なし)

例外的な CTCP です. 受け取った側は返答しません. 自動応答を期待して送られる他の CTCP とは異なり, メッセージに属性を付けるために使用します.

通常のメッセージ, たとえば

:Alice PRIVMSG #channel :hello

には,

Alice は #channel に向かって「hello」と発言しました ( or 言いました).

という意味があると考えられます. CTCP ACTION の場合は, この「発言しました」の部分まで送信者が記述します.

そのため,

この 2 つは同じ意味であると考えられます. 日本語の場合は,

が同じ意味になると考えられます.

CTCP ACTION は, 送信者が自分の動作や状態を表現するために使用します. "\x01ACTION eat dinner\x01" のように記述します. 受け取った側は, "Alice eat dinner" のように, 受信した ACTION 内容の頭に送信者のニックを付けて表示することが一般的です.

ACTION は「自分の動作や状態を現す手段」であることに注意が必要です. そして「受信 client 上ではその文章の頭に送信者の nick が付加される」 ということから, 「自分の nick が頭に付くような文から, 頭に付いている nick を除去した結果となる文字列」を ACTION にて送信することになります.

この CTCP ACTION は, 多くの (ほとんど全ての) client soft が対応しています. どのような client であっても, CTCP ACTION に対して, 自動返答しない方が良いでしょう.

[index] [here]

DCC

使用例

Q: DCC SEND filename ipv4-addr port size
Q: DCC CHAT chat ipv4-addr port
A: なし

DCC (Direct Client to Client ; server を経由しない client 同士の直結) を実現します. この CTCP-query が, DCC 接続の要求となります. DCC SEND と DCC CHAT の 2 つが一般的に普及しています. それ以外の DCC も client 独自として多く存在します.

DCC のパラメーターには, 自分の IPv4-Address と待ち受ける port 番号を 10 進数文字列で記述する部分があります. IPv4-Address の箇所は, 符号無し 32 bit 整数値の 10 進数表記文字列を記述します. IPv4-Address が a.b.c.d であれば, (((a*256)+b)*256+c)*256+d という値になります. おそらく ntohl() などが使われることでしょう.

DCC SEND の場合は, "DCC SEND" という文字列, 送信しようとするファイル名, IPv4-Address, PORT, そしてファイルのサイズを記述します.

DCC CHAT の場合は, "DCC CHAT" という文字列, "chat" という文字列 (この部分はおそらく他でも可?), IPv4-Address, PORT を記述します.

他の CTCP と異なり, 受け取った側は, NOTICE コマンドによる server 経由の返答を行いません (それが一般的です). 送る側は, CTCP DCC (CHAT/SEND) を送る直前に, 指定する PORT 番号で Listen (待ち受け) します. すなわち DCC を発信した側が DCC (client 間直結) の server となり, DCC を着信した側が DCC (client 間直結) の client となります. それは FTP でいうところの PORT であり PASV ではありません. DCC を着信した側は, DCC を発信した側が指定する IPv4-Address:PORT に接続を試みます.

これは DCC 対応 client のみ対応している CTCP です. (多くの場合対応しているはずです)

[index] [here]

DCC について

IRC client 間で簡単にファイルの受け渡しをするために (?) 作られたプロトコルです. DCC (Direct Client to Client - server を経由しない client 同士の直結) により client 間が接続されれば, 任意のデータを流すことができます. 接続のための「タイミング」「待ち受け場所 (IPv4-address port-number)」 を伝える用途のために CTCP DCC が利用されています. client 間直結の接続が成功した後は, IRC server も IRC プロトコルも無関係となります.

一般的な DCC には, SEND CHAT があります. CTCP DCC の書式には, 自分の IPv4-Address と, 待ち受ける port-number を 10 進数文字列で記述する部分があります. port-number の表記は URL に記述される物と同じ文字列ですので, 誰もが簡単に分かることでしょう. IP-Address の表記は, ピリオド区切りではなく, 符号無し 32 bit 整数値の 10 進数表記文字列 printf("%u",n) となります.

CTCP (privmsg の trail 部分を 0x01 で挟む) の書式は以下の通りです.

通常, CTCP-query を受け取ると, 受け取った client が 自動的に, NOTICE コマンドにて CTCP-reply を返します. しかし, DCC の場合は, ここで reply を返さないのが一般的のようです.

前述と繰り返しになりますが, DCC SEND/DCC CHAT を発信した側は, 発行する直前に自ら指定した port-number を listen (接続待ち受け) します. すなわち DCC を発信した側が DCC 接続の server となり, DCC を着信した側が DCC 接続の client となります. DCC を着信した側は, 指定の IPv4-Address:port-number に接続を試みます.

DCC CHAT において, 日本語を使って会話を行う場合, IRC server 経由のときに使用していた (する予定の) charset と同じ charset を使うと良いでしょう. ただし, ISO-2022-JP に限らず, Shift_JIS/EUC-JP などを使うこともあります. また, 改行コードは, CR+LF に限らず, LF のみのこともあります. 日本語の送信に関して, その選択を考慮することもあるでしょうけれど, 日本語の受信に関しては, 選択の考慮は全く不要であり, 全て自動認識とするべきです.

[index] [here]

DCC SEND について

DCC SEND は, ファイル送受信のために必要な基本的な情報しか送りません. ファイルのサイズについては, CTCP DCC SEND に付加されている数値が正しいサイズとします.

DCC SEND には, 他の (IRC 以外の ftp, http などの) プロトコルにはあまり見かけない ACK という概念/動作があります. ファイル受信側は, ひとつのパケットを受け取るごとに, 受け取った総サイズを返答します. 返答は, 4byte (32bit) の数値です. もし, 受け取ったファイルの累積サイズが 40000 の場合, 以下のような返答となるでしょう.

/* unsigned long size=40000; */
unsigned long sizeN=htonl(size);
send(socket,(char*)&sizeN,sizeof(unsigned long),0);
	

ACK を返し, ACK を受けることによるメリットは, ファイル送信側の実装の容易さです. 送信側は, 常に ACK を待ち受け, ACK が返ってきたとき次のパケットを送信するだけでよいでしょう. もし, ACK なしの場合, 送信側は, とりあえずバッファーが溢れるまでできるだけ多くのデータを流し込み, バッファーが溢れたら, しばらく待機し, タイマーでまた溢れたパケットを送り直す必要があります. タイマーは毎秒程度, もしくはそれより高頻度となるでしょう.

面倒ですね. 面倒ですね. けれども, 貴方が IRC client を作成し, DCC SEND を実装しようとするならば, ACK だけに頼らず, この動作も実装すべきです. 強制的な送り込みをすることでファイル転送速度は飛躍的に向上します. ACK を待ちながらのんびり送信するモードと, ACK を無視して強制的に送信するモード, この2者を切替えるオプションを用意してもよいでしょう. GUI ならば送信直前に表示するダイアログボックスに, 送信モードを指示するチェックボックスを含めるのも手段です.

というわけで理想の実装としては, 送信側は返ってきた ACK を無視して (取り込みをして, それを捨てる), 次々とデータを流し込みます. 溢れたらその部分でひとまず諦め, 毎秒程度のタイマーにて, その部分からまた送り直します. 受信側の実装は, とりあえず ACK を返すべきです. ACK を返さないと続きを送ってくれないような IRC client も時には存在します. しかしながら, さらなるいやらしい実装も可能です. 「どうやら送信側はACKとは無関係で送って来るようだ」 ということを受信側が憶測します. ACK不要ならば途中からACKの送信をやめましょう. それでデータが止まってしまうようならば, また ACK を送るモードに切替えます.

ちなみに, IRC client が動作しているホスト間でファイルを送受信したい場合, DCC SEND が事実上最も高速な手段となります. ここで言う速さは, 転送開始から転送終了までの時間ではなく, ユーザーが「送ろう|受けよう」と判断してから それが完了するまでの時間を基準とします.

IRC client 間で FTP を利用してファイル転送する場合, 何らかの方法で, PRIVMSG(or NOTICE) を使って, タイミングと場所のハンドシェイクを行います. client soft は, その情報を FTP client soft に送る, もしくは自分自身が FTP client となります. この伝達部分が手作業であれば, 極めて不正確かつ長い時間を要することとなります. そのあと, FTP Client/Server 間にて, ユーザー認証が行われ, そのあとデータ用のコネクションにて データの送受信が始まります. DCC SEND であれば, ここまでの時間が不要となります.

一度データが流れ始めてしまえば, FTP も DCC SEND も, 速度は同じです. ただし, 一部 IRC client の中には ACK 処理で無駄な時間をかけてしまうなど, 平均速度が低速となる種類もあるようです. 通常の, 高速送信を考慮して作られた IRC client であれば, その転送手段より早くファイルを送る一般的な方法はないと考えられます. どうしてもさらに高速化したい場合は自動圧縮の検討です. さらに高速化したければ TCP を捨てるしかありません.

[index] [here]

1 つの client 接続が JOIN できる channel 数の限界

一般的に, MCPU (Max Channels per User) = 10 もしくは 20 であり, すなわち同時に JOIN できる channel は 10 もしくは 20 箇所までであり, 多くの server の設定はそうなっているようです. ただ「多くの server がそうなっている」という情報は, 「その server ではどうなっているのか?」という疑問への回答としてふさわしくありません. IRCnet の場合, 2.10 系に移り始めている時期においては, MCPU=20 の server が増えてきているようです. 実際に使っている server で, どのような設定になっているかは, STATS コマンドで調べてください.

ここで表示される status の中の, `MCPU' が同時に参加できる channel の最大値です.

[index] [here]

channel 名

channel 名の prefix 文字として, channel 名の頭には何らかの奇妙な記号文字が付くでしょう. その記号文字は channel の種類を現します.

ircd 2.10.x 系では, `#', `&', `+', `!' の 4 つが channel 名 prefix 文字となっています.

[index] [here]

#channel-name

通常, channel 名の頭には, `#' がつきます. これは, `#' も含めて channel 名となります. 名前の頭に `#' が付いた channel は, IRC 空間 (接続された IRC server 群) で共通の channel となります.

[index] [here]

&channel-name

頭に `&' が付くと, server 内でだけ有効な channel になります. 同じ server に接続している client 同士でしか会話ができません. server が異なれば, 同じ名称であっても異なる channel として扱われます.

また, `&' が頭に付いた channel では, `+a' つまり "MODE &channel-name +a" のコマンドで, anonymous channel (匿名 channel) になります. anonymous channel になると names who のリストから他の参加者を知ることができなくなります. 発言などは, 全て "anonymous" というユーザーからのように見えます. channel 内のユーザー状況が全く分からなくなる +a (anonymous) channel ですが, 例外として, /list &channel-name とすれば, 人数だけ知ることができます.

[index] [here]

#channel-name:*.jp

channel 名末尾に, ":" (コロン) とドメイン名を記述すると, その channel は, その条件に一致するドメイン名の `server' からしか利用できません. 条件の対象は, client のドメインではなく, server のドメインであることに注意が必要です. つまり, :*.jp がついた channel に参加したい場合は, *.jp の server から入れば, 海外ドメインの client からでも参加可能となります. これについての更なる情報は後述します.

[index] [here]

%channel-name

"%" + channel 名という書式は, IRC として存在しません. しかしこれは一部の client で使用できる書式です. その一部の client は, "%channel-name" を "#channel-name:*.jp" に置き換えて server と通信します (その *.jp の部分はユーザーの設定により変化します). 本来, 正しくは "#channel-name:*.jp" と記述するべきところですが, それを client の機能で "%channel-name" という短い記述に対応したまでです. つまりこれは, client 内部で完結する alias 機能です.

[index] [here]

+channel-name

"+" + channel 名 という名称の channel では, オペレータ権限が一切使えません. 通常の channel では, 最初に JOIN したユーザーが自動的に channel-op となりますが, "+" が頭につく channel 名の場合, 最初に JOIN したユーザーが自動的に channel-op とならない, と考えることもできます.

[index] [here]

!channel-name

ircd の 2.10.x 系で利用できる種類です. 2.9.x 系にはありません. 2.10 から作られた新しい機能「安全な channel」のための prefix です.

新規作成する場合は, JOIN !channel-name ではなく, JOIN !!channel-name です. 新規作成のための JOIN は `!' (エクスクラメーションマーク) が 先頭に 2 つ連続付きます. 新規作成に成功すると server はその channel に数文字の文字からなる ID を与えます. 例えば, "JOIN !!channel-name" とコマンド発行すれば, ":mynick!myname@myhost JOIN !ABC123channel-name" というメッセージが返ってくるでしょう. それと同じ channel に入りたい別の人は, "JOIN !channel-name" や "JOIN !ABC123channel-name" といったコマンドを発行することになります.

名称の頭に作成行為の ID となる文字列が付加されるため, net-split を利用した攻撃は不可能となります. もし net-split が発生し, そのまま数日経過し, channel を攻撃するために誰かが遠方の server 上で "JOIN !!channel-name" とコマンド発行したとしましょう. そのコマンドは成功することでしょう. そして ":othernick!otheruser@otherhost JOIN !XYZ456channel-name" というようなメッセージが返ってきます. 確かに "!channel-name" というような channel の作成に成功したのですが, そう, ID の部分が異なっています. そのため, そのまま net-split が回復しても, 両者の channel は 「名前が似ているけれども (ID の部分に違いがあるため) 違う channel」 となります. ここが「安全な channel」です.

当然のことですが, あえて書きます. `#' channel を `!' channel に変えることで 必ずしも安全性が高まるというわけではありません. `!' の機能は, 貴方だけを守ってくれるわけではなく, 貴方の敵となる者も同じように守ってくれます. `!' の目的は, 悪意ある攻撃から狙われている channel を守ることではないようです.

どちらが本当の創設者か判断できない場合, 従来から存在する `#' channel では 「どちらも創設者である」 という考えが適用されます. その結果, 両陣営が争うことになるかもしれません. `!' channel では, 複数存在する全ての創設者の意思を 尊重し保護するために, 「違う channel として扱う」 という考えが適用されます.

[index] [here]

channel 名についての注記

channel 名は, 頭の `#' や `&' の文字を含めて channel 名です. `#' 以降が channel 名になるわけではありません. `#' も channel 名の一部となります. すなわち, `#channel' と `&chennel' は全く別の物です.

[index] [here]

channel 名の中の日本語

channel の名称の末尾に, コロン (":") と server 名の条件を記述することで, 使用可能な server を制限できるという仕組みがあることは先ほど記述しました.

この仕組みについてさらに記述しますと, channel 名にコロンが含まれている場合, 最も後ろ側にあるコロンより右側が server のドメイン名の条件となります. "#channel:*.jp:*.us" という名称であれば, 条件は *.us となります. "#channel" "#channel:*.jp" "#channel:*.us" "#channel:*.jp:*.us" これらが同じ channel かというと, そうではなく, 条件の部分も名称の一部となるため, 異なる名称の channel として扱われます.

このコロンについては, JIS 2 byte 文字の一部に含まれるコロンであっても同様の扱いを受けます. よく例として挙げられるのが "#ず" です (有名な方の名前だからでしょう; 前述リンクの章参照). "#ずズ" のデータは, "#\x1B$B\x24\x3A\x25\x3A\x1B(B" であり, つまり "#\e$B$:%:\e(B" です. コロンが含まれているので 最も末尾のコロンの右側にある3 byte 文字列 "\e(B" が server の条件となります. そういう名前の server が存在するならばその server 上で使用可能な channel ですが, どう考えても存在しませんので, 全ての server 上で使用不可能な channel となります. どうしても「そのような感じの」名称を使いたければ, "#ずズ:*.jp" と, 末尾に条件を付加してしまう方法があります. 「日本限定なんて絶対に駄目だ」 とくるならば, 例えば "#ずズ:*" でしょう. ある種の日本語化パッチを当てた ircd 上では, "ず" を「気にすることなく」使用可能です. しかし, ircネットワークとして接続している別の server の中に そのパッチが当たっていない場合, その server 上では使用できない channel となります.

さて, channel 名の中に記述できる日本語文字ですが, ほとんどの文字は使用可能です. 先ほど例を挙げた「コロンを含む文字」の場合, 多少の手間ないし問題はありますが使用可能です. 以下の文字はコロンを含みます (機種依存文字まで含む粗雑な羅列ですのであまり役に立ちません. 以下の部分は, 半テキスト半バイナリーとでも扱ってください) .

"此〆頃∈今困ず坤ズ墾婚Ш恨┷懇昏昆根梱Y混痕紺虻艮浦魂"
"穏些該佐敢叉戯唆矯嵯刑左減差杭査査沙産瑳失砂什詐昇鎖榛"
"裟精坐塑座尊挫炭債頂催添再萄最悩哉蛤塞漂妻丙宰忘彩椋才"
"雄採虜栽郎歳从済兀災匣采唳犀垪砕婪砦嶌祭弸斎愃細拑菜攤"
"裁杠載楮際欹剤涅在澪材犧罪畉財盧冴禳坂篋阪綺堺羣榊膾肴"
"荳咲藝崎蟶埼觝碕貂鷺躡作邵削鏈咋雕搾餾昨鮑朔鷓柵窄策索"
"錯桜Y鮭ク笹Y匙ク冊刷"

channel 名にはほとんどの文字が使用可能なはずですが, 一部使用不可能な文字もあります. メッセージの内部のあらゆるところで使用禁止となっている 0x00 NUL, 0x0A LF(NL), 0x0D CR の3種類は使用できません. 0x07 (BEL; ^G) は, MODE 付き JOIN を表現するとき JOIN メッセージのパラメーター channel 名称の後ろに MODE 情報を付加するために予約されています. そのため, 0x07 は使用できません. 0x20 (SPACE) はあらゆる場面で区切り用文字として用いられます. そのためこれも channel 名の一部として使用できません. "JOIN #a,#b,#c" といった channel 名の羅列を可能とするため `,' (カンマ) は区切り文字として予約されています. このカンマも channel 名の一部として使用できません. それら 6 種類の使用禁止文字 ( NUL, LF, CR, BEL, ` `, `,') 以外の全ての文字は channel 名の一部として使用可能です.

日本語 channel 名を考えるとき, 問題となるのは最後のカンマです. カンマを含む文字はいくつかあります.

"゜↑がガΜК━穐卯岡階巻規喬桑謙幸根錆蒔習宵尻征銭測狸"
"潮適頭葱八必分訪蓑揖略婁亂僵飭哮坎姙妛廳悴扛擡朏棯檪洙"
"潭爼甃皙祠筱絳罨膃茗薔蟐覓讙蹶遯鍖隱飫鬪鵺KェKェ"

オリジナルの ircd 上において, これらの文字を使用することはほとんど不可能であると考えられます. どうしても使用しなければならないときは, Shift_JIS や EUC-JP にしてしまうという方法もありますけれど, 普通の IRC client を使用しているユーザーは, その channel に来てくれないでしょう. 上記のうち "卯巻銭狸蓑略檪" であれば, 旧字体の "夘卷錢貍簑畧櫟" を使用するという手もとりあえずあります...

ちなみに, この「がガが使えない問題」は, ずズ同様, ある種の日本語化パッチを与えた ircd 上ならば, 解決するようです. ただし, これもずズ同様, ネットワーク上に存在する 非日本語対応 ircd 上では使用できない channel となります.

[index] [here]

username の前に付く記号

prefix (:nickname!username@hostname) やユーザー情報などは, nickname!username@hostname という構成になっています. ときどき, この username の頭に記号が付きます. その記号の意味は以下のようになっています.

I linei line (+r)
ident あり(記号無し)+
ident あり (違うデータ)^=
ident なし (もしくは要求無し)~-

I line に記述されている場合は, 通常の制限のない接続状態です. i line に記述されている場合は, +r (restricted) の状態で, NICK, MODE などのコマンドが使用制限されている状態です. I line/i line の条件は各 server によって異なっており, その一覧は "stats i [ server]" コマンドで知ることができます.

[index] [here]

server が付加する Quit Message

I Quit

Trail なしで QUIT コマンドを発行したとき, server が自動的に付加してくれる Trail です. デフォルト値であると考えてください.

Excess Flood

client から server に対するコマンドなどの
`送信量が一定時間の間に一定量を越えた状態'
です.
client の送信が, あまりに激しすぎると判断した server が, 負荷を上げないために切断します.

このメッセージを見ると, client からの送信が激しいという理由で切断されていることが分かります. client soft は, Excess Flood で切断されることを防ぐため, 過度の送信を防ぐための機能を付ける必要があります.

更に, CTCP 質問責めが起きたとき, すべての質問に答えず 一定時間は ignore するように対策した方が良いでしょう. 前回質問されたとき (前回回答したとき) の時刻を記録しておき, 次の質問が来たとき現在時刻とそれを比較し, その時間差の値によってどのような行動をとるべきか判断しなければなりません. Flood Protection の実装を行ったからといって, もし, すべての CTCP に素直に答えてしまうと, client 内部のバッファーが Flood 状態となってしまいます. ゆっくり送信する能力がある client が, 大量の CTCP-reply をゆっくりと長時間送り続けることになってしまうと, 他のコマンドが出て行かなくなります (時には PONG も含む).

「送信部にバッファーを付け, ゆっくり送信する」 「CTCP の返答は, 送信バッファー内での優先順位を下げる (後から他のコマンドを送信したくなったとき, CTCP 返答を後回しにする)」 「CTCP の質問に, 1 度返答したら, それ以降 5 秒から 10 秒程度, 返答を行わない (具体的な数値は作成者の判断)」 「送信バッファー内に蓄えられる CTCP の返答には, 短い有効期限を付ける (20 秒以内に送信の順番が回ってこなかった場合は削除, など)」 これらの機能のうち, どれを実装するかは, IRC client 作者の判断となるでしょう.

Excess Flood と判定される条件については, IRC server の仕様を探ると良いでしょう. ircd であれば, ircd のソースファイルを確認することも良い手段です. 条件に関する他の情報は, 本文書に別記しています.

server1 server2

2つの server 名が, スペースを開けて記述されている場合です.

この場合, client が server から切断されているとは限りません. server 停止, net-split などが原因で, そこを利用しているユーザーが 近くの IRC ネットワーク群から (利用している server ごと) 不在となった 場合の QUIT メッセージです. SQUIT と前後して送られることが多いでしょう. (特殊な channel &SERVERS に join することで, SQUIT メッセージのタイミングを確認することが可能となります)

後方 (右側) にかかれる server2 の方には, 切断されてこちらから見えなくなった server, もしくは落ちた server, もしくは切断された server の代理となるような server 名 などが記述されます. 前方 (左側) に書かれる server1 の方には, 自分から見て, 切断されていない server のうち, 最初にその検出を知った server などが記述されるでしょう.

Bot client はこのメッセージを受けて何らかの判断の決定をしてはいけません. この手の quit message はユーザーの冗談や悪戯で付加することができます. まずは &SERVERS に join しましょう.

Killed

nick collision (衝突) の場合, メッセージは以下のような書式となります.

:落ちた本人のニック!落ちた本人のユーザー名+ホスト名 QUIT :Killed (kill 発行 server ((落ちた本人のユーザー名+ホスト名) 送り先 server 群 <- (ぶつかった相手のユーザー名+ホスト名) 送り元 server 群 [相手 server]))

このうち, QUIT コマンドの trail 部分の Killed の後ろに書かれてある 括弧の中だけを抜き出すと以下のような書式になります.

kill 発行 server
(
  (落ちた本人のユーザー名+ホスト名) 送り先 server 群
  <-
  (ぶつかった相手のユーザー名+ホスト名) 送り元 server 群
  [ぶつかった相手が使用している server]
)
	  

server から (自動的に, もしくは server 管理者の操作によって) 強制的に排除することが目的で発行されるコマンドが KILL であり, KILL によって切断されたことを 「KILL されたユーザーと同じ channel に参加していた他のユーザー」 に知らせるメッセージが「QUIT :Killed」です. server 管理者権限を持つユーザーが発行するか, もしくは, nick collision (ニックネームの衝突) が起きたとき, このメッセージになることが多いようです.

client soft を作る場合, 以下の点に注意しなければなりません.

ユーザーは, 自分の意志で, Quit メッセージの trail 部分の先頭に, 「Killed」という文字列を書くことはできません. 「QUIT Killed」と送信しても, パラメータ部分は存在していないと扱われます (そして "QUIT :I Quit" となります). そのため, Quit メッセージの trail 部分の頭 6 byte が 「Killed」であるかをチェックするだけで, Killed (killed user) の存在を知ることができます.

他人の Quit メッセージの trail の頭に「Killed」を発見したとき, 故意か偶然か, ニックネームの衝突が起きていることを 認識すべきです.

故意の場合もあるため, 続いて自分が Kill されないよう とりあえず自動でニックネームを変更することは極めて大切な判断でしょう. ただし, すべて の Killed に反応することは考えものですから, 「誰が Killed となったときに自動変更するか」 を考慮する必要があります. また, 自分に対しての Kill は, 「QUIT Killed」ではなく, 「KILL」メッセージとして送られてきます. KILL が送られるとしばらくそのニックネームは使用できないため, 続いて再接続する場合は, 先ほど使用していたニックとは異なるニックで再接続処理をしなければなりません. 同じニックで接続処理をすると, server は 「そのニックは駄目です. 他のニックを入力してください」 なんて prompt にはならず, 即時強制切断します. そのため, 「とりあえず先ほどと同じニックで再接続処理を試して, そのときエラーなら別のニックを送り直そう」と考えてはいけません.

Killed の発見は, 「自分, もしくは, 自分のいる channel」 への攻撃を前もって知る手段かもしれません. channel 内メッセージの混雑を防ぐために時間差 +o を行っている channel もあるでしょう. そういう channel であっても Killed を発見した時は, すぐにまだ渡していない op を全て渡しましょう. その後一定時間, 落ちついた状態となるまで, 時間差 op を中止して, 激しく配るようにしましょう. それと同時に自分達のニックを時々自動で変更します. ただし, この自動処理を実装するとき 「変えたために避けることができたKILL」もあれば 「変えたために受けることになったKILL」もあることに注意が必要です. スプリットが短時間であるなら, 貴方の nick の名称は保護され, 離れてしまった server 上で一定時間は使用不可能な名称となります. nick を変更しなければ衝突は起きないのですが, もしスプリット中に nick を変更してしまえば, 新しい nick は保護されないため, 簡単に衝突を受けることとなります.

No Route to Host

client server 間の経路の途中にあるゲートウェイが停止したときなど, client と server を結ぶ手段がなくなったとき, このメッセージとなるようです. TCP/IP レベルのエラーがソケットレベルのエラーとなり, そしてこのメッセージとなるようです.

connection reset by peer

shutdown() 等, client からの切断により TCP/IP のコネクションが切れ, それを server が検出できたときこのメッセージとなるようです. . 通常の切断は, client から server に向かって "QUIT" コマンドを発行, それを server が認識することです. その通常の切断と異なり, client がソケットを閉じ, server がそれを認識できた場合がこのメッセージです.

「QUIT を送らずにソケットを閉じた, server はそれを知った」という状態です.

Ping Timeout

server が定期的に送信している PING メッセージに, client は正常であれば PONG を返します. その返答が一定時間経過しても返ってこなかった場合, すなわち, 定時間質問に対する client からの返事が一定時間送られてこない 状態のとき, このメッセージによる切断となります. server は 「いつまでも返事がないのは client が落ちているからではないのか」 と考え, 「Ping Timeout」であることを理由に切断します. ダイアルアップの場合, モデムの電源停止, ISP からの切断などが起きたとき, client から見れば切断された状態でも, その切断状況が server に伝わらないため (server から見れば繋がった状態), しばらく経過した後 Ping Timeout で落ちることとなります. また, client のサイトに対して直接攻撃がなされた場合, もし物量攻撃であるならば, ほぼ確実にこの切断メッセージとなります.

Dead Socket

ソケットのエラーが原因です. client の受信バッファーが追いつかず, server の送信バッファーがオーバーし, server の送信ができなくなった場合 (もしくは送信時に何らかのエラーが発生した場合など), このメッセージによる切断となります. server の送信バッファー flood (溢れ) です.

"Dead Socket" は, client の受信能力が足りないときに *起きやすい* 事態です. 受信バッファーが小さい場合, 受信頻度や速度が少ない場合, client server 間の回線が遅い場合, などといった条件のとき NAMES/WHO/LIST など大量のデータを受け取ってしまうコマンドを発行すると, 高確率で発生します.

例えばダイアルアップのモデム強制切断をしたときなど, client 側が切断しているにもかかわらず server 側がその切断を検出できず繋がったままであると認識している場合, "Ping Timeout" もしくは "Dead Socket" というメッセージで切断されることがほとんどです. "Ping Timeout" は「client からの返事が server に届かない」という判断結果です. "Dead Socket" は「client が今まで送ったデータを受信していないため, バッファー溢れを起こしこれ以上送ることができない」という判断結果です.

まれに PRIVMSG/NOTICE による物量攻撃 (例えば 400 byte * 10 行 * 数百から数千台の送信元 client で 数十秒の間に 1MB から 10MB 程度のメッセージ) が原因で Dead Socket となることもあるようです. そのようなことが起きる前に channel 宛ならば +m +n +b (もしくは PART) で, client 宛ならば NICK で, 対策をしたほうが良いでしょう.

[index] [here]

RFC1459 を読みながら

RFC1459 の謎みたいなもの・・・について.

[index] [here]

RFC1459 「4.2.3.1 Channel modes」

RFC1459 「4.2.3.1 Channel modes」 の末尾が, 途中で終わっているようです.

   When using the 'o' and 'b' options, a restriction on a total of three
   per mode command has been imposed.  That is, any combination of 'o'
   and

'o' と 'b' のオプションを使うとき, その制限は, mode コマンド 1 つにつき 3 つまでである. これは, あらゆる組み合わせで 'o' と ......

ちなみに, MODE コマンド内の +o-o+b-b の組合せですが, 最大で 3 つまでです. ただし, +o-o は 1 コマンドあたり 2 つまでにした方がよいでしょう (初回の送信を除く). ペナルティーの時間は, 1 つの場合 4 sec, 2 つの場合 7 sec, 3 つの場合 10 sec です. すなわち, +o を 6 個発行するために必要な時間は, 1 つずつの場合 24 sec, 2 つずつの場合 21 sec, 3 つずつの場合 20 sec です. +oo であっても +ooo であってもほとんど差はありません. +ooo の方が若干高速ですが, ペナルティー 10 秒の長さは敬遠すべきでしょう. +ooo を送信した直後, 非常に重大なメッセージを受信したとしても, 10 秒間は身動きとれません. 複数の協力関係にある bot が存在し, それらが裏で同期を取っていない場合, +ooo -ooo の 3 個同時送信を行えば, 異なる bot が同じ動作をするという無駄も増えてきます. 状況によっては, 連射可能な +o -o 1 つだけの MODE コマンドも良い選択です.

なお, +o -o の送信が必要とされる状況で, +b -b を操作するという「わき見」をしてはいけません; 自分や協力関係の bot は deop されてしまうでしょう. KICK コマンドも同様です; fake 発生となるでしょう.

[index] [here]

+s +p

MODE #channel +s +p について.

--s-p+p-s+s-pComment
LISTlistednot listed4.2.6 List message
NAMESlistednot listed4.2.5 Names message
LIST 一覧に表示有り 一覧に表示無し ircd
WHOIS
NAMES (-i ユーザーのみ) 参加者の一覧表示 表示無し, 無反応
WHO

channel mode -s-p / +p-s / +s-p について記述します.

channel mode -s-p
これは, 多くのことを公開します. channel が open (公開) であるという, channel mode です. channel 参加者への WHOIS, (mask の有無に関わらず) LIST, これらのコマンドを介して, その channel の存在を知らない者に, その存在を知らせることができます. channel 名称を指定した NAMES (もしくは WHO) コマンドを使うことで, その channel が存在しているかどうかの情報と, 英字大小文字に関する「正しい channel 名」を知ることができます. また, user mode -i となっている参加者に限って, その参加者一覧を得ることができます.
channel mode +s-p
これは上記と全く逆です. channel が Secret (秘密/隠蔽) であるという, channel mode です. LIST / WHOIS のコマンドの結果に 一覧の一部としてその channel の名称が掲載されることはありません. その channel の存在 (名前) を知らない人は, Secret channel の存在を知ることができません. あらかじめ存在 (名前) を知っていたとしても, WHO / NAMES にて, 現時点での channel の有無を知ることも, 人数や参加者一覧を得ることもできません. ただし, MODE command を利用することで, その channel の MODE を知ることはできます. それはすなわち, その存在の有無と, (英字大小文字に関する) 正式な名称を 知り得ることとなります.
channel mode +p-s
これは上記, Secret に似ています. channel が Private (非公式/個人的) であるという channel mode です. Secret との違いがあります. WHOIS, LIST などの一覧に掲載されないため, その channel の存在 (名前) を知らない者が at random な channel 探索を行っても, その channel の存在を知ることはできません. すなわち, その channel の存在を初めから知らないような client に対して, 「このような channel がありますよ」と, わざわざ channel の名称を教えるようなことはありません. ここまでは Secret と同じです. しかし, すでに channel の存在 (名前) を知っているユーザーに対しては, Secret 扱いとならず, open と同じ扱いになります. すなわち, NAMES, WHO のコマンドには, -s-p と同じ結果が返ります. (ちなみにここでの NAMES WHO コマンドは, 具体的な channel の名称をパラメーターとして与える書式としています)

user mode +i にしている参加者の情報は, channel mode が何であれ, 外側のユーザーが発行する WHO, NAMES の結果に出力されることはありません. ただし (当然ながら?), その channel に JOIN している Client からは, channel の全てを知ることができます.

[index] [here]

+b target mask

+b の param に記述する, target mask では, ? * をメタ記号とした簡易ワイルドカード表記が可能です. この場合, なんらかの形で既存の +b 情報と重複する場合は, 追加できません.

どのようにすれば, 類似の +b 情報を登録できるか, IRC Client(user or bot) はこれを判断しなければなりません. また, これから発行したい +b 情報は既存の +b 情報と重複するかという判定, さらに重複するならば既存の +b を削除, 変更, もしくは新規 +b をあきらめるという判断, これらも IRC Client(user or bot) に必要とされる能力です.

[index] [here]

+b のピリオド

+b に書かれる target mask のうち, 最も重要な部分は, hostname の mask です. IP address もしくは, domain name が記述されることでしょう. ここには, ほぼ確実にピリオド記号が記述されます. このピリオド記号を多くするか (すなわち省略しないか), 少なくするか (すなわち省略するか), には大きな違いがあります. 前述の ``重複により登録できない問題'' も時には絡んでくるでしょう.

'?' 記号も時には有効です. 「+b *!*@*?flooder.atacker」 「+b *!*@*.flooder?atacker」 といった 2 つの +b 情報は, 同時に登録が可能です. また, 「co.jp の co と jp の間のピリオド」など TLD (Top Level Domain) と 2ndLD (2nd Level Domain) の間のピリオドを, 何らかの条件がある場合にかぎり, '.' ではなく '?' にするという手段も, 時には有効でしょう. どのような状況の時 `?' を使用すればどういったメリットがあるのかは, 各ユーザーの環境によって異なるでしょう. ただ, うまく判断できないときは (明確な理由がないときは), `?' ではなく `.' を使用する方が無難でしょう. 正規表現で /x.co.jp/ と記述するよりも /x\.co\.jp/ と記述する方が望ましいことと同じです. どちらの表現も目的文字列と match することに変わりはありません. しかし, 想定外の文字列と match することまで望んでいるわけではないでしょう.

「x!x@yahoo.com」というユーザーを ban する場合, 「+b *!*@yahoo.com」という ban 情報は, 時には適切でないかもしれません. なぜなら「x!x@hehehehe.yahoo.com」 というユーザーが続いて入ってくるかもしれないからです. だからといって, 「*!*@*.com」と広く ban してしまうのも問題であるとしましょう. 組織ドメイン名の下のサブドメインが存在しないと推定できる場合は, 「+b *!*@*yahoo.com」という記述にします. ここでうっかりピリオドを入れてしまい 「+b *!*@*.yahoo.com」と記述してしまうと ホスト名が「yahoo.com」である目的のユーザーは ban されないことになるため注意が必要です. この判定も bot の能力の一つです. すなわち bot には, client のドメイン名から, 国/地域名, 種類, 組織名, アクセスポイントなど抽出する能力が要求されます. そこから判断された情報を元に, bot は +b のためのワイルドカード文字列を生成します. jp ドメインは 2ndLD が組織名でなく種類です. イギリスや韓国も同じようになっているようです. フィンランドや gTLD は 2ndLD が組織名です. このあたりの常識風な知識も bot が保有しなければなりません. boobooboo.co.to から攻撃が来た場合, +b @*.co.to で良いとしても, boobooboo.co.jp から攻撃が来た場合, +b @*.co.jp が良いとは限りません. この場合 +b @*boobooboo.co.jp が良いのかもしれません.

また, 異常に長いドメイン名も, 時には存在します. client を作成する場合, 30 bytes, 60 bytes などといった, 固定の長さの領域確保は危険です. 全て動的に判断しながら確保です.

時には, ユーザー名を含めて ban したいこともあります. 時には, ユーザー名を '*' にして ban したいこともあります. この両者の要求が同時に発生することもありますが, そのまま server は同時に許可しません. それを防ぐために, 既存の ban list や過去の記録などから, 各種推理をする必要があるかもしれません. これは bot にとって大変なことです. 人間にとっても大変なことです. そこで, 「ユーザー名を含ませる場合」「含ませない場合」に分け, それぞれのルールを決めておくと良いでしょう.

ユーザー名を含ませる場合 「+b *!*user@*subdomain.topdomain」, ユーザー名を含ませない場合 「+b *!*@*.subdomain.topdomain」, という分け方も一つの手段です. ユーザー名を含ませる場合 「+b *!*user@*subdomain?topdomain」, ユーザー名を含ませない場合 「+b *!*@*subdomain.topdomain」, という `*' '?' を使用した分け方も一つの手段です. うまく使い分けると一方の ban が他方を邪魔することはなくなるでしょう.

[index] [here]

バッファーオーバーラン対策

nick name など常識的には数 bytes で収まるはずの文字列が, たとえ mega bytes や giga bytes のサイズとなったとしても, 「何等問題はない」ということが「当たり前であるべき」 という方針, 価値観が要求されます. 一般的な ircd なら「nick は最大 9 byte」と制限を付けてくれますが, そうではない IRC server soft も存在します. 「まさかニックが 40 byte を越えるようなことはあるまい」 という間の抜けた考えが残っていると穴が開きます.

CHOCOA の一部バージョンには 「server から送られてくる TOPIC メッセージの Trail 部分が異常に長くなっていると, オーバーランにより任意のコマンドが server から実行指示可能」 という穴があったそうです.

自分が join している channel 内の client の数が 1 万を超える場合 どのように動作するか, 自分や他人の nick name や host name, server の host name, server からのメッセージなどの文字列が非常識な長さ (例えば k byte, 例えば M byte) となった場合どのような処理を行うか, 完全に対策する必要があります. Perl や C++ 文字列 class を利用すると, その手の問題は自然に解決してしまうかもしれませんが, 注意は必要です. char sNick[10]; char sHost[128]; char sUser[MAX_LEN]; char * sHost = new char[MAX_LEN]; などと固定サイズ確保をしないことです. もし固定サイズにしたければ, server からのメッセージを全面的に信用しないことです. 作る人がおかしな価値観を持っていない限り, 本来バッファーオーバーランによる穴は発生しません.

[index] [here]

ircd 2.10.x 次期 IRC 仕様

ircd 2.10.x 系という, 仕様の変わった ircd が開発されているようです. また, その仕様は, RFC1459 から大きく発展しているため, 新しい RFC が出現すると予想されます. その元となる Internet-Draft がすでに出ています. 例えば IRCnet など すでに多くの IRC ネットワークで ircd 2.10.x が採用されているようです.

RFC や Internet-Draft に関しては, RFCFIND などを参照ください.

[index] [here]

Internet-Draft

比較的新しい, IRC に関する Internet-Draft には, 以下の物が存在します. 頻繁に改版されることもあります.

[index] [here]

概要 (?)

おそらくそのうち出るであろうと予想する RFC1459 の次の RFC を予想します.

channel に関して機能追加

大きく変わるのは, channel に関する部分のようです.

http://www.ircnet.org/channel_docs/pling.html , http://www.stealth.net/~kalt/irc/channel.html たとえば, このような文書は参考になるかもしれません.

新しい channel prefix

'!' が追加されます. 合わせて, '#' '&' '+' '!' が channel prefix となるようです.

'!' が channel prefix (前置記号) となる channel は, "safe channels" と呼ばれるようです (詳細不明). 他の種類の channel と異なり, JOIN コマンドによる新規作成に付加機能が付き, それによる衝突攻撃はありえないようです. この種の channel は, channel への攻撃から, 最も守りやすい仕様になっているようです.

ただ「その機能を働かせること」自体が攻撃の目的だとすれば, これは非常に守りにくい channel となります (`#' よりも遙かに悪い状態). 例えば既存の channel の既存の channel-op を追い出すことが目的ではなく, 既存の channel と同一の名称である別の channel を作成し, どちらが本家か不明な状態で両方を維持させ, その後新しく入ろうとするユーザーを混乱させることが目的であるならば, この攻撃から守る手段はもしかするとないかもしれません. しかし, どちらの立場であっても 「我々が本家」と主張する行為が正当であるとは言えません. 「私が本当の jack であり貴方は jack ではないと jack に向かって言う jack」 この姿を想像してください. channel の所有権を主張する行為は, 多くの場合これと同じです. この件につきましては, 部屋とチャンネルの話 を御覧ください.

新しい channel mode

'O' 'r' 'e' 'I' が追加されるようです.

+e, +I は +b 同様リスト状態のモードです. +e は +b の例外指定, +I は +i の例外指定だと考えれば良いでしょう. +e, +I, +b の合計数が +b の件数の制限となることに注意が必要です. +b 最大 20 件の server で, +e を 20 件登録してしまうと +b の登録はできなくなります. +O +r は, '!' channel のみ使用可能だそうです. +r は, channel 全体のモードです. reop モードがセットされていると, もし channel 内の op が全て消滅しても, ある程度の時間待っていれば, server が (ランダムに) channel 内の誰かに op をつけてくれるそうです. +O は, channel のモードですがメンバーごとにセットされる状態 (+o +v と同様) です.

[index] [here]

RFC1459(May 1993) に記述されていない IRC server reply code

333

RPL?TOPIC?CHANGE?
変更したユーザーの nick と日時情報といった, トピック変更に関する情報です.

:server_name 333 mynickname (param1) (param2) (param3)
param1 は, 対象となる channel 名.
param2 は, 変更した者の nick.
param3 は, 変更した日時. time_t の値. 10 進数表記文字列.

437

ERR?TEMPORARY?NAME?
Nick もしくは Channel の名称が一時的に使用不可能というエラーです.

:server_name 437 mynickname (middle1) :(trail)
middle1 は, 使用不可能になっている名称です. それが Nick であるか, Channel であるかは, その文字列の先頭の文字を見て client が判断します (非常に粗悪な仕様).
trail は, "Nick/channel is temporarily unavailable" など.

[index] [here]

粗悪 IRC

IRC の仕様の中には, 一部粗悪な仕様が混ざっています. それは IRC client を作成する際, どのようにすれば良いのか分からない部分です. また 「その疑問点については ircd のソースや付属の client のソースを見れば分かる」 とは言えるけれども「RFC を見れば分かる」とは言えない点です. 他にも不思議な価値観が IRC の中には隠れています. ここではその粗悪の情報と対応を記述します (の予定).

[index] [here]

437

RFC1459 に記載されていません. nick もしくは channel の名称が一時的に使用できないというエラーコードです. つまり NICK もしくは JOIN のいずれかのコマンドの 不成功を伝えます. それが nick であるか channel であるかは, 437 に続くパラメーターの文字列から client が判断しなければなりません. 437 は RFC1459 より後から追加された仕様ですが, それまでの RFC に存在する reply code の中で, 「それが nick となる名称か channel となる名称か, client が文字列から判断しなければならないような reply code」 はありません. PRIVMSG のターゲットも, 「自分の nick と同一の文字列か」という単純な文字列比較だけで済みます.

さて, これに対する対策ですが, まずはとりあえず先頭 1 byte を見るしかありません. これが問題となります. ircd のバージョンや種類によって, 必要とされる判断が異なってきます. ときには, channel 名の先頭に prefix 記号を必要としない IRC server もあります. そのような server や普通の ircd の両方に対応しながら, かつ 437 をうまく処理する client を作成するのは非常に難しいでしょう. 現実として簡単に対処するならば以下のようになるかもしれません.

もし名称の先頭 1 byte が英数字であれば nickname であると判断した方が良いでしょう. '#', '&', '+', '!' この 4 つの場合は channel name であると判断できます. しかし, この 4 つとの比較だけを判断条件としてはいけません. ircd 2.9.x 系に合わせて作られた client ならば, `!' で始まる名称を nick name だと判断してしまうかもしれません. 同じように ircd 2.10.x にぴったり合わせて作られた client ならば, 将来の ircd や現在でも亜流の ircd 上で不具合が発生します. とりあえず nick name らしき文字を全て nick と判断して除外していきましょう.

ここで少し問題が発生します. nick の名称に使用できる文字は, RFC1459 内で以下のように定義されています.

   <nick>       ::= <letter> { <letter> | <number> | <special> }
   <letter>     ::= 'a' ... 'z' | 'A' ... 'Z'
   <number>     ::= '0' ... '9'
   <special>    ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}'

ところが多くの ircd は, これとは異なる仕様を内蔵しており, 記号は RFC で許可されている '-', '[', ']', '\\', '`', '^', '{', '}' だけに限らず, '_' '|' まで使用可能となっています. 先頭文字に関して言えば, RFC は letter (英字 26*2 文字) のみを許可しているのですが, ircd の実装は上記に出現した記号のほとんどを許可しています (数値とハイフンを除きます). この腐り具合が 437 問題に輪をかけてくれます. とりあえず 'A' (0x41) 以上 0x7E 以下の文字, 数値, ハイフンは nick name としてしまうと良いかもしれません.

'#' '&' '+' '!' はすでに channel name として判明しています. 0x20, ',' は区切り用として予約されています. '*', '?' は簡易ワイルドカード表記でメタ文字となるため, nick かもしれないあいまいな名称に含まれることは (おそらく) ありえません (ありえない状態となった場合はエラー). '"' '$' '%' ''' '(' ')' '.' '/' ':' ';' '<' '=' '>' '@' 残るはこれだけですが, 通常は名称の先頭文字がこのような記号になった場合, エラー扱いです. しかし, IRC 仕様の将来のバージョンまで今の段階から仮に対応したければ, これらを「channel name の prefix」として扱っておくとよいかもしれません. 「新しい仕様の channel がまた追加されるかもしれない. しかし, nick name の仕様が変更されることはないだろう」という憶測です.

さて, このような問題に対して, もっと本質的な解決とする考え方があります. 「自分が何かを送らない限り 437 は返ってこない」 という前提条件を利用します. 具体的には, NICK, JOIN コマンドを送ったときはそれをヒストリーに記憶しておき, 437 を受けたときはそれらヒストリー内を検索するという方法です. この方法を使用すれば, channel name の先頭に英字を置ける亜流 IRC server であろうと, ircd 2.10 であろうと, また, 将来登場するかもしれない 新しい channel prefix であろうと, ほぼ完璧に対応できるでしょう. 「送った NICK, JOIN コマンドをヒストリーに一時保存する」 機能を internal function とする client は 現在少ないのではないかと予想しています.

[index] [here]

接続完了のメッセージ

IRC server に接続し, [PASS,] USER, NICK のコマンドの受付が正常終了し, 「これにて接続処理完了」となった段階で, それを知らせるメッセージを server は送ってきません. 続いて JOIN を送りたくても, それをいつ送って良いのかが難しいところです.

現実での対処としては, end of motd の 376 もしくは error no motd の 422 のいずれかで判断できるでしょう (もしくはこれに 001 などを加えます) . しかし, 376 のような reply は, 接続時だけでなく MOTD コマンドへの返答としても返ってきます. となると「接続時に必要な処理は完了した」を示す真のメッセージは「ない」のです. そのあたりのタイミングをどうしても判断したければ, 376 が初回か 2 回目以降かを判断しなければならず, 結局そのような無駄を IRC は client に要求しているわけです. client はその要求に従わなければなりません.

[index] [here]

Excess Flood

100 の client が 1 つの client に対して同時に質問しました. その質問が CTCP の形であったため, 質問を受けた client は馬鹿正直に一気に全ての質問に答えようとしました. それを見た server はまだ 50 も返答されていない段階で 「煩い馬鹿者」とばかりに切断しました. これが Excess Flood による切断, およびそれを狙った攻撃です. 正直な client も愚かですが, この場面で真の馬鹿は事態を正確に把握する能力に欠けている server です. 1 client あたり一方は 1 行で他方は 50 行弱かもしれませんが, 1 ユーザー分として合計すれば一方は 100 行になります. 50 行弱連続送信したユーザーを煩いと判断する能力を持ちながら, 100 行連続送信したユーザーを煩いと判断する能力を持っていないわけです. しかしその能力の実装には現実問題として, 「不可能」な面や「困難」な面があります. 残念ながら client は, 現状の馬鹿な server に合わせなければなりません. そのため flood protection の実装が必要となります.

flood protection 等に関しては後述します.

[index] [here]

Excess Flood の条件について

client がメッセージを送信しても, それを受け取った server はすべて即時解釈するわけではありません. 1 つのメッセージが解釈され実行される毎に, ペナルティという時間が発生します. 何かのメッセージが実行されたあと, そのペナルティとなる時間が経過するまでは, その後に続くメッセージの解釈は行われません. 次の解釈が行われるまで, client が送信した (そしてしばらく解釈されない) メッセージは, server 内の (接続 client 毎に用意されている) バッファーに蓄えられます. そのバッファーに蓄えられているメッセージの総サイズが, server が定める値より大きくなったとき, Excess Flood という判定から切断されます.

client の実装をこの Excess Flood に (そう判断されないように) 対応させようとする場合, client は server の動きを把握しなければなりません. すなわち, client 内部で server のバッファー状態を予測し, シミュレートします. それを行うために, まず以下の点は必要な情報です.

Flood であると判断される定められた境界値は, ircd の場合, 多くの server 環境では, 「コンパイル時にオプションを記述するためのヘッダファイルに値を指定する」 という状態だと思われます. この値は, STATS d の結果 CF (Client Flood) を見ることで分かります. この値を 1000 にしている環境は多いようです.

どのようなタイミングでバッファーに追加されていくかに関しまして. これは, client が server にメッセージを送りそれが届いたときです. 到着の都度そのタイミングで全てバッファーに追加されていくと考えると良いでしょう.

どのようなタイミングでバッファーから削除されていくか, につきまして, これが Excess Flood 対策を行う上で最も重要な点でしょう. まず, メッセージ (コマンド) が解釈され, 実行された時に, そのメッセージはバッファーから削除されます. 当然, queue ですから, 先 (時点の値が小さい時点) に送ったコマンドから先に解釈されていきます (FIFO). そして, メッセージが解釈されたあと, 一定時間はペナルティとして, 次のコマンドの解釈は行われません. ペナルティとなる時間は, ほとんどのコマンドで 2 sec です. channel-op を使用する一部では, それより長くなります. KICK の場合, 4 sec となるでしょう. MODE の場合, パラメータの '+'/'-' と共に付加される英字の数によって変化します. ペナルティは, 1 sec + 3 sec * 英字の数 となります. MODE +ooo は 10 sec です. MODE +tn は 7 sec です.

ただ, このペナルティーのタイミングの他に, server は 2 sec ごとにバッファーのチェックを行う という周期もありますので, 7 sec というペナルティーは 表面上 6 sec と 8 sec のいずれかとなるでしょう (まるでランダムに見えるでしょう).

IRC client を実装する場合に注意すべき点があります. server の CF が 1000 であったとしても, シミュレーションを行うとき, 1000 という値を使用しないことです. 600 など, 厳しい値でシミュレーションを行えば, 確実に Excess Flood を防ぐことができます. 1000 であると想定し, server のバッファーぎりぎりまでデータを流し込むと, ちょっとしたネットワークのラグタイムがあるだけで, まとめて送られたデータによって Excess Flood 切断されてしまいます.

また, 512 byte より小さい値でシミュレーションをしてしまうと, そのサイズより大きなサイズのデータを送信しようとしたとき, ロックしてしまうようなバグが発生するかもしれないため注意が必要です (そのようなバグ付きで公開されている software もあります). そのようなバグを抱えてしまうと, 巨大な CTCP の質問を受けたとき, それに対して巨大な返答を行おうとしますが, その返答 1 行が flood protection に引っ掛かってしまい, それ以降無言となってしまいます.

flood protection は server のバッファー状況をシミュレーションします. 例えば Perl で実装すると以下のようなコードになります. 文字列を送信する場合は send_exec の代わりに send_buffered を呼び出します. flush_buffer は 1 秒ないし 2 秒程度の周期で呼び出します.

sub send_buffered
{
  my ( $line ) = $_[0];
  $line =~ s/[\r\n]+$//;
  if ( $line eq "" ) { return; }
  $line = substr ( $line, 0, 500);
  push ( @send_buf, "$line\r\n" );
  &flush_buffer;
}
$end_of_penalty = 0;
sub flush_buffer # 毎秒程度タイマーで呼ばれる
{
  my ( $line );
  while ( $#send_buf >= 0
   && length("$send_buf[0]@sent_buf") < 600 )
  {
    $line = shift ( @send_buf );
    &send_exec ( $line );
    push ( @sent_buf, $line );
  }
  if ( $#sent_buf >= 0 )
  {
    # 実行中時計の調整が行われた場合への対策
    if ( $end_of_penalty > time + 20 ) { $end_of_penalty = time + 20; }
    if ( time >= $end_of_penalty )
    {
      $line = shift ( @sent_buf );
      $end_of_penalty = time + 2;
      if ( $line =~ m/^KICK /i || $line =~ m/^MODE /i )
        { $end_of_penalty += 2; }
      if ( $line =~
        m/^MODE +[^ ]+ +[\+\-]?[a-z][\-\+]?([a-z])[\-\+]?([a-z]?)/i )
        { $end_of_penalty += 3 * length ( "$1$2" ); }
    }
  }
}
sub reset_buffer # 接続前, 切断後
{
  @send_buf = ( );
  @sent_buf = ( );
  $end_of_penalty = 0;
}

注意: draft-code として雑記しました. 動作確認などされていません :-).

また, 実際に実装する場合は, 優先順位の異なるバッファーを複数用意するなど, 更なる考慮が必要です.

サーバーバッファーをシミュレーションするとき, さらなるコツがあります. 条件「サイズ 600 byte」に, 条件「行は 3 行まで」を加えるのです. そして flood protection モジュールだけでなく, 送信を行おうとする他のモジュール (例えば channel op 操作の bot モジュールなど) においても, サーバー内バッファー状況を考慮します. これにより 「昔送信しようとしたコマンドがバッファー内で沢山溜り, その処理待ちのためしばらく身動き取れない」 という悲惨なバグを防ぐことができるでしょう.

[index] [here]

各地の IRC SERVER 群

IRCnet が世界最大規模の IRC server 群だそうです. しかし, それ以外にも EFnet などの大きな server 群はあります. また小規模 server 群, 単独の server も存在します. 一般公開されている興味深いと思われる IRC server を以下に並べてみます.

MSN

irc://irc.msn.com 6667

Microsoft の MSN の server で, MS CHAT 向けとして Microsoft が公開しています. `MS CHAT' は, Microsoft が無料でバイナリー配付している IRC client soft です. 現在では, MS CHAT 以外の client であったとしても接続可能です. MS CHAT の独自コードを利用した channel が沢山あり, またほとんどの channel ではそれらコードを流しても良い雰囲気があります. MS CHAT の client soft を使用するなら面白い server かもしれません. ircd の仕様はいくつか異常な点がみられます. 一般的な ircd ではなさそうです (将来は一般的な ircd に変わるかもしれません) .

TRPG.NET

TRPG.NET table RPGに関するサイトです. IRC情報 のページに各種情報やリンクがあります.

TRPG 向けの irc server sv.trpg.net:6667 が公開されています.

Dreamcast 海外

irc://irc0.dreamcast.com:6660-6669

海外 (おそらく米国) 向けです.

Dreamcast 日本向け

irc://irc.dricas.com 6661 -

SEGA が発売したコンシューマ向けゲーム機 Dreamcast には, IRC Client soft が入っており, IRC を利用することができます. http://www.dricas.com/ という WWW サイトもあります. この IRC server irc.dricas.com は, その Dreamcast 向けに公開されている (されていた) IRC server です. Draemcast 以外でも接続可能です.

1998 年年末 Dreamcast 発売と共にこの IRC server が公開されました. 初期の頃は人数制限 200 人程度にしていたため, ほとんど接続不可能な server となっていました. 1999 年の年明け後, 最大 1000 人受け入れ可能に変更され, それ以降は接続容易な server となりました.

Dreamcast Default 指定 server のためか, 意外と人気があったりするようですが, この server に接続するメリットはほとんどないと考えられます. 初期の頃は, user +i が無効となるなど, 各種仕様に他の irc server (ircd 2.9.x) と異なる点がいくつも見られました.

その後, この server にマナーの悪いユーザーが増え続けたため, SEGA は, 1999 年 5 月に, 運用停止を発表しました. この件については, 別記しています.

IWANGO

irc://210.162.163.34 6667 (閉鎖済)

DWANGO が Internet 向けに IWANGO というゲームロビーソフトを開発し配付しています. ゲームルームを実現するツールと IRC client との融合を考えているようです. 私が見た時点で, IWANGO IRC client 自身は極めて低機能な IRC client であり, Dreamcast IRC client と同レベルくらいといえます (細かいところはそれ以下). しかしバージョンの変更と共に品質や仕様は変化しています. この irc server は, IWANGO が日本人ユーザーに向けて提供している server です. 開設当時, とりあえず ircd 2.9.x となっていました. 開発目的のため, hostの変更や閉鎖は十分ありますし, すでに上記Hostは閉鎖済の様子です.

ReichaNet

www: ReichaNet http://www.reicha.net/

irc server: irc://irc.reicha.net

irc.reicha.net は, DNS で複数の irc server ホストのアドレスに振り分けられます. ( irc.osn.u-ryukyu.ac.jp irc.ryukyu.ad.jp irc.ii-okinawa.ne.jp irc.ivo.or.jp irc.infovalley.ad.jp irc.infoaomori.ne.jp irc.oitaweb.ad.jp irc.matatabi.or.jp irc.mcu.or.jp irc.olug.gr.jp irc.note.iri.co.jp など)

1999-05 時点で 100-200 人程度. 沖縄インターネット協議会, 琉球大学, など いくつかの組織が参加し運用しているようです.

JPchat

JPChat http://www.jp-chat.to/

irc server: irc://irc.jp-chat.to

JPchat の上記 irc server は, は, DNS で複数の irc server ホストのアドレスに振り分けられます. ( almond.scsi.or.jp penguin.deux.co.jp pine.biznet.to ns.deux.co.jp golden.pclab.ne.jp sun001.shinobu-unet.ocn.ne.jp ns.epsnet.co.jp dns1.groove.shinjuku.tokyo.jp doberman.biznet.to など)

有志で作る草の根 IRC リンク (irc server 間連結) だそうです. 1999-05 時点, 200 人程度の利用者.

日本国内商用 ISP 間 IRC server 接続実験

関連 www の URL は以下の通り.

商用 ISP 間接続の実験ですが, ISP はどのように IRC システムを商用するのか, これもまた実験の一つなのかもしれません. 「ユーザーサポートに利用」 「広告表示」 「接続料金の有料化」 「自社ユーザーへの限定」などなどいろんな方向があるでしょう. 他に ISP にとってどのような利用方法があるのか, 興味深いところです.

3web (threeweb)

www: http://www.threeweb.ad.jp/

IRC server: irc://irc.threeweb.ad.jp:6667-?

プロバイダー 3web の IRC server です.

SEGA USA

IRC server: irc://irc.sega.com:6667-?

米国 SEGA の IRC server です. ユーザーは米国人がほとんどです.

Undernet

IRC Server: jp.undernet.org, irc.ionet.net, irc.mit.edu など

EFnet

IRC Server: irc.funet.fi irc2.mit.edu irc.colorado.edu irc.texas.net など

米国では主流です. 人口などの規模は IRCnet ほどではないにしろ, その次に巨大です.

NERV

www: http://www.heart.to/

IRC Server: irc.nerv.ne.jp, irc.heart.to

[index] [here]

dricas IRC Server 停止について

SEGA が運営していた IRC Server irc.dricas.com が停止しました. 以下は, SEGA からのお知らせに関するページの URL です.

SEGABBS にある程度の話題はあるようです. ただしこの BBS は流れが速く, Expire が短期間です.

ドリームパスポート被害者同盟」 のページがあります. ここは DCer 漂流の被害に遭った WebTV IRC User が作成したページで, SEGA BBS の一部過去ログが掲載されているようです (* このページは消えたそうですが, とりあえずURL残します).

なおこの章は voidさん に教えて頂いた情報がいくつか(いくつも?)含まれています. 受け売りや伝聞もありますので, 信憑性低いでしょう.

[index] [here]

マナーが悪いという評判

DCer, DC-CHATer の評判は各地で流れていますが, 「マナーが悪い」の評価がほとんどです. 「喧嘩」「いたずら」「ナンパ」「嫌がらせ」など 各種悪戯や他のユーザーに邪魔となる行為を行っていたようです. DCer の動向を観察する watcher の方々によると, それを「行った加害者」と「行われた被害者」が明確に分かれるわけではなく, DCer の多くが, その加害者にも被害者にもなっているようです. DCer 全体とも言える混乱状況に対して, Server 運営の SEGA は対応することもできず, IRC server irc.dricas.com の運用停止となりました. 停止時点では無期限停止とも言われていました.

[index] [here]

評判の元

DCer の多くは「マナーが悪い」と評され, それは DCer 全体に対する評価となっています (当然のことながら, 全員が同様とはいえません).

彼らは完全にコンピューターやネットワークに関する初心者です. 経験, 知識, 技術などがありません. また, 順を追わず突然初心者同士の IRC 社会からスタートしています. ネットワーカーの多くは, 最初のうち人に聞いたり資料を読んだりなど, 順を追ってマナーや習慣などを学んでいきますが, 彼らはそれをすることなく, 突然に「初心者同士の IRC 社会」によって ネットワークに慣れていきます. そして, DCer 全体に言えることは, 他のネットワーカーに比べ, 低年齢であるということがあります. 「学ぶことなく, 慣れる」という原因もあり, また他にもあるでしょうが, いろんな理由から, 1998 年末よりスターとした Dreamcast の利用者である 彼ら DCer は「マナーが悪い」ネットワーカーになりました.

[index] [here]

dricas server 停止の結果

irc.dricas.com は停止時期において 1000 人収容でした. 停止以前から, 他の server にも DCer は存在しましたが, 多くはスタート地点である irc.dricas.com 内での活動です. そこに多くを収容されていた「マナーの悪い DCer」達は, server 停止と共に移動を余儀なくされます. すでに CHAT 中毒となってしまった DCer 達に, CHAT をしないという選択肢はありません. server 停止直後から各地の IRC server 網に分散漂流していきました. 漂流先の対象は, さまざまです.

米国 SEGA, reichanet, 3web, WebTV, IRCnet などなどあらゆる各地の server に dricas server 停止直後から DREAMCAST-USER が出現しています.

ある server 群では, 既存の channel があっというまにボロボロに崩されてしまい, DCer 接続排除となりました (実際は DCer でなくとも, 運営側の会員でなければ接続不可能の処置) .

ある server 群では, channel list 取得不可能のため, list から徘徊する放浪者の DCer として身動きが取れず, 変化はほとんど見られませんでした.

ある server 群では, 元のメンバーの努力により, なんとか悪化をくい止めている状態です.

ある server 群では, 日本人ユーザーが少数派であり, 英語の使用を余儀なくされるため, 日本人の子供が大半を占める DCer として上手く活動できない状態です. ただし, 英語しか通じない member が揃っている channel に入りながらも, 無理矢理漢字の日本語や謎の英語らしき単語 (しかも JIS 2 byte char の英字) で, 騒ぎ続ける DCer は沢山存在します. その IRC 空間においては, JP is shit の風潮が広がっています.

[index] [here]

例をみない DCer の特徴

この DCer 漂流問題を起こしている DCer は特徴的です. このような現象や集団は, ネットワークにおいてあまり例がないでしょう. まず各地から言われている DCer 全体に対する「マナー悪い」の評価, そして, その要因です. また, 一定期間, 閉ざされた空間に隔離収容されていた集団が 突発的に漂流を始めたこと, そして 1000 人規模 (それ以上?) という人数です. また, DC client 自身が持つ IRC Client としての特徴もあります.

[index] [here]

例をみない DCer の特徴 : 用語

彼らの用語の特徴もあります. 既存のネットワーカーから隔離され, 初心者同士の社会からスタートして, そのまま長期間ネットワークに慣れ親しんだため, 独特の用語が出てきます.

[index] [here]

例をみない DCer の特徴 : Client

Client Soft の特徴について.

画面に 6 行しか表示されず, ログ画面バックスクロールもありません. そのため早い入力をするユーザーを嫌がります. 彼らのタイプ能力か画面仕様の制限か, ほとんどのメッセージは, 1 行あたり日本語 10 文字未満, 7 文字前後となります.

channel list 取得機能はあります. しかしそこに topic は表示されません. そのため, DCer が channel を作成する場合, 説明的に異様に長い channel name とする傾向があります.

DC IRC Client は, op の使用ができません. channel の各種 MODE (+-b +-o など含む), KICK など, 操作は不可能です. DC IRC Client は, MODE 変更などの表示を見ることができません. 誰かが誰かを deop しても, 誰のどういう行動か知ることができません. JOIN PART も表示されないと聞きます. しかし, 現在誰が op を持っているかの現状については表示されると聞きます (曖昧).

DCer は, 「とある特定の channel に join することが目的で, IRC をしている」 わけではありません. chat が可能であればどこでも良いため, channel list 取得が必要条件となります. 「通常の DC Client では channel list 取得が困難となる server 群」 において DCer の活動は大きくありません. 関連情報ですが, DCer は, 電話や掲示板など, 別の場所であらかじめ連絡を取り合い, その結果, どこかの server , どこかの channel に集合することが多いようです.

DC Client は, whois をはじめ, 各種コマンドの操作が不可能です. そのため PC User が行う whois などを嫌います. 自ら公表し, (whois までやらなくとも) who 程度で相手の client に自動表示されるような情報, 例えば hostname などの情報も, 彼らにとっては知られるべきでない情報です. hostname を元に会話 (たとえば, そのプロバイダーって**にあるんですよね) を行えば「ストーカーだ」と騒ぎます.

DC Client は, どうやら JOIN, PART, QUIT などの情報を, リアルタイムに得ることが困難なようです (曖昧). そのため, 自分のメッセージにより参加退出を明確にさせようとし, 参加時, 退出時の挨拶が派手になります. DC は, IRC を操作しながら mail 書きの操作はできないため, IRC 利用中は, 携帯電話経由の「ショートメール」らしき手段を同時に使用することもあるそうです.

[index] [here]

ひとまずまとめ

以上, DC server 停止直後の DCer の動向. いろんな情報を提供してくださった方々に感謝いたします.

[index] [here]

部屋とチャンネルの話

「私」ではありません. 「話」です. 部屋と channel の違い, channel の意味の話です.

channel をカタカナで表現すると, 「チャネル」もしくは「チャンネル」と書くことができます. いきなり余談ですけれど, `/.anne./' をどのようにカタカナ化するかは, 単語によって人によって異なるようです. .anne. となる英単語を適当に羅列した表を以下に置きます:

anneアネアンネ
channelチャネルチャンネル
channelerチャネラーチャンネラー
channelingチャネリングチャンネリング
multichannelマルチチャネルマルチチャンネル
spannerスパナースパンナー
scannerスキャナースキャンナー
mannerマナーマンナー
bannerバナーバンナー
mannequinマネキン,マヌカンマンネキン,マンネカン
Johannesburgヨハネスブルグヨハンネスブルグ
runnerラナーランナー
plannerプラナープランナー

「ン」を入れない機会の方が多いのではないかと予想します. しかし, どちらであっても厳密には間違いです. どちらも元の英単語の発音を正確に表現できていないからです. ちなみに, channeler, channeling, multichannel をカタカナ化する場合, チャネラー, チャネリング, マルチチャネルと記述する人が多いと予想しております. 役に立たないでしょうけれど, /.[aeiou]nn[aeiou][bcdfghjklmnpqrstvwxyz]/ となる英単語を適当に羅列した表を以下に置きます:

tennisテニステンニス
savannaサバナサバンナ
announcerアナウンサーアンナウンサー
antennaアンテナアンテンナ
cannonキャノンキャンノン
cannonballキャノンボールキャンノンボール
connectionコネクションコンネクション
innerイナーインナー
annaアナアンナ
kennelケネルケンネル
tunnelトネルトンネル

さて, 話を本題である「 channel の意味」に戻します. 英和辞書を見ると `channel' という単語の意味として, いくつか(多く)の日本語が並んでいるはずです. 「水路, 海峡, 導管, 溝, 伝達手段, 輸送手段, 経路, 道筋, 路線, 通路, 伝達, 媒介, 系統, 分野, 方向, 注ぐ, 導く, 通信路」などが見付かるはずです. 通信やコンピューターの分野における channel という言葉の使われ方を考えますと, IRC における channel という言葉の意味は, 「系統, 経路, 通信路, 手段」 という日本語が持つ意味に近いと, 私は考えます.

そして 「系統, 経路, 通信路, 手段」である channel は, room (部屋) ではありません. channel は誰かの所有物ではなく, 基本的に誰も所有権を主張することはできません ( `!' channel の場合は, creator, owner, 所有者という *ような* フラグと概念が存在します )

頻繁に図書館へ通う学生が居て 「まるで図書館に住んでいるようだ」 と表現するにふさわしい状態であったとしても, 実際に住んでいるわけではありません. どこかの channel を頻繁に利用し, そしてその状態が長い年月継続したとしても, その利用者はその channel の持ち主ではありません. 最初にその channel に join した人物であっても同じことです.

東京大阪間を徒歩で移動しようという目的がある場合, 途中の経路となる道にはあらゆる組合せが存在するでしょう. 山を超え, けもの道を歩くという手段もあります. そこで選択すべきは, 経路であり通路であり, そして手段であり, これが channel です. 同じ目的のある別の人が同じ時刻に歩いている場合, 同じ経路 (channel) を利用していれば一緒に会話をすることができるかもしれません. 別の経路 (channel) ならば会話をすることができる可能性は下がるでしょう (ただし, IRC の場合は, 会話をすること自体が目的であるため, この例と完全に一致するわけではありません).

「この道を使って東京大阪間を歩いたやつは今までに居ない. この channel の最初の利用者は俺なのだ」と主張する人がでてくるかもしれません. しかし, いくらそれが事実でも, またそれを大声で叫んだとしても, その道の所有者となるわけではありません. 携帯電話などの MCA (Multi Channel Access) システムも同様で, これはそのとき偶然空いている周波数を探しだし, その周波数を一時的に利用して会話を行います. 会話が終了し閉局すれば, すなわち電話を切れば, その周波数は解放されます. 最初にその周波数を使用したからといって, その周波数の所有者になるわけではありません. IRC の channel もこれと同じことなのです.

IRC のシステムの場合, 大抵は同一のサーバー群に多くの人が接続しています. しかし, 利用者はその接続ユーザー全てに対してメッセージを送りあう, すなわち会話を望んでいるわけではありません. 例えば IRCnetであれば, 6 万人以上のユーザーが接続していることもあります. しかしその利用者は同時に 6 万人の人と会話を望んでいるわけではなく, そのうちの少なくて数人, 多くて数百人と会話をしたいわけです. そのとき, 6 万人という利用者の中から, 会話対象となる一部メンバーを選択する「手段」が channel であり, JOIN している channel の名称が同一であれば, メッセージが伝わる仕組みとなっています.

それは「手段」であり「経路」であるのが channel です. 物理的にも論理的にも, それは所有されるべき空間ではなく, すなわち 「channel を room (部屋) と呼ぶことがふさわしくないシステム」 が IRC なのです. ただし「場」と呼ぶ場合は別となります. room とは異なり, 「場」は 「誰かに所有されるべきもの」というニュアンスを含むことなく 使用可能な言葉です.

IRC のシステムを利用する場合, channel を room (部屋) と呼んでしまう愚かな行為をしないよう, 注意しなければなりません. それと同時に, 「表向きの言葉としては room (部屋) と呼んでいないけれども, 本質的にはそう呼ぶことと同様ともいえる考え方をしている」 という過ちをしてしまわないよう注意しなければなりません. これが重要です.

具体的には, 「ここは俺達の場だ」 と主張してしまうことが問題となります. チャンネルは誰の所有物でもありません. 「元から居たから」という理由で後から来たものを排除することは 「可能」です. これは chennel-op の使い方次第です. しかし, 可能だからといって, それが正当であるわけではありません. もちろん間違いとも言えませんが, 「元から居た」を理由として持ち出せば正しさを主張できると考えるなら, それは間違いです. 同時に, 後から来たユーザーが元から居たユーザーを追い出すことも可能です. そして「どちらの行為が正しいか」 ということを比較すること自体が間違いとなります.

このあたりの価値観が狂っている人は意外と大勢います. 価値観が狂っている人は自分のことを正常だと思い, 自分の価値観が常識的であると判断し, 主張するでしょう. しかしその考えが常識とは限らないのです.

2つの集団 crew-A, crew-B があり, その2つは仲の悪い集団であるとします. その集団が, 1つのチャンネル名称をかけて争っており, crew-A は 「このチャンネルは俺達が 4 年間使い続けて来たものだ」 と主張しているとします. その channel を crew-B が奪い取り, crew-A のメンバーを追い出し, 占拠をして 1 週間ほど経過し現在に至るとします. さてどちらが悪いのでしょうか? 答えは簡単, 「どちらが悪いのか」なんてことを考える人間が一番悪いのです.

過去 1 週間にわたって, crew-B のメンバーは crew-A のメンバーを 問題となる channel から追い出しました. すなわちその場を利用する権利を 1 週間奪い続けたわけです. もしこれが悪だと言うのであれば, crew-A が行った 「過去 4 年間に渡ってその場を利用する権利を crew-B から奪った」 行為はさらなる悪となります.

実際の channel 争いは, やはり人間同士の衝突ですから, 当事者が持つ色々な問題が複雑に絡んできます. この手の問題は IRC 上で「民事的な」争いと言われています. 夫婦喧嘩同様, 本来他人が口を挟むべきものではありません. 他人が民事的な争いに口を挟み, 自分なりの道徳を基準に事の善悪を判断しようとすること自体が間違いであり, 本来排除されるべき悪なのです. また, crew-A であろうと crew-B であろうと, 「自分達が真の所有者であり, 相手はそうではない」 と主張することも, またその考えを元に自分達の行動を正当化しようとすることも間違いです.

「早いもの勝ちが普通でしょう?」 という考えを基準とし, channel を room と扱い, 最初に作成した人が所有権を主張することを望む人がいるかもしれません. ドメイン名や実際の土地の開拓者など, 早いもの勝ちを主張するには, それなりの労力やコストが必要となります. IRC channel の場合は, 接続したクライアントが自動処理にて次々と適当な名称で JOIN をするだけで 多くの作成が可能となります. 労力もコストもほとんどゼロの者が, ただタイミングが早かっただけのことで所有権を主張したところで, それを認めてくれるような環境は少ないでしょう.

それでもなお「やはり早いもの勝ちが普通でしょう?」 と考える人がいるかもしれません. とある個人が個人的に IRC server を稼働させたとします. そこに知らない人が接続し, 自動処理にて, ありがちな名称の channel を次々と作成したとします. 「早いもの勝ち」でその人の所有権主張を許すと, 個人的に始めた自分の server の中で, 使用できる channel の権利を次々と他人に奪われることが 可能となってしまいます. 個人的な server であれば, server 管理者がその記録を削除し, 接続拒否の設定を行えば元の状態に戻せるかもしれません. しかし個人的ではない IRC server であれば, そのような個人的な行動は不可能でしょう.

それでもまた 「早いもの勝ちにすべきだ. それが本来 chat にあるべき姿だ」 と主張したいのであれば, IRC を使用しないことで解決するでしょう. IRC とは異なる別のプロトコルを作り出し, それに合わせたプログラムを作り出せば, 問題は解決です.

[index] [here]

437 Nick/channel is temporarily unavailable

net split が起きたとき, ちょうど孤立 server に一人でいたため, 入りなおして channel op を得ようと考えるかもしれません. そのとき, 切断された server の向こう側に channel op があって (現時点での状態は手元の server から見えないため過去の情報), 手元の server に無い場合, 入りなおすことはできません.

この場合, 全員が出たと同時に, その server 上のその channel (の名称) はしばらく使用不可能となります. これにより, channel 荒らしが net split を利用して お気楽に channel op の取得をすることが難しくなります. このときのエラーメッセージは, Error Code 437 です (Nick/channel is temporarily unavailable) .

これは, net split 発生直後に, 「向こう側で使われている Nick や Channel の名称を保護するために存在する 機能 (エラー) です. その名称が Nick であろうと Channel であろうと, エラーコード 437 となります.

この, 一時的な使用不可能状態は, 一定時間経過するか, net split が回復するまで続きます. 一定時間は, ほとんどの server で 15 分以上となります. ただし, その起点が, net split 発生時なのか, channel の場合, 最後のユーザーが PART したときなのか, に関しては知りません. 「15 分以上」と言われていますが, 実際の各地の server の設定では, 30 分, 80 分など, それより更に長い時間保護されるようになっています.

channel の防衛や攻撃のための soft (bot) を作る場合, channel 向けの 437 を受けたときの処理は注意する必要があります. まずは, JOIN コマンドをしばらく発行するわけですが, 短時間挑戦してだめなら, 当分は無理であると判断します. 無理と判断しながらも, 完全にあきらめるわけではなく, その後定期的に JOIN を送信することは有効です. 更に賢い bot にしたければ, `&SERVERS' に JOIN し, LINKS による自動調査を行い, それらから得られる情報を元に今の net split の状況を把握してしまいましょう.

[index] [here]

channel-split について

channel-split は, server-split (net-split) と異なる現象です.

ラグのある server 間で発生します. channel-split が発生すると同じ IRC server 群, 同じ channel であっても, server によって channel-mode(ope 状況など) に違いが発生します. ただし, server 同士の net split はおきていません. client のコマンド操作により発生し, 10 秒程度のラグがあれば発生 (作成) は容易です.

例えば, 遠く離れた 2 つの server 間にラグがあるとき, 両端の server にそれぞれ client を接続し, お互いがお互いを蹴ると仮定しましょう. それぞれ自分が接続している server 上では KICK コマンド成功となります. しかし, 相手の server に KICK コマンドが到達するころには, 既にその場で相手の KICK が成功しているため, 自分の KICK コマンドはエラーとなります. そうなると, お互いが, 「自分が接続している server 上では蹴られていないが, 相手の server 上では蹴られている」 ことになります.

この状態は, channel-split の影響を受けているユーザーが退出するなりの方法を使い, ユーザーの意思で復元作業を行う, もしくは, net-split が発生するまで継続します. ただし, net-split の発生回復によって, 必ずしも channel-split が回復するとは限りません. channel 内の人数が増え, server 間の矛盾情報が増えてくると (例えば双方で多くの KICK をしている場合などは) 回復に時間がかかります.

一部の server にのみ存在するユーザーが CHANNEL に MODE コマンドを発行すると, その一部の server では問題なく成功しますが, 「居ないはずの人が channel に MODE コマンドを送っている」わけですから, 居ないと認識している残りの server では, エラーとなります. このエラーのことを fake mode といいます.

server にどういう fake mode の ERROR が発生しているかは, 特殊 channel "&CHANNEL" にて見ることができます. この channel を見れば, channel-split の状況, どこの channel で起きているのかを, 知ることができます.

[index] [here]

channel 荒らしの動き方

ときどき channel 荒らしと呼ばれる存在を見かけます. 他人の channel で channel-op を取得し, 先住民の channel-op を剥奪し, あとは channel-op を利用してうまく MODE を操り, channel を占拠するパターンが多いでしょう. IRCnet上であれば, 多くの場合は欧州の学生によるプレイです. 動き方のパターンは, 皆ある程度似ています. 以下に, よくあるパターンを並べます. 攻撃することについて, 守ることについて, channel op の攻防について考えるための参考になるかもしれません.

なお, ここに記述されている状態や動きは, 極めて単純化された, 一般的な状態, そして軽度な攻防です. 実際の「現場」の状態は, ここで表現しているような単純な事態ではないでしょう. 攻撃する側の動きとしては, さらに複雑で, 強力な活動もあります. 大規模な「smurf 戦」になると, 日本でトップクラスの規模となるプロバイダーであったとしても, そのバックボーンは攻撃パケットできっちり埋まることでしょう. 単純な「op 戦」であったとしても, 戦略ゲーム同様先読みの能力まで問われるかもしれません.

なお, 本文書著者は, 「smurf 戦」を全く推奨しません (これは単純物量 DoS-atack のことを指し, tfn なども含みます). smurfer は, 初心者からも上級者からも, あらゆる者から軽蔑されます. 果物 1 つをスーパーから万引するためだけに, 店員と客を全て殺すような人がいますか? channel を 1 つ取るためだけに, 障害となる client (もしくは server) が所属するプロバイダーを まるごと停止に追い込む必要がありますか?

とりあえず「荒し」という単語が出ます. しかし, 「何かを荒らす」「荒らされる人の迷惑」 といった, 事の善悪らしき価値観は, この章に存在しません. ここでは単純に「op 戦」をスポーツやゲームと見なし, 道徳的な要素には触れず, 技術的な要素のみ着目します. 隙があれば攻撃し, 可能であれば破壊する, そういうのが当たり前であり, 悪でもなんでもないという価値観が必要です. 実際に破壊をすれば悪かもしれませんが (そうでしょうけれども), だからといって, 「そこまでやっちゃうと「悪」だから, たぶんそこまではやられないだろう」 と甘く見るのはただの甘えです. スポーツやゲームにはありえない考えです. 「自分の方針では xx による攻撃をしない」 と言うのは勝手ですけれど, それをやらられたからといって腹を立てるならば, 初めから争わないことです. channel に荒しが来たとしても, すぐに明け渡して別の名称の channel に移動し MODE +s するのです. channel が攻撃されたとき, その攻撃を受け止めて, 相手が普段利用していそうな channel を探し出して, そこを攻撃し, WHO, WHOIS の組み合わせから別の関連 channel も攻撃, その結果自分のシステムが破壊されたとしてもしかたがない, そういう心構えがあるならば, この章は少しだけ役に立つかもしれません.

[index] [here]

「全ての server 上で先住民が op を持ち, 荒らしが op を持っていない状態」

この場合は, 荒らす側は以下のいずれかの状態になるように行動します.

一般的には, まず全ての op を消滅させ 「全ての server 上で誰も op を持っていない状態」 を狙います. そのために, nick-change, CTCP などの各種攻撃を行います. 時には 偽装パケットや攻撃パケットなどが client に向かって直接流れるでしょう. また, タイミング良く net split が発生し, それが数十分程度であれば, nick 衝突による kill を狙うこともあります. 時には server をクラックした者が, server op を利用して kill の連続発行を行うでしょう. これを防ぐには, それら攻撃で落ちにくい (そして落ちてもすぐに復活する), client を多数常設し, それら複数台の bot が相互にガードし, KILL, QUIT, SQUIT, SERVER など, 各種メッセージを検出をした瞬間 nick-change で回避すればよいでしょう. ただし, 激しく nick-change を行うと, その行為だけで server から切断されてしまう場合があります. 検出後の自動 nick-change 回避は, 一定時間無効にする必要があるでしょう. server op による KILL と, 攻撃パケット, 偽装パケット, DNS 偽装などによる hostname 偽装, などなど厳しい部類の攻撃もありえます. しっかりした bot はそれらをできるだけ考慮し, できるかぎり対策しなければなりません.

net split が長時間の場合, 対岸で「437 name temporary unable error」による保護が効かなくなります. そうなると, 「net-split 状態で, 両岸に分かれた両方が op を持っている状態」 を狙うことは容易です. 防ぐことはほとんどできません. 対策するならば, 先住民が全ての server に接続しなければなりません. ただし, 全ては不可能だとしても, できるだけ多くの server から接続することは有効です.

「全ての server 上で先住民が op を持たず, 荒らしが op を持っている状態」 を狙っている場合, CTCP などによる攻撃で場を混乱させたあと, 先住民の誰かに似た nick もしくは同じ nick を利用して 「op」というような発言をすることがあります. 「なると」もあります. 欧米のユーザーであっても, カットアンドペーストを使用して 「なると」と発言することがあります. うっかり nick だけを見た先住民の誰かが配ってしまう可能性があるでしょう. もしくは, 観察によってその channel の自動 op の設定状態を把握し, その条件に合うドメインから入り込むという手もあります. *.jp に配ってしまう channel では, *.jp に該当するドメインから入るだけで op 取得可能です. 海外ユーザーが *.jp を名乗る場合, OpenSocks やクラックした jp サイト, 何らかの方法で入手した shell acount などの 利用, そして hostname の偽装が考えられます. hostname の偽装が始まると, hostname, username, nickname など全て同一もしくは類似になります. それらの情報に依存してはいけません. ユーザー認証のために, それ以外の「別の何か」を利用しましょう.

[index] [here]

「全ての server 上で誰も op を持っていない状態」

この場合, 短時間の net-split でも容易に op を得ることができるため, 「全ての server 上で先住民が op を持たず, 荒らしが op を持っている状態」 を狙うことは容易です. 防ぐ方法はないと考えられます. net-split が発生しなくても, CTCP 攻撃だけで得られる場合もあります. 特にこの場合は op 不在であり CTCP 攻撃をいつまでも続けることができます. 結果, 耐えられなくなった先住民が自主的に立ち去ることもあります.

この状態で, 「op を得たい」「相手が op を得てほしくない」と考えるのであれば, 相手が接続している全ての server に接続する, もしくは, 相手より多くの server に接続するなどの対応が必要です.

また, 誰も op を持っていない状態で, 自分側も相手側も少人数の場合は, にらみ合いとなります. 特に 1 台, 2 台程度の client の場合は, 一瞬の PART/JOIN で状況が変わるかもしれません. 相手が性能の悪い bot の場合は, PART/JOIN を連続で発行することで, それにつられて相手も PART/JOIN するかもしれません. 自分の PART/JOIN の時間間隔を調整することで, 場合によっては op を得ることができるかもしれませんが, 逆に奪われる可能性もあります. まず, 相手が PART をして, 自分一人になったからといって, つられて PART/JOIN を発行しないことです. また, PART ではない QUIT ですら注意する必要があります. 2 台の client を用意し, 1 台は JOIN しないで待機, 残りの 1 台を JOIN させておき, その 1 台を QUIT した瞬間に, 待機中の 1 台が JOIN するという手もあります. 相手の立ち去りに自動反応して, PART/JOIN をするような client は非常に危険だということが分かります. 誰かの立ち去りを引き金にするならば, 最後に立ち去った client の信頼度を確認しなければなりません.

[index] [here]

「net-split 状態で, 両岸に分かれた両方が op を持っている状態」

net-split 回復と同時に op 合戦が始まります. client の自動処理の性能や人数などで勝負が決まり, どちらかのみが op を持つ状態か, channel-split (fake) の状態になります. 互角の力では, channel-split になる可能性が極めて高いようです. また, ラグのある server 間での戦闘も同じことになります. この状態で狙うのは, 「net-split ではなく channel-split, 両岸に分かれた両方が op を持っている状態」 もしくは 「全ての server 上で先住民が op を持たず, 荒らしが op を持っている状態」 です.

[index] [here]

「net-split ではなく channel-split, 両岸に分かれた両方が op を持っている状態」

次回の net-split 発生と回復のときに, 「全ての server 上で先住民が op を持たず, 荒らしが op を持っている状態」 になるよう狙います. もしくは単純に向こう側で op を持っている client を調べ, それに対して直接攻撃をします. 相手側が即時 KICK を行う場合, 向こう側の op 状況を知ることは困難かもしれませんが, PART/JOIN/NAMES のコマンドの組み合わせを使用することで, 指定 server 上の状況を得ることができるでしょう. いつまでもこの状態が続くか, もしくはどちらかの op がなくなるかは, server の不調状態, net-split 回復時のメッセージ送信タイミング, 両者の client の性能や台数などで変わってきます. 攻撃する側も防御する側も同一立場になっているため, 防ぐための方法や奪うための方法はほとんど同一となります. 基本的に手元の server に相手が存在しないよう ban kick をしておきます. 逆として, 相手側の server から join できるよう挑戦します. また, net-split 発生・回復のとき, 相手側の client の負荷を高めるための準備として, 相手にとって都合悪くなるような channel モードを指定しておきます.

このような状態のときは, names コマンドが有効です. 相手が接続している server から channel へ join できなくても, 手元の server で join できれば, 相手側 server 上での参加者一覧を取得することが可能です. names コマンドには, パラメータとして, 質問先 server を指定できることに注意してください. 相手側 server 上で kick されている場合は, names を得ることはできません. しかし, join 直後は「決して kick されていない状態」ことを考えれば, part コマンドが「相手側 server の参加者一覧」を得るために利用可能であることが分かるはずです.

deop 合戦のときは, 各種コマンド (KICK, MODE) を, どのような順序で発行するか, 慎重に検討する必要があります. ただやみくもに KICK や deop すれば良いというわけではありません. 当然, 自分も相手も複数 client で待ちかまえますが, その複数の bot の動作が重複しないよう気を付けなければなりません. 全員総掛かりで相手のうちの一人の op を奪う行為は無駄になります. その間に相手が「1 人あたり 3 人 deop」を分担作業すれば, あっというまに奪われてしまいます. 短時間に発行可能なコマンドは限られるため, deop, op, ban, KICK など担当を分けることも良いかもしれません. 大規模な deop 合戦においては, 役割分担も必要になるでしょう. 0x07-o JOIN (すなわち +o join) を検出した直後からの数行が大きな意味を持つこともあります. KICK コマンドは, 自らの op が fake でないことを確認しなければ発行できません. このあたりの推論機能を bot に組み込むことが重要であり, client 数が同一であれば, bot の思考能力で勝負が決まります. EggDrop など一般的な bot を使う場合, ほとんどの bot は, しっかり動くにしても, 推論が足りない (悪く言えば, 悪知恵が足りない) ため, 何らかの改造を入れない限り, その点が弱いと思われます (あいまい情報).

[index] [here]

「全ての server 上で先住民が op を持たず, 荒らしが op を持っている状態」

これが荒らし成功の状態です. channel モード b n m t i k l などを利用して, 先住民が使いにくくなるような channel に変えることが一般的です. +ibk などで完全に入れなくした上, いつまでも常駐することがあります. また, 参加自由にしておいて, トピックのみ占拠, +m -m の連続, ときどき kick など, 反応が目に見える悪戯もあります. こういうときは, 全員が channel を捨てて引っ越し, チャンスがくるのを待つ方が良いでしょう. 長期的でない荒らしは, 成功した後すぐに立ち去ることがあります. その場合も, なにもしないで立ち去る, +mt などを置いて立ち去る, などいろんなパターンがあります.

この状態になってしまった以上, その時点では, 荒らしが先住民であり, 先住民が荒らしという立場になります. もし channel を奪回しようとすれば, その行動は, 先住民に対して攻撃する荒らしと同じことになります. 奪回の行動, 方法, 技術は, 荒らしの行動, 方法, 技術です. IRC の op 合戦は channel への攻撃が多少有利ですので, 荒らし達が channel を奪い取ることに成功したように, 元先住民達が channel を奪回することに成功する可能性は十分あります.

ただし, 最初に奪おうとした荒らし集団 (もしくは個人) と これから奪い返そうとする先住民には, 人数などの違いがあります. 人数が多いということは, ときには障害となります.

勝ち取るために求められるのは, client の性能, client の数, 接続 server の数, IRC op 合戦のための技術, IRC op 合戦の経験, そして運です. 運が良ければ, 数も技術も経験も無い状態で, 勝ち取ることも `希' にあります.

[index] [here]

日本語対応 IRC client の日本語対応問題

日本語対応 IRC client は, 幾つかフリーウェアなどでオンライン公開されていますが, 多くの client は日本語や各種コードの扱いに問題を抱えているようです. とくに, 0x80 以上のキャラクターコードの扱い (送受信など) が難しく, ほとんどの client で問題を抱えているようです. ここでは, それら問題点の一部を挙げてみます.

[index] [here]

CHOCOA 0.2 シリーズ, takirc などで, mode コマンドの param 部分 0x80 以上

":prefix MODE #channel -bb a\xF0\x20a\r\n"
を受信することで, chocoa 0.2 シリーズなどの client は, 落ちてしまうようです. この現象はバージョンによって異なるでしょう.

IRC client 作成時の注意や対策:
そもそもこういう問題が起きること自体おかしいと考えるべきです. -bbb +bbb などの mode コマンドを解釈する際, その後ろに param がいくつ並ぶかは, -bbb の部分で予想することはできても, 確定することは出来ません. まずこれが 1 つの考え方です. そして重要なのは, params は, \x20 で区切られるということです. 区切りであることを認識し, まず解釈の初期段階で区切っておき, そのあと日本語について考慮すべきです. \xF0 のようなコードが登場したとき, 続く 1 文字は, 2 byte 文字の 2 byte 目であると憶測可能でしょう. しかし, それは続く 1 文字を見て判断すべきことです.

[index] [here]

"\x1B$B$\x20" をユーザー情報に含むことで whois をうまく見ることが出来ない

"\x1B$B$\x20" (末尾の "\x20" はユーザー情報そのものではなく whois result に含む区切り) をユーザー情報, 特に joined channel 名に含ませることで, 一部の日本語対応 client は, whois の結果をうまく表示できないことがあります.

IRCnet の日本の server では, good user name が設定されているため, username にこのようなコードを含ませることはできません.

IRC client 作成時の注意や対策:
\x20 は, いかなる日本語文字にも含まれることはないことを考えるべきです. 2byte 目や, ISO-2022-JP の日本語セットに切り替わっているときなど \x20 や, 本来あるべき範囲の外のコードが現れたら, そこ, およびそれ以降が US-ASCII であると考えるべきです. 異常コード周辺を「全てバイナリー」と扱う手段も良いでしょう.

そしてここで重要な点は, 受け取った文字列をいきなり日本語コード変換しないことです. 必要な params の分割を行った後, 変換すべき部分だけ変換すればよいでしょう. また, 日本語コード変換 (例えば JIS から SJIS へのような変換) を行う場合も, \x20 などのコードは, 2byte 文字としてありえないと考えるべきです.

また `#あ' という channel 名があったとき, それはどのようなコードで構成されているのかを考えてみます. 普通の日本語 IRC client であれば, "#\x1B$B$\"\x1B(B" となります. mIRC のような IRC client を 日本語 Windows 上でそのまま動作させてしまうと, これは Shift_JIS で "#\x82\xA0" となるでしょうし, EUC-JP を入出力する端末上でなにも考えず "#あ" と送信すれば, "#\xA4\xA2" になってしまうでしょう. ISO-2022-JP の場合, \x1B$B ではなく \x1B$@ が使用されるかもしれませんし, \x1B(B ではなく \x1B(J が使用されるかもしれません. もしくは "あ" の終わりには切り替えコードが付加されないかもしれません. そうなると, "#\x1B$B$\"\x1B(B", "#\x1B$B$\"\x1B(J", "#\x1B$B$\"", "#\x1B$@$\"\x1B(B", "#\x1B$@$\"\x1B(J", "#\x1B$@$\"", の 6 通りが "#あ" になってしまいます. この 6 に先ほどの Shift_JIS もしくは EUC-JP が加わり, "#あ" を現すコードは (多くの日本語環境上で) 7 通りもあることになります. この 7 つの表記は, 日本人ユーザーが日本語対応 IRC client を経由すると どれも同じ "#あ" に見えます. しかし, 実際は全て異なる channel です. 逆に "#ち" と "#め" は, 日本人ユーザーが日本語対応 IRC client を経由して眺めると 異なる channel のようですが, 実際は "#\x1B$B$A\x1B(B" と "#\x1B$B$a\x1B(B" の同一 channel 扱いとなります. 同じに見えるが違う名前, 違って見えるが同じ名前, これらの問題をうまく解決できてこそ, 本当の日本語対応 IRC client です.

[index] [here]

mode の param に 0x80 以上のコード

+k (keyword), +b (ban) の param に, 0x80 以上のデータを含むと, それを解除することが出来ないという IRC client が一部あるようです. 「日本語未対応」の IRC client はほとんどこの問題を持っていません.

IRC client 作成時の注意や対策:
mode コマンドの param には, channel 名を除いて, 日本語が存在しないと考えるべきです. これは, 送受信ともにいえることで, 送受信時の文字セット変換の対象外にしましょう.

channel 名にすら, 日本語コードはありえないと考えると, さらに安全となります. しかし不便になることもあります.

[index] [here]

nick/channel の名称空間における英字大小の同一視 (その 1)

NICK および CHANNEL の名称については, 英字の大文字小文字が同一視されるという仕様があります.

すなわち, nick name `test', `TEST', `Test' これらすべて同一扱いされます. channel name `#test', `#TEST' も同一扱いされます. これは, ASCII 「'A'(0x41)-'Z'(0x5A),'a'(0x61)-'z'(0x7A)」 が対象ですが, 他のコード 「'['(0x5B) と'{'(0x7B)」 「'\'(0x5C) と'|'(0x7C)」 「']'(0x5D) と'}'(0x7D)」 「'^'(0x5E) と'~'(0x7E)」 も, また同一視されます. 欧州の一部フォントでは アルファベットに該当するためでしょう.

当然のことなのですが, 英字同一視は, あきらかに英字に見える channel name に限らず, 日本語 ISO-2022-JP に含まれる ASCII 英字に該当する部分も対象となります.

channel name 「#たちつてと」は, ISO-2022-JP charset で表記すると,

です. そして以下の 2 つは当然同一視されます.

ちなみにこの表記の場合, 「#たちつてと」と「#ためやゆよ」 になります. すなわち, その 2 つの channel は, 同一 channel となってしまうわけです.

これは日本語 channel name の channel を利用している人にとって, 常に十分注意すべき点であると考えた方がよいでしょう. channel 名の破壊という攻撃が考えられるためです.

たとえば「#たちつてと」という channel が存在し, ユーザーも多いとします (現状存在しないようですが). その channel 名を破壊しようとする人は, 常に「#ためやゆよ」に join するように心がけるわけです. 運良く全員が退出すれば, その際「#ためやゆよ」に re-join をします. 運悪くとも, net split など, IRC ネットワーク空間の異常を利用するなどして, 「#ためやゆよ」 という名称の確保を行います. その channel の規模や動きにもよりますが, 時間, リソースをかけることにより, 名称が変更される可能性は少しずつ上がっていきます. 手作業ならば根気が必要となりますが, 自動で行えばただの放置です.

さて, これが成功したあと, 変更された名称のダンプを見る限りは「A」から「a」への変化という 英字大小文字 (alphabet case) の違い程度にすぎません. しかし, (大抵の client では) 日本人から見れば「全く異なる日本語の文字」になるわけです. もちろん, 正しい日本語対応 IRC client であれば, 問題は起きません.

毎日人数ゼロになるような小規模 channel ではほとんど問題ありません. しかし, 人数ゼロになる可能性がほとんどない規模の channel では, 致命的なダメージです. これを防ぐのは, channel op 防衛とほとんど同じと考えて良いでしょう. net split などを利用した攻撃から OP だけでなく, 名称もカードしなければならないのです. op の場合は, 攻撃者に取得されても deop という対策が残されています. しかし channel 名破壊の場合, 一度壊された名前は, 同じ方法で壊し返して元に戻すしか対策がありません.

一般的に普及している既存の日本語対応 IRC client soft において, この問題点で不正終了など致命的なダメージを受ける soft はほとんどないでしょう (エラーで終了してしまう client が一部有り) . とりあえず使うことはできます. しかし, 名称は変更されます. すなわちほとんどの client において, 落ちてしまうようなダメージは受けないが, 対策はされていない, という状態です. もっとも, どのような対策が望ましいかという件については, 容易に結論がでません.

[index] [here]

nick/channel の名称空間における英字大小の同一視 (その 2)

前述「その 1」で触れたのは, ISO-2022-JP セットの, JIS X0208 部分 (漢字などの 2BYTE 文字部分) です. しかし, 名称に対する英字大小同一視に影響を受けるのはその部分だけではありません. ASCII から X0208 への切替部分も同様です. すなわち "\x1B$B" も "\x1B$b" も同一になります. この問題点は「その 1」より注目すべき点でしょう. 英字大文字 `B' は全ての日本語名に最低 2 個は含まれています.

この問題点による症状はいつでも発生します.

もし, channel 「#たちつてと」 ("\x1B$B$?$A$D$F$H\x1B(B") が存在するとき,

このコマンドが何を意味するか, 理解できるでしょうか.

まず, 極めて一部の日本語 client は, これを受けるだけで不正終了します.

また, ほとんどの日本語 client は, どの channel に送られたメッセージか理解しません. 「メインウィンドウ」「コンソールウィンドウ」と呼ばれるような 別の場所に表示されることでしょう (さらにそれを見たユーザーは, てっきり個人宛のメッセージだと勘違いし, 「なにか用ですか?」と返事をしてしまいます). すなわち, その PRIVMSG の middle に記述されたターゲットが 自分が join している「#たちつてと」に対するコマンドであることを理解しません. TOPIC, MODE コマンドにおいては, PRIVMSG と異なり, 「channel が保有する情報」となるためなのでしょうか, 接続している server 上での名称空間からの情報を元に, 正常な名称へ置換されます. PRIVMSG, NOTICE などメッセージは見事送信コマンドの middle に従います.

TOPIC, MODE の扱いと, PRIVMSG, NOTICE の扱いに違いがあります. もし, この違いがなければ問題は軽いのかもしれません. PRIVMSG, NOTICE も TOPIC, MODE 同様, server が正常な名称へあらかじめ置換すると良いのでしょうけれど, これは server 側の不備ということで, client はその不備をカバーするだけの機能を装備しなければならないわけです.

この問題の対象に PRIVMSG が含まれるということは, すなわち CTCP も含まれるということです. たとえば, "#たちつてと" に CTCP flooding atack をかけたい場合, "PRIVMSG \x1B$b$?$a$d$f$h\x1B(b :\x01.....\r\n" という形での PRIVMSG コマンドも有効になるわけです. 一部の bot およびユーザーが直接操作用として利用している client は, PRIVMSG の target がどこの channel であるか, channel に対する攻撃であるか, すぐに把握しないでしょう. 多くの client からみれば, 画面に QUIT メッセージだけ流れることになります (ここで常連の nick を騙ると, あっと言う間に占拠完了かもしれません) .

しかし, あらかじめ注意深く対策しておけば, この症状を対策困難と見ることはないでしょう.

日本語対応 client soft の作成において, 「英字大小同一視」という仕様を十分に考えておくことです. ルールは単純で, 「0x61 から 0x6E は 0x41 から 0x4E と等しい」だけです. まず, channel name など内部に保有する情報は, Shift_JIS, EUC, unicode など, 内部のコードに変換せず, すべて生の状態で保有すべきです (server から受信されたまま, 送信するまま). そして, それらの英字大小が同一扱いであることを考慮しておきます. たとえば自分が「#たちつてと」に join している状態で, 「#ためやゆよ」へ PRIVMSG が到達した場合, 少なくとも, PRIVMSG の middle に書かれた target は, 「#たちつてと」を意味すると解釈し, 「#たちつてと」の channel メッセージ解釈部分に受け渡します. その際, 内部的に middle を置換するという手もありますし, 置換しないで「#ためやゆよ」へのメッセージという情報を保持したまま, 「#たちつてと」のウィンドウへ出力するという手もあります.

日本語対応 client soft を作るにおいて, もうひとつ考慮すべき点は, さきほど述べた重要な問題点 "\x1B$B" と "\x1B$b" です. 送信する場合は, 当然原則として「$B」を使用します. 受信の場合は, 「$B」も「$b」も, JIS 2 byte 文字スタートとして認識することが大事です. ISO-2022-JP には, JIS X0208-1983 スタート "$B" だけではなく JIS X0208-1978 スタート "$@" も存在しますから, まずは, "$B" "$b" "$@" この 3 つを, JIS 漢字スタートと解釈すれば良いでしょう. 同じように, ASCII スタートも, "(B" "(b" "(J" "(j" となります.

メッセージの trail 部分については, 「$b や$j など, そんな腐ったデータは捨てても良い」 と開き直ることができます. しかし, それ以外の params 部分については, 粗雑な扱いが望ましくありません. 「channel 名」「mode +k のキーワード」 この中に $B $@ などを入れられるとどういう結果になるか, 日本語対応 IRC client soft を作る上で, 必ず検討しなければならない事項です.

残念ながら, この点を十分考慮して作られている soft は, ほとんどありません.

また, 「日本語非対応 client + コード変換 proxy」 という形の運用では, 上記の 「内部で保有する情報は server 送受信を行う生のままのコードで取り扱う」 という対策が不可能となります. 「mIRC + 日本語コード変換 proxy」 という運用を見かけることもありますが, これは確実に問題を抱えています.

[index] [here]

おわりに

このページに書かれている情報は IRC についてのほんの一部でしかありません. RFC を含め, すべてを理解して, ようやく, 初心者から初級者になれるかもしれません. これら全てを理解したからといって, 決して高いスキルを得られるわけではないことにご注意ください. また, 記述内容に嘘や間違いがある可能性は十分あります. 文章の著者は, それにより発生するいかなる事柄に対しても, 責任を負いません. 読む場合は, 自己責任において, 読むようにしてください.

ときどき, ここに書かれてある内容を一部だけ読んで 「あーなるほど」と勘違いし, 部分的に利用している人がいます. しかし, それでは, 情報を有効に利用することができません. 初級者どころか, 初心者の状態のままです. 一部の情報だけ読み出し, それを利用して, channel 攻撃をする人もいます. ほとんどの場合は, 効果がないでしょう. 普通の channel であれば, 初心者の攻撃程度で, 変化は現れません. そして, 攻撃を行い, それに失敗したという情けない過去は記録に残ってしまいます.

ここに書かれてある内容や, ここには書かれていない他の情報まで理解して, ようやく初級者になるでしょう.

もし, 初級者の状態から, さらにスキルアップしたいのであれば, さらに研究が必要です. あらゆる種類の client を, 作り上げましょう. そして, いろんな動作や試験を行い, さらに, 様々な op 合戦を体験し, 実戦でしか得られないコツを身につけましょう. もっとも, 自分だけや, 仲間内だけの op 合戦には意味がないでしょう. 予想も付かないパターンで, 予想も付かない攻撃を受けると, 「こういう状態ではどんなコマンドを優先して送れば良いか」 ということを深く検討できるようになります. しっかり研究をすれば, 中級者になれるかもしれません.

もし中級者の状態から, さらにスキルアップしたいのであれば, さらに研究が必要です. さらに細やかで複雑な, 技や情報を得る必要があるでしょう. しかし, このあたりの情報は, おそらくどこにも掲載されていません. 自ら探しだし, 自らの経験から, 見つけだしていくしかないでしょう. 知識や技, リソースやスピードを高めていきながら, 最後には, そのノウハウをぎっしり詰め込んだプログラムを次々と作っていきましょう. そして, 世界各地のサイトからシェルアカウントを入手し, 世界中のあらゆるサイトから, あらゆる server に接続可能な環境を作り上げることで, もしかすると, 上級になれるかもしれません.

もし上級者になった場合, その知識や技術を私のような初級者に提供していただければ幸いです.


/ jcol tool lab / RFC から読めない IRC


last-update: 1999-11-23 (automatically update)
Copyright (C) 1996-1999, jcol <info@netnews.to> All rights reserved
all-counter: (since:1996-05-24) - -