Naptify Guild Protocol 1.0(草案)

この文書は翻訳です。英語版が正本です。両者が食い違うときは、英語版に従います。 文書のライセンスは CC BY-ND 4.0 です。この仕様を実装することは誰でも自由で、使用料は求めません。

0. この文書について

項目 内容
拡張の名前 Naptify Guild Protocol(略して NGP。英語の表記は Guild)
版 文書は 1.0 草案(2026-09-27)、プロトコルの版は 1
発行元 Naptify プロジェクト
公開先 https://naptify.net/ (版ごとの固定の URL は未定)
準拠 OpenNap プロジェクトが公開したプロトコル仕様の原典 [NAP](§18)に準拠する(§1)
対象 [NAP] のクライアント向けの電文のうち、本書が本文を流用するもの(§1.1)を実装した OpenNap 系のサーバーなら、どれでも実装できる。8000 番台のサーバー間リンクや、OpenNap のサーバー間の電文(10010 番台)は実装していなくてよい
既存のリンクとの関係 独立している。8000 番台(SlavaNap 系のリンク)と OpenNap のサーバー間の電文を、使わないし変えない。同じ待受ポートで共存できる(§6.1)。同じ 2 台のあいだに、リンクとギルドを同時には張らない

ギルドとは。 別々の持ち主が動かす OpenNap サーバーどうしが、お互いに登録した相手と 1 対 1 で直接つながる仕組みである。

  • 中継するもの:チャット、IM、在席、参照、検索、ファイル転送の段取り、wallop。
  • 共有しないもの:登録ユーザー、BAN、級(レベル)、ポイント、制限。
  • 各サーバーは、自分にログインしている利用者についてだけ責任を持つ。

1. 準拠する範囲と、独自に足す範囲

1.1 準拠する点

  • フレーム。 [NAP] §2 の形に従う。長さ 2 バイトと種別 2 バイトの 4 バイトの見出しで、どちらもリトルエンディアン。そのあとに本文が続く。
  • 文字列の書き方。 [NAP] §2 に従う。
  • 欄は空白 1 つ(0x20)で区切る。
  • 空白を含みうる値は " で囲む。
  • 行の終わりの CR・LF は付けない。
  • 既存の電文の意味を変えない。 次の電文の本文は、[NAP] の書式のまま、本書の電文の中に入れて運ぶ。
  • 200・201(検索の要求と結果)
  • 203・204・206(ダウンロードの要求・許可・エラー)
  • 205(IM。サーバーからクライアントへの形)
  • 211・212・213(参照)
  • 403・406・407・410(チャンネルの発言・入室・退室・話題)
  • 501(ファイアウォール越しの許可)
  • 609(アップロードの断り)
  • 627(wallop。サーバーからクライアントへの形)
  • 824(エモート)
  • クライアントには新しい電文を送らない。 相手のサーバーの利用者のことは、既存の電文だけでクライアントに見せる。

1.2 独自に足す点

  • 種別 9000〜9199 の割り当てと、その意味(§5〜§13)。
  • 相互の認証、版と能力の交渉、在席の同期、名前の見せ方の規則、要求番号、切断と断りの理由の番号。
  • ギルドの電文の本文の文字コードを UTF-8 に定めること(§4.2)。

1.3 この文書が定めないこと

  • クライアントとサーバーのあいだの手順([NAP] のまま)。
  • 8000 番台のリンク。
  • クライアントどうしの転送そのもの([NAP] §5 のまま)。

2. 用語と規範の言葉

用語 意味
サーバー OpenNap のクライアントを受け付けるサーバー
相手 ギルドとしてお互いに登録し合ったサーバー
ギルドの接続 相手とのあいだの、認証が済んだ 1 本の TCP 接続
繋ぐ側/受ける側 その TCP 接続を開いた側/受け付けた側
自分の利用者 そのサーバーにクライアントとしてログインしている利用者
相手の利用者 相手のサーバーの自分の利用者で、在席(§8)で知らされた人。利用者名と出どころの組で見分ける
出どころ(origin) 電文を作ったサーバーの名前
見せる名前 相手の利用者を、自分の利用者に見せるときの名前(§8.3)
能力 任意の機能を実装していることを示す短い語(§6.5)
鍵 2 台の運用者があらかじめ分け合った秘密のバイト列(§6.4)
要求番号 検索と参照の要求と応答を結び付ける数(§11)

規範の言葉は RFC 2119 と RFC 8174 [RFC2119][RFC8174] に従う。

日本語版での対応

本書の言葉 対応
しなければならない MUST
してはならない MUST NOT
すべきである SHOULD
すべきでない SHOULD NOT
してもよい MAY

