1. 程式人生 > >IPv4 和 IPv6的互操作性

IPv4 和 IPv6的互操作性

IPv4客戶與IPv6伺服器通訊
步驟如下:

    1、IPv6伺服器啟動後建立一個IPv6監聽套接字,我們假定伺服器把通配地址繫結到該套接字
    2、IPv4客戶呼叫gethostbyname找到伺服器的A記錄(IPv4地址)。服務主機既有一個A記錄,也有一個AAAA記錄(IPv6地址),因為它同時支援IPv6和IPv4,不過客戶只需要A記錄
    3、客戶呼叫connect,導致客戶傳送一個IPv4 SYN到伺服器
    4、伺服器接收這個目的地址為IPv6監聽套接字的IPv4 SYN,設定一個標誌指示本連線應該使用IPv4對映的IPv6地址,然後響應一個 IPv4 SYN/ACK。連線建立後,由accept返回給伺服器的地址即為這個IPv4對映的IPv6的地址
    5、當伺服器主機往這個IPv4對映的IPv6地址傳送TCP分節時,其IP棧產生目的地址為所對映IPv4地址的IPv4載送資料報。因此,客戶與伺服器之間所有通訊都是IPv4的載送資料報
    6、除非這個伺服器顯式的檢查這個IPv6地址是不是一個IPv4地址對映的IPv6地址(IN6_IS_ADDR_V4MAPPED),否則它永遠不知到自己其實是在和一個IPv4客戶通訊,同樣的,客戶也不知道自己是和一個IPv6伺服器在通訊
        (上述情形的一個支撐性假設是,雙棧伺服器主機既有一個IPv4地址,又有一個IPv6地址。在所有IPv4耗盡前,這個假設沒問題)    


    如果收到一個目的地為某個IPv6套接字的IPv4資料報,那麼核心把與該資料報的源IPv4地址對應的IPv4對映的IPv6地址作為由accept或recvfrom返回的對端IPv6地址(對映是可行的,因為任何IPv4總能表示成一個IPv6地址。客戶和伺服器之間交換的是IPv4資料報)
    相反卻不能成立,因為一般來說,一個IPv6無法表示成一個IPv4地址



大多雙棧主機在處理監聽套接字時應使用如下規則:
    1、IPv4套接字只能接收來自IPv4客戶端的外來連線
    2、一個IPv6套接字,如果設定了IPV6_V6ONLY,那麼只能接收來自IPv6客戶的連線請求



IPv6客戶與IPv4伺服器通訊
步驟如下:

    1、一個IPv4伺服器在只支援IPv4的一個主機上啟動後建立一個IPv4套接字
    2、IPv6客戶啟動後呼叫getaddrinfo單純的查詢IPv6地址。既然只支援IPv4的伺服器只有A記錄,那麼返回給客戶的是一個IPv4對映的IPv6地址
    3、IPv6客戶設定這個IPv4對映的IPv6地址呼叫connect,核心檢測到這個對映地址後自動傳送一個IPv4 SYN到伺服器
    4、伺服器響應一個IPv4 SYN/ACK到客戶,連線於是通過使用IPv4資料報建立


    因此,如果一個IPv6的TCP客戶指定一個IPv4對映的IPv6地址以呼叫connect,或者一個IPv6的UDP客戶指定一個IPv4對映的IPv6地址以呼叫sendto,那麼核心檢測到這個對映地址後改為傳送一個IPv4資料報而不是IPv6資料報

最後這裡做一個總結: