RFC2812 Internet Relay Chat: Client Protocolを読んでみた。（１）

# はじめに
どうも。こんにちは。
[42tokyo](https://42tokyo.jp/)といったところで、IRCサーバの実装を行なっています。

前回は、[RFC2810 Internet Relay Chat: Architectureを読んでみた。](https://qiita.com/gu-chi/items/0f84537a89c00dd932da)を書きました。
今回は、[RFC2812 Internet Relay Chat: Client Protocol](https://datatracker.ietf.org/doc/html/rfc2812)を、読んで行きます。

[RFC1459 Internet Relay Chat Protocol](https://datatracker.ietf.org/doc/html/rfc1459)との差を意識しながら読んでいきます。

とりあえず、自作IRCサーバーと既存IRCクライアントが接続完了するまで実装したいので、
この記事では、以下の章について書いております。
* Abstract
* 1.Labels
* 2.The IRC Client Specification
* 6.Current implementations
* 7.Current problems

間違い等があれば、ご指摘ください。

# Abstract
* ここでは、クライアントプロトコルを定義している
* 読者が[RFC2810 Internet Relay Chat: Architecture](https://datatracker.ietf.org/doc/html/rfc2810)に精通していることを前提とする
# 1.Labels
* この章では、IRCプロトコルのさまざまなコンポーネントに使用される識別子を定義する

## 1.1 Servers
* サーバは、一意な名前で識別される
* サーバ名は、最大63文字
* サーバ名に使用できる文字とできない文字については、[2.3.1 Message format in Augmented BNF](#231-message-format-in-augmented-bnf)を参照

## 1.2 Clients
* 全てのサーバは、各クライアントに関する以下の情報を持たなければならない **[MUST]**
* ネットワーク内で、そのクライアントを表す一意な識別子(識別子のフォーマットはクライアントのタイプに依存)
* そのクライアントが、直接接続しているサーバに関する情報

### 1.2.1 Users
* ユーザは、一意なニックネームで識別される
* ニックネームは、最大9文字（将来的に長くなることもあるので、より長い文字列を受け入れるべき **[SHOULD]** ）

* ニックネームに使用できる文字とできない文字については、[2.3.1 Message format in Augmented BNF](#231-message-format-in-augmented-bnf)を参照

#### 1.2.1.1 Operators
RFC1459とほぼ同じなので、省略
参考：[RFC1459 Internet Relay Chat Protocolを読んでみた。（１）](https://qiita.com/gu-chi/items/d14c99f716da6133bce8#121-operators)

以下、違い
RFC1459より
> To allow a reasonable amount of order to be kept within the IRC network,
a special class of clients (operators) is allowed to perform
general maintenance functions on the network.

RFC2812より
> To allow a reasonable amount of order to be kept within the IRC network,
a special class of users (operators) is allowed to perform
general maintenance functions on the network.

RFC1459では、operatorsは、Clientsの特殊なもの。となっているが、RFC2812では、usersの特殊なもの。となっている。

### 1.2.2 Services
* サービスは、サービス名によって区別される
* サービス名は、ニックネームとサーバ名からなる
* ユーザのニックネームを使用する場合、そのニックネームは最大9文字となる
* ニックネームに使用できる文字とできない文字については、[2.3.1 Message format in Augmented BNF](#231-message-format-in-augmented-bnf)を参照

## 1.3 Channels
* チャンネル名は、最大50文字の文字列
* 接頭辞に「&」、「#」、「+」、または「!」を付ける（接頭辞は、チャンネルの種類を表す）
（チャンネルの種類については、[RFC2811 Internet Relay Chat: Channel Management](https://datatracker.ietf.org/doc/html/rfc2811)を参照）
* チャンネル名に、スペース(「　」)、コントロールG(^GまたはASCII code 7)、
カンマ(「 , 」)を含んではならない
（スペースはパラメータの区切り文字、コマンドはプロトコルのリスト項目の区切り文字として使用される。またダブルコロン(":")もチャンネルマスクの区切り文字として使用できる。）
* チャンネル名は大文字、小文字を区別しない
* チャンネル名の正確な構文は、[2.3.1 Message format in Augmented BNF](#231-message-format-in-augmented-bnf)を参照

# 2.The IRC Client Specification
## 2.1 Overview
* RFC2812は、IRCプロトコルのうち、クライアントとサーバ間で行われる通信について説明する

## 2.2 Character codes
RFC1459と同じなので、省略
参考：[RFC1459 Internet Relay Chat Protocolを読んでみた。（１）](https://qiita.com/gu-chi/items/d14c99f716da6133bce8#22-character-codes)

## 2.3 Messages
RFC1459と同じなので、省略
参考：[RFC1459 Internet Relay Chat Protocolを読んでみた。（１）](https://qiita.com/gu-chi/items/d14c99f716da6133bce8#23-messages)

### 2.3.1 Message format in Augmented BNF
RFC1459とほぼ同じなので、省略した部分あり
参考：[RFC1459 Internet Relay Chat Protocolを読んでみた。（１）](https://qiita.com/gu-chi/items/d14c99f716da6133bce8#231-message-format-in-pseudo-bnf)

```:拡張BNF表現は次の通り:
message    =  [ ":" prefix SPACE ] command [ params ] crlf
prefix     =  servername / ( nickname [ [ "!" user ] "@" host ] )
command    =  1*letter / 3digit
params     =  *14( SPACE middle ) [ SPACE ":" trailing ]
           =/ 14( SPACE middle ) [ SPACE [ ":" ] trailing ]

nospcrlfcl =  %x01-09 / %x0B-0C / %x0E-1F / %x21-39 / %x3B-FF
              ; any octet except NUL, CR, LF, " " and ":"
middle     =  nospcrlfcl *( ":" / nospcrlfcl )
trailing   =  *( ":" / " " / nospcrlfcl )

SPACE      =  %x20
              ; space character
crlf       =  %x0D %x0A
              ; "carriage return" "linefeed"

target     =  nickname / server
msgtarget  =  msgto *( "," msgto )
msgto      =  channel / ( user [ "%" host ] "@" servername )
msgto      =/ ( user "%" host ) / targetmask
msgto      =/ nickname / ( nickname "!" user "@" host )
channel    =  ( "#" / "+" / ( "!" channelid ) / "&" ) chanstring
                [ ":" chanstring ]
servername =  hostname
host       =  hostname / hostaddr
hostname   =  shortname *( "." shortname )
shortname  =  ( letter / digit ) *( letter / digit / "-" ) *( letter / digit )
              ; as specified in RFC 1123 [HNAME]
hostaddr   =  ip4addr / ip6addr
ip4addr    =  1*3digit "." 1*3digit "." 1*3digit "." 1*3digit
ip6addr    =  1*hexdigit 7( ":" 1*hexdigit )
ip6addr    =/ "0:0:0:0:0:" ( "0" / "FFFF" ) ":" ip4addr
nickname   =  ( letter / special ) *8( letter / digit / special / "-" )
targetmask =  ( "$" / "#" ) mask
              ; see details on allowed masks in section 3.3.1
chanstring =  %x01-07 / %x08-09 / %x0B-0C / %x0E-1F / %x21-2B
chanstring =/ %x2D-39 / %x3B-FF
                  ; any octet except NUL, BELL, CR, LF, " ", "," and ":"
channelid  = 5( %x41-5A / digit )   ; 5( A-Z / 0-9 )

その他のパラメータ構文：

user       =  1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF )
              ; any octet except NUL, CR, LF, " " and "@"
key        =  1*23( %x01-05 / %x07-08 / %x0C / %x0E-1F / %x21-7F )
              ; any 7-bit US_ASCII character,
              ; except NUL, CR, LF, FF, h/v TABs, and " "
letter     =  %x41-5A / %x61-7A       ; A-Z / a-z
digit      =  %x30-39                 ; 0-9
hexdigit   =  digit / "A" / "B" / "C" / "D" / "E" / "F"
special    =  %x5B-60 / %x7B-7D
              ; "[", "]", "\", "`", "_", "^", "{", "|", "}"
```
NOTE:
（１）
* \<middle\>と\<trailing\>は、表現が異なるだけで、同種のパラメータとして扱う
* message中に、NULL(%x00)文字を含むことはできない（文字列処理が複雑になるため）
* \<hostaddr\>は、IPアドレスの書式を表しているだけ
これは、IRCプロトコルは、トランスポート・ネットワークプロトコルとしてTCP/IPを使用していることを示す（しかし、他のプロトコルの使用を妨げるものではない）

（２）
* IRCメッセージは、最大512文字
* \<hostname\>は、最大63文字（IRCプロトコル特有の制限）
* \<hostname\>が63文字以上のホストから接続する場合、ホスト名の代わりにホストアドレスを使用する

（３）
* これ以降の章で出てくるパラメータで、上記の拡張BNF表現にないものは、\<params\>として扱う
* これらのパラメータ名は、解説する上で便宜的に付けられたもので、特別な意味は持たない

## 2.4 Numeric replies
RFC1459とほぼ同じなので、省略
参考：[RFC1459 Internet Relay Chat Protocolを読んでみた。（１）](https://qiita.com/gu-chi/items/d14c99f716da6133bce8#24-numeric-replies)

## 2.5 Wildcard expressions
* ワイルドカードを含んだ文字列を「mask」と呼ぶ
* IRCプロトコルは、２つの特殊文字を使用できる
  * 「?」(%x3F)：任意の１文字にマッチする
  * 「*」(%x2A)：任意の数の文字にマッチする
* 特殊文字は「 \\ 」(%x5C)でエスケープする

```:拡張BNF
mask       =  *( nowild / noesc wildone / noesc wildmany )
wildone    =  %x3F
wildmany   =  %x2A
nowild     =  %x01-29 / %x2B-3E / %x40-FF
              ; any octet except NUL, "*", "?"
noesc      =  %x01-5B / %x5D-FF
              ; any octet except NUL and "\"
matchone   =  %x01-FF
              ; matches wildone
matchmany  =  *matchone
              ; matches wildmany

Examples:
a?c         ; Matches any string of 3 characters in length starting
               with "a" and ending with "c"
a*c         ; Matches any string of at least 2 characters in length
               starting with "a" and ending with "c"
```

# 6.Current implementations
* IRCソフトウェア(version 2.10)は、IRCプロトコルに完全準拠している
* [RFC1459](https://datatracker.ietf.org/doc/html/rfc1459)以来、クライアントプロトコルの変更は少量

# 7.Current problems
* この文章で説明しているプロトコルは、後方互換性を保つために、[RFC1459](https://datatracker.ietf.org/doc/html/rfc1459#section-9)以来の問題を多数抱えている

## 7.1 Nicknames
RFC1459と同じなので、省略
参考：[RFC1459 Internet Relay Chat Protocolを読んでみた。（１）](https://qiita.com/gu-chi/items/d14c99f716da6133bce8#921-nicknames)

## 7.2 Limitation of wildcards
* エスケープ文字「 \\ 」(%x5C)をエスケープする方法はない
* よってワイルドカードの前に「 \\ 」(%x5C)を持つマスクは作れない

## 7.3 Security considerations
* セキュリティについては、[RFC2813 Internet Relay Chat: Server Protocol](https://datatracker.ietf.org/doc/html/rfc2813)を参照

# 12.Full Copyright Statement

> Copyright (C) The Internet Society (2000).  All Rights Reserved.
>
> This document and translations of it may be copied and furnished to others,
and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any kind,
provided that the above copyright notice and this paragraph are included on
all such copies and derivative works.
However, this document itself may not be modified in any way,
such as by removing the copyright notice or references to the Internet Society
or other Internet organizations, except as needed for the purpose of developing 
Internet standards in which case the procedures for copyrights defined in
the Internet Standards process must be followed, or as required to
translate it into languages other than English.
>
> The limited permissions granted above are perpetual and will not be revoked by
the Internet Society or its successors or assigns.
> 
> This document and the information contained herein is provided on an "AS IS" basis and 
THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE 
INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF 
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
>
> Acknowledgement
> 
> Funding for the RFC Editor function is currently provided by the Internet Society.

# さいごに
Clientsとusersの違いが曖昧でした。

私の理解は、以下の通り
* Clientsは、IRCクライアントと呼ばれるソフトウェアを指す言葉
* usersは、IRCクライアントを操作する人を指す言葉

ワイルドカードの実装を考えると、少し寒気がします。
次回からは、RFC1459 4.1 Connection Registrationを読んで行きたいと思います。
ありがとうございました。
# 参考
https://datatracker.ietf.org/doc/html/rfc1459

https://datatracker.ietf.org/doc/html/rfc2810

https://datatracker.ietf.org/doc/html/rfc2811

https://datatracker.ietf.org/doc/html/rfc2812

https://datatracker.ietf.org/doc/html/rfc2813

https://qiita.com/gu-chi/items/d14c99f716da6133bce8