2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RFC2811 Internet Relay Chat: Channel Managementを読んでみた。

Posted at

はじめに

どうも。こんにちは。
42tokyoといったところで、IRCサーバの実装を行なっています。

今回は、RFC2811 Internet Relay Chat: Channel Managementを読み、
IRCプロトコルにおけるchannelについて学んでいきます。

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

Abstract

  • IRC(Internet Relay Chat)プロトコルの最大の特徴は、channelと呼ばれる枠でユーザをグループ化し、複数ユーザと同時にコミュニケーションする手段を提供できること
  • channelにはさまざまな種類がある
  • 本文書では、IRCサーバが、channelと、それに関連する情報の管理方法を規定する

1. Introduction

  • 本文書では、IRCサーバのchannel管理方法を詳細に定義する
  • 本文書で定義している概念は、IRCサーバの実装において重要(クライアントの実装でも重要とはいえない)
  • 本文書で定義している概念には、RFC2810 Internet Relay Chat: Architectureを念頭に置いて設計されているものが多い
  • しかし、会議システムを提供するために、他のアーキテクチャに適用することができる概念も多くある
  • IRCユーザには以下の章に関心を持つ人が多いと思われる

2. Channel Characteristics

  • channelとは、そのchannel宛てのメッセージをすべて受信する
  • channelとは、1人または複数のユーザで構成する名前付きグループのこと
  • channelは、channel名、プロパティ(各種の設定)、現在のメンバ(所属ユーザ)によって表される

2.1 Namespace

  • channel名は、最大50文字までの文字列で表す

  • channel名は、prefixに「&」、「#」、「+」または「!」を付ける(channel prefixと呼ぶ)

  • channel名は、大文字と小文字を区別しない

  • channel名に、以下の文字は使用してはいけない

    • スペース「 」
    • コントロールG(「^G」または「ASCII 7」)
    • カンマ(「,」はプロトコルでリスト項目の区切り文字として使用される)
    • コロン(「:」はチャンネルマスクの区切り文字として使用される)

    ※ channel名の正確な構文は RFC2813 Internet Relay Chat: Server Protocolで定義?
      RFC2811 Internet Relay Chat: Client Protocolのことか?

  • 異なるchannel prefixを使うことで、channel名には4つの異なる名前空間ができる
    ※ 名前空間に関するプロトコルの制限について6.1 Labelsを参照のこと

2.2 Channel Scope

実装対象外のため、参考程度

  • channelの実体は、IRCネットワーク上に存在する1つ以上のサーバが把握している
  • ユーザは、そのユーザが直接接続しているサーバが把握しているchannelのメンバになることができる
  • 特定のchannelの存在を知っているサーバのリストは、IRCネットワークの連続した部分でなければならない [MUST]
  • そのリストは、それら特定のchannel宛のメッセージを届けるために活用される [MUST]
  • それ以外のchannelは、channel maskによって、ネットワークに接続されている1つ以上のサーバに知られている:
    • channel maskがない場合、そのchannelはすべてのサーバに知らされる

    • channel maskがある場合、以下のどちらかの条件を満たすとき、そのchannelを管理するサーバの近隣サーバにのみ知られなければならない [MUST]

      • ローカルユーザが所属するchannelを持つサーバ
      • channel maskがローカルサーバ名と近隣サーバ名の両方と同一名称の場合
    • 他のサーバは、そのようなchannelの存在についてまったく知らないので、channel maskに一致する名前を持つサーバによって形成される領域は、すべてのサーバがchannelを知るために連続的でなければならない

    • channel maskは、サーバーのホストマスクと併用するのが最適
      ※ 参考:RFC2813 Internet Relay Chat: Server Protocol

2.3 Channel Properties

  • channelは、プロパティ(設定)を持つ
  • プロパティは、channel modesによって定義される
  • channel modesは、channel memberによって操作される
  • channel modesは、サーバがchannelを管理する方法に影響する
  • prefixに「+」を持つchannelは、channel modesをサポートしない
    これは「t」channel flagが設定されていることを除いて、すべてのchannel modesが未設定であることを意味する

2.4 Privileged Channel Members

  • 一部のchannel memberには、そのchannelにおける管理者権限が与えられる
  • 管理者権限を与えられたメンバは、そのchannel上で以下のアクションを実行できる:
INVITE  - クライアントを招待専用channelに招待する (モード +i)
KICK    - channelからクライアントを追い出す
MODE    - channelのモードやメンバの権限を変更する
PRIVMSG - channelにメッセージを送信する (モード +n, +m, +v)
TOPIC   - channelのトピックを変更する (モード +t)

