下位層の接続

下位層の接続

[1] 本項で言う下位層の接続とは、 TCP接続やそれに類するものを言います。 信頼性のある全二重バイト列輸送路です。

仕様書

プロトコル

[2] 次のような具体的なプロトコルがあります。

状態と API

[18] 接続の端点は、その種類に依存した接続確立の処理によって作成されます。 接続の確立完了時に、接続の種類に依存した情報をアプリケーションに引渡します。

[3] 接続の端点は、次の状態を持ちます。

種別
「サーバー」または「クライアント」。
送信閉じ済みフラグ
初期状態では未設定。
受信閉じ済みフラグ
初期状態では未設定。
送信待ちバッファー
初期状態では空のリスト。

[6] アプリケーションは、接続の端点に次の指示を行えます。

  • バイトの送信の指示
  • 正常終了の送信の指示
  • 中断の指示
  • credentials の送信の指示

[7] バイトの送信の指示は、送信するバイト (0-255 のいずれかの値)と、 緊急データか否かのフラグ (既定値は未設定。) を引数とし、次のように処理します。

  1. [41] 送信閉じ済みフラグが設定されていれば、例外を投げて停止します。
  2. [19] 送信待ちバッファーが満杯なら、例外を投げて停止します。
  3. [21] 緊急データフラグが設定されていて、 接続の種類が緊急データに対応していないものなら、 例外を投げて停止します。
  4. [20] 送信待ちバッファーの末尾に、 引数のバイト、 引数の緊急データか否かのフラグ、 約束の組を追加します。
  5. [22] 追加した約束を返します。

[23] 返された約束は、バイトが送信された際に解決されます。

[24] バイト列を送信するとは、当該バイト列について先頭のバイトから順にバイトの送信の指示を行い、最後のバイトが返した約束を返す (空バイト列なら解決済みの約束を返す) ことをいいます。

[31] 正常終了の送信の指示は、次のように処理します。

  1. [39] 送信閉じ済みフラグが設定されていれば、例外を投げて停止します。
  2. [36] 送信閉じ済みフラグを設定します。
  3. [35] 接続の種類に応じた処理を行います。

[32] 中断の指示は、次のように処理します。

  1. [40] 送信閉じ済みフラグ受信閉じ済みフラグの両方が設定されていれば、 例外を投げて停止します。
  2. [37] 送信閉じ済みフラグを設定します。
  3. [38] 受信閉じ済みフラグを設定します。
  4. [33] 送信待ちバッファーの先頭の項目から順に、 約束拒絶していきます。
  5. [34] 接続の種類に応じた処理を行います。
  6. [57] 中断の通知を行います。リセットフラグを設定します。

[90] credentials の送信の指示は、 接続の種類に応じた処理を実行します。そのようなものがなければ、 例外を投げます。 なお引数として、接続の種類に応じた credentials を受け取ります。

[4] 接続の端点は、アプリケーションに対して次の通知を行います。

[25] 接続の種類に依存した方法で次のバイトを送信可能であると判断したら、 次のようにします。

  1. [26] 送信待ちバッファーが空なら、ここで停止します。
  2. [27] 送信待ちバッファーの先頭の項目を取得し、バッファーからは削除します。
  3. [28] 接続の種類に依存した方法で取得した項目のバイトを送信します。 (あれば) 緊急データフラグを引渡します。
  4. [29] 取得した項目の約束解決します。

TCP の場合

[58] 接続の確立は、送受信者の IPアドレスポート番号を決定し handshake を適切に行い、正常に完了することによります。 端点におけるフロー制御その他のオプションも適切に設定します。

[85] 確立の完了時に、相手の IPアドレスポート番号アプリケーションに通知します。

[8] TCPセグメントを受信したら、次のようにします。

  1. [54] TCP に従い処理し、不適切と判断すればここで停止します。
  2. [53] RST フラグが設定されていれば、
    1. [44] 送信閉じ済みフラグを設定します。
    2. [45] 受信閉じ済みフラグを設定します。
    3. [47] 中断を通知します。リセットフラグを設定します。
  3. [49] データの各バイトについて、順に、
    1. [48] バイトの受信を通知します。当該バイトの値を渡します。 緊急ポインターが本バイトを指していれば、緊急データフラグも設定します。
  4. [50] FIN フラグが設定されていれば、
    1. [52] 受信閉じ済みフラグを設定します。
    2. [51] 正常終了の受信を通知します。

[9] タイムアウトその他の理由で接続が利用できないことを検知したら、 次のようにします。

  1. [46] 送信閉じ済みフラグを設定します。
  2. [55] 受信閉じ済みフラグを設定します。
  3. [56] 中断を通知します。

[30] バイトを送信できるかどうかは、フロー制御輻輳制御その他の状況により決定します。