3. 全体の形

  1. 直接だけ。 各サーバーは、自分が登録した相手とだけ直接つながる。 – 相手から受けた在席・発言・要求を、ほかの相手や、ほかのサーバー間の手順(リンクなど)へ転送してはならない(MUST NOT)。 – 転送しないので、つながりが輪になってもよい。 – A と B、B と C がギルドのとき、A と C のあいだでは何もやり取りされない。A と C がやり取りするには、A と C が直接ギルドを組む。
  2. 自分の利用者のことだけ告げる。 在席で知らせるのは、自分の利用者だけでなければならない(MUST)。
  3. 出来事を送り、命令は送らない。 – 電文が運ぶのは、自分の利用者がしたことの結果(発言した、入室した、など)である。 – 相手の利用者やサーバーの状態を変える命令は、この拡張には無い。 – 受け側は、相手の級を理由に、自分の利用者や自分の保存している情報を変えてはならない(MUST NOT)。
  4. 規則を当てるのは、その利用者がいるサーバー。 – 発言の口止め、連投の制限、ダウンロードの条件などは、その利用者がログインしているサーバーが、送る前に当てる。 – 受け側は、自分の利用者への配送を、自分の判断で止めてよい(MAY)。

4. 電文の共通の決まり

4.1 フレーム

+--------+--------+--------+--------+----------------+
| len lo | len hi | typ lo | typ hi | payload (len)  |
+--------+--------+--------+--------+----------------+
  • len と typ は、符号なし 16 ビットのリトルエンディアン。
  • 受け側は、65535 バイトまでの本文を受けなければならない(MUST)。
  • ビッグエンディアンの形を使ってはならない(MUST NOT)。

4.2 文字コード

  • ギルドの電文の本文は UTF-8 でなければならない(MUST)。 正しくない UTF-8 を含む電文は捨てなければならず(MUST)、9007(理由 6)を返してもよい(MAY)。
  • クライアントと別の文字コード(CP932、CP1252 など)で話すサーバーは、ギルドへ送る前に UTF-8 に直し、受けたら自分のクライアントの文字コードに直す。
  • 自分のクライアントの文字コードで表せない文字を含む名前・チャンネル名・ファイル名は、? などに置き換えて見せてはならない(MUST NOT)。見せられないものとして扱う(その利用者・その結果を、そのクライアントには出さない)。
  • ファイル名の往復についての注意(参考)。 CP932 のクライアントが送るファイル名は、ふつう Windows が Unicode から変換して作ったバイト列なので、UTF-8 を経て CP932 に戻しても同じバイト列になる。例外は、同じ文字に 2 つの符号を持つ文字(NEC 選定 IBM 拡張文字、NEC 特殊文字の一部)を、標準と違う側の符号で持つファイル名である。これは往復で別のバイト列に変わるので、ギルド越しのダウンロードが失敗しうる。

4.3 欄の型

型 書き方
srv サーバー名。ASCII の英数字と . - _ だけで、1〜63 バイト。比べるときは ASCII の小文字に直す
nick 利用者名。UTF-8 で 1〜255 バイト。空白(U+0020)、"、制御文字(U+0000〜U+001F、U+007F)を含まない
ch チャンネル名。UTF-8 で 1〜255 バイト。空白(U+0020)、"、制御文字(U+0000〜U+001F、U+007F)を含まない
token ASCII の印字できる文字で、空白を含まない。1〜255 バイト
int 10 進の 0 以上の整数。先頭に 0 を付けない(0 そのものを除く)。上限は欄ごとに示す。握手が済んだあとの電文では、上限を越えた値は、書式の誤り(§14 の理由 6)として扱う。握手のあいだ(9000〜9003)は §6.2 に従う
hex 小文字の 16 進
md5 [NAP] の 204・501 の md5 の欄と同じ。値は変えずにそのまま運ぶ
qstr " で囲んだ文字列。中に " を含まない
abbr サーバーの略称。各サーバーの運用者が自分のサーバーについて設定する短い呼び名。Unicode のコードポイントで数えて 1〜16 文字、かつ UTF-8 で 64 バイト以下。空白・"・(・)・制御文字を含まない。設定していなければ - を送る
rest その位置から本文の終わりまでの全部。空白を含んでよい。最後の欄にだけ使う
body(N) [NAP] の電文 N の本文そのもの。常に最後に置く
  • 利用者名は、ASCII の英字の大文字と小文字だけを同じと見なし、そのほかはバイトで比べる。
  • 実装が自分の規則でもっと広く同じと見なす場合(全角の英字など)は、そう見なした名前どうしも同じ名前として扱わなければならない(MUST)。

4.4 出どころの欄

  • 利用者に関わる電文(9010 以降)は、最初の欄に出どころ srv を持つ。
  • 版 1 では、出どころは接続の相手の名前(§6 で認証したもの)と同じでなければならない(MUST)。
  • 違う電文は捨てて、9007(理由 14)を返すべきである(SHOULD)。繰り返すなら 9006(12)で切ってよい(MAY)。

4.5 行為者の確かめ

  • 電文が相手の利用者の名前を行為者(発言者、IM の送り手、要求者、ダウンロードする人、アップロードする人、wallop の送り手)として含む場合、受け側はその名前が、その相手の在席にあることを確かめなければならない(MUST)。
  • 無ければ捨てる(理由 13)。