2.4.1 Channel Operators

  • channel operator(「chop」または「chanop」とも呼ばれる)は、そのchannelを「所有」しているとみなす

  • channelの所有権は、channel operator間で共有される

  • channelは、channel operatorに関するプロパティを持つ

  • そのプロパティには、channel operatorのニックネームが入る(NAMES、WHO、WHOISコマンドへのリプライ時に、channel operatorのニックネームの横に「@」シンボルが付く。これによってクライアントは、channel operatorのニックネームを識別できる。)

  • prefixに「+」を持つchannelは、channel modeをサポートしないので、 どのメンバもchannel operatorのステータスを持つことはできない

2.4.2 Channel Creator

  • prefixに「!」を持つchannelを作成したユーザーは「channel creator」として識別される
  • また、このユーザはchannel operatorのステータスも与えられる
  • channel creatorには、channelの特定のモードを切り替える権限が与えられる
    この特定のモードは、channel operatorが操作できないモードとなる
  • channel creatorは、適切なMODEコマンドを発行することで、channel operatorと区別できる
    ※ 詳細は、RFC2812 Internet Relay Chat: Client Protocolを参照のこと

3.Channel lifetime

  • channelの寿命は、2種類のタイプで分かれる
channel name prefix
standard channels 「&」、「#」または「+」
safe channels 「!」

3.1 Standard channels

  • Standard channelsは、最初のユーザがそのchannelに参加(JOIN?)したとき、暗黙のうちに作成される

  • そして最後のユーザがそのchannelを去ったとき、消滅する

  • channelが存在する間は、どのクライアントもchannelの名前を使用してchannelを参照することができる

  • channelを作成するユーザは、自動的にchannel operatorになる
    (しかし、channel名のprefixに「+」が付くchannelは例外)
    (channel operatorの詳細については2.4.1 Channel Operatorsを参照のこと)

channel名の重複を避ける例

  • ある1つのIRCネットワークが、ある2つのサーバ間で分割された場合
    • channel operator(2.4.1 Channel Operatorsを参照)が、ネットワーク分割のためにchannelを去った場合、そのchannel名は再利用するべきでない [SHOULD NOT]
      この場合、そのchannel名は一時的に使用できなくする
    • チャンネル名として利用できない期間は、IRCネットワークごとに設定する必要がある

これは、ローカルユーザが同名のchannel作成を防ぐが、リモートユーザが同名のchannel作成を防ぐものではないので注意。後者は通常、分割された2つのサーバ間が再び繋がったときに起こる

  • このchannel名の重複を避ける仕組みはprefixが「#」で始まるchannel名に対してのみ意味を持つが、prefixが「+」で始まるchannel名に使用しても構わない
  • この仕組みは一般に「Channel Delay(チャンネル遅延)」と呼ばれる

3.2 Safe Channels

  • 「Safe channels」は、暗黙に作成されない
  • 「Safe channels」を作成したいユーザは、特別なJOINコマンドをサーバに送信する
  • そしてchannel識別子(作成時は不明)を文字「!」に置き換えて作成を要求しなければならない [MUST]
  • 「Safe channels」の作成プロセスは、厳密に制御される
  • 「Safe channels」のchannel名は、
    「サーバが作成したprefix(5文字のchannel識別子)」 + 「ユーザが考えた「short name」」
  • 「Safe channels」のchannel名は、一意でありネットワーク分割に基づく悪用からchannelを保護する
  • 「Safe channels」を作成したユーザは、自動的に「channel creator」になる
    ※ 「channel creator」の詳細は、2.4.2 Channel Creator
  • 以下の場合、サーバは新しい「Safe channels」を作成してはならない [MUST NOT]
    • 同じ「short name」を持つ別のchannelが存在する場合
    • 同じ「short name」を持つ別のchannelが存在し、そのメンバがネットワーク分割によって退出した場合
      • このようなchannelは、最後のユーザが退出し、かつネットワークの分裂によって、一定期間メンバの居ない状態が続いた場合、削除する
      • このような形でchannelが削除されても、channel名が使用できなくなることはない
        5.2.2 Channel Delayの仕組みとは異なる)
  • channelを作成したユーザだけが「Channel Creator」となる
  • 既存の空channelに参加したユーザは自動的に「Channel Creator」にも「Channel Operator」にもならない
  • channel名の一意性を保証するために、サーバが作成するchannel識別子は特定のルールに従わなければならない [MUST]
    ※ channel識別子に関する詳細は5.2.1 Channel Identifierを参照

4. Channel Modes

