全球 IP 網際網路 (The Global IP Internet)

Overview Table

主題 核心內容 書頁
Internet 應用組織 user code(sockets interface)→ kernel code(TCP/IP)→ hardware(network adapter) p.960
TCP/IP 協定家族 IP(不可靠、host-to-host datagram)、UDP(process-to-process、不可靠)、TCP(可靠、全雙工、process-to-process 連線) p.960
IP address unsigned 32-bit 整數,存於 struct in_addr,一律 network byte order (big-endian) p.961
Byte order 轉換 htonl / htons / ntohl / ntohs(無 64-bit 版本) p.962
Dotted-decimal 每 byte 十進位、以 . 分隔;inet_pton / inet_ntop 與 binary 互轉 p.962
Domain names 階層樹狀結構,ICANN 管理 first-level;DNS 分散式資料庫維護 name ↔ IP 映射 p.963-965
Internet connection point-to-point、full duplex、reliable 的 byte stream p.965-966
Socket / port socket = 連線端點,socket address = address:port;client 用 ephemeral port、server 用 well-known port p.966
Socket pair 連線由 (cliaddr:cliport, servaddr:servport) 唯一識別 p.966-967

Internet 應用的軟硬體組織 (p.960)

全球 IP Internet 是最著名、最成功的 internet 實作,自 1969 年存在至今;雖然內部架構複雜且持續演變,但 client-server 應用的組織方式自 1980 年代初以來非常穩定。每台 Internet host 都執行實作 TCP/IP 協定的軟體,client 與 server 透過 sockets interface 函式 加上 Unix I/O 函式 溝通。

     Internet client host                Internet server host
    +--------------------+              +--------------------+
    |  Client (user code)|              | Server (user code) |
    +--------------------+              +--------------------+
        | Sockets interface (system calls)      |
    +--------------------+              +--------------------+
    | TCP/IP (kernel code)|             | TCP/IP (kernel code)|
    +--------------------+              +--------------------+
        | Hardware interface (interrupts)       |
    +--------------------+              +--------------------+
    |  Network adapter   |              |  Network adapter   |
    +---------+----------+              +----------+---------+
              |                                    |
              +------- Global IP Internet ---------+
協定 層級 可靠性 通訊單位 說明
IP host → host 不可靠 datagram(封包) 提供基本命名機制與傳遞機制;datagram 遺失或重複時不做任何回復
UDP process → process 不可靠 datagram 對 IP 做小幅擴充,讓 datagram 在 process 之間傳遞(本書不討論)
TCP process → process 可靠 byte stream 建構在 IP 之上,提供**可靠、full duplex(雙向)**的 process 間連線
程式設計師視角的 Internet

可把 Internet 想成具備三項性質的全球 host 集合:(1) host 集合映射到 32-bit IP address 集合;(2) IP address 集合映射到 Internet domain name 集合;(3) 一台 host 上的 process 可透過 connection 與任何其他 host 上的 process 通訊。11.3.1-11.3.3 分別對應這三點。

簡化與例外:IPv4 vs. IPv6 (Aside, p.961)

原始的 32-bit 位址協定為 IPv4;IETF 於 1996 年提出 IPv6,使用 128-bit 位址,原意為 IPv4 的後繼者,但截至 2015 年絕大多數流量仍走 IPv4(僅約 4% 使用者以 IPv6 存取 Google)。本書聚焦 IPv4,但後續教的 client/server 寫法(如 getaddrinfo)採用與協定無關 (protocol-independent) 的現代介面。本書「把 TCP/IP 視為單一整體協定」也是簡化,不談其內部運作、不談 UDP。

11.3.1 IP Addresses (p.961-962)

IP address 是一個 unsigned 32-bit 整數。網路程式將它存放在 IP address 結構 struct in_addr 中——把純量位址包進 struct 是早期 sockets interface 實作留下的歷史包袱 (unfortunate artifact),因既有應用程式規模龐大,已無法更改。

/* IP address structure */
struct in_addr {
    uint32_t s_addr; /* Address in network byte order (big-endian) */
};

Network byte order 與轉換函式

不同 host 的 byte order 可能不同,因此 TCP/IP 為封包標頭中攜帶的任何整數資料(如 IP address、port)定義了統一的 network byte order = big-endianin_addr 中的位址永遠以 network byte order 存放,即使 host 是 little-endian(參見 02-Information-Representation/01-Information-Storage-and-Bits 的 byte ordering 討論)。

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);   /* host → network, 32-bit */
uint16_t htons(uint16_t hostshort);  /* host → network, 16-bit */
uint32_t ntohl(uint32_t netlong);    /* network → host, 32-bit */
uint16_t ntohs(uint16_t netshort);   /* network → host, 16-bit */

Dotted-decimal 表示法與 inet_pton / inet_ntop

IP address 呈現給人類時使用 dotted-decimal notation:每個 byte 以十進位表示、以句點分隔。例如 128.2.194.2420x8002c2f2(128=0x80、2=0x02、194=0xc2、242=0xf2)。Linux 上可用 hostname -i 查詢本機的 dotted-decimal 位址。

#include <arpa/inet.h>
int inet_pton(AF_INET, const char *src, void *dst);
        /* Returns: 1 if OK, 0 if src 不是合法 dotted-decimal, -1 on error(設 errno) */
const char *inet_ntop(AF_INET, const void *src, char *dst, socklen_t size);
        /* Returns: 指向 dotted-decimal 字串的指標 if OK, NULL on error */
 "128.2.194.242"  --- inet_pton (p→n) --->  0x8002c2f2 (big-endian 存放)
 (presentation)   <--- inet_ntop (n→p) ---  (network binary)
三種表示、兩組轉換

(1) host byte order 整數 ↔ network byte order 整數:htonl/ntohl/htons/ntohs
(2) dotted-decimal 字串 ↔ network byte order binary:inet_pton/inet_ntop
混用這兩組(例如以為 inet_pton 回傳 host byte order)是常見錯誤。

11.3.2 Internet Domain Names (p.963-965)

client 與 server 實際通訊時使用 IP address,但大整數難以記憶,因此 Internet 另外定義了一組人性化的 domain name,以及 domain name 集合到 IP address 集合的映射機制。domain name 是由句點分隔的一串字詞(字母、數字、連字號),如 whaleshark.ics.cs.cmu.edu

Domain name 階層

domain name 集合構成一個階層 (hierarchy),每個 domain name 編碼了它在階層中的位置。階層以表示,節點的名稱由「回到根的路徑」組成;子樹稱為 subdomain

                        (unnamed root)
                              |
        +---------+----------+----------+
       mil       edu        gov        com          <- first-level(ICANN 定義)
                  |                     |
          +-------+--------+         amazon         <- second-level(向 ICANN 授權
         mit     cmu    berkeley        |               代理機構先到先得申請)
                  |                    www           <- third-level(組織自行建立)
          +-------+------+       176.32.98.166
         cs             ece                          <- cs.cmu.edu(cmu 的 subdomain)
          |
   +------+------+
  ics           pdl                                  <- 4th-level
   |             |
whaleshark      www                                  <- 5th-level
128.2.210.175  128.2.131.66     (完整名:whaleshark.ics.cs.cmu.edu)

DNS:domain name ↔ IP address 映射

映射型態 例子 (p.964-965)
localhost → 127.0.0.1 每台 host 都有本地定義的 localhost,永遠映射到 loopback address 127.0.0.1;方便可攜地引用同一台機器上的 client/server(debug 特別有用)
一對一 whaleshark.ics.cs.cmu.edu128.2.210.175
多名稱 → 同一 IP cs.mit.edueecs.mit.edu18.62.1.6
多名稱 → 同一組多個 IP twitter.comwww.twitter.com → 4 個相同位址
合法名稱但無 IP eduics.cs.cmu.edu → nslookup 回 "No answer"
中間節點不一定有位址