4.6 順番と、知らない電文

  • 受け側は、受けた順に処理しなければならない(MUST)。
  • 9000〜9199 の中の知らない種別は、無視しなければならない(MUST)。9007(理由 8)を返してもよい(MAY)。
  • ギルドの接続に来た、範囲の外の種別も無視しなければならない(MUST)。
  • クライアントの接続に来た 9000〜9199 の電文を、ギルドの電文として扱ってはならない(MUST NOT)。例外は、ログイン前の最初の 9000 だけである(§6.1)。

5. 番号の割り当て

範囲 使い道
9000〜9007 接続・認証・生存確認・切断(§6・§7)
9010〜9012 在席(§8)
9020〜9024 チャンネル(§9)
9030〜9031 IM(§10)
9040〜9043 参照と取り消し(§11)
9050〜9052 検索(§11)
9060〜9064 転送(§12)
9070 wallop(§13)
上の間の空き、9080〜9099 版 1.x の予備
9100〜9189 将来の版のための予約
9190〜9199 実装者の試験用。正式には割り当てない。相手が同意していない限り送ってはならない(MUST NOT)

6. 接続と握手

6.1 接続の見分け方

  • 繋ぐ側は、相手の OpenNap の待受ポートへ TCP で繋ぎ、最初のフレームとして 9000 を送る。
  • 受ける側は、ログイン前の最初のフレームの種別で見分ける。
  • 9000 ならギルドの握手。
  • 既存のリンクの電文(8000 など)ならリンク。
  • そのほかならクライアント。
  • 9000 の本文は、先頭が ASCII の GUILD でなければならない(MUST)。違えば 9006(理由 2)で切る。
  • 運用者は、ギルド専用のポートを別に開いてもよい(MAY)。

6.2 流れ

繋ぐ側 I                                            受ける側 A
  | 9000 GUILD <vmin> <vmax> <I名> <nI> <capsI> <abbrI>  --> |  I が登録された相手か確かめる
  |  <-- 9001 <ver> <A名> <nA> <capsA> <abbrA>               |
  | 9002 <proofI>  -->                                       |  proofI を確かめる
  |  <-- 9003 <proofA>                                       |
  | proofA を確かめる                                        |
  |============= 双方が在席の一覧を送る(§8.2) =============|
  • 握手の全体は 30 秒以内に終えなければならない(MUST)。越えたら、どちらも理由 2 で切ってよい(MAY)。
  • 握手が済むまでに 9000〜9003・9006 以外の電文を受けたら、9006(理由 2)で切る。
  • 握手のあいだ(9000〜9003)に、書式の誤りや上限を越えた値を含む電文を受けたら、9006(理由 2)で切る。

6.3 電文

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9000 GUILD_HELLO 繋ぐ側→受ける側 token "GUILD"、int 最低の版(上限 65535)、int 最高の版(上限 65535)、srv 繋ぐ側の名前、hex nI(32 桁、128 ビット)、token 能力、abbr 略称 次の順に確かめる。① 書式が違えば 9006(2)。② 名前が登録されていなければ 9006(4)。③ 登録がリンクなら 9006(10)。④ 無効にされていれば 9006(7)。⑤ 共通の版が無ければ 9006(3)。⑥ どれでもなければ 9001 を返す
9001 GUILD_CHALLENGE 受ける側→繋ぐ側 int 選んだ版(上限 65535)、srv 受ける側の名前、hex nA(32 桁)、token 能力、abbr 略称 受ける側の名前が、自分の登録している相手の名前と違えば 9006(12)。選んだ版が、自分が 9000 で送った範囲に入っていることを確かめなければならない(MUST)。入っていなければ 9006(3)。どちらでもなければ 9002 を返す
9002 GUILD_AUTH 繋ぐ側→受ける側 hex proofI(64 桁) 一定の時間で比べる。違えば 9006(5)。合えば 9003 を返し、接続を確立したものとする
9003 GUILD_WELCOME 受ける側→繋ぐ側 hex proofA(64 桁) 違えば 9006(5)。合えば確立する
  • nI と nA は、暗号として安全な乱数から作らなければならない(MUST)。同じ値を 2 度使ってはならない(MUST NOT)。

6.4 証明の計算

入力 = "GUILD1" SP 役 SP I名 SP A名 SP nI SP nA SP ver SP capsI SP capsA SP abbrI SP abbrA
proof = hex( HMAC-SHA256( 鍵, 入力 ) )
  • 役は、proofI なら initiator、proofA なら acceptor。
  • 名前は ASCII の小文字に直す。能力は送ったとおりの綴り。SP は空白 1 つ。
  • 略称は送ったとおりのバイト列(UTF-8)を使う。
  • HMAC は [RFC2104]、SHA-256 は [FIPS180-4] に従う。
  • 鍵は、2 台の運用者がこの拡張の外で分け合った、16 バイト以上のバイト列とする(32 バイトを推奨)。
  • やり取りには、16 進の文字列を使うべきである(SHOULD)。
  • 鍵そのものを電文に載せてはならない(MUST NOT)。
  • 能力が入力に入っているので、途中で能力の一覧を削る細工は証明の失敗になる。

