13.7.5 再送処理
送信したデータに対する確認応答が待っている間に再送タイマーの時間が来ると、tcp_output()が呼ばれて再送処理を行う
再送を同じタイミングでやると遅れるので、ランダムではない方法でデータを送る。
バックオフ www.atmarkit.co.jp
変数snd_nxtの値を最新のシークエンス番号からsnd_unaの値に戻す。
FreeBSDでは送出したパケットのコピーを保管していない。
データを小出しにして、データがまとまっているので他のシステムよりでかいデータを送ってしまうっていう話。
古いデータと新しいデータがごっちゃになって送られてしまうという可能性。
13.7.6 スロースタート
多くのTCP接続は、発信元と送信先の間で複数のネットワークを経由する。
確認応答が届くうちは一度に送る数を増やしていく
- 接続が遅くてデータがつまる。
- 接続開始時にバーストしてデータ送信がおかしくなる場合もある。
- データの流れが安定すると大きなデータウィンドウをサポートできるようになるかもしれない。
- 太さは帯域をあらわしている
- 下はACK(確認応答)
確認応答を受けて、クロッキングして、データの送信する量を調節して、理想的な間隔でデータを送り出す。
データ送信量がバーストすると、送信量を調節する。
(電車の待ち時間の調整みたいな感じ)
スロースタートアルゴリズムは、TCP接続を↑の状態に持っていくためのアルゴリズム。
データ送信がバーストするのをやめるためのアルゴリズム。
数字がシーケンス番号。時間が経過するごとに、データ送信がつまらずになだらかに送信されていくのを表現している。
- データを送る
- データが無事送れたからちょっと増やしてみる
- 確認応答を受信するたびにデータ送信量上限が倍々に増えていく
- ACK(あっくと読む)
- ウィンドウのオープンが指数的に進行する
- ウィンドウはどんどん広げられていく
- データ送信量と確認する量は等しい?
- 調整してちょうど良いスピードになっている
輻輳ウィンドウ
ネットワークがその接続に対して提供することが出来るバッファ量の推測値に基づいて管理される
- スロースタートの考えを表現しているのが輻輳ウィンドウ
- ここでいうパケットはTCPのパケットではなくIPのパケット
流れが混雑することを輻輳という。
- シークエンス番号の範囲がウィンドウの定義
- P671 スライディングウィンドウ ウィンドウが広がると、扱えるシーケンス番号も増えていく
- 二重に送信が管理されている。
- 輻輳ウィンドウがどうあるべきかは受信側からは分からないので、送信側が調べてあげないといけない。データの送信量が増えていって運用が困ったので、あとから実装している。
- 輻輳ウィンドウがどんどん広がっていったので、しょうがないので二重管理にしている。
- エンドの端末の自分自身の都合だけを通知している
輻輳ウィンドウまわりはあとから実装しており、最初から設計思想が存在していたわけではない
スロースタートの強制
- 送信がタイムアウトするたびに1パケットにリセット
- バースト→中断を繰り返す
- 一度接続が停止すると、確認応答の同期を再度行う必要がある
スロースタートアルゴリズムは問題が起きたから実装して、結果うまくいったやつ
スロースタートアルゴリズムは、TCPの一般的なアルゴリズムだけど、他のOSだとどうなの?っていうのは不明。(BSDだとデータ送信量は倍々だけど、Linuxはどうなの?)
- 具体的な数字がなくても成り立つ
RFC2001にスロースタートアルゴリズムのことが書いてある。
http://www.imasy.or.jp/~yotti/rfc2001j.txt
13.7.7 ソースクエンチの処理
ソースクエンチ(source quench)というICMPエラーメッセージをパケットの発信元に送り、送信頻度を控えるべきであることを通知できる
13.7.8 バッファとウィンドウのサイズ
- TCP接続の性能は、当然のことながら、接続が経由しなければならない経路の伝送帯域に依存する
- バッファは帯域と遅延の積に相当する
蓄積転送型=ストアアンドフォワード ストアアンドフォワード - Wikipedia
反対語はカットスルー e-words.jp
複数の接続はなくて、1対1の送受信が理想的。でも現実は遅延が発生する。
- ネットワークが遅いと送信側 受信側両方で苦労する
- 接続のためのウィンドウサイズを徒に増やしても待ち時間が増えるだけで意味はない(=リソースの無駄)
13.7.9 スロースタートによる輻輳の回避
(まだ続くのかこの話…)
TCPにスロースタートアルゴリズムが実装されたことで、接続はネットワークを許容する速度でパケットを送り出すことが出来、パケットがネットワークを抜け出ると同時に新たなパケットが送り込まれるような安定した状態を達成できる
- 送信パケット量が多すぎる場合は、帯域と遅延の積を増やすよりパケットを捨てるほうが理想的
- いたずらに増やすだけだと待ち時間が増えるだけなのでネットワークが破綻してしまう
- ウィンドウサイズは理想的なサイズが理想。
- 自律的に調整する性質がTCPには求められる
- データ量が多いとキューを伸ばすかパケットを捨てるかが求められる
- でもウィンドウサイズ増加→リセットを繰り返すと無限ループになるので別のアルゴリズムが求められる
- 状態変数スロースタート閾値が用意され、経路に対する実効的なウィンドウサイズの予測値を管理する
- 32で溢れたら16に戻す(これがオクテット数の半分の意味)。このとき、(おそらく)閾値は16と32の間なので、理想的な閾値を探していく
パケットが喪失しない限り接続のウィンドウサイズは線形に伸びるが、輻輳の兆候が見られるとウィンドウサイズは指数的に減少する
ファイル周りはネットワークが切れたら洒落にならない
スロースタートアルゴリズムはこんなかんじ 3 Minutes Networking No.42
13.7.10 早期再送
パケットの喪失の原因
- 輻輳
- 損傷
どちらの場合もTCPではそれを検出して再送する
- 輻輳があったらスロースタート閾値を下げつつ、送信→輻輳を繰り返しながら、閾値を調節する。でも、輻輳があった時点でスループットが低下する
- 届いていないものは無視する
- データを何度も送ることで、どのデータが喪失したかを確認出来る
- 送信するデータの順序に不正が見られれば、FreeBSDでは早期再送を行う
- 同じ確認応答を3つ受信すると再送処理を行う。のでスロースタートを行う必要はない
- ネットワークが復旧したらキューに溜まったパケットを送信する
- 早期再送のあとに重複する確認応答を受け取ると、輻輳ウィンドウを作為的にセグメント長ぶんだけ前進させる
- バッファは多いほうがいい(さっきと言っていることが違う)
(早期再送についてもRFC2001に書いてある) http://www.imasy.or.jp/~yotti/rfc2001j.txt
13.8 インターネット制御メッセージプロトコル(ICMP)
- IPv4上の制御情報とエラーメッセージを運ぶためのプロトコル
- エラーパケット
- エラーの原因となったパケットのIPv4ヘッダ
- ソレに続く最低8オクテットのデータが含まれる
- パケットの生存フィールド
- エラーが返ってくる 最初はping
- リプライを返してくる
エラーさえかえってくれば何でもいい
到着したICMPメッセージに対する処理と応答はICMPモジュールによって行われる
- エラーやソースクエンチを受信するとsockaddr構造体のなかに汎用アドレスを用意
- リダイレクトメッセージによる経路変更指示はrtredirect()関数によって処理
- ポート到達不能
- 到着したICMPメッセージのカーネルによる処理が終わると、ICMP RAWソケットによる受信を処理するためにrip_input()に渡される
- ICMPは、インターネット上の別のネットワークプロトコルがエラーメッセージを受信するために使用することもある
- UDPは一方的に送りつける。TCPは別の手段
- もっと近いルータがあるよって気を利かせて言ってくる(そのルータがインチキかどうかは分からないので、性善説に基づいている)
- ICMPはポートを持たず、IPとは別枠で持たれている
- ポート番号を教えてくれる
- カーネルが送ってくる
- UDPで受け取りたかったら予めbindしておく必要がある。
- 捨てちゃったエラーが出てくるから、IP層ではルータでエラーがいっぱい検知される
- UDPは基本的に投げっぱなしジャーマンだけどエラーを検知したい時もある
- connectで送りつけたやつをカーネルに知らせておく(keepしておく)ので、エラーメッセージを配送しておく
- プログラマにとっては単純でも、カーネルからしたらかなり複雑なことをやっている
- OSが世話をしないといけない
13.9 IPv6
インターネットアドレスの枯渇からの新しいIPの体系が開発された。
- サブネット
- CIDR
あまり効果的な解決策ではない
からの、IPv6プロトコル(RFCのいくつかで策定された)
大きな違い
- ネットワーク層でのでの128ビットアドレスの採用
- 自動設定機能の充実
- セキュリティプロトコルの標準実装
アドレスをブロックとして集約し、ISPはそれをさらに小さなブロックに分割して顧客に分配する
RFC792(INTERNET CONTROL MESASAGE PROTOCOL)
IPv4はJPNicからはもう割り当てをしていない。
Phase1はIPsecが含まれない Phase2はIPsecは含まれる
IPv6 トンネル経由の IPv4 の設定方法 (IPv6 の管理)
どっかで破綻しそうな話
13.9.1 IPv6アドレス
従来の4元ドット記法(xxx.xxx.xxx.xxx)ではないので、書き方がRFCで策定されている
- ユニキャスト
- マルチキャスト
- エニーキャスト
インターネット10分講座:IPv6アドレス~技術解説~ - JPNIC
- IPv6はブロードキャストアドレスという概念が存在しない
IPアドレスを持たない状態でもホストがサービスを発見する方法を提供することで対応
OK 1080:0:0:8:0:0:200C:417A
- OK 1080:::8:0:0:200C:417A
- NG 1080::0:8:0:0:200C:417A
NG 1080::8::200C:417A
わけがわからないから省略するの辞めたほうがいいのでは…
- 001って始まるユニキャストアドレスってあるの?
- IPv4→IPv6にあたり、アドレスクラスという概念が捨てられた
すべて同じ。/60はサブネットマスクみたいなものか
- 1234:0000:0000:1230:0000:0000:0000:0000/60
- 1234::1230:0:0:0:0/60
1234:0:0:1230::/60
4ビット区切りにするならどっちでもいい
- アドレスの長さ
- ユニキャストアドレスの一種の形
- IPv6はアドレスのつけかたから覚えないといけないからかなりしんどい。しんどいわりにあんまり普及していないのもつらい
- IoTがキラーコンテンツになるのか 中国でインターネットが爆発的に普及したらIPv4が本格的に枯渇するのか
13.9.2 IPv6のパケット形式
ルータがパケットを転送するために必要な作業の軽減がIPv6設計の目標であった。それを以下の方法で実現する
- パケットヘッダの簡素化
- 固定長のパケットサイズ
- ネットワーク層でのフラグメント化を極力行わない
- IPv4でやってたことをIPv6でやめるとIPv6の普及を阻害すると考えられた
- IPv6における拡張機能は拡張ヘッダで実装
- すべての拡張ヘッダは次ヘッダフィールドとその拡張部分の長さを8バイトを単位として示す長さフィールドで始まる
ネットワークエンジニアを目指して・TCP/UDP - IPv6 ヘッダフォーマット - ネットワークエンジニアを目指して
- ルータは、パケットを転送する際にホップバイホップオプションヘッダ以外の拡張ヘッダは参照しない
IPv6ネットワークへの招待(3):IPv6のヘッダフォーマット - @IT
- 破損したパケットを取り扱う場合はどうしたらいいんだろう
- IPv6でチェックサムをやって上位層に渡す
- TCPは6 UDPは17
13.9.3 ソケットAPIの変更
- IETFは実装ではなくプロトコルを定義する
IPv6のための拡張インタフェイスを定義した
変更によって既存のアプリケーションを阻害してはいけない
- アプリケーションをIPv6対応にするために必要な変更点を最小限に抑える
- IPv6とIPv4のホスト間の相互運用性を確保する
データ構造内に置かれるアドレス情報は、64ビットアーキテクチャにおける性能を最適化するために64ビット境界に揃える
いくつかスコープを設定している
- 128ビットアドレスは事故の原因なので、DNSを通してIPv6を持つ対象を取り扱う
13.9.4 自動設定
より簡単に計算機をネットワークに接続する。この仕組みを自動設定という。
ホストが次ホップルータを見つける方法 * 定期的にルータ広告メッセージを発信 * それぞれのホストは、ルータエントリのリンクリストを管理 * パケットを送るべき次のホップが自身と同じリンク上に存在することをホストが確認するためにはそのリンクのプレフィックスを知っていなければならない * プレフィックス情報はルータ広告メッセージのオプションとして送られる * プレフィックス長フィールドを60に設定 * リンク層アドレスを取得しなければならない * ホストは近隣要請と近隣広告の一対のメッセージを利用して近隣ホストのリンク層アドレスを取得する * パケットは最終的にip6_output()関数に送られて様々な検査を受ける * nd = neighbor discovery * リンク層アドレスは経路テーブルに保管 * IPv4のARPモジュールはメッセージの送受信ができるようにネットワークインターフェイスに組み込まれていた * 毎秒実行されるnd6_timer()関数は近隣探索のリンク層アドレスリストと、デフォルトルータおよびインターフェイスリストを走査して、有効期限の切れたエントリを削除する
- DHCPとブロードキャストの分離=IPv6(ARPではまずい) Geekなぺーじ:getaddrinfo
13.10 セキュリティ
- IPv6の一部としてセキュリティプロトコルが開発された
- プロトコル・スタックのなかからネットワーク層を選択する
- ネットワーク層でセキュリティを実装する理由
- 統一的なプラットフォームとして機能
- 何もしなくてもセキュリティプロトコルを使用できる
- システムデーモンが自動的に鍵管理を行うことができる
- IPsecが提供するセキュリティにはいくつかの側面がある
- あるホストが何者であるかを信用することが出来る能力
- 過去のデータを再生したことを検出する能力
- データの秘匿性の確保(暗号化)
- セキュリティアーキテクチャを提供するのは複雑な問題
- FreeBSDでは2種類のIPsecを実装
- KAME
- Fast IPsec
- 復号化するときにつらい
- データが改ざんされていたら復号化出来ない
13.10.1 IPsecの概要
- IPsecを構成するプロトコルは、インターネット上のホストとルータが使用するセキュリティフレームワークを提供する
- セキュリティアソシエーションと呼ばれる関係を互いの間に構築
- 送信先アドレスと使用するセキュリティプロトコルに加えてセキュリティパラメータインデックス(SPI)と呼ばれる32ビットの値によって一意に定義される
- SAは2つのモードで動作
- トランスポートモード(IPsecのヘッダとデータとともにIPヘッダの一部も保護される)
- トンネルモード(パケット全体がIPの上にIPを通すトンネルによって作られる)
- トンネルモードは仮想プライベートネットワーク(VPN)の実装で利用されることが多い
13.10.2 セキュリティプロトコル
- 2つのセキュリティプロトコル
- 認証ヘッダ
- カプセル化セキュリティペイロード
- 認証ヘッダ(AH)を理解するためにはパケットヘッダの内容を見るのがいちばん
- 再生(replay)
他人の物を再利用する
- 認証は、パケットに対する整合性チェック値(ICV)を計算することで実現する(key-valueのv)
- ICVを計算してパケットの認証データフィールドの値と比較する(一致しなければ破棄、一致すればパケットを受け入れる)
- 通信経路に対する攻撃手段として、正しい発信元から送られたデータを使って偽りのデータを挿入する方法があり、これを再生攻撃(replay attack=反射攻撃)という
- これを防ぐためにAHプロトコルはSA上を流れるすべてのパケットを一意に特定するためのシークエンス番号フィールドを持っている(これはTCPとはまったく別物)
- シークエンス番号をウィンドウに照会するが3つの結果が存在する
- パケットのシークエンス番号がウィンドウの左端の値より小さい場合、そのパケットは破棄
- パケットのシークエンス番号がウィンドウに収まっている場合、パケットが重複していれば破棄、していなければウィンドウに挿入する
パケットのシークエンス番号が現在のウィンドウの右端よりも大きい場合、ICVを検証し、それが正しければ新しいシークエンス番号を含むようにウィンドウを右方向に移動する
ラップする固定長の値(ウィンドウパターン的なやつ)
シークエンス番号が循環するのでSAを再構築する必要がある
- すべての発信者は受信者が再生攻撃対策を行うことを想定し、常にシークエンス番号を進めるが、管理者の判断で無効にできる
ESPは暗号化を使って秘匿性を実現する
ペイロードデータに続くパディングは3つの目的で使用される
- 暗号化するデータ全体を想定している大きさに調整
- パケットの一部を適正な境界に配置
- 攻撃者が通信の流れから何らかの情報を得ようとするのを防ぐ
ペイロードデータのパディング
IP Encapsulating Security Payload (ESP)
- 中身を見られたくないならESP
- ヘッダといいつつ本体も入っている
(次回は13.10.3 鍵管理から)
書籍
- 作者: マーシャル・カークマキュージック,ジョージ・V.ネヴィル‐ニール,砂原秀樹,Marshall Kirk McKusick,George V. Neville‐Neil,歌代和正
- 出版社/メーカー: アスキー
- 発売日: 2005/10/18
- メディア: 単行本
- クリック: 122回
- この商品を含むブログ (57件) を見る