domain name 階層中的節點(如 eduics.cs.cmu.edu)可以是合法的 domain name 卻不映射到任何 IP address;不要假設「每個 domain name 都能 resolve」。

11.3.3 Internet Connections (p.965-967)

Internet client 與 server 透過 connection 收送 byte stream 來通訊。connection 有三大性質:

Socket、socket address 與 port

服務 Well-known port Well-known name
Web 80 http
Email 25 smtp
軟體 port ≠ 硬體 port

這裡的 port 是軟體概念,與網路 switch/router 上的硬體 port 完全無關(footnote, p.966)。

Socket pair:連線的唯一識別

一條 connection 由其兩端的 socket address 唯一識別,這對 socket address 稱為 socket pair,記為:

(cliaddr:cliport, servaddr:servport)

   Client socket address                    Server socket address
   128.2.194.242:51213                      208.216.181.15:80
        +--------+                              +--------+
        | Client |======= connection ===========| Server |
        +--------+      socket pair             |(port 80)|
             ^   (128.2.194.242:51213,          +--------+
             |    208.216.181.15:80)                 ^
   client host address                     server host address
     128.2.194.242                           208.216.181.15

例中 51213 是 kernel 分配的 ephemeral port,80 是 Web 服務的 well-known port;整條連線由 socket pair (128.2.194.242:51213, 208.216.181.15:80) 唯一決定。這個唯一識別性是之後 server 能同時服務多個 client 的基礎(參見 11-Network-Programming/03-Sockets-Interface)。

歷史脈絡(Asides, p.966-968)

Exam/Test Patterns

情境/關鍵字 答案
IP address 是什麼型別? unsigned 32-bit 整數,存於 struct in_addr(成員 uint32_t s_addr),network byte order
network byte order 是哪種 endian? big-endian;in_addr 內永遠 big-endian,與 host byte order 無關
host ↔ network byte order 轉換 htonl/ntohl(32-bit)、htons/ntohs(16-bit);無 64-bit 版本
inet_pton 的 p 與 n 意義 p = presentation(dotted-decimal 字串)、n = network(binary);回傳 1 成功、0 = src 非法字串、-1 錯誤(設 errno)
dotted-decimal ↔ hex 轉換(Practice 11.1 型) 逐 byte 換算:128.2.194.242 = 0x8002c2f2;0x00000080 = 0.0.0.128;0xFFFFFF00 = 255.255.255.0;0x0A010140 = 10.1.1.64
寫 hex→network-order 小程式(Practice 11.2/11.3 型) 16-bit 用 htons(印出)與 ntohs(讀回),搭配 inet_pton/inet_ntop 概念
first-level domain 由誰定義? ICANN;second-level 由授權代理先到先得分配;之後組織可自建 subdomain
domain name ↔ IP 映射存在哪? 1988 前:HOSTS.TXT 單一檔案;之後:分散式資料庫 DNS;查詢工具 nslookup
domain name 與 IP 的對應關係? 多對多(等價類):可一對一、多名對一 IP、多名對多 IP,也可能合法名稱無任何 IP
localhost 對應到? loopback address 127.0.0.1,每台 host 皆有,適合本機 debug
connection 三性質 point-to-point(一對 process)、full duplex(雙向同時)、reliable(順序不變送達)
ephemeral port vs. well-known port client 端由 kernel 自動分配 ephemeral port;server 端用固定 well-known port(http=80、smtp=25),記錄於 /etc/services
一條 connection 由什麼唯一識別? socket pair (cliaddr:cliport, servaddr:servport)
IPv4 vs. IPv6 位址長度 IPv4 = 32-bit、IPv6 = 128-bit;本書聚焦 IPv4,但介面寫法 protocol-independent