6.5 版と能力

  • 版は整数である。受ける側は、双方の範囲に共通する最大の版を選ぶ。
  • 能力は、カンマで区切った語で書く。何も無ければ - とする。
能力 意味 必須
(なし) 在席(§8)と §7 必須
chat §9 任意
im §10 任意
browse §11 の参照 任意
search §11 の検索 任意
xfer §12 任意
wallop §13 任意
  • 使える能力は、双方にあるものだけとする。
  • 使えない機能の電文を送ってはならない(MUST NOT)。受けたら無視し、9007(8)を返してもよい(MAY)。
  • 知らない語は無視しなければならない(MUST)。tls は予約語で、版 1 では意味を持たない。

6.6 同じ相手と 2 本つながったとき

同じ相手と確立した接続が 2 本になったら、両側で同じ規則を当て、片方を 9006(6)で切る。

  • 2 本とも同じ側が繋いだものなら、新しいほうを残す。
  • 向きが逆なら、繋ぐ側の名前(小文字にしたバイト列)が小さいほうの接続を残す。

6.7 例(試験値)

条件: – 鍵 = 000102…1e1f(32 バイト) – I = alpha.example、A = beta.example – nI = 00112233445566778899aabbccddeeff、nA = ffeeddccbbaa99887766554433221100 – capsI = chat,im,search,browse,xfer,wallop、capsA = chat,im,wallop – 略称は、I が A、A が B – 版は 1

電文: – 9000 の見出しは 5c 00 28 23。本文は GUILD 1 1 alpha.example 00112233445566778899aabbccddeeff chat,im,search,browse,xfer,wallop A(92 バイト)。 – 9001 の見出しは 40 00 29 23。本文は 1 beta.example ffeeddccbbaa99887766554433221100 chat,im,wallop B(64 バイト)。 – proofI = 3fa063c1f3b56d9bcc22f3dd8bd942f606038d557714597425705abdb3cb7854 – proofA = 4b4c7e994c54f19a840baae11aa721e59669a35c6a3921ab7f70e83c356d2d79

(Python の hmac と hashlib で計算した値。公開の前に、独立した実装でもう一度確かめる。)

7. 生存確認・エラー・切断

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9004 GUILD_PING 双方 rest 合言葉(ASCII、32 バイト以下) 同じ合言葉で 9005 を返さなければならない(MUST)
9005 GUILD_PONG 双方 rest 合言葉 生存を記録する
9006 GUILD_CLOSE 双方 int 理由(下の表。上限 255)、rest 説明(任意) 返事をせずに TCP を閉じ、記録する。§7.1 に従って繋ぎ直す
9007 GUILD_ERROR 双方 int 対象の種別(上限 65535)、int 理由(§14。上限 255)、rest 説明(任意) 知らせるだけで、接続は保つ。記録する
  • 60 秒のあいだ何も送らなかったら、9004 を送るべきである(SHOULD)。
  • 180 秒のあいだ何も受けなかったら、9006(8)で切ってよい(MAY)。

切断の理由

番号 意味 自動の繋ぎ直し
1 通常の終了(運用者の操作、停止) 30 分以上あける
2 手順の違反(書式、順番、握手の時間切れ) 運用者が手を入れるまでしない
3 版が合わない しない
4 相手として登録されていない名前 しない
5 認証の失敗 しない
6 重複した接続(§6.6 で残したほうの接続を使う) しない
7 相手を運用者が無効にしている しない
8 生存確認の時間切れ 間隔を延ばしながらする
9 資源の上限(送り待ちのあふれ、在席の数の上限) 間隔を延ばしながらする
10 種類の違い(この相手はリンクとして登録されている) しない
11 再起動(すぐ戻る見込み) 30 秒後からする
12 名前の食い違い(相手の名前、出どころ) しない

7.1 繋ぎ直し

  • 「間隔を延ばしながら」は、30 秒から始めて倍にしていき、上限を 10 分とする。
  • 「しない」とした理由で切られた側は、自動で繋ぎ直すべきでない(SHOULD NOT)。

7.2 送り待ちがあふれたとき

  • 在席とチャンネルの入退室の電文は、落としてはならない(MUST NOT)。送れないなら 9006(9)で切る。
  • 検索と参照の結果は落としてよい(MAY)。ただし、終わりの電文は落としてはならない(MUST NOT)。送るかどうかは §11 の規則に従う。

8. 在席

8.1 電文

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9010 GUILD_USER 双方 srv 出どころ、nick 名前、int ログイン時刻(UNIX 秒、UTC。上限 2^63−1)、token 級(User・Moderator・Admin・Elite・Leech)、int 共有数(上限 4294967295)、int 速度(0〜10)、qstr クライアント、int 旗(上限 4294967295) 在席を加える。同じ相手から同じ名前が既にあれば、欄を置き換える。ログイン時刻が変わっていたら、退室して入り直したものとして扱う。見せる名前を §8.3 で決める
9011 GUILD_USER_QUIT 双方 srv 出どころ、nick 名前 その在席を消す。その人のチャンネルの入室もすべて消し、自分の利用者に 407 を送る。hotlist の 210 もここで送る
9012 GUILD_SYNC_END 双方 srv 出どころ、int 送った 9010 の数(上限 4294967295) 初回の一覧が終わったものとする。数が受けた 9010 の数と合わなければ、記録してもよい(MAY)。接続は保つ
  • 級は表示のためだけのものである。 受け側は、級を権限の判断に使ってはならない(MUST NOT)。
  • 旗:ビット 0(値 1)は「一覧に出さない」。受け側は、一覧・名簿・whois にこの利用者を出してはならない(MUST NOT)。知らないビットは無視する。
  • qstr クライアント に " が含まれるときは、送る側が取り除く。
  • IP アドレスとデータのポートは、在席に載せない。転送(§12)と検索の結果(201 の本文)にだけ現れる。

8.2 初回の一覧

接続が確立したら、双方は次の順で送る。

  1. 自分の利用者全員の 9010。
  2. 能力 chat を交渉した場合は、共有するチャンネルの 9020(全員の入室)と 9024(話題)。
  3. 最後に 9012。
  • 9012 より前に、ほかの種類の電文を送ってはならない(MUST NOT)。
  • 接続が切れたら、受け側はその相手の在席と入室を、すべて消さなければならない(MUST)。

8.3 名前の見せ方

相手の利用者は、利用者名と出どころの組で見分ける。同じ利用者名の人が、別のサーバーに同時にいてよい。ギルドを理由に、利用者を切断したりログインを断ったりはしない(下の 3 を除く)。

  1. ぶつからない名前は、そのまま見せる。 相手の利用者の名前が、次のどれとも同じでなければ、その名前のまま自分の利用者に見せる。 – 自分の利用者(ログイン中)の名前 – 自分のサーバーに登録されている名前(その人がオフラインでも) – すでにそのまま見せている、ほかの相手の利用者の名前
  2. ぶつかる名前には出どころを付ける。 上のどれかと同じなら、出どころを付けた名前で見せなければならない(MUST)。 – 形は 名前(出どころ) を推奨する(例:masa(guild-b.example))。括弧は ASCII の ( と ) で、どの文字コードのクライアントでも表せる。 – 相手の利用者を、自分の利用者や登録名と同じ名前のまま見せてはならない(MUST NOT)。なりすましを防ぐためである。 – 実装は、ぶつからない場合も含めて、常に出どころを付けた形で見せてもよい(MAY)。 – @ を区切りに使うべきでない(SHOULD NOT)。@ は、利用者が名前の一部としてよく使っている。 – 出どころの代わりに、相手が握手で名乗った略称(§4.3 の abbr)を使ってよい(MAY)。例:masa(B)。ただし、次のどれかに当たる略称は使ってはならず(MUST NOT)、サーバー名に戻す。
    • -(設定なし)
    • ほかの相手の略称やサーバー名と同じ
    • 自分のサーバー名や自分の略称と同じ
    • 名前の比べ方は §4.3 の利用者名と同じ(ASCII の英字の大文字と小文字だけを同じと見なす)。
  3. 見せる名前の予約。 次の名前での自分の利用者のログインと登録は、拒まなければならない(MUST)。 – 相手の利用者をそのまま見せている名前([NAP] の「すでにログインしている」の断りを使う)。 – 出どころを付けた形になっている名前。推奨の形なら、(相手のサーバー名) で終わる名前である。 – 実装は、相手のサーバー名と略称(と、自分のサーバー名と略称)を含む名前を、すべて禁止の語として拒むべきである(SHOULD)。ただし、1〜2 文字の略称は普通の名前に含まれやすいので、(略称) の形だけを拒めばよい。形を問わずに拒むので、括弧の付け方を変えた名乗りも防げる。 – 相手を後から登録したとき、その名前を含む既存の登録名は、そのまま使えてよい(MAY)。ただし、その利用者を相手の利用者と取り違えないよう、運用者に知らせるべきである(SHOULD)。
  4. 宛先の読み替え。 自分の利用者が、見せる名前(出どころを付けた形を含む)を宛先にして IM・whois・参照・ダウンロードを求めたら、サーバーは相手の利用者(名前と出どころの組)に読み替えて、その相手へ送る。相手へ送る電文の中の名前は、出どころを付けない元の名前である。
  5. 相手が 9011 を送ったり接続が切れたりして、ある見せる名前が空いても、ほかの相手の利用者の見せる名前を途中で変える必要はない。変えてもよい(MAY)。変えるなら、自分の利用者へ 407 と 406 で入り直したように見せる。