[10] バイトの送信は、次のようにします。

  1. 緊急データフラグが設定されていれば、
    1. 指定されたバイトをデータとして含み、緊急ポインターが当該バイトを指すセグメントを送信することにします。
  2. それ以外なら、
    1. 指定されたバイトをデータとして含むセグメントを送信することにします。

[11] 実際の送信時には、前後のバイトとまとめたセグメントで送信されたり、 必要に応じて再送されたりします。

[92] 緊急データに対応しています。

[12] 正常終了の送信の指示があれば、次のようにします。

  1. [42] FIN フラグが設定されたセグメントを送信することにします。

[13] 中断の指示があれば、次のようにします。

  1. [17] 必要に応じて FIN フラグが設定されたセグメントを送信することにします。
  2. [96] TCP で受信したデータの処理を以後行わないことにします。

TLS の場合

[59] 接続の確立は、指定された下位の接続において、 TLS handshake を適切に行い、正常に完了することによります。

[61] 警告を受信していれば、アプリケーションにその旨を通知します。

[89] 確立の完了時に、次の情報をアプリケーションに引渡します。

[73] 下位の接続からバイトを受信したら、バイト緊急データフラグを TLS に従い処理します。

[67] closure alert を受信したら、次のようにします。

  1. [68] 正常終了の受信を通知します。

[15] error alert を受信したら、次のようにします。

  1. [63] alert level警告なら、
    1. [66] 警告を通知します。
  2. [65] それ以外なら、
    1. [106] 送信閉じ済みフラグを設定します。
    2. [107] 受信閉じ済みフラグを設定します。
    3. [64] 中断を通知します。リセットフラグを設定します。

[62] 下位の接続から正常終了を受信したら、次のようにします。

  1. [69] 受信閉じ済みフラグが設定されていなければ、
    1. [70] 受信閉じ済みフラグを設定します。
    2. [71] 正常終了の受信を通知します。

[72] 下位の接続から中断を受信したら、次のようにします。

  1. [74] 受信閉じ済みフラグ送信閉じ済みフラグのどちらかが未設定なら、
    1. [108] 送信閉じ済みフラグを設定します。
    2. [109] 受信閉じ済みフラグを設定します。
    3. [75] 中断を通知します。

[76] バイトの送信は、 TLS に従い処理します。

[83] バイトを送信できるかどうかは、新たなバイトを入力として TLS で処理できるかどうかとします。

[78] 正常終了の送信の指示があれば、次のようにします。

  1. [79] closure alert を送信します。
  2. [80] 下位の接続に正常終了の送信を指示します。

[81] 中断の指示があれば、下位の接続に中断を指示します。

[77] TLS の処理によりバイト列を送信するべきときは、 下位の接続で指定されたバイト列を送信します。

[84] TLS の最初の handshake または再折衝によりクライアント証明書を要求された時は、 次のようにします。

  1. [86] challenge の受信を通知します。
    接続
    この接続
    challenge
    (サーバーなら) ClientHello や (クライアントなら) CertificateRequest に含まれる情報のうち必要なもの。

[82] credentials の送信は、次のようにします。

  1. [87] TLScredentials を受け付ける状態でなければ、例外を投げて停止します。
  2. [88] そうでなければ、与えられた credentialsTLS の処理に引渡します。

HTTP/1 CONNECT の場合

[120] 状態として、次のものを持ちます。

HTTP
HTTP接続クライアントHTTP接続の処理参照。
接続確立済みフラグ
初期値は未設定。

[97] 接続の確立は、target について、次のようにします。

  1. [98] 種別が「クライアント」の場合、
    1. [121] HTTP を、引数として受け取ったHTTP接続クライアントに設定します。
    2. [100] HTTP に、要求を送信します。ただしクライアントが適切な状態になく要求を送信できないときは、 例外を投げて停止します。
      method
      CONNECT
      request target
      target
      header list
      Host
      target
      Proxy-Connection
      keep-alive
      User-Agent
      default `User-Agent` value
    3. [101] HTTP からの通知を、次のように処理します。
      1. [102] 要求のヘッダー受信完了の通知の場合、
        1. [127] 応答の状態符号が 200 なら、
          1. [130] 接続確立済みフラグを設定します。
          2. [110] 接続が確立されたとします。
        2. [128] それ以外なら、
          1. [129] 接続の確立は失敗とします。
      2. [104] 要求のデータ受信の通知の場合、
        1. [131] 接続確立済みフラグが設定されていれば、
          1. [94] データの各バイトについて、順に、
            1. [95] バイトの受信を通知します。当該バイトの値を渡します。
      3. [105] 要求のデータ終了の通知の場合、
        1. [132] 接続確立済みフラグが設定されていれば、
          1. [117] 受信閉じ済みフラグを設定します。
          2. [116] 正常終了の受信を通知します。
      4. [103] 要求の完了の通知の場合、
        1. [115] 終了の失敗フラグが設定されていれば、
          1. [111] 接続確立済みフラグが設定されていれば、
            1. [16] 送信閉じ済みフラグを設定します。
            2. [93] 受信閉じ済みフラグを設定します。
            3. [114] 中断を通知します。
          2. [113] それ以外なら、
            1. [112] 接続の確立は失敗とします。
  2. [99] 種別が「サーバー」の場合、