チャンネルで利用可能なモード
O - 「Channel creator」のステータスを与える
o - 「Channel operator」の権限を付与/剥奪
v - 音声特権(voice privilege)を付与/剥奪
a - 匿名チャンネルフラグ(the anonymous channel flag)の切り替え
i - 招待専用チャンネルフラグ(the invite-only channel flag)の切り替え
m - 管理されたチャンネル(the moderated channel)設定の切り替え
n - 外部クライアントからチャンネル宛のメッセージを禁止する設定の切り替え
q - the quiet channel flagの切り替え
p - プライベートチャンネルフラグ(the private channel flag)の切り替え
s - 秘密チャンネルフラグ(the secret channel flag)の切り替え
r - サーバー再開チャンネルフラグ(the server reop channel flag)の切り替え
t - チャネル運営者のみが設定可能なトピックフラグ設定の切り替え

k - チャンネル・キー(the channel key)(パスワード)の設定/解除
l - channelへのユーザ制限の設定/解除

b - ユーザを立ち入り禁止にする禁止マスクの設定/解除
e - 禁止マスクを上書きする例外マスクの設定/解除
I - 招待専用フラグ(the invite-only channel flag)を自動的に上書きする招待マスクの設定/解除

4.1 Member Status

  • 本節で紹介するモードは、channelメンバのニックネームを引数として取り、そのユーザへ付与する権限に影響を与える

4.1.1 "Channel Creator" Status

O - 「Channel creator」のステータスを与える
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.1.1 "Channel Creator" Status

4.1.2 Channel Operator Status

o - 「Channel operator」の権限を付与/剥奪

  • oモードは、channelメンバーのoperatorステータスを切り替える

4.1.3 Voice Privilege

v - 音声特権(voice privilege)を付与/剥奪
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.1.3 Voice Privilege

4.2 Channel Flags

  • 本節で紹介するフラグは、channelの動作に影響を与えるプロパティを定義するために使用される

4.2.1 Anonymous Flag

a - 匿名チャンネルフラグ(the anonymous channel flag)の切り替え
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.2.1 Anonymous Flag

4.2.2 Invite Only Flag

i - 招待専用チャンネルフラグ(the invite-only channel flag)の切り替え

  • channel flag「i」が設定されている場合、そのchannelに参加できるメンバ(ユーザ)は以下の通り
  • このフラグによって、INVITEコマンド(参照:3.2.7 Invite message)の使用もchannel operatorに制限される

4.2.3 Moderated Channel Flag

m - 管理されたチャンネル(the moderated channel)設定の切り替え
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.2.3 Moderated Channel Flag

4.2.4 No Messages To Channel From Clients On The Outside

n - 外部クライアントからチャンネル宛のメッセージを禁止する設定の切り替え
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.2.4 No Messages To Channel From Clients On The Outside

4.2.5 Quiet Channel

q - the quiet channel flagの切り替え
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.2.5 Quiet Channel

4.2.6 Private and Secret Channels

p - プライベートチャンネルフラグ(the private channel flag)の切り替え
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.2.6 Private and Secret Channels

4.2.7 Server Reop Flag

r - サーバー再開チャンネルフラグ(the server reop channel flag)の切り替え
※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 4.2.7 Server Reop Flag

4.2.8 Topic

t - チャネル運営者のみが設定可能なトピックフラグ設定の切り替え

  • channelフラグ「t」は、TOPICコマンドの実行権限をchannel operatorに制限する

4.2.9 User Limit

l - channelへのユーザ制限の設定/解除

  • channelフラグ「l」を使用することで、channelに参加できるユーザ数を設定できる
  • サーバは、参加人数の上限に達したchannelへ参加するローカルユーザが出た場合、その要求を拒絶しなければならない [MUST]
  • 参加人数の上限値は、サーバがMODEクエリ(コマンド?)に対して送信するリプライによってのみ、channelのメンバに公開されなければならない [MUST]

4.2.10 Channel Key

k - チャンネル・キー(the channel key)(パスワード)の設定/解除

  • モード「k」を使用してchannelキーが設定された場合、サーバは、ローカルユーザのchannel参加(キーなし)要求を拒否しなければならない [MUST]
  • channelキーは、サーバがMODEクエリ(コマンド?)に対して送信するリプライによってのみ、channelのメンバに公開されなければならない [MUST]

4.3 Channel Access Control

  • 本節で解説するモードは、channelへのアクセスを制御するために使用する
  • これらのモードは、引数としてマスクを取る
  • サーバは特定のchannelに設定されるアクセスを制御するモードの最大数に制限を設けてもよい [MAY]
    (channelに設定されるアクセス制御モードのグローバルデータベースのサイズを小さくする目的として)
  • 上記の制限が課される場合、その制限はユーザリクエストにのみ影響を与える [MUST]
  • 上記の制限は、IRCネットワーク単位で均質であるべき [SHOULD]