9. チャンネル(能力 chat)

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9020 GUILD_CHAN_JOIN 双方 srv 出どころ、body(406) = ch nick int 共有数 int 速度(共有数は上限 4294967295、速度は 0〜10) 自分もそのチャンネルを共有していれば、名簿(408・825)に見せる名前で加え、自分の利用者の入室者へ 406 を送る。共有していなければ無視する
9021 GUILD_CHAN_PART 双方 srv 出どころ、body(407) 名簿から外し、407 を送る
9022 GUILD_CHAN_PUBLIC 双方 srv 出どころ、body(403) = ch nick rest 本文 自分の利用者の入室者へ、見せる名前で 403 を送る
9023 GUILD_CHAN_EMOTE 双方 srv 出どころ、body(824) = ch nick "本文" 自分の利用者の入室者へ 824 を送る
9024 GUILD_CHAN_TOPIC 双方 srv 出どころ、body(410) = ch rest 話題 自分のチャンネルの話題として当ててよい(MAY)。当てたら 410 を送る
  • どのチャンネルを共有するかは、各サーバーが決める。送る側は共有しないチャンネルの電文を送ってはならず(MUST NOT)、受け側は無視する。
  • チャンネル名は、ASCII の大文字と小文字を区別せずに比べる。
  • 送る側は、口止め・連投の制限・チャンネルの決まりを、自分の利用者に当ててから送る。
  • 受け側は、自分のチャンネルの決まりを理由に、相手の利用者の発言を自分の利用者へ配らなくてよい(MAY)。
  • キック・BAN・オペレーターの任命・モードの変更は、運ばない。

10. IM(能力 im)

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9030 GUILD_PRIVMSG 送り手のサーバー→宛先のサーバー srv 出どころ、nick 宛先、body(205) = nick 送り手 rest 本文 宛先が自分の利用者なら、送り手の見せる名前で 205 を届ける。いなければ 9031(1)を返す。宛先の設定(無視の一覧など)で届けないなら、黙って捨てるか 9031(2)を返す
9031 GUILD_PRIVMSG_FAIL 宛先のサーバー→送り手のサーバー srv 出どころ、nick 元の送り手、nick 元の宛先、int 理由(上限 255) 元の送り手が自分の利用者なら、404 で知らせる

11. 参照と検索(能力 browse・search)

  • 要求番号は int で 1〜4294967295。要求する側が接続ごと・向きごとに 1 から増やしていくべきであり(SHOULD)、応答が済んでいない番号を使い回してはならない(MUST NOT)。
番号 名前 向き 欄の並びと型 受けたときの振る舞い
9040 GUILD_BROWSE 要求側→応答側 srv 出どころ、int 要求番号、nick 要求者、int 最大件数(1〜4294967295)、body(211) = nick 対象 対象が自分の利用者なら、最大件数を越えない数の 9041 を送り、最後に 9042(0)を送る。いなければ 9042(1)。止めていれば(5)。方針で断るなら(3)
9041 GUILD_BROWSE_ITEM 応答側→要求側 srv 出どころ、int 要求番号、body(212) 要求者に 212 を届ける(利用者名は見せる名前に直す)
9042 GUILD_BROWSE_END 応答側→要求側 srv 出どころ、int 要求番号、int 理由(上限 255)、body(213) 要求者に 213 を届ける。理由が 0 でなければ、その前に 404 で知らせてよい(MAY)
9043 GUILD_QUERY_CANCEL 要求側→応答側 srv 出どころ、int 要求番号 その要求を打ち切るべきである(SHOULD)。終わりの電文の扱いは、下の「上限と打ち切り」に従う
9050 GUILD_SEARCH 要求側→応答側 srv 出どころ、int 要求番号、nick 要求者、int 最大件数(1〜1000)、body(200) 自分の利用者の共有だけを、自分のクライアントと同じ意味で探す。件数は、最大件数と本文の MAX_RESULTS の小さいほうを越えない。結果の 9051 を送り、最後に 9052 を送る(終わりの電文の扱いは、下の「上限と打ち切り」に従う)
9051 GUILD_SEARCH_ITEM 応答側→要求側 srv 出どころ、int 要求番号、body(201) 要求者に 201 を届ける(利用者名は見せる名前に直す)。自分の方針の件数の上限を越えた分は捨てる
9052 GUILD_SEARCH_END 応答側→要求側 srv 出どころ、int 要求番号、int 理由(上限 255)、int 送った件数(上限 4294967295) その相手の分は終わりとする