[118] バイトは常に送信可能とします。

[119] バイトの送信は、次のようにします。

  1. [122] HTTP でトンネルに指定されたバイトを送信します。

[123] 正常終了の送信の指示があれば、次のようにします。

  1. [124] HTTP に接続の正常終了を指示します。

[126] 中断の指示があれば、次のようにします。

  1. [125] HTTP に中断を指示します。

HTTP/2 CONNECT

SOCKS4 の場合

[145] 接続の確立は、次のようにします。下位層の接続接続、 宛先IPv4アドレスホスト、宛先ポート番号ポートを引数として受け取ります。

  1. [146] 種別が「クライアント」の場合、
    1. [148] 接続で 0x04 0x01 p1 p2 a1 a2 a3 a4 0x00 を送信します。
    2. [149] 接続から8バイト受信するのを最大30s待ちます。
    3. [150] 受信した最初の2バイトが 0x00 0x5A でなければ、
      1. [151] 接続の中断を指示します。
      2. [152] 接続の確立を失敗とします。ここで停止します。
    4. [153] 接続を確立できたとします。
  2. [147] 種別が「サーバー」の場合、

[154] 接続確立後は、指示は接続への指示とし、 接続からの通知があればそれを通知します。

SOCKS5 の場合

[155] 接続の確立は、次のようにします。下位層の接続接続、 宛先ドメイン名 (長さ255以下バイト列) または IPv4アドレスまたはIPv6アドレスホスト、 宛先ポート番号ポートを引数として受け取ります。

  1. [156] 種別が「クライアント」の場合、
    1. [157] 接続で 0x05 0x01 0x00 を送信します。
    2. [158] 接続から2バイト受信するのを最大30s待ちます。
    3. [159] 受信したのが 0x05 0x00 でなければ、
      1. [160] 接続の中断を指示します。
      2. [161] 接続の確立を失敗とします。ここで停止します。
    4. [162] 接続で 0x05 0x01 0x00 A p1 p2 を送信します。
    5. [163] 接続から5バイト受信するのを最大30s待ちます。
    6. [164] 受信した最初の3バイトが 0x05 0x00 0x00 でないか、 第4バイトが 0x01, 0x03, 0x04 のいずれでもないか、 5バイトに満たなければ、
      1. [165] 接続の中断を指示します。
      2. [166] 接続の確立を失敗とします。ここで停止します。
    7. [167] 第4バイトが 0x01 なら、接続から5バイト受信するのを最大30s待ちます。
    8. [168] 第4バイトが 0x03 なら、第5バイトを8ビット符号無し整数として解釈し、 接続からそのバイト数 + 2 バイト分受信するのを最大30s待ちます。
    9. [169] 第4バイトが 0x04 なら、接続から17バイト受信するのを最大30s待ちます。
    10. [170] 得られたのが指定のバイト数に満たなければ、
      1. [171] 接続の中断を指示します。
      2. [172] 接続の確立を失敗とします。ここで停止します。
    11. [173] 接続を確立できたとします。
  2. [174] 種別が「サーバー」の場合、

[175] 接続確立後は、指示は接続への指示とし、 接続からの通知があればそれを通知します。

UNIX domain socket の場合

[133] 接続の確立は、次のようにします。

  1. [134] 種別が「クライアント」の場合、
    1. [136] ソケットAPIを使って新たに接続します。 アドレス族AF_UNIX、パス名は引数で指定されたパスソケット型SOCK_STREAM とします。
    2. [137] 接続に失敗すれば、確立は失敗とします。そうでなければ、確立できたとします。
  2. [135] 種別が「サーバー」の場合、

[138] バイトが送信可能かどうかは、 send によりバイト列を送信できるかどうかとします。

[139] バイトの送信は、 send によります。

[140] 正常終了の送信の指示があれば、 shutdown SHUT_WR を実行します。

[141] 中断の指示があれば、 shutdown SHUT_RDWR を実行します。

[142] recv によりバイト列を受信したら、 各バイトを順に、バイトの受信を通知します。

[143] recv で何も受信しなくなれば、 送信閉じ済みフラグを設定し、正常終了の受信を通知します。

[144] sendrecv でエラーが発生したら、 送信閉じ済みフラグ受信閉じ済みフラグを設定し、 中断を通知します。