# RFC 1459 ## 1. Introduction IRC 프로토콜은 텍스트기반 회의에 사용되기 위해 몇년간 디자인되어 왔다. 이 문서는 현 IRC에 대한 설명을 한다. IRC 프로토콜은 TCP/IP 네트워크 프로토콜로 개발되어 왔다. 다만 그 작동은 더이상 필요로 요구되지 않는다.(`although there is no requirement that this remain the only sphere in which it operates.`) IRC는 분산 방식으로 동작하는 다수의 기기에 적합한 원격회의 시스템이다. 전통적인 방식은 클라이언트들을 연결하고 요청메시지를 전송/다중화등의 기능을 수행하기 위해 중앙 포인트를 형성한 하나의 프로세스(서버)를 포함한다. ### 1.1 Server 서버는 클라이언트가 다른 클라이언트와 대화하는 포인트, 다른 서버와 연결하는 포인트를 제공하는 IRC의 중추(`backbone`)이다. 네트워크 설정(`network configuration`)은 각 서버들이 나머지 서버의 중앙노드역할을 하는 최소신장트리(`spanning tree`)뿐이다. ``` [ Server 15 ] [ Server 13 ] [ Server 14] / \ / / \ / [ Server 11 ] ------ [ Server 1 ] [ Server 12] / \ / / \ / [ Server 2 ] [ Server 3 ] / \ \ / \ \ [ Server 4 ] [ Server 5 ] [ Server 6 ] / | \ / / | \ / / | \____ / / | \ / [ Server 7 ] [ Server 8 ] [ Server 9 ] [ Server 10 ] : [ etc. ] : [ Fig. 1. Format of IRC server network ] ``` ### 1.2 client 클라이언트는 하나의 서버만 연결된다. 각각의 클라이언트는 유니크한 닉네임으로 구별되고 최대 9문자(`9 char`) 길이를 가진다. 닉네임에 사용가능한 것에 대해서는 문법적 프로토콜 규칙(`protocol grammer rule`)을 참고한다. 덧붙여서 모든 서버는 모든 클라이언트에 대해 호스트의 진짜 이름(`the real name of the host that client is running on`), 호스트의 클라이언트 이름(`username of the client on that host`), 클라이언트가 연결된 서버(`server to which client is connected`) 포함해야 한다. ### 1.2.1 Operators IRC 네트워크내의 적절한 한도의 명령을 허용하기 위해, 일반 유지 기능(`general maintenance`)이 허용되는 클라이언트의 특수 클래스(`operator` = 아마도 운영자?)가 존재한다. 비록 오퍼레이터에게 권한이 있는것은 위험할 수 있지만, 그러함에도 오퍼레이터는 필수로 여겨집니다. 오퍼레이터는 나쁜 네트워크(`bad network`) 라우팅의 장기적 사용을 방지하기 위해 필요에 따라 서버 연결해제 및 재연결과 같은 기본 기능을 수행할 수 있어야 한다. 이러한 필요성을 인지함에, 문서 내 논의된 프로토콜은 오퍼레이터가 이러한 기능들을 수행할 수 있도록만 제공한다. [4.1.7(SQUIT)]()와 [4.3.5(CONNECT)]()를 참고한다. 오퍼레이터의 권한중 더욱 논란이 많은것은 유저를 강제적(`force`)으로 네트워크 내에서 제거(`remove`)하는 것이다.<i.e>클라이언와 서버의 연결을 끊을(`close`) 수 있다. 이에대한 정당성은 남용되었을 시 굉장히 파괴적(`destructive`)이고 성가시기(`annoying`) 때문에 조심시럽다. 자세한 내용은 [4.6.1(KILL)]()을 참고한다. ### 1.3 Channels 채널은 지정된 주소의 모든 메시지를 수신할 수 있는 클리이언트들의 명명 그룹(`named group`)을 뜻한다. 채널은 첫 클라이언트가 참여할때 생성되고 마지막 클라이언트가 떠날 때 제거된다. 채널이 존재하는 동안, 모든 클라이언트가 채널의 이름을 통해 채널을 참고(`reference`)할 수 있다. 채널은 '&', '#'로 시작되는 200자 내의 문자열 이름은 가진다. 이름은 빈 공간(' ')과 콤마(',')를 가질 수 없다. 두가지 타입의 채널이 존재한다. 하나는 네트워크에 연결된 모든 서버가 알고있는 분산 채널(`distributed channel`)이다. 이 채널은 존재하는 서버내의 클라이언트들이 참여할수 있고 첫번째 문자로 표기된다.(`These channels are marked by the first character being a only clients on the server where it exists may join it.` = 해석 불명확). 이 서버는 첫 문자가 '&'이다. 두 타입 이외에(`On top of`) 다양한 개별 채널의 특성을 변경할 수 있는 다양한 채널 모드가 있다. 새로운 채널을 만들거나 존재하는 재철의 파트가 되기 위해선 채널에 사용자의 참여가 요구된다. 만약 채널이 존재하지 않는다면, 채널이 생성되고 생성사용자는 채널의 오퍼레이터(`operator`)가 된다. 채널이 이미 존재한다면 채널의 참가 수락 여부는 채널의 현재 모드에따라 다르다. 예를들어 채널이 'invite-only' 모드라면 초대에 의해서만 참여가 가능하다. 프로토콜의 일부로써, 사용자는 다용한 채널에 동시에 참가할 수 있지만, 최대 10개의 채널 제한이 모든 참가자에게 충분하다고 추천된다. [8.13]()을 참고하자. 만약 IRC 네트워크가 두 서버간 분할로 인해 분리(`disjoint`)된다면 각각의 채널은 각각의 채널에 연결된 클라이언트로만 구성되어 한쪽에 존재하지 않을 수 있다. 다시 결합될 때, 연결된 서버들은 서로에게 각각의 유저와 채널 모드를 알려준다. 만약 채널이 양쪽 모두 존재한다면 연결된 양 사이드가 각각의 클라이언트와 모드를 동의(`agree`)할 수 있도록 참가(`JOIN`)와 모드(`MODE`)들이 포괄적인 방식(`inclusive manner`)으로 해석된다. ### 1.3.1 Channel Operators 채널 오퍼레이터(`chop` or `chanop`)는 해당 채널을 소유(`own`)한 것으로 간주된다. 이런 지위를 인정하여, 채널 오퍼레이터는 채널의 제어(`control`)와 온전성(`sort of sanity`)를 유지할 수 있는 권한이 주어진다. 채널 소유자로써 채널 오퍼레이터는 그들의 행동(`actions`)에 이유를 요구하지 않는다. 그들의 행동이 비사회적이고 모욕적이라면 클라이언트는 IRC operator에게 요청하거나 채널을 떠나거나 본인의 채널을 만들어야한다. 채널 오퍼레이터는 아래와 같은 명령을 사용할 수 있다. ``` KICK - 클라이언트 추방 MODE - 채널 모드 변경 INVITE - 클라이언트를 초대(invite-only 채널 = mode +i 채널) TOPIC - 채널 토픽을 변경 (mot +t 채널) ``` 채널 오퍼레이터는 닉네임 마지막에 `@`로 표기하고 언제든지 채널과 연관되어있다.(`is associated with a channel`) <`(ie replies to the NAMES, WHO and WHOIS commands). `> ## 2 IRC Specification ### 2.1 Overview 문서 내 프로토콜은 서버간 연결, 서버와 클라이언트 연결 보두에 사용된다. 다만, 범위가 클라이언트 연결쪽에 더 제한되어있다. ### 2.2 Charactor codes 적절한 문자 세트가 규정되어 있진 않다. 프로토콜은 옥텟(`octat`)으로 만들어진 8비트로 구성된 코드 세트를 기반으로 한다. 각각의 메시지는 어떠한 수의 옥텟으로 구성되어 있다. 다만, 일부 옥텟값들은 메시지 구분자(`delimiter`)로 행동하는 제어 코드(`control code`)에서 사용된다. 8비트 프로토콜의 사용과 관계없이 구분자(`delimiter`)와 키워드(`keyword`)들은 프로토콜이 대부분 USASCII terminal과 telnet 연결에 사용될수 있도록 한다. IRC의 scandanavian origin때문에, '{}|'는 '[]\\'의 소문자로 간주된다. 이는 두 닉네임의 동일성을 결정하는데 중요 이슈(`critical issue`)이다. ### 2.3 Message 서버와 클라이언트들은 응답을 생성하거나 생성하지 않는 메시지들을 서로에게 보낸다.(`send`) 메시지가 뒤에 서술할 타당한 명령(`command`)를 포함한다면 클라이언트는 특정한 응답을 기대(`expect`)할 것이나 응답을 영원히 기다려서는 않된다. 클라이언트와 서버, 서버와 서버의 연결은 자연스러운 상황에서 근본적으로 비동기식이다.(동시에 발생하지 않는다) 각각의 IRC 메시지는 접두문(`prefix`)(선택적), 명령(`command`), 파라미터(`command parameter`)라는 세가지 주요 파트로 구성된다. 각각의 파트는 하나 이상의 ASCII space(`0x20` = ' ')로 구별된다. 접두문(`prefix`)의 존재는 메시지의 첫문자여야하는 ASCII 콜론(`0x3b` = ';')으로 표시한다. 접두문과 콜론사이에는 space가 존재해선 안된다. 접두문에는 서버에서 메시지의 진짜 기원을 표시하는데 사용된다. 만약 접두문이 메시지에 없다면 수신(`be recived`)된 연결로부터 시작한 것으로 가정한다. 클라이언트들은 메시지를 보낼때 접두믄을 기본적으로 사용하지 않고 유효한 접두문은 클라이언트와 연관된 닉네임뿐이다. 접두문에서 식별된 소스(`source`)가 서버의 DB에 없거나 소스가 도착된 메시지로부터의 링크와 다른 링크로 등록되어있다면, 서버는 메시지를 자동으로 무시해야한다. 명령은 반드시 유효한(`valid`) IRC 명령이거나 ASCII text로 표기된 3자리 숫자여야 한다. IRC 메시지는 항상 CR-LF 쌍으로 종료되는 라인문자들(`line of characters`)이고 이러한 메시지들은 CR-LF를 포함하여 512 문자를 넘을 수 없다. 따라서 총 510문자가 명령어와 파라미터에서 허용된다. 연속된 메시지 라인에 대한 규정은 없다.(`There is no provision for continuation message lines.` = 해석 불명확) [Section 7]()을 참고한다. #### 2.3.1 Message format in 'pseudo' BNF 프로토콜 메시지는 반드시 근접한 옥텟의 흐름(`contiguous stream of octets`)으로부터 추출(`extract`)되어야 한다. 현재의 방법은 CR, LF가 메시지 구분자(`message separator`)로 디자인되어있다. 빈 메시지는 자동으로 무시므로 별도의 문제없이 메시지 사이에 CR-LF 시퀀스를 사용하는게 가능하다. 추출된 메시지는 접두문(`prefix`), 명령(`command`), \<middle\>이나 \<trailing\>에 매치된 파라마터리스트로 파싱된다. BNF표현은 아래와 같다. ``` <message> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf> <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ] <command> ::= <letter> { <letter> } | <number> <number> <number> <SPACE> ::= ' ' { ' ' } <params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ] <middle> ::= <Any *non-empty* sequence of octets not including SPACE or NUL or CR or LF, the first of which may not be ':'> <trailing> ::= <Any, possibly *empty*, sequence of octets not including NUL or CR or LF> <crlf> ::= CR LF ``` 1. /<SPACE/>는 ASCII space(`0x20`)으로 구성되어 있다. 특히 탭(`Tabulation`)과 다른 제어문자는 모두 space로 간주되지 않는다.(`NON-WHITE-SPACE`) 2. 파라미터리스트를 추출한 후, 모든 파라미터는 /<middle/> 이나 /trailing/> 어느쪽에 매치되더라도 동등한 관계로 간주한다. /<trailing/>은 파라미터 내부에 space를 구문적 트릭(`syntatic trick`)으로 허용한다. 3. CR과 LF가 파라미터내에 나타날수 없는것은 메시지 프레이밍의 결과이다.(`The fact that CR and LF cannot appear in parameter strings is just artifact of the message framing` = 해석 불명확). 이는 이후 바뀔 것이다. 4. NUL문자는 메시지 프레임에서 특별한 문자가 아니며, 기본적으로 파리미터를 끝내는 역할(`end up`)을 한다. 다만 이는 일반적인 C 문자열 처리에서 부가적인 복잡성(`extra complexity`)을 야기할 수 있다. 5. 마지막 파라미터는 빈 문자열이다. 6. 확장된(`extended`) 접두문은 서버와 서버간 통신에는 사용되지 않고, 서버와 클라이언트간 통신에서 클라이언트에게 추가적인 쿼리를 사용하지 않고 누구로 부터 메시지가 발신되었는지에 대한 정보를 제공하기 위해 사용된다. 대부분의 프로토콜 메시지는 리스트 내에서 그들의 위치에따라 추출된 파라미터에 대한 추가적인 구문(`syntax`)과 의미(`semantics`)를 가진다. 예를 들어 많은 서버 명령들은 명령후의 첫 파라미터가 아래와 같이 설명될 수 있는 대상 목록이라고 가정한다. ``` <target> ::= <to> [ "," <target> ] <to> ::= <channel> | <user> '@' <servername> | <nick> | <mask> <channel> ::= ('#' | '&') <chstring> <servername> ::= <host> <host> ::= see RFC 952 [DNS:4] for details on allowed hostnames <nick> ::= <letter> { <letter> | <number> | <special> } <mask> ::= ('#' | '$') <chstring> <chstring> ::= <any 8bit code except SPACE, BELL, NUL, CR, LF and comma (',')> Other parameter syntaxes are: <user> ::= <nonwhite> { <nonwhite> } <letter> ::= 'a' ... 'z' | 'A' ... 'Z' <number> ::= '0' ... '9' <special> ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}' <nonwhite> ::= <any 8bit code except SPACE (0x20), NUL (0x0), CR (0xd), and LF (0xa)> ``` ### 2.4 Numeric replies 서버로 보내진 대부분의 메시지는 특정 종류의 응답(`reply`)을 생성한다. 대부분의 일반(`common`) 응답은 수적 응답(`numeric reply`)으로 에러와 일반 응답 양쪽 모두에 사용된다. 수적 응답은 반드시 발신인 접두문(`sender prefix`), 세자리 숫자(`three digit numeric`), 응답 목적지(`target of reply`)로 구성된 한대의 메시지로써 보내져야한다. 수적응답은 클라이언토로부터 시작되는것을 허용하지 않는다. 서버로부터 받은 이러한 메시지는 자동으로 삭제된다. 키워드(`keyword`)가 문자(`string of letters`)가 아닌 세자리숫자(`3 numeric digits`)로 구성되어있는 것을 제외한 다른 모든 측면에서 수적 응답은 일반 메시지와 동일하다. 응답들의 목록은 [section 6]()에서 참고하자. ## 3. IRC Concept 이 섹션은 실질적은 IRC의 콘셉트와 메시지 클래스들을 전달하는 방법을 설명한다. ``` 1--\ A D---4 2--/ \ / B----C / \ 3 E Servers: A, B, C, D, E Clients: 1, 2, 3, 4 [ Fig. 2. Sample small IRC network ] ``` ### 3.1 One-to-one communication 일대일 커뮤니케이션(`One-to-one communication`)은 서버간 트래픽이 서버가 서로 통신하는 결과가 아니기에 클라이언트에 의해서만 수행된다. 클라이언트가 서로 통신하는 보안 수단을 제공하기 위해서, 모든 서버는 메시지를 클라이언트에 도달하기 위한 스패닝 트리(`spanning tree`)의 정확한 한 방향으로 보낼수 있게끔 해야한다. 메시지 통로는 스패닝트리의 두 포인트의 가장 짧은 패스이다. Fig 2와 함께 아래 샘플을 참고하자. Example 1 : 클라이언트 1과 2 사이의 메시지는 클라이언트 2로 직접 전송하는 서버 A에서만 확인할 수 있다. Example 2 : 클라이언트 1과 3 사이의 메시지는 서버 A, B 그리고 클라이언트 3에서만 확인할 수 있다. 다른 어떠한 클라이언트나 서버로 해당 메시지를 확인 할 수 없다. Example 3 : 클라이언트 2와 4의 사이의 메시지는 서버 A, B, C, D와 클라이언트 4에서 확인할 수 있다. ### 3.2 One-to-many IRC의 목표는 쉽고 효융적으로 회의(`conferencing` = `one to many conversation`)을 허용하는 포럼(`forum`)을 제공하는데 있다. IRC는 이를 수행하기 위한 다양한 수단을 제공한다. ### 3.2.1 To a list 일대다 대화(`one-to-many conversation`)의 최소한(`least`)의 효율적인 스타일은 클라이언트가 사용자 리스트(`list of users`)와 대화하는 것이다. 이를 수행하는 방법은 자명하다. 클라이언트가 메시지가 전송되어야 할 목적지의 리스트(`list of destination`)를 제공하고, 서버가 이를 분해하고 메시지의 구분된 사본을 각각의 목적지에 전송한다. 대상목록이 분할되고 중복 항목이 각 경로로 전송되지 않는지 확인하지 않고 발송되므로 그룹(`group`)을 사용하는 것 만큼 효율적이진 않다. ### 3.2.2 To a group (channel) IRC 채널은 멀티캐스트 그룹(`multicast group`)과 동등한(`equivalent`) 역할을 한다. 채널은 동적(`dynamic`)으로 존재하며(유저가 참여(`join`)하거나 떠나면서(`leave`) 존재가 결정됨) 채널에서 수행되는 실질적 대화는 채널의 유저를 지원하는(`supporting`) 서버로만 보내진다. 만약 같은 채널의 서버에 다수의 이용자가 있다면, 메시지는 서버에 단 한번만 보내진 후 채널 내 클라이언트 서로에게 보내진다. 그 이후 해당 작업(`action`)은 메시지가 팬아웃(`fan out`)되어 채널의 멤버에게 도달할 때까지 클라이언트 서버 조합(`client-server combination`)에서 반복된다. 아래 예시를 Fig 2.와 살펴보자. Example 4 : 1명의 클라이언트가 있는 채널의 메시지는 서버로 보내진후 다른 곳으로 이동하지 않는다. Example 5 : 2명의 클라이언트가 있는 채널의 모든 메시지는 채널 외부의 두 클라이언트간에 개인 메시지처럼 경로를 통과한다. Example 6 : 클라이언트 1, 2, 3이 채널에 있을 때, 단일 클라이언트(`single client`)의 개인 메시지(`private message`)라면 채널의 모든 메시지는 모든 클라이언트와 메시지가 반드시 통과해야하는 서버에만 전달된다. ### 3.2.3 To a host/server mask 대규모의 사용자에게 메시지를 보내는 기술(`some mechanism`)을 IRC 오퍼레이터에게 제공하기 위해서 호스와 서버마스크 메시지(`host and server mask messages`)가 제공되어진다. 이러한 메시지들은 호스트나 서버 정보가 마스크에 매치된 유저들에게 보내진다. 메시지는 채널과 유사한식으로 사용자의 위치(`location`)로 보내진다. ### 3.3 One-to-all 모든 클라이언트 혹은 서버, 혹은 둘다에게 보내지는 타입의 메시지(`One-to-all message`)는 브로드캐스트 메시지라 말한다. 대규모 네트워크 에서 단일 메시지(`single message`)는 모든 목적지(`destination`)에 네트워크를 통해 보내지면서 대규모 트래픽을 유발 할 수 있다. 일부 메시지는 각 서버가 보유한 상태 정보의 서버간 일관성을 유지하기 위한 브로드캐스트를 제외한 옵션이 없다. ### 3.3.1 Client-to-Client 단일 메시지(`single message`)로부터다른 모든 클라이언트로 전송되는 메시지는 메시지 클래스(`class of message`)가 없다. ### 3.3.2 Client-to-Server 상태정보(채널 멤버십, 채널 모드, 유저 상태 등등)를 변화시키는 명령은 반드시 모든 서버에 기본적으로 보내져야한다. 이는 클라이언트에 의해 바뀌지 않는다. ### 3.3.3 Server-to-Server 대부분의 서버간의 메시지가 모든 기티(`other`) 서버로 보내지는 반면, 사용자, 채널 또는 서버에 영향을 미치는 모든 메시지에만 요구된다.(` While most messages between servers are distributed to all 'other' servers, this is only required for any message that affects either a user, channel or server.` = 해석 불명확) 이는 IRC에서 기본항목이므로 서버에서 시작하는 거의 모든 메시지가 연결되어있는 다른 모든 서버로 브로드캐스트된다. ## 4. Message details