上限と打ち切り – 応答側は、受けた要求ごとに、終わりの電文(9042 または 9052)を必ず 1 度送らなければならない(MUST)。例外は 9043 で取り消された要求だけで、このときは送らなくてよい(MAY)。 – 応答側は、要求をほかへ転送してはならない(MUST NOT)。 – 応答側は、要求者の級や共有数を理由に断るべきでない(SHOULD NOT)。その規則は要求者のサーバーが当てる。 – 応答側は、相手ごとに同時に処理する要求の数を決めてよい(MAY)。越えた分は、終わりの電文の理由 4 で断る。 – 要求側は、1 つの相手に対して同時に 16 を越える要求を出すべきでない(SHOULD NOT)。 – 応答側は、60 秒以内に終わりの電文を送るべきである(SHOULD)。 – 要求側は、90 秒待っても終わらない相手の分を打ち切ってよい(MAY)。打ち切るときは、応答側へ 9043 を送るべきである(SHOULD)。打ち切ったあとにその要求番号で届いた分は捨てる。 – 自分の結果と全部の相手の終わり(または打ち切り)がそろったら、利用者に 202 を送る。 – 結果の中の IP アドレス(201・213 の欄)は、応答側が「外から届く住所」として入れる。 – 接続が切れたら、その接続の上の要求はすべて終わったものとする。

12. ファイル転送の段取り(能力 xfer)

転送そのものは、クライアントどうしが直接行う([NAP] §5)。この節の電文は、段取りだけを運ぶ。本文を作るのは行為者のいるサーバーで、IP アドレスとポートは、そのサーバーが自分の利用者について外から届く値を入れる。

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9060 GUILD_XFER_REQUEST ダウンロードする人のサーバー→アップロードする人のサーバー srv 出どころ、nick ダウンロードする人、body(203) = nick アップロードする人 "ファイル名" アップロードする人が自分の利用者なら、607 ダウンロードする人の見せる名前 "ファイル名" 速度 を届ける。いなければ 9063
9061 GUILD_XFER_ACCEPT アップロードする人のサーバー→ダウンロードする人のサーバー srv 出どころ、nick ダウンロードする人、body(204) = nick アップロードする人 int ip int port "ファイル名" md5 int 速度(ip は上限 4294967295、port は上限 65535、速度は 0〜10) ダウンロードする人に 204 を届ける
9062 GUILD_XFER_REFUSE 同上 srv 出どころ、nick ダウンロードする人、body(609) 609 を届ける
9063 GUILD_XFER_NOTFOUND 同上 srv 出どころ、nick ダウンロードする人、body(206) = nick 相手 "ファイル名" 206 を届ける
9064 GUILD_XFER_PUSH ダウンロードする人のサーバー→アップロードする人のサーバー srv 出どころ、nick アップロードする人、body(501) = nick ダウンロードする人 int ip int port "ファイル名" md5 int 速度(ip は上限 4294967295、port は上限 65535、速度は 0〜10) アップロードする人に 501 を届ける。いなければ、出どころへ 9063 を返す

流れ(D は S_D の利用者、U は S_U の利用者) – 通常のダウンロード: 1. D が S_D に 203 を送る。 2. S_D は自分の規則で D を確かめ、S_U に 9060 を送る。 3. S_U は U に 607 を届ける。 4. U が 608 を返したら、S_U は S_D に 9061 を送り、S_D は D に 204 を届ける。U が 609 を返したら、9062 と 609。 – ファイアウォール越し(204 のポートが 0 のとき):D が S_D に 500 を送り、S_D は D の外から届く IP とポートを入れた 9064 を S_U に送り、S_U は U に 501 を届ける。

確かめと規則 – 受け側は、行為者の在席を確かめる(§4.5)。届け先が自分の利用者でなければ捨てる。 – ダウンロードの可否(ポイント、共有の条件など)は、ダウンロードする人のサーバーが当てる。 – アップロードする人のサーバーは、自分の規則をダウンロードする人に当てるべきでない(SHOULD NOT)。ただし、要求の頻度の制限は当ててよい(MAY)。 – 218〜221(転送の数の知らせ)は各サーバーの中だけで扱い、運ばない。

13. wallop(能力 wallop)とアナウンス

番号 名前 向き 欄の並びと型 受けたときの振る舞い
9070 GUILD_WALLOP 双方 srv 出どころ、body(627) = nick 送り手 rest 本文 自分の利用者のうち、自分の定義で wallop を受ける人へ 627 を届ける。転送してはならない(MUST NOT)。自分の方針で受けなくてもよい(MAY)
  • 送る側は、自分の決まりで wallop を送ってよい利用者のものだけを送る。
  • アナウンス(628)は運ばない。 628 に当たる電文はこの拡張に無く、628 をギルドの接続で送ってはならない(MUST NOT)。

14. 断りの理由の番号

9007・9031・9042・9052 で使う。

番号 意味
0 成功(通常の終わり)
1 その利用者はオンラインでない
2 利用者の設定で断られた
3 サーバーの方針で断られた
4 混んでいる(同時の要求の上限)
5 休止中(検索・参照を止めている)
6 書式の誤り(正しくない UTF-8 を含む、欄の値が上限を越える)
7 文字を表せない
8 対応していない(能力が無い、知らない種別)
11 名前として扱えない
12 そのチャンネルを共有していない
13 行為者の食い違い(その名前はその相手の在席に無い)
14 出どころの食い違い(出どころが接続の相手の名前と違う)