4.3.1 Channel Ban and Exception

  • あるサーバに所属するユーザが、channelへの参加を要求したとき、そのchannelを管理するローカルサーバは、ユーザのアドレスがchannelに設定された「ban masks」と一致するかチェックする

  • 一致した場合、そのアドレスがchannelに設定された「exception masks」と一致するかチェックし、一致しなければそのユーザのリクエストを拒否する

  • サーバは、channelの「ban masks」に該当するユーザがchannel上で発言することを許可してはならない [MUST NOT]
    (そのメンバがchannel operatorか、音声特権(Voice Privilege)を持つ場合を除く)
    参考:4.1.3 Voice Privilege

  • channelの「ban masks」に該当するユーザだが、channel operatorから招待されたユーザは、そのchannelに参加できる

4.3.2 Channel Invitation

  • 招待専用フラグ(Invite Only Flag)が設定されているchannle(4.2.2 Invite Only Flagを参照)では、そのchannelに設定されているinvitation maskとアドレスが一致するユーザは、招待なしでそのchannelに参加することができる

5. Current Implementations

  • 本章に出てくる実装をIRCプロトコルの一部として現在実装しているのは、IRCサーバのversion2.10だけ
  • 本章以下の内容は、主にサーバを実装したい人にとって重要な問題を扱うが、クライアントを実装する人にも興味のある部分があるかもしれない

5.1 Tracking Recently Used Channels

  • channelの動向を追跡する仕組みを「チャンネル遅延(Channel Delay)」と呼ぶ
  • 「Channel Delay」は、大抵prefixが「#」のchannelにのみ適用される(3.1 Standard channels)
  • IRCネットワークの分割が発生したとき、サーバは、分割の結果「channel operator」を失ったchannelを記録するべき [SHOULD]
  • 「channel operator」を失ったchannelは、ある期間だけ「特別な状態」になる
  • 「特別な状態」の間、channelが無くなることはない

「特別な状態」について

  • channelに所属する全メンバが退出すると、そのchannelは使用不可となる

  • channelが空である限り、サーバのローカルクライアントは、そのchannelに参加できない

  • いったん使用不可能になったchannelが、再度利用可能になるには、2つの場合がある

    • リモートユーザがchannelに参加した(ネットワークの回復による場合が多い)
    • 遅延時間が経過した(この場合、一度channleは無くなり、再作成される可能性がある)
  • channelがなくなるまでの猶予(遅延期間)は、多くの要素を考慮して設定されるべき [SHOULD]
    (IRCネットワークのサイズ(ユーザ数)、ネットワークが分裂する通常の期間など)

  • また、IRCネットワークのすべてのサーバで統一されるべき [SHOULD]

5.2 Safe Channels

  • 本節では「Safe Channels」といった概念を紹介する
  • 「Safe Channels」は、prefixに「!」を持つ名前を持ち、「name space」での衝突を避けるために多大な努力が払われている
  • 衝突は可能だが、非常に起こりにくい

5.2.1 Channel Identifier

  • 「チャンネル識別子(Channel Identifier)」は、UNIXタイムスタンプを使用して5つの文字列を生成する
  • 以下のベースを使って5文字の文字列に変換する:
    ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
    (各文字は「A = 0」から「0 = 35」までの10進数値を持つ)
     * よってchannel識別子の周期は36^5秒(約700日)となる

5.2.2 Channel Delay

  • 「Safe Channels」は、5.1 Tracking Recently Used Channelsで述べられている仕組みに従わなければならない [MUST]
  • ただし、この仕組みは「Safe Channels」に合わせて少し修正されている
  • サーバは、ユーザがchannel operatorであるかどうかに関係なく、ネットワーク分割の結果としてメンバを失ったchannelをすべて追跡しなければならない [MUST]
  • しかし、メンバを失ったchannelが利用できなくなることはなく、channelが空でも参加することは可能

5.2.3 Abuse Window

  • 周期性が非常に長いため、特定のchannel名に対する攻撃は少ない
  • しかし、ユーザがchannel名の衝突を引き起こすことは可能
  • channel名の衝突を避けるために、サーバは近い将来に使用される、「Channel Identifier」(channel名?)のリストを保持しなければならない [MUST]
  • サーバが維持する負担を下げるために、このリストは小さくすべき [SHOULD]
  • サーバはこのリストを使って、「Channel Delay」よりも長い期間、衝突を引き起こす名前を使ったchannelの再作成を防ぎ、channel名の衝突を回避すべき
  • 最終的にサーバは、この手順を拡張して、同じ短縮名のみを持つchannelの作成を禁止する(その場合「Channel Identifier」は無視される) [MAY]

