去年十一月,我第一次參加了 IETF 會議。IETF 是個有趣的地方;似乎有三分之一是維護的雜事,三分之一是擴展現有技術,還有三分之一是異想天開的瘋狂想法。我參加主要是因為想看看大家對 TCP BBR 的反應,當時它在那裡首次亮相。(回應:大多是正面的,但帶有懷疑。感覺好得有點不真實。)
總之,IETF 會議中有大量關於 IPv6 的演講,這個本應取代 IPv4 的協議,而 IPv4 才是網際網路的基礎。(有些人會說 IPv4 已經被取代;有些人會說這已經發生了。)伴隨著這些關於 IPv6 的演講,還有許多人認為它很棒,是有史以來最偉大的發明,他們確信它「任何一天」都會流行起來,而 IPv4 只是需要被淘汰的巨大漏洞集合,以便網際網路能再次變得優雅。
我認為這是一個真正弄清楚到底發生了什麼的好機會。為什麼 IPv6 與 IPv4 相比如此複雜混亂?如果它只是 IPv4 加上更多位址位元,會不會更好?但它不是,哦天啊,它一點也不是。所以我開始四處詢問。以下是我發現的。
很久以前,有電話網路,它使用實體電路交換。本質上,這意味著移動連接器,讓你的電話連接實際上只是一條非常長的線路(「OSI 層 1」)。「租用線路」是你從電話公司租用的一條非常長的線路。你在線路的一端輸入位元,它們會在稍後的時間出現在另一端。你不需要位址,因為每端只有一台機器。
最終,電話公司對此進行了一些優化。時分多工(TDM)和「虛電路交換」誕生了。電話公司可以透明地從多條線路接收較低位元率的位元,將它們與多工器和解多工器組合在一起,讓它們通過電話系統的中間部分,使用比以前更少的線路。這項工作有點複雜,但對我們這些撥接用戶來說,你仍然是在一端輸入位元,它們會在另一端出現。不需要位址。
網際網路(當時還不叫網際網路)建立在這些電路之上。你有一堆線路,可以將位元輸入其中,然後在另一端取出。如果一台電腦有兩個或三個介面,那麼它就可以,如果給予正確的指令,將位元從一條線路轉發到另一條線路,這樣你就可以做一些比每對電腦之間單獨的線路更有效率的事情。於是 IP 位址(「層 3」)、子網路和路由就誕生了。即使在那時,對於這些點對點鏈路,你也不需要 MAC 位址,因為一旦封包進入線路,它就只有一個地方可以出來。你使用 IP 位址來決定之後要去哪裡。
同時,區域網路(LAN)被發明出來作為一種替代方案。如果你想在本地連接電腦(或終端機和主機),為每條到衛星電腦的線路配備多個介面,並以星狀配置排列,那會非常不方便。為了節省電子設備,人們想要一個「匯流排」網路(也稱為「廣播網域」,這個名稱稍後會很重要),其中多個站點可以插入單一線路,並與連接到同一線路的任何其他站點通信。這些人與構建網際網路的人不是同一批人,所以他們沒有為此使用 IP 位址。他們都發明了自己的方案(「層 2」)。
早期的區域匯流排網路之一是 arcnet,這讓我懷念(我在 1990 年代寫了第一個 Linux arcnet 驅動程式和 arcnet 詩歌,那時 arcnet 已經過時了)。Arcnet 層 2 位址非常簡單:只有 8 位元,由網路卡背面的跳線開關或 DIP 開關設定。作為網路擁有者,你的工作是配置位址並確保沒有重複,否則就會發生混亂。這有點麻煩,但 arcnet 網路通常很小,所以只是有點麻煩。
幾年後,乙太網路出現了,並通過使用更多的位元(事實上是 48 位元)作為層 2 位址,一勞永逸地解決了這個問題。這足夠多的位元,你可以為製造的每個設備分配一個不同的(分段順序)位址,並且不會有任何重疊。這正是他們所做的!因此,乙太網路 MAC 位址誕生了。
各種區域網路技術來來去去,包括我最喜歡的 IPX(網際網路封包交換,雖然它與「真正的」網際網路無關)和 Netware,只要所有客戶端和伺服器都在單一匯流排網路上,它們就能正常工作。你從來不需要配置任何位址。它很美觀、可靠,而且有效。基本上是網路的黃金時代。
當然,有人必須搞砸它:大型公司/大學網路。他們想要如此多的電腦,以至於在它們之間共享 10 Mbps 的單一匯流排網路成為巨大的瓶頸,所以他們需要一種方法來擁有更多的匯流排,然後互連——如果你願意的話——這些匯流排。「網際網路互連」。你可能會想,當然!使用網際網路協議來做到這一點,對吧?哈哈,不。網際網路協議,當時還不叫這個名字,還不成熟或不受歡迎,而且沒有人認真對待它。Netware-over-IPX(以及當時的許多其他區域網路協議)是認真的業務,所以就像認真的企業一樣,他們發明了自己的東西來擴展已經流行的東西,乙太網路。乙太網路上已有的設備有位址,MAC 位址,這是各種區域網路協議人員唯一能達成一致的項目,所以他們決定使用乙太網路位址作為其路由機制的金鑰。(實際上他們稱之為橋接和交換,而不是路由。)
乙太網路位址的問題在於它們是按順序在工廠分配的,所以它們不能是層級式的。這意味著「橋接表」不像現代 IP 路由表那樣好,後者可以一次處理整個子網路的路由。為了實現高效的橋接,你必須記住每個 MAC 位址可以在哪個網路匯流排上找到。人類不想手動配置每一個,所以它需要自動找出答案。如果你有一個複雜的橋接網際網路互連,這可能會變得有點複雜。據我所知,這就是導致生成樹詩歌的原因,我想我就到此為止。詩歌在網路中非常重要。
總之,它大部分情況下是有效的,但有點混亂,而且偶爾會出現廣播洪水,路由也不總是最佳的,而且幾乎不可能除錯。(你絕對無法編寫類似 traceroute 的東西來進行橋接,因為製作它所需的所有工具——例如中間橋接器甚至擁有位址的能力——在純乙太網路上都不存在。)
另一方面,所有這些橋接器都是硬體優化的。整個系統基本上是由硬體人員發明的,作為一種欺騙軟體的方法,軟體對多個匯流排和它們之間的橋接一無所知,以便在大型網路上更好地工作。硬體橋接意味著橋接可以非常非常快——快到乙太網路的速度。現在聽起來沒什麼特別的,但當時這是一件大事。乙太網路是 10 Mbps,因為你可能通過將大量電腦同時連接到網路上來使其飽和,而不是因為任何一台電腦都能使 10 Mbps 飽和。那是瘋狂的想法。
總之,重點是,橋接很混亂,而且無法除錯,但它很快。
在所有這些事情發生的同時,那些網際網路人員變得非常忙碌,當然也沒有對發明酷炫的廉價區域網路技術視而不見。我認為 ARPANET 可能在這個時候被正式更名為網際網路,但我不確定。讓我們假設是這樣,因為如果我聽起來自信,這個故事會更好。
在某個時候,事情從通過點對點長距離鏈路連接單獨的網際網路電腦,發展到希望通過點對點鏈路連接整個區域網路。基本上,你需要一個長距離橋接器。
你可能會想,嘿,這沒什麼大不了的,為什麼不乾脆製作一個長距離橋接器然後就結束了呢?聽起來不錯,但行不通。我現在不深入細節,但基本上問題是擁塞控制。乙太網路橋接的深層黑暗秘密是它假設你所有的鏈路速度都差不多,並且/或者完全沒有擁塞,因為它們沒有辦法減速。你只是盡可能快地發送數據,並期望它能到達。但是當你的乙太網路是 10 Mbps 而你的點對點鏈路是 0.128 Mbps 時,那就完全沒希望了。另外,通過廣播所有鏈路來找出正確路由的想法——這實際上是橋接通常的工作方式——對於慢速鏈路來說是極大的浪費。在低延遲和高吞吐量的本地網路上,次優路由只是一個煩惱,但在慢速、昂貴的長距離鏈路上卻很糟糕。它根本無法擴展。
幸運的是,那些網際網路人員(如果當時已經稱為網際網路的話)一直在研究這些確切的問題。如果我們能使用網際網路的東西來連接乙太網路匯流排,我們就會處於有利地位。
於是他們設計了一種用於乙太網路(以及 arcnet,還有其他各種區域網路)上網際網路封包的「幀格式」。
這就是一切開始出錯的時候。
第一個需要解決的問題是,現在,當你將網際網路封包放入線路時,就不再清楚哪個機器應該「聽到」它並可能將其轉發。如果多個網際網路路由器位於同一個乙太網路網段上,你不能讓它們都接收並嘗試轉發;那樣就會導致封包風暴和路由迴圈。不,你必須選擇乙太網路上哪個路由器應該接收它。我們不能僅僅使用 IP 目的地位址來做到這一點,因為我們已經將它用於最終目的地,而不是路由器目的地。相反,我們使用乙太網路幀中的 MAC 位址來識別所需的路由器。
所以基本上,要設置你的本地 IP 路由表,你想說類似「通過 MAC 位址為 11:22:33:44:55:66 的路由器發送 IP 位址為 10.1.1.1 的封包。」這才是你真正想表達的。這很重要!你的目的地是一個 IP 位址,但你的路由器是一個 MAC 位址。但是,如果你配置過路由表,你可能會注意到沒有人這樣寫。相反,因為你的作業系統的 TCP/IP 堆疊的作者很固執,你會寫類似「通過 IP 位址為 192.168.1.1 的路由器發送 IP 位址為 10.1.1.1 的封包。」
實際上,這只是在使事情複雜化。現在你的作業系統必須首先查找 192.168.1.1 的乙太網路位址,找出它是 11:22:33:44:55:66,然後生成一個目的乙太網路位址為 11:22:33:44:55:66 和目的 IP 位址為 10.1.1.1 的封包。192.168.1.1 在封包中沒有出現;它只是人類層級的抽象。
為了完成這個毫無意義的中間步驟,你需要添加 ARP(位址解析協議),一個簡單的非 IP 協議,它的工作是將 IP 位址轉換為乙太網路位址。它通過向本地乙太網路匯流排上的所有人廣播來做到這一點,要求他們回答是否擁有該特定 IP 位址。如果你有橋接器,它們都必須將所有 ARP 封包轉發到它們的所有介面上,因為它們是乙太網路廣播封包,這就是廣播的含義。在一個大型、繁忙的乙太網路上,有許多互連的區域網路,過多的廣播開始成為你最大的噩夢之一。在 Wi-Fi 上尤其糟糕。隨著時間的推移,人們開始製作帶有特殊技巧的橋接器/交換機,以避免將 ARP 廣播到技術上應該去的所有地方,試圖減少這個問題。有些設備(尤其是 Wi-Fi 接入點)只是製作假的 ARP 回應來試圖提供幫助。但做任何這些都是一個 hack,儘管有時是必要的 hack。
時間流逝。最終(這實際上花費了相當長的時間),人們幾乎完全停止在乙太網路上使用非 IP 協議。所以基本上所有網路都變成了一個實體線路(層 1),匯流排上有許多站點(層 2),多個匯流排通過橋接器互連(抓到了!仍然是層 2!),然後這些匯流排通過 IP 路由器互連(層 3)。
過了一段時間,人們厭倦了手動配置 IP 位址(像 arcnet 那樣),並希望它們能自動配置(像乙太網路那樣),只是因為 a) 設備已經用乙太網路位址製造,而不是 IP 位址,b) IP 位址只有 32 位元,不足以永遠製造而沒有重疊,以及 c) 僅按順序分配 IP 位址而不是使用子網路會讓我們回到原點:這將再次變成乙太網路,而我們已經有了乙太網路,所以已經太晚了,無法真正像乙太網路那樣做。
所以這就是 bootp 和 DHCP 的來源。順便說一句,這些協議有點像 ARP 那樣特殊(除了它們假裝不特殊,技術上是 IP 封包)。它們必須是特殊的,因為一個 IP 節點必須能在它還沒有 IP 位址之前傳輸它們,這當然是不可能的,所以它只是用基本上是無意義的內容填充 IP 頭部(儘管是 RFC 指定的無意義內容),所以頭部就好像可以省略一樣。(你知道這些「IP」頭部是無意義的,因為 DHCP 伺服器必須打開一個原始套接字並手動填充它們;核心 IP 層無法做到。)但是沒有人會覺得發明一個不是 IP 的全新協議會感覺良好,所以他們假裝它是 IP,然後他們感覺良好。嗯,感覺好得不能再好了,當你正在發明 DHCP 的時候。
總之,我離題了。這裡的關鍵細節是,與真正的 IP 服務不同,bootp 和 DHCP 需要了解乙太網路位址,因為畢竟,它們的工作是接收你的乙太網路位址並為你分配一個 IP 位址。它們基本上是 ARP 的反向,但我們不能這麼說,因為有一個協議叫做 RARP,它字面上是 ARP 的反向。實際上,RARP 工作得很好,並且在比 bootp 和 DHCP 簡單得多的同時做了同樣的事情,但我們不談論它。
這一切的重點是,乙太網路和 IP 越來越緊密地交織在一起。如今它們幾乎密不可分。很難想像一個網路介面(除了 ppp0)沒有 48 位元的 MAC 位址,也很難想像那個網路介面沒有 IP 位址也能工作。你使用 IP 位址編寫你的 IP 路由表,但當然你知道當你用 IP 位址命名路由器時你在撒謊;你只是間接表示你想通過 MAC 位址路由。還有 ARP,它被橋接但又不是真的,還有 DHCP,它是一個 IP 封包但實際上是一個乙太網路協議,等等。
此外,我們仍然同時擁有橋接和路由,隨著區域網路和網際網路的日益複雜,它們各自也變得越來越複雜。橋接仍然主要是基於硬體的,並由 IEEE 定義,IEEE 是控制乙太網路標準的人。路由仍然主要是基於軟體的,並由 IETF 定義,IETF 是控制網際網路標準的人。兩組人仍然試圖假裝對方不存在。網路運營商基本上根據他們希望的速度有多快以及他們有多討厭配置 DHCP 伺服器(他們真的非常討厭)來選擇橋接與路由,這意味著他們盡可能多地使用橋接,並在必要時使用路由。
事實上,橋接已經變得完全失控,以至於人們決定將層 2 橋接決策完全提取到一個更高的層級(當然,使用基於 IP 的協議交換橋接器之間的配置!),以便它可以被集中管理。這就是所謂的軟體定義網路(SDN)。與讓你的交換機和橋接器隨心所欲相比,它幫助很大,但它本質上也很愚蠢,因為你知道什麼是軟體定義網路嗎?IP。它字面上就是,而且一直是我們用於互連過於龐大的網路的軟體定義網路。但問題是,IPv4 最初太難以硬體加速,而且無論如何,它沒有得到硬體加速,配置 DHCP 確實是一個巨大的麻煩,所以網路運營商只是學會了如何橋接越來越大的東西。如今,大型數據中心基本上都是 SDNed,在數據中心裡使用 IP 幾乎沒有意義,因為沒有人在路由封包。它基本上就是一個巨大的虛擬匯流排網路。
很棒的故事,對吧?對。現在假裝所有這些都沒有發生,我們回到了 1990 年代初期,那時大部分事情實際上已經發生了,但 IETF 的人們仍然假裝沒有發生,並且可以避免「即將到來」的災難。這是好部分!
有一件事我在上面那個冗長的故事中忘了提:在整個事件鏈中,我們完全停止使用匯流排網路了。乙太網路實際上不再是匯流排了。它只是假裝是匯流排。基本上,我們無法讓乙太網路著名的 CSMA/CD 在速度提高時繼續工作,所以我們回到了老式的星狀拓撲。我們從交換機運行電纜束,以便我們可以從每個站點運行一條電纜回到中心點。牆壁、天花板和地板充滿了大型、厚實、昂貴的乙太網路線束,因為我們無法弄清楚如何在第一層讓匯流排正常工作……這有點好笑,如果你想想的話。如果你覺得悲傷的事情很有趣。
事實上,在一個額外的瘋狂舉動中,即使是 Wi-Fi——終極匯流排網路,對吧,字面上每個人都在共享同一個開放的「匯流排」——我們幾乎普遍使用 Wi-Fi 的一種模式,稱為「基礎設施模式」,它模擬了一個巨大的星狀拓撲。如果你有兩個連接到同一個接入點的 Wi-Fi 站點,它們不會直接通信,即使它們都能很好地聽到對方。它們將封包發送到接入點,但目標是另一個節點的 MAC 位址。然後接入點將其彈回給目標節點。
等等,讓我為你審查一下。那裡有一個小陷阱。當節點 X 想通過 IP 路由器 Y,通過 Wi-Fi 接入點 A,發送給網際網路節點 Z 時,封包看起來是什麼樣的?為了畫個圖,這就是我們希望發生的情況:
Z 是 IP 目的地,所以顯然 IP 目的地欄位必須是 Z。Y 是路由器,我們上面學到的是,我們通過在乙太網路目的地欄位中使用它的乙太網路 MAC 位址來指定它。但在 Wi-Fi 中,X 無法直接發送封包給 Y,原因有很多(包括它們不知道彼此的 WPA2 加密金鑰)。我們必須發送給 A。你可能會問,我們把 A 的位址放在哪裡?
沒問題!802.11 有一個叫做 3 位址模式的東西。它們在每個幀中添加第三個乙太網路 MAC 位址,以便它們可以談論實際的乙太網路目的地和中間乙太網路目的地。此外,還有稱為「to-AP」和「from-AP」的位元欄位,它們告訴你封包是從站點到 AP,還是從 AP 到站點。但實際上它們可以同時為真,因為這就是你如何製作 Wi-Fi 中繼器(AP 發送封包給 AP)。
說到 Wi-Fi 中繼器!如果 A 是中繼器,它必須沿途發送回基地台 B,這看起來像這樣:
X->A 使用三位址模式,但 A->B 有一個問題:乙太網路來源位址是 X,乙太網路目的地位址是 Y,但實際在空中傳輸的封包是從 A 發送到 B;X 和 Y 完全不involved。足夠說的是,有一個叫做 4 位址模式的東西,它的工作方式和你想像的差不多。
(在 802.11s 網狀網路中,有一個 6 位址模式,這就是我放棄理解的地方。)
Avery,我被承諾了 IPv6,你甚至還沒提到 IPv6
哦,糟糕。這篇文章有點失控了,不是嗎?
這就是整個重點。IETF 的人們,當他們考慮 IPv6 時,看到了這個混亂的產生——也許預測到了一些額外的混亂會發生,儘管我懷疑他們能預測到 SDN 和 Wi-Fi 中繼器模式——他們說,嘿,等一下,就到這裡為止。我們不需要這些爛東西!如果世界是這樣運作的,會怎麼樣?
想像一下,我們生活在這樣一個世界裡:Wi-Fi 中繼器將只是 IPv6 路由器。Wi-Fi 接入點也是。乙太網路交換機也是。SDN 也是。ARP 風暴將消失。「IGMP 窺探橋接器」將消失。橋接迴圈將消失。每個路由問題都可以通過 traceroute 解決。最重要的是,我們可以從每個乙太網路封包中刪除 12 個位元組(來源/目的地乙太網路位址),從每個 Wi-Fi 封包中刪除 18 個位元組(來源/目的地/AP 位址)。當然,IPv6 比 IPv4 增加了 24 個位元的位址,但你刪除了 12 個位元的乙太網路,所以增加的開銷只有 12 個位元——與使用兩個 64 位元 IP 位址但必須保留乙太網路頭部相比,非常接近。我們可以有一天刪除乙太網路位址的想法有助於證明過大的 IPv6 位址是合理的。
這本來會很美好。除了一個問題:這從未發生。
我工作中的一個人說得最好:「層級只會增加,從來不會減少。」
所有這些美妙的東西都依賴於能夠重新開始並拋棄我們已經建立的遺留垃圾。不幸的是,這幾乎是不可能的。即使 IPv6 的普及率達到 99%,這也不意味著我們將擺脫 IPv4。如果我們沒有擺脫 IPv4,我們就不會擺脫乙太網路位址或 Wi-Fi 位址。如果我們必須保留 IEEE 802.3 和 802.11 幀標準,我們就永遠無法節省那些位元組。所以我們將永遠需要「IPv6 鄰居發現」協議,它只是比 ARP 更複雜。即使我們不再有匯流排網路,我們也將永遠需要某種廣播模擬器,因為 ARP 就是這樣工作的。我們將需要在家裡繼續運行本地 DHCP 伺服器,以便我們過時的 IPv4 燈泡能夠繼續工作。我們將繼續需要 NAT,以便我們過時的 IPv4 燈泡能夠繼續連接到網際網路。
這還不是最糟的。最糟的是我們仍然需要層 2 橋接這個無限的怪物,因為 IPv6 團隊又犯了一個錯誤。不幸的是,當他們在 1990 年代暢想 IPv6 時,他們忽略了解決「移動 IP」問題。據我所知,這個想法是先部署 IPv6——這應該只需要幾年——然後在 IPv4 和 MAC 位址被消除之後再處理它,那時應該更容易解決,而且在此期間,反正沒有人真正擁有「移動 IP」設備。我的意思是,那甚至意味著什麼,比如帶著你的筆記型電腦四處走動,然後連接到一系列乙太網路埠,同時 ftp 一個文件?聽起來很蠢。
當然,經過幾十年的歷史,現在我們知道了一些關於帶著電腦(你的手機)四處走動並讓它連接到一個又一個無線接入點的用例。我們經常這樣做。而且對於 LTE 來說,它甚至大部分情況下都能正常工作!對於 Wi-Fi,有時也能工作。很好,對吧?
不太好,因為網際網路的秘密恥辱:所有這些東西之所以能工作,都是因為層 2 橋接。網際網路路由根本無法處理移動性。如果你在 IP 網路上移動,你的 IP 位址會改變,這會破壞你所有打開的連接。
企業 Wi-Fi 網路為你偽造它,在層 2 上橋接它們的整個 LAN,這樣中央 DHCP 伺服器無論你連接哪個企業 Wi-Fi 接入點,都會給你相同的 IP 位址,然後將你的封包傳送給你,最多只有幾秒鐘的混亂,而橋接器會重新配置。那些帶有多個擴展器/中繼器的新式家庭 Wi-Fi 系統也做同樣的事情。但是,如果你在街上從一個 Wi-Fi 網路切換到另一個——比如有一個「公共 Wi-Fi」服務在一系列商店裡——好吧,太糟糕了。每一個都會給你一個新的 IP 位址,每次你的 IP 位址改變時,你都會終止所有連接。
LTE 甚至更努力。即使你旅行了數英里並在眾多蜂窩塔之間切換,你仍然保留你的 IP 位址(通常是移動網路情況下的 IPv6 位址)。怎麼做?嗯……它們通常只是將你的所有流量隧道傳輸回一個中央位置,在那裡所有流量都被橋接在一起(儘管有很多防火牆),形成一個超級巨大的虛擬層 2 LAN。你的連接得以繼續。代價是大量的複雜性,以及令人尷尬的額外延遲,它們非常想解決,但幾乎不可能。
所以,這是一個很長的故事,但我最終從那些 IETF 人員那裡提取了它。當我們談到這一點時——移動 IP 的問題——我忍不住問。出了什麼問題?為什麼我們無法讓它工作?
答案出乎意料地簡單。偉大的設計缺陷在於如何定義著名的「4 元組」(來源 IP、來源埠、目的 IP、目的埠)。我們使用 4 元組來識別給定的 TCP 或 UDP 會話;如果一個封包具有相同的四個欄位,那麼它就屬於給定的會話,我們可以將其傳遞給處理該會話的任何套接字。但是 4 元組跨越了兩個層級:網際網路互連(層 3)和傳輸(層 4)。如果我們改為僅使用層 4 數據來識別會話,那麼移動 IP 就可以完美工作。
讓我們快速舉個例子。X 埠 1111 與 Y 埠 80 通信,所以它發送一個帶有 4 元組(X,1111,Y,80)的封包。響應回來時帶有(Y,80,X,1111),核心將其傳遞給生成原始封包的套接字。當 X 發送更多標記為(X,1111,Y,80)的封包時,Y 會將它們全部傳遞給同一個伺服器套接字,依此類推。
然後,如果 X 的 IP 位址發生變化,它會得到一個新名稱,比如 Q。現在它將開始發送帶有(Q,1111,Y,80)的封包。Y 不知道那是什麼意思,並將其丟棄。同時,如果 Y 發送標記為(Y,80,X,1111)的封包,它們就會丟失,因為不再有 X 來接收它們。
現在想像一下,我們在沒有參考 IP 位址的情況下標記了套接字。為了讓它工作,我們需要更大的埠號(目前是 16 位元)。讓我們把它們設為,比如說,128 或 256 位元,某種唯一的雜湊。
現在 X 向 Y 發送標記為(uuid,80)的封包。請注意,封包本身仍然包含(X,Y)的位址資訊,在層 3 的位置——這就是它們如何被路由到正確機器的原因。但是核心不使用層 3 資訊來決定傳遞到哪個套接字;它只使用 uuid。目的埠(在此例中為 80)僅用於啟動新會話,以識別你要連接的服務,之後可以忽略或省略。
對於返回方向,Y 的核心會緩存這樣一個事實:針對(uuid)的封包會發送到 IP 位址 X,這是它最近收到(uuid)封包的位址。它會將返回封包發送到 X。
現在想像一下 X 將位址更改為 Q。它仍然向 IP 位址 Y 發送標記為(uuid,80)的封包,但現在這些封包來自位址 Q。在機器 Y 上,它接收封包並將其與與(uuid)關聯的套接字匹配,注意到發往該套接字的封包現在來自位址 Q,並更新其緩存。它的返回封包現在可以發送,標記為(uuid),發送到 Q 而不是 X。一切都正常工作!(儘管需要一些小心來防止冒名頂替者劫持連接。2)
只有一個問題:UDP 和 TCP 並非如此工作,而且現在更新它們已經太晚了。更新 UDP 和 TCP 就像將 IPv4 更新到 IPv6 一樣;一個聽起來很簡單的項目,在 1990 年代,但幾十年後,才完成不到一半(而且前半部分是簡單的部分;長尾部分要困難得多)。
好消息是,我們也許可以通過另一層級的違反來解決這個問題。如果我們拋棄 TCP——它也已經相當老了——而是使用基於 UDP 的 QUIC,那麼我們就可以完全停止使用 UDP 4 元組作為連接識別符。相反,如果 UDP 埠號是「特殊移動層」埠,我們就解開內容,它可以是另一個帶有正確 uuid 標籤的封包,將其與正確的會話匹配,並將這些封包傳遞給正確的套接字。
還有更多好消息:實驗性的 QUIC 協議已經,至少理論上,具有正確的封包結構可以這樣工作。事實證明,如果你想使用無狀態封包加密和身份驗證,而 QUIC 確實如此,你仍然需要唯一的會話識別符(金鑰)。所以,也許不用花費太多精力,QUIC 就可以支持透明漫遊。那將是多麼美好的世界!
到那時,我們所要做的就是消除網際網路上所有剩餘的 UDP 和 TCP,然後我們就絕對不需要層 2 橋接了,這次是真的,然後我們就可以擺脫廣播和 MAC 位址以及 SDN 和 DHCP 以及所有那些東西。
然後網際網路將再次變得優雅。
1 編輯 2017-08-16:事實證明,本節中的任何內容都不需要 IPv6。即使使用 IPv4 和 NAT,甚至跨多個 NAT 漫遊,它也能正常工作。
3 編輯 2017-10-24:除了 QUIC,還有幾種其他協議可以作為此類協議的候選者,包括 MinimaLT。我最初沒有提到 MinimaLT,因為它不是我與 IETF 人員原始對話的一部分,但我的意思並不是暗示 QUIC 是唯一可能的漫遊能力 TCP 替代方案。事實上,MinimaLT 是我聽說過的第一个優雅地解決了漫遊問題的協議。未來可能被採用的解決方案,包括 QUIC,很可能會模仿 MinimaLT 的解決方案。
更新 2020-07-09:我在 Tailscale 部落格上發布了更多關於 IPv4/IPv6 遷移和互操作性的想法。