rust-network - 背景

歴史的経緯

インターネットプロトコルの発展

  • ARPANET(1969年)
- パケット交換ネットワーク - ノード間通信

  • TCP/IP(1974年)
- Vint Cerf, Bob Kahn - 信頼性のある通信

  • BSD Sockets(1983年)
- ソケットAPI - 現在の標準

  • DNS(1983年)
- ドメイン名システム - 階層的な名前解決

OSI参照モデル vs TCP/IP

OSI層 TCP/IP層 プロトコル例
7.アプリケーション アプリケーション HTTP, DNS
6.プレゼンテーション TLS
5.セッション
4.トランスポート トランスポート TCP, UDP
3.ネットワーク インターネット IP
2.データリンク ネットワーク Ethernet
1.物理 インターフェース

コンピュータサイエンス的な意味

TCP vs UDP

特性 TCP UDP
接続 コネクション型 コネクションレス
信頼性 順序保証、再送 なし
オーバーヘッド 高い 低い
用途 Web、メール ゲーム、DNS

TCPの信頼性メカニズム

送信側: [Data 1] → [Data 2] → [Data 3]
        ↓         ↓         ↓
受信側: [ACK 1]   [ACK 2]   [ACK 3]
        ←         ←         ←

パケットロス時:
送信側: [Data 2] → (lost) →
        タイムアウト
        [Data 2] → (再送)

DNSの階層

                    ルートDNS (.)
                    /    |    \
              .com    .org    .jp
             /   \            |
        google  example     co.jp
                             |
                          example

実践での活用

ロードバランサー

// 簡易ラウンドロビンLB
struct LoadBalancer {
    backends: Vec<SocketAddr>,
    current: AtomicUsize,
}

impl LoadBalancer {
    fn next_backend(&self) -> SocketAddr {
        let idx = self.current.fetch_add(1, Ordering::Relaxed);
        self.backends[idx % self.backends.len()]
    }

    fn forward(&self, client: TcpStream) {
        let backend = self.next_backend();
        let mut backend_conn = TcpStream::connect(backend)?;
        // 双方向にデータを転送
    }
}

ネットワーク診断

// TCP接続テスト
fn check_port(addr: &str) -> bool {
    TcpStream::connect_timeout(
        &addr.parse().unwrap(),
        Duration::from_secs(5)
    ).is_ok()
}

// RTT測定
fn measure_rtt(addr: &str) -> Duration {
    let start = Instant::now();
    let _ = TcpStream::connect(addr);
    start.elapsed()
}

実世界とのギャップ

Nagleアルゴリズム

// 小さなパケットをまとめて送信
// → レイテンシが増加する場合がある

// リアルタイム通信では無効化
socket.set_nodelay(true)?;

MTUとフラグメンテーション

MTU (Maximum Transmission Unit):
- Ethernet: 1500バイト
- PPPoE: 1492バイト

大きなパケットは分割される
→ Path MTU Discovery で最適サイズを検出

NATの問題

プライベートネットワーク → NAT → インターネット

問題:
- サーバーがプライベートIP側からアクセス不可
- P2P通信が困難

解決策:
- UDPホールパンチング
- STUNサーバー
- TURN中継