5.2.4 Preserving Sanity In The Name Space

  • 5.2.2 Channel Delayおよび5.2.3 Abuse Windowで説明した仕組みの組み合わせによって、 ユーザがchannel名の衝突を起こすことは非常に難しくなっている
  • しかし、同じ「short name」だが「channel識別子(Channel Identifier)」が異なるchannelを多数作成する攻撃方法もある
  • これを防ぐために、サーバは現在存在するchannelと同じ「short name」を持つ新しいchannelの作成を禁止しなければならない [MUST]

5.2.5 Server Reop Mechanism

※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 5.2.5 Server Reop Mechanism

6. Current problems

6.1 Labels

  • 本節では、IRCプロトコルで使用される多くのラベルの1つを定義する
  • (channel名のprefixに基づく)いくつかの異なる名前空間があるが、各名前空間内でのchannel名の重複は許可されていない
  • 現在、異なるサーバに接続しているユーザが、ラベルを選択することが可能であり、衝突を引き起こす可能性がある
    (衝突を回避できる1つのサーバだけが知っているchannelは例外)

6.1.1 Channel Delay

  • prefixに「#」を持つchannelでの「channel delay(5.1 Tracking Recently Used Channels)」は、channel名の衝突を防ぐための単純な試みだが、通常の状況下において、この方法は非常に効率的である。しかし、適切な解決策と言い難い

6.1.2 Safe Channels

  • 「Safe channels(3.2 Safe Channelsで解説)」は、ユーザがラベルを設定することによって発生するchannel名の衝突を防ぐ、より良い方法と言える(ユーザがラベルを設定するため、サーバ側で完全にコントロールすることができない状況)
  • しかし、このようなラベルの設定方法は、ユーザフレンドリーでないことが欠点
  • だが、この欠点はクライアント・プログラムで容易に改善することができる

6.2 Mode Propagation Delays

※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 6.2 Mode Propagation Delays

6.3 Collisions And Channel Modes

※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 6.3 Collisions And Channel Modes

6.4 Resource Exhaustion

  • 4.3 Channel Access Controlで定義されたマスクに基づくモードは、IRCサーバおよびネットワークの脆弱性に繋がる
  • 一人のchannel operatorが、特定のchannelに多くの異なるマスクを設定することができる
  • これは、サーバのメモリやネットワーク帯域幅の浪費を簡単に引き起こす可能性がある
    (情報が他のサーバに伝搬されるため)
  • このため、4.3 Channel Access Controlで述べられているように、channelごとのマスク数に制限を設けることが推奨される [RECOMMENDED]
  • さらに、同じchannelに冗長なマスクが設定されるのを避けるために、より複雑なメカニズムを使用してもよい [MAY]

7. Security Considerations

7.1 Access Control

  • channelへのアクセスを制御する方法として、ユーザ接続のユーザー名とホスト名に基づくマスクを使用する方法がある
  • この方法が効率的かつ安全に動作する前提には、IRCサーバへのクライアント接続時に成りすましを防止していることが挙げられる
  • 成りすましを防止する実装は可能だが、実際に実装されているケースは少ない
  • そのため、クライアント接続におけるユーザ名とホスト名の正確性はほぼ保証されていない
  • アクセスを制御するもう1つの方法は、channel keyを使用することだが、このキーは平文で送信されるため、従来の中間者攻撃に対して脆弱
  • 理論的にはこのような厳密な認証メカニズムを実装することは可能だが、ほとんどのIRCネットワーク(特にパブリックネットワーク)ではこのようなものは実装されておらず、特定のクライアント接続のユーザ名とホスト名の正確性についてはほとんど保証されていない
  • アクセスを制御するもう1つの方法は、チャネルキーを使用することであるが、このキーは平文で送信されるため、従来の中間者攻撃に対して脆弱

7.2 Channel Privacy

※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 7.2 Channel Privacy

7.3 Anonymity

※ 実装対象外のため、省略
参考:RFC2811 Internet Relay Chat: Channel Management 7.3 Anonymity

8.Current support and availability

9.Acknowledgements

10. References

11. Author's Address

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.

さいごに

ラベルやマスクといった言葉の意味や、実装方法の想像が出来ず、読むのが難しかったです。
今回実装するサーバは、サーバ間の接続は行わないので、IRCネットワーク関連の箇所は省略しました。
IRCプロトコルにおけるchannelについて理解を深めることができました。

ありがとうございました!

参考

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?