(9・10 は欠番。)

15. クライアントへの見せ方(参考、規範ではない)

  • whois(603):受け側が在席から 604 をその場で組み立ててよい。オフラインの相手の利用者は「オンラインでない」とする。どのサーバーの利用者かを示すことを勧める。
  • 一覧・名簿・hotlist(830・408・825・209・210):相手の利用者を、見せる名前で含めてよい。

16. 互換性

  1. この拡張を知らないサーバーに繋いだとき。 9000 は、ログイン前のクライアントからの知らない電文として扱われる。応答が無いか、すぐに切られる。繋ぐ側は、30 秒で握手を打ち切り、「相手はギルドに対応していない」と運用者に示すべきであり(SHOULD)、自動の繋ぎ直しの間隔を延ばすべきである(SHOULD)。
  2. 版が違うとき。 §6.5 で共通の最大の版を選ぶ。無ければ理由 3 で切る。
  3. 機能の一部だけの実装。 在席のほかは能力で交渉するので、一部だけの実装でも繋がる。
  4. 知らない種別。 §4.6 のとおり無視する。版 1.x で足す電文は、この決まりに頼る。
  5. クライアント。 新しい番号がクライアントに届くことは無い。クライアントは変えなくてよい。見せる名前に (出どころ) が付くことがある(§8.3)。
  6. リンクとの共存。 同じポートで、最初の電文で見分ける。同じ 2 台のあいだにリンクとギルドを同時には張らない。ギルドで知った情報を、リンクなどほかの手順へ流してはならない(MUST NOT)。

17. セキュリティの考慮

  1. 認証。 HMAC-SHA256 による相互の確認で、鍵は電文に載らない。128 ビットの使い捨ての乱数と役の語で、証明の使い回しと送り返しを防ぐ。能力を入力に入れて、機能を落とさせる細工を防ぐ。
  2. 認証のあとは守られない。 版 1 は暗号化も改ざんの検出もしない(OpenNap の本体と同じ)。信用できない経路を通すなら、VPN や TLS のトンネルを使うべきである(SHOULD)。tls は将来のために予約する。
  3. 鍵の扱い。 相手ごとに別の乱数の鍵を使い、この拡張の外で渡す。保存するときは暗号化すべきである(SHOULD)。漏れたら取り替える。
  4. 権限を相手に及ぼさない。 相手の状態を変える電文は無い。級は表示のためだけに使う。管理者の操作・BAN・登録・設定・アナウンスは運ばない。
  5. なりすまし。 §8.3 のとおり、相手の利用者を、自分の利用者や登録名と同じ名前のまま見せてはならない(MUST NOT)。
  6. 個人の情報。 在席に IP アドレスは載せない。検索の結果と転送の段取りには載る(OpenNap の本体と同じ)。運用者は、ギルドに加わると自分の利用者の IP アドレスが相手の利用者へ見えうることを、利用者に知らせるべきである(SHOULD)。
  7. 資源を食いつぶす攻撃。 受け側は、相手ごとに在席の数・同時の要求の数・1 秒あたりの電文の数の上限を設けてよい(MAY)。在席の数を越えたら理由 9 で切る。握手の 30 秒の時間切れと、接続元ごとの接続数の制限を当てるべきである(SHOULD)。
  8. 登録されていない名前での接続。 理由 4 で、名前が登録されているかどうかが分かってしまう。気にする運用者は、理由 4 のかわりに 5 を返してよい(MAY)。

18. 参考文献

  • [NAP] drscholl@users.sourceforge.net(OpenNap プロジェクト)『napster messages』。原文の日付は 2000-04-07、変更の記録は 2001-04-07 まで。https://opennap.sourceforge.net/napster.txt 。原文は冒頭で、自らを “an open specification” と述べている。本書が参照する節は原文の節番号のままで、§2(Client-Server protocol。フレームと文字列)、§3(Message Types。200〜206・209〜213・218〜221・403・404・406〜410・500・501・603・604・607〜609・627・628・824・825・830)、§5.1・§5.2(Client-Client Protocol のうち 5.1 Normal Downloading と 5.2 Firwalled Downloading [sic]。クライアントどうしの転送)。
  • [NAP-JA] 『Nap プロトコル仕様書』日本語訳 v1.0(2002-02-08)。[NAP] とその改訂版の翻訳。参考情報であり、規範の参照ではない。
  • [RFC2119] Key words for use in RFCs to Indicate Requirement Levels.
  • [RFC8174] Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words.
  • [RFC2104] HMAC: Keyed-Hashing for Message Authentication.
  • [FIPS180-4] Secure Hash Standard.
  • [RFC3629] UTF-8, a transformation format of ISO 10646.

原典との照合は 2026-09-27 に行った(節の立て方、参照する電文の定義、欄の並び)。バイト単位の照合は公開の前に行う。

付録 A. 変更の記録

  • 1.0 草案(2026-09-27):最初の草案。