--- tags: 電腦網路, 大二筆記 --- # 電腦網路 Chapter 2 : Application Layer ## Principles of Network Applications ### 網路應用程式架構 Network Application Architecture #### 主從式架構 Clinent-server Architecture * 主從式架構中,一定有個 **伺服器 (Server)** 來服務 **客戶端 (Client)** 所發送來的請求 * 伺服器 Server * 不會關機 * 擁有固定的 IP 位址 * 通常位於 **資料中心 (data center)**,以提供大量的流量服務 * 客戶端 Client * 向伺服器端發送請求 * 浮動 IP 位址 * 每個客戶端無法互相溝通 * 基於主從式架構的服務:HTTP, FTP, Email #### 對等式架構 Peer-to-peer Architecture * 不需要依賴資料中心的伺服器,而是對等的主機互相連接,因而稱為 **peer-to-peer (P2P)** * 去中心化,在資源的使用上較有效率,但是缺乏安全性 * P2P 具備 **自我擴展性能 (Self Scalabiliity)**,可根據需求自動調整以實現更高的可擴展性和性能 * 主機間的 IP 會浮動,所以常常會使用混和式架構:伺服器用以追蹤各個客戶端的 IP,而通信則是使用 P2P 的方式在電腦間互傳 ### 程序間溝通 Processes Communicating * 兩個執行在不同終端裝置上的 **程序 (Process)** 需要透過網路來交換 **訊息 (Message)** * 會有專門的程序將訊息發送到網路上,也有專門收訊息的程序 #### Client and Server Processes * 我們將兩個進行通訊的程序分為 **客戶端 (Client)** 和 **伺服器端 (Server)** > 無論是在主從式架構或是 P2P 都是以這種方式,發起通訊的電腦會被定義為 **客戶端** #### 插座 Socket * 兩個網路應用程式透過網路傳遞訊息使用的介面 * 應用程式將訊息由 Socket 送出至傳輸層,而傳輸層會幫助將訊息送到目的地;收信方也需要透過自己的 Socket 去收取信息 ![Socket](https://hackmd.io/_uploads/H1-iV4pJR.png) * 可以看到 Socket 是位於應用層和傳輸層中間溝通的介面,因此又稱為應用程式與網路間的 **應用程式介面 (Application Programming Interface, API)** * 開發者只對應用層有操控權,上到傳輸層就由系統控制 #### Addressing Processes * 電腦傳輸信息時,除了需要知道收信端程序的位址,還要知道是哪個程序要收信。因此程序需要一個 **識別符 (Identifier)**: * 識別符內容包含: * **IP 位址**:收信電腦的位址 * **埠號 (Port)**:用以辨別收信的程序 (準確來說是 Socket) #### 應用層協議 Application-layer Protocol * 協定內容: * 交換訊息的形式 * request, response... * 訊息的語法 * 有哪些欄位,欄位怎麼分配 * 訊息的語意 * 欄位代表的意義 * 規則 * 送出或接收到訊息後要做的事情 * Open Protocol * 通用的協定,大家都可以通用 * HTTP, SMTP * Proprietary Protocol * 私人的協議 * Skype ### Transport Services Available to Applications 傳輸層協定提供的程式服務大致分為四個面向: #### 資料完整性 Data Integrity * 有些應用程式不能遺失封包,例如網路銀行轉帳 * 有些協議能提供某種機制,保證封包能完整到達目的地,我們稱他提供 **可靠的資料傳輸 (Reliable Data Transfer)** * 不是每個應用程式都需要,例如大部分的語音及視訊通話,掉包頂多延遲而已 #### 吞吐量 Throughput * 一些應用程式需要一定的吞吐量來維持品質,如語音通話 * 這種對吞吐量有要求的應用程式我們稱為 **對頻寬敏感的應用 (Bandwidth-sensitive Application)** * 而相對的 **有彈性的應用程式 (Elastic Application)** 對吞吐量的要求不大,有多少用多少。如:網頁服務、Email #### 時間差 Timing * 網路遊戲、網路電話這種需要低網路延遲的應用程式,就需要保證其封包傳輸的時間差 #### 安全性 Security * 傳輸層協定可以提供跟安全性有關的服務 * 加密、資料完整性和終端身分驗證 > 這裡的資料完整性比較像是:確保資訊不受未授權的竄改或在竄改後能及時被發現 |應用服務|是否能忍受掉包|對吞吐量的需求|對最大時差是否有要求| |:-:|:-:|:-:|:-:| |**檔案傳輸/下載服務**|不能掉包|沒有特殊需求|沒有要求| |**Email**|不能掉包|沒有特殊需求|沒有要求| |**網頁服務**|不能掉包|沒有特殊需求(只會用固定幾 kbps)|沒有要求| |**網路電話/視訊會議**|可以掉包|音訊: few kbps - 1 Mbps<br>影片: 10 kbps - 5 Mbps|不得超過 100 msec| |**影音串流**|可以掉包|同上|不能超過數秒| |**互動式遊戲**|可以掉包|few kbps - 10 kbps|不得超過 100 msec| |**文字訊息**|不能掉包|沒有特殊需求|有時有有時沒有| ### Transport Services Provided by the Internet #### TCP Service * 可靠的資料傳輸 Reliable Transport * TCP 可以確保傳送出去的資料都能完整的並按照順序送到收信端 * 流量控制 Flow Control * 保證收發兩端的傳輸速度保持一致 * 壅塞控制 Congestion Control * 將長度過長的訊息切小,壅塞時自動降速 * 連線導向的服務 Connection-oriented Service * TCP 規定兩台電腦傳遞訊息 **之前**,要先進行 **交握 (Handshaking)** * 當交握完成,我們會說一個 **TCP 連線** 存在於雙方的 **Socket** 之間 * 為 **全雙工 (Full-duplex)** 的連線,雙方可以同時傳訊息給對方 * 傳輸完成後,連線就必須關閉 * **並沒有** 提供 * 時間差 * 最低頻寬保證 * 安全性 #### UDP Service * 提供最輕量化的傳輸協定,講難聽點就是啥都沒有 * 資料傳輸前不需要交握,也沒有可靠的資料傳輸 * 代表把資料丟進 UDP 的 Socket,不保證資料一定能到對方手上,順序也無法保證 * **沒有** 提供 * 可靠的資料傳輸 * 流量控制 * 壅塞控制 * 連線的建立 * TCP 沒有的服務 |應用服務|應用層協定|底下的傳輸層協定| |-|-|-| |**電子郵件**|SMTP [RFC 5321]|TCP| |**遠端終端機存取**|Telnet [RFC 854]|TCP| |**網頁服務**|HTTP [RFC 2616]|TCP| |**檔案傳輸**|FTP [RFC 959]|TCP| |**多媒體串流**|HTTP (e.g., Youtube)|TCP| |**網路電話**|SIP [RFC 3261], RTP [RFC 3550],或是專有軟體 (e.g., Skype)|UDP or TCP| 電子郵件、終端機存取、網頁服務及檔案傳輸都無法容忍掉包,需要可靠的資料傳輸,因此選用 TCP;而網路電話可以容忍掉包,但對於最小傳輸速率有要求,因而使用 UDP,可以規避一些 TCP 的流量控制及壅塞控制 #### Securing TCP 可以發現,原本的 TCP 是沒有加密服務的,那上傳密碼不就被看光光 * 傳輸層安全協定 Trnasport Layer Security, TLS * 提供加密的 TCP 連線 * 資料完整性 (Data Integrity) > 確保信息沒有遭竄改 * 提供端點認證 (End-point Authentication) ## Web and HTTP ### HTTP Overview 超文本傳輸協定 (HyperText Transfer Protocol, HTTP),為網頁所使用的應用層協定 * **網頁 (Web Page)**,由多個物件組成 * **物件 (Object)** 是一個簡單的檔案,例如:HTML頁面、圖片或影片。每個物件都能用一個 **URL** 來定址 * 大部分網頁都由一個 **Base HTML-file** 和多個被 **參照 (referenced)** 的物件組成 * **URL** 用以參照物件,每個 URL 都有兩個部分 * 主機名稱 (下圖的 ```www.someSchool.edu```) * 檔案路徑 (下圖的 ```someDepartment/picture.gif```) ``` http://www.someSchool.edu/someDepartment/picture.gif ``` * 網頁瀏覽器 (Web Browser) 為 HTTP 的客戶端,用來發送 **請求 (Request)**,接收並顯示網頁物件 * 網頁伺服器 (Web Server) 為 HTTP 的伺服器端,用來存放物件,並在接受到請求後發送 **回應 (Response)** ![HTTP Request and Respond](https://hackmd.io/_uploads/rJT-qBa1A.png) * HTTP 使用 TCP 協定,因此 HTTP 訊息一發送,絕對會送到對方手中,也不用擔心順序問題 * HTTP 為 **無狀態的協定 (Stateless Protocol)**,並不會記錄客戶端的狀態 > 這就是為什麼打開一個網頁用 F12 亂改後,重新整理網頁又會恢復如初 ### HTTP Connections #### 非持續性的連線 Non-persistent HTTP * 一次 TCP 連線只會傳送一個物件,因此當要下載多個物件時,就需要建立多個連線 * 假設有一個網頁由一個 base HTML file 和 10 個圖片所組成,11 個物件都放在同台主機上, base HTML file 的網址為: ``` http://www.someSchool.edu/someDepartment/home.index ``` 那整個傳輸過程就會是: 1. HTTP 客戶端的程式會要求對 `www.someSchool.edu` 這個主機發起一個 TCP 連線,指定埠號 80 > 80 為 HTTP 協定預設的埠號 2. HTTP 伺服器端回復客戶端,同意連接 3. 客戶端會透過 Socket 送出一個 **HTTP 請求訊息** 到伺服器端,請求包含 `someDepartment/home.index` 這個名稱 4. 伺服器端收到這則 HTTP 訊息後,就會找出 `someDepartment/home.index` 這個物件,將其封裝為 **HTTP 回應訊息**,再藉由 Socket 送出這則訊息回客戶端 5. 確認客戶端收到後,伺服器關閉 TCP 連線 6. 客戶端收到回應訊息,TCP 連線關閉,將回應訊息中的檔案 (HTML) 抽出來,檢查 HTML 檔案,在當中尋找到 10 個圖片的參照 7. 重複以上的動作直到取得每一個圖片 * 上述的例子中,每傳完一個物件,TCP 連線就會被關閉,因此像這次有 11 個物件要傳,就會建立 11 個 TCP 連線 * **往返時間 (Round-trip Time, RTT)**:封包由客戶端送出抵達伺服器端,再從伺服器端回來所需的時間 * 以這個例子來講,網頁的傳輸大概需要兩個 RTT 外加網頁的傳輸時間 ![Non-persistentHTTP](https://hackmd.io/_uploads/SJeCQY6yA.png) * 缺點:非持續性連線每次傳一個物件就需要一個新的 TCP 連線,而每次傳輸都要耗費兩個 RTT,非常浪費資源,因此才有下面的持續性連線 #### 持續性的連線 Persistent HTTP * 一個連線可以傳送多個物件 * 可以實現 **管線化 (Pipelining)** ### HTTP Message Format 分為請求訊息和回應訊息 #### HTTP Request Message HTTP 請求訊息: ``` GET /somedir/page.html HTTP/1.1 Host: www.someschool.edu Connection: close User-agent: Mozilla/5.0 Accept-language: fr ``` * 第一行為 **請求行 (Request Line)**,分為三個欄位: * 方法欄位:有以下幾種 * GET 從伺服器傳送資料要求 * POST 建立或取代伺服器上的資源 * HEAD 擷取伺服器的 HTTP 回應標頭 * PUT 更新伺服器上的資源 * DELETE 從伺服器中刪除資源 * URL 欄位:要請求一個物件的時候,物件的位址就會寫在 URL 欄位 * HTTP 版本號欄位 * 第二行以下都是 **標頭行 (Header Lines) * `Host: www.someschool.edu`:說名要請求的物件是被放在 `www.someschool.edu` 這個主機上 * `Connection: close`:回復這個請求後就將連線關閉 * `User-agent: Mozilla/5.0`:說明是哪種 user agent,也就是甚麼種類的瀏覽器,這個例子中,請求是由 Firefox 發出的 * `Accept-language: fr`:使用者想看到的語言 ![HTTP Request](https://hackmd.io/_uploads/HkqOPFakA.png) #### HTTP Response Message ``` HTTP/1.1 200 OK Connection: close Date: Tue, 18 Aug 2015 15:44:04 GMT Server: Apache/2.2.3 (CentOS) Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT Content-Length: 6821 Content-Type: text/html (data data data data data ...) ``` * 第一行為 **狀態行 (Status Line)**,有三個欄位 * 版本號欄位:伺服器使用 HTTP 版本號為 1.1 * 狀態碼 * 狀態訊息 :::info * 200 OK:請求成功執行,回應正常回傳 * 301 Moved Permanently:物件被移動到另一個地方了,新的 URL 會寫在標頭中 `Location:` 欄位 * 400 Bad Request:當伺服器看不懂請求時會用的錯誤碼 * 404 Not Found:請求的檔案不在這個伺服器上 * 505 HTTP Version Not Supported:請求所使用的 HTTP 版本不支援 ::: * 二到七行為 **標頭行 (Header Lines)** * `Connection: close`:告訴客戶端伺服器會把 TCP 連線關掉 * `Date: Tue, 18 Aug 2015 15:44:04 GMT`:這段回應訊息被送出的時間 * `Server: Apache/2.2.3 (CentOS)`:伺服器是 Apache 網頁伺服器 * `Last-Modified: Tue, 18 Aug 2015 15:11:03 GMT`:請求的物件最後被修改的時間 * `Content-Length: 6821`:送出的物件長度為 6821 位元組 * `Content-Type: text/html`:送出的物件是個 HTML 文字檔 > 檔案類型以標頭內的為準,而不是看副檔名 ![HTTP Response](https://hackmd.io/_uploads/B1f45KTkR.png) * 最後面為 **實體主體** ### Cookies 由於 HTTP 伺服器是無狀態的,因此要使用 Cookies 紀錄使用者 ![Cookies](https://hackmd.io/_uploads/HkNoiYpJ0.png) * Cookies 包含四個部分 1. HTTP 回應訊息中的 cookies 標頭欄位 2. HTTP 請求訊息中的 cookies 標頭欄位 3. 由瀏覽器管理的 cookies 檔案 4. 在伺服器端的資料庫 * 使用者第一次造訪某網站時,伺服器會回傳 **set-cookie** 給瀏覽器,而之後使用者發出請求時,瀏覽器就會將 cookie 加在請求的標頭內,這樣伺服器就認出該使用者 ### Web Caching * **Web 快取**,又稱 **代理伺服器 (Proxy Server)**,可以儲存最近有人存取過的網頁物件副本 * 假如一瀏覽器想請求 `http://www.someschool.edu/campus.gif`: 1. 瀏覽器建立一個通往代理伺服器的 HTTP 請求,並請求物件 2. 代理伺服器會先檢查自己有沒有該物件的副本,如果有,直接把物件回應給瀏覽器 3. 沒有的話就會開啟通往原伺服器的 TCP 連線,並請求物件 4. 當代理伺服器從原伺服器收到該物件,會先存一份副本在自己這裡,然後將副本回應給瀏覽器 * 由 ISP 購入並安裝 * 優點: 1. 大幅降低客戶端請求物件所需時間 2. 減少大型機構的接取網路與網路核心間的流量 3. 減少 Web 服務在整個網際網路中的流量 * 來看一個範例: ![](https://hackmd.io/_uploads/H1tCwq6kR.png) * 有兩個網路:大型機構的網路和公用網際網路。機構網路內部傳輸速率為 1 Gbps,機構網路的路由器和網際網路的路由器由一條傳輸速率 1.54 Mbps 的線路連接,假設一個網頁物件的大小為 100K bits,而機構網路中瀏覽器發送 HTTP 請求的平均速度為每秒 15 個請求,RTT (**網際網路延遲**) 為 2 秒,求總回應時間 > 網際網路延遲 Internet Delay:發出一個請求到收到請求的回應經過的時間 * 總回應時間 (End-end Delay) = 區域網路延遲 (LAN Delay) + 接取網路延遲 (Access Link Delay) + Internet Delay * 先計算流量強度 * 區域網路流量強度為:$$15*(100*10^3)/(1*10^9)=0.0015$$ * 接取網路流量強度為:$$15*(100*10^3)/(1.54*10^6)=0.97$$ * 我們幾乎可以忽略區域網路延遲,但是接收網路的流量強度接近 1,造成的延遲就會很大。那我們該如何解決這個問題 * 增加接取線路的頻寬,增加至 154 Mbps,這樣流量強度就變成$$15*(100*10^3)/(154*10^6)=0.0097$$但是這是一筆不小的開銷 * 因此我們可以選擇使用 Web 快取,將其安裝在機構網路裡面,如下圖 ![](https://hackmd.io/_uploads/Hkm4yi6kR.png) * 假設快取的 **命中率 (Hit Rate)** 為 0.4%,則有 40% 的請求可以由快取中取得,大約花費 10 毫秒;而另外 60% 則需要通過接取線路經由網際網路中的原伺服器來滿足 * 因為通過存取線路的流量下降至 60%,因此接取往流量強度會降低為 0.6,而 0.6 時在此線路上延遲已經變成毫秒等級 * 因此我們可以計算:$$d_{end-end-delay}=0.6*2.01+0.4*0.01=1.21secs$$ * 又快又便宜 ### The Conditional GET 當伺服器上的檔案被修改時,快取的副本還會是舊版,為了補全這個錯誤,HTTP 有個機制為 **條件請求 (Conditional GET)** * 滿足條件 1. 請求方法為 **GET** 2. 請求的標頭內有一個 `If-Modified-Since:` * 範例:當一個物件可能被修改過,當有瀏覽器請求這個物件時 1. 快取會向原伺服器發送請求: ``` GET /fruit/kiwi.gif HTTP/1.1 Host: www.exotiquecuisine.com If-modified-since: Wed, 9 Sep 2015 09:23:24 ``` `If-modified-since:` 告訴伺服器檔案如果在這個時間後有被修改,才需要傳檔案過來 2. 如果檔案沒有被修改,則回應: ``` HTTP/1.1 304 Not Modified Date: Sat, 10 Oct 2015 15:39:29 Server: Apache/1.3.0 (Unix) (empty entity body) ``` 狀態為 `304 Not Modified` 告訴快取直接使用你的副本即可 3. 如果檔案有被修改: ``` HTTP/1.1 200 OK . . . data... ``` 這時就會用新的檔案將舊的副本覆蓋,接著將副本回應給瀏覽器 ### HTTP/2 目標:希望降低具有很多物件的 HTTP 請求的延遲 * **HTTP 1.1**:一個 TCP 連線中,有多個且管線化的 GETs (持續性的連線) * 伺服器端按照順序依序回應 GET 請求 (**first-come-first-served secheduling, FCFS**) * 大物件在傳輸時,小物件就須在大物件後等待 (**head-of-line blocking, HOL**) * 萬一有封包丟失,在重傳期間傳輸會暫停 ![](https://hackmd.io/_uploads/r1jf5E0yC.png) * **HTTP/2**:降低多物件 HTTP 請求的延遲 * 請求、回應欄位均與 HTTP1.1 大致相同 * 由客戶端指定物件的優先度來決定傳輸順序 * 在客戶端還沒發送特定物件請求前,就先將該物件 **push** 給客戶端 * 將物件打包成二進位的 **訊框 (frame)**,調度每個訊框減輕 HOL blocking ![](https://hackmd.io/_uploads/HkEN5EAJ0.png) * 封包丟失時,物件的傳輸還是會暫停 * 沒有安全性保護 * **HTTP/3**:增加安全性保護、透過 UDP 來實現物件錯誤及壅塞控制 ## E-mail <img src="https://hackmd.io/_uploads/SyAyhNAyA.png" height="500"> * 三大元件 1. 使用者代理 User Agent, UA 2. 信件伺服器 Mail Server 3. 簡單郵件傳輸協定 Simple Main Transfer Protocol, SMTP ### 使用者代理 User Agent * 功能:讀、寫、轉發、儲存信件 * 寄信時,使用者代理會將信寄給信件伺服器 * 當收信時,使用者代理會從伺服器抓取信件 ### 信件伺服器 Mail Server * **信箱 (Mail Box)** 位於信件伺服器中,儲存該使用者收到的信件 * 電子郵件會經過以下路徑: 1. 寄件人的使用者代理 2. 寄件人的信箱 3. 收信人的信件伺服器 4. 收信人的信箱 * 如果送出的信件沒有成功送達,會被暫存於 **信件隊伍 (Message Queue)**,並稍後嘗試重傳 ### 簡單郵件傳輸協定 SMTP * 規範於 RFC 5321 * 使用 TCP 保證訊息能正確送達 * 埠號通常為 25 * 訊息編碼為 7-bits ASCII * 假設 Alice 要傳送 Email 給 Bob: 1. Alice 使用 UA 提供 Bob 的信箱地址 `bob@someschool.edu`,並寫了一封信寄出 2. Alice 的 UA 將信建送到她的信件伺服器,這封信被放在信件隊伍中 3. 客戶端的 SMTP 與 Bob 的信件伺服器的伺服器端 SMTP 建立 TCP 連線 4. SMTP 客戶端將 Alice 的信件送入 TCP 5. Bob 的信件伺服器上,SMTP 伺服器端收到了信件,將其放入郵箱中 6. Bob 透過 UA 閱讀信件 ![](https://hackmd.io/_uploads/ByzB7HAk0.png) * 特別注意,SMTP 不會使用中介伺服器,就算兩個信件伺服器遠在地球另一端,SMTP 還是會建立一個直通的 TCP 連線,因此如果另一端的信件伺服器未開啟,信件就需一直待在信件隊伍中等待發送 ### Comparison with HTTP * HTTP 為 Pull Protocol:TCP 連線是由收信方建立 * SMTP 為 Push Protocol:TCP 連線是由送信方建立 * SMTP 需使用 7-bits ASCII,如果出現非 7-bits ASCII 的字元,須將其重新編碼為 7-bits ASCII,而 HTTP 不需要 * HTTP 的每個物件單獨使用一個訊息傳送,而 SMTP 則將全部的訊物件放於同一條訊息內傳送 ### Mail Message Format * 規範於 RFC 5322 * 格式: * 標頭: ``` From: alice@crepes.fr To: bob@hamburger.edu Subject: Searching for the meaning of life. ``` > 所有標頭必須包含 `From:` `To:`,而 `Subject:` 不強迫 * 一行空格 * 最後為 **實體主體**,只有 ASCII 字元 ### 郵件存取協議 Mail Access Protocols 如果說 SMTP 專門用來送郵件,那我們還需要一個協議來讓收信人存取信件 * 郵局協定第 3 版 Post Office Protocol -- Version 3, POP3 UA 開啟一個通往信件伺服器的 TCP 連線 (埠號 110),當連線建立完成,執行三階段: * 身分認證:UA 必須傳送正確的使用者名稱及密碼 * 交易:獲取信件、標記刪除信件、移除標記及獲取信件統計資料 * 更新:在客戶端發出 `quit` 結束 POP3 之後觸發,信件伺服器會刪除標記的信件 * 網際網路資料存取協定 Internet Message Access Protocol, IMAP * IMAP 允許使用者在信件伺服器上創建資料夾,使其較方便管理 * 所有操作都在伺服器上完成,因此不同裝置不會有不同步的問題 * 允許使用者下載郵件的部分元素 ### Web-based Email * 網頁瀏覽器當作 UA 來使用 * 使用 HTTP 與遠端信箱通訊,讀信寄信都是,但伺服器間還是使用 SMTP ## 網域名稱系統 Domain Name System, DNS 人類喜歡用 **主機名稱 (Hostname)** 來辨認主機 `www.facebook.com` 而路由器偏好 **IP 位址** `157.240.31.35` 因此我們需要一個類似查號台的服務,而這就是 **DNS** 的用處 ### DNS RFC 1034 * 一個由 DNS 伺服器以階層式架構所組成的 **分散式資料庫 (Distributed Database)** * 一個讓所有主機能夠查詢上述分散式資料庫的應用層協定 * 提供的服務有: * 將主機名稱換成 IP 位址 瀏覽器請求 `www.someschool.edu/index.html` 時,該使用者的機器有 DNS 的客戶端 1. 瀏覽器會將 `www.someschool.edu` 傳給 DNS 客戶端 2. DNS 客戶端會發送包含主機名稱的請求到 DNS 伺服器端 3. DNS 客戶端會收到一個來自 DNS 伺服器的回應,回應中包含對應主機名稱的 IP 地址 4. 瀏覽器收到 IP 地址,就可以與 HTTP 主機建立 TCP 連線 * 主機別名 Host Aliasing * 假如一個主機名稱太長,我們就可以幫它取別名 * 而原本的名稱被稱為 **正規主機名稱 (Canonical Hostname)** * 別名則稱為 **主機別名 (Aliasing Hostname)** * 信件伺服器別名 Mail Server Aliasing * 負載分散 Load Distribution * 流量大的主機都會有許多 **副本伺服器 (Replicated Web Server)**,擁有不同的 IP 位址 * 正規主機名稱對應到的是這些副本伺服器 IP 位址的集合 > DNS 客戶端請求到對應的正規主機名稱,DNS 伺服器會回應整個 IP 地址的集合,並將集合順序輪轉一格。因為瀏覽器使用的都會是集合中的第一個,因此這樣能夠分散流量的效果 ### Overview of How DNS Works #### A Distributed, Hierarchical Database ![](https://hackmd.io/_uploads/rJNu8OA1C.png) * DNS 伺服器可以分成三類 * 根域名 DNS 伺服器 Root DNS Server * 如果其他 DNS 伺服器無法解析的主機名稱,就會送到這裡來 * DNSSEC:提供安全性 * 由 **ICANN (Internet Corporation for Assigned Names and Numbers)** 所管理 * 頂級域名 DNS 伺服器 Top-level Domain (TLD) DNS Server * 所有的頂級域名或是國家域名 `.com` `.org` `.tw` `.jp` 等,都有一個對應的 TLD 伺服器 * 權威域名 DNS 伺服器 Authoritative DNS Server * 想在網際網路上提供公開存取的主機的組織,要提供自己的主機名稱對應到的 IP 位址,權威域名伺服器就是用來存儲這些資訊的 * 他們可以選擇自行實作權威域名伺服器,或是外包給其他服務商 * 本地 DNS 伺服器 Local DNS Server * 不嚴格屬於上面那幾類 * 每一個 ISP 都有自己專屬的本地伺服器 > 又稱 **預設域名伺服器 (Default Name Server)** * 當有主機送出 DNS 查詢時,會先經過本地伺服器,會由這個機器作為代理,將請求轉發到上面提到的幾種伺服器 ![](https://hackmd.io/_uploads/HJuwX9RkA.png) * 查詢順序範例:假設 `cse.nyu.edu` 想要查詢 `gaia.cs.umass.edu` 的 IP 位址,而本地 DNS 主機名稱為 `dns.nyu.edu` 且負責 `gaia.cs.umass.edu` 的權威域名 DNS 主機名稱為 `dns.umass.edu` 1. `cse.nyu.edu` 會先往 **本地** 伺服器 `dns.nyu.edu` 送出請求,請求內容包含 `gaia.cs.umass.edu` 2. **本地** 會將請求轉達至 **根域名** 伺服器 3. **根域名** 就會根據 `.edu` 而回傳負責 `.edu` 的 **頂級域名** 伺服器列表 4. **本地** 隨機挑選一個 **TLD** 並將原本的請求發送過去 5. **TLD** 根據 `umass.edu` 傳回麻薩諸塞大學 (UMASS) 的 **權威域名** 伺服器的 IP 位址 `dns.umass.edu` 6. **本地** 將請求發到 `dns.umass.edu` 7. **權威域名** 就會將 `gaia.cs.umass.edu` 的 IP 地址回傳到 **本地** 8. **本地** 再將結果回傳給 `cse.nyu.edu` * 以上的例子使用了 **迭代查詢 (Iterative Query)** 與 **遞迴查詢 (Recrusive Query)** * 迭代查詢:回應直接傳給請求的主機 > 「我不知道欸,你可以問他」 > 上個例子的 (2, 3), (4, 5), (6, 7) * 遞迴查詢:被請求的主機幫忙尋問其他主機去找到結果 > 「我不知道欸,但我可以幫你問」 > 上個例子的 (1, 8) #### DNS Cashing * 每當一個 DNS 伺服器收到一個回應,就可以將其對應表存入自身的記憶體中,下次有人來問就可以直接回答 * 能讓大部分 DNS 請求跳過根域名伺服器 ### DNS Records and Messages DNS 資料庫中,儲存了 **資源紀錄 (Resource Records, RRs)** * RRs 由四個元組組成: ``` (Name, Value, Type, TTL) ``` > TTL:該紀錄的存活時間,紀錄什麼時候這筆資料要從快取中刪除 * `Type=A` 時,`Name` 為主機名稱,`Value` 為 IP 位址 * `Type=NS` 時,`Name` 為網域名稱,`Value` 為該網域的權威域名 DNS 伺服器的主機名稱 * `Type=CNAME` 時,`Name` 為某個主機的別名,`Value` 為其正規名稱 * `Type=MX` 時,`Name` 為某信件伺服器的別名,`Value` 為其正規名稱 ### DNS Messages DNS只有兩種訊息:**詢問 (Query)** 及 **回應 (Reply)**,兩者格式一模一樣 ![](https://hackmd.io/_uploads/S1FkTqRyA.png) * 前面 12 Byte 為標頭區段 (Header Section): * 識別碼 (Identification),為 16-bit 的數字,會被複製到該詢問的回應上,讓客戶端辨別該回應是對應到哪個詢問 * 旗標欄位 (Flags), * 1-bit 標示訊息是詢問 (0) 或是回應 (1) * 1-bit 回應的 DNS 伺服器是權威域名時為 1 * 1-bit 當客戶端請求希望使用遞迴查詢時設定為 1 * 1-bit 收到請求的 DNS 主機支持遞迴查詢時,回應時會設定為 1 * 問題區段 (Question Section) * 一個 name 欄位,代表所詢問的主機名稱 * 一個 type 欄位,代表欲查詢的紀錄為哪種類型 * 回答區段 (Answers Section) * 包含原本查詢的名字的 RRs * 權威區段 (Authority Section) * 包含其他權威域名伺服器的紀錄 * 備註區段 (Additional Section) * 提供有用信息 ### Inserting Records into DNS Database * 域名註冊商 DNS register 負責驗證域名的獨一性、把域名輸入資料庫 * 例:我們現在要向域名註冊商註冊 `networkutopia.com` 這個網域名稱 1. 要向註冊商報備主要及次要的權威域名伺服器的主機名稱和 IP 位址 > 假設主機名稱為`dns1.networkutopia.com` `dns2.networkutopia.com` > 對應的 IP 位址為 `212.212.212.1` `212.212.212.2` 2. 將以下資訊註冊到 DNS 系統中 ``` (networkutopia.com, dns1.networkutopia.com, NS) (dns1.networkutopia.com, 212.212.212.1, A) ``` ## Peer-to-peer File Distribution * 沒有保持開啟的伺服器,只有斷斷續續連線的主機,這些主機我們稱之為 **Peer** * 相比於主從式有一個固定 IP 的伺服器,P2P 之間都是使用浮動 IP * P2P 相較主從式架構有更好的 **自擴展性 (Self Scalability)**,每多一個新的 peer,就能帶來更好的服務能力 * 假設一台伺服器要向大量的主機分享大型檔案,如果使用主從式架構,伺服器就需要親自將每個檔案送到每個主機上,容易造成伺服器的負擔 * 在這個情況下使用 P2P,每個 peer 都可以把自己手上的檔案分享給其他 peer,而收到的 peer 再將檔案分享給其他 peer,這樣伺服器的負擔就會相對較小 * 舉例來說:假設有個伺服器和 N 個 peers 都透過接取線路連接到網際網路上,現在伺服器要將一份大小為 F bits 的檔案送給所有的 peers,我們將伺服器的上傳速率設為 $u_{s}$,第 $i$ 個 peer 的上傳速率與下載速率分別為 $u_{i}$ 和 $d_{i}$ * 先來計算主從式架構的傳送時長,將其計為 $D_{cs}$ * 由於不會有任何 peer 幫忙傳遞,所以伺服器總共要上傳 $NF$ bits,因此上傳需要花費 $NF/u_{s}$ 秒 * 接下來我們再取得下載最慢的機器會花費多少時間:$F/min\{d_{1}, d_{2}...d_{N}\}=F/d_{min}$ * 考慮以上兩點,我們可以得到:$$D_{cs}\geq max\{\frac{NF}{u_{s}}, \frac{F}{d_{min}}\}$$ * 我們可以看到,N 越大,所需要花費的時間也會劇烈增加 * 接下來使用 P2P 的方式,將其計為 $D_{P2P}$ * 首先,伺服器要先上傳檔案到整個 peers 系統裡面:$F/u_{s}$ 秒 > 不一定要傳第二次,因為 peers 之間會幫忙傳遞 * 我們一樣要考慮下載最慢的機器所花的時間:$F/min\{d_{1}, d_{2}...d_{N}\}=F/d_{min}$ 秒 * 如果我們將整個系統視為一體,則系統的上傳速率會等於伺服器的上傳速率加上所有 peers 的上傳速率,而總共要上傳 $NF$ 個 bits,因此最小傳遞時長為 $NF/(u_{s}+u_{1}+u_{2}+...+u_{N})=NF/u_{s}+\sum_{i=1}^N u_{i}$ 秒 * 考慮以上三點,我們可以得到:$$D_{P2P}=max\{\frac{F}{u_{s}}, \frac{F}{d_{min}}, \frac{NF}{u_{s}+\sum_{i=1}^N u_{i}}\}$$ ![](https://hackmd.io/_uploads/ByX2sTRyC.png) ### BitTorrent 檔案傳輸用的 P2P 協議 * **Torrent**:共同參與傳遞檔案的 peers 的集合 * **Tracker**:用來跟蹤 Torrent 裡面的 peers * 通常會把一個大檔案拆成一個個 **Chunk**,一個 Chunk一般來說是 256KB * 簡單來說: * 當一個 peer 剛加入一個 torrent 時: * 先向 tracker 註冊,並且定期告訴它自己還在裡面 * 嘗試與所有 peer 建立 TCP 連線,順利連接的 peer 我們稱為 **鄰接 (Neighboring Peers)** > 隨著時間經過,會有其他 peers 想要與我們建立 TCP 連線,因此一個鄰接會是浮動的 * 下載進行中: * 每個 peer 都會擁有目標檔案的 chunk,我們會定期向鄰接的 peers 要求他們擁有的 chunk 列表,這樣就知道缺哪個 chunk 要向誰發送請求 > 通常會 **先拿最稀有的** * 當收到請求時,會先優先回覆*提供他資料速率最快的鄰居* * 假如說挑出最快的四個鄰居,我們會傳送 chunk 給他們 * 每 10 秒鐘會重新測一次速率 * 這些人被稱為 **unchocked** * 每隔 30 秒,會隨機選擇一個鄰居並傳送 chunk 給他 * 我們稱這個人為 **optimistically unchoked** ## Video Streaming and Content Distribution Networks ### Internet Video * 影片 Video:一連串的照片,以固定的 **幀率 (frame rate)** 進行播放 * **位元速率**:影片位元速率愈高,畫質愈好 > 100kbps 低畫質 > 3Mbps 高畫質 ### DASH Dynamic, Adaptive Streaming over HTTP * 伺服器將影片分成一個個資料塊 * **清單檔案 (manifest file)**:記錄每一個資料塊的位置 * 持續監控使用者的流量速度,決定一個適合使用者的檔案 (解析度) ### Content Distribution Network, CDN 我們該如何串流影片同時送給數百萬個使用者? * 建立一個大型資料中心? * 如果客戶端很遠,就會導致延遲 * 同一個影片可能在一條線路被傳送了很多次 * 單一資料中心會有單點故障問題 * 因此我們會使用 **內容傳遞網路 (CDN)** 來實現 * CDN 通常會遵循以下兩個原則: * Enter Deep:伺服器部屬到世界各地,盡可能接近使用者 * Bring Home:將伺服器部屬於網際網路交換中心 (IXP) ### CDN Operation 使用者透過瀏覽器請求下載某影片時,CDN 會將請求攔截下來以決定: 1. 使用哪個伺服器來服務這個客戶端 2. 將該請求導向到適合的伺服器