VPN編寫總結

最後一個網絡lab是實現一個簡單的VPN。其實我更覺得這是一個典型的Client-sever的程序。因爲收到一個需要轉發的包後,將網絡層及以上的協議棧內容當作數據(我使用的數據包socket,即爲UDP協議的payload),原封不動地轉發出去,內核會根據目的IP地址自動確定路由規則。收到一個需要分發給客戶端的包後,去除前面所說的UDP及以下的協議棧(UDP、IP、ETH),即,將UDP的payload當作鏈路層的負載,直接發送,因爲UDP的payload本來就有IP層,只差一層鏈路層了,這時使用RAW IP發送再合適不過。

也就是說,總共用到3個socket,收包用ETH_P_IP參數,發包分別用數據報socket和RAW IP:

// open sockets, arguments counts
void opensocket() {
    // receive all IP packets as low level frame
    if ((recvfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP))) == -1) {
        errExit("open recvfd socket");
    }
    // distribute raw IP packets, we don't care link layer
    if ((distributefd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) {
        errExit("open distributefd socket");
    }
    // simply forward packet, we don't care link layer and IP layer
    if ((forwardfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        errExit("open forwardfd socket");
    }
    // bind forwardfd to our port, tell host we are here, and prevent later vpn process running
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(vpnport);
    if (bind(forwardfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
        errExit("bind");
    }
}

轉發流程圖如下:

received packet


+--------------+                   by adding an offset to
|              |                   throw out link layer data
| Link layer   |                   (because it is no need)
|              |
+--------------+  if it is from PC1   +---------------
|              |  then forward it     |              |
| Network Layer|  +--------------->   | Network Layer|
|              |                      |              |
+--------------+                      +--------------+
|              |                      |              |
| ...          |                      | ...          |
|              |                      |              |
+--------------+                      +--------------+


                                                      +-----------------+  +--+
                                                      |                 |     |
                                                      | Link layer      |     |
                                                      |                 |     |
                                                      +-----------------+     |
                                                      |                 |     |
                                                      | Network Layer   |     | by kernel
                                                      |                 |     |
                                                      +-----------------+     |
                                                      |                 |     |
                                                      | Transport layer |     |
                                                      |                 |  +--+
+---------------                                      +-----------------+
|              |   then see it as payload of UDP,     |                 |  +--+
| Network Layer|   (wrap link layer, network layer,   | Network Layer   |     |
|              |   transport layer by kernel)         |                 |     |
+--------------+  +-------------------------------->  +-----------------+     | payload
|              |                                      |                 |     |
| ...          |                                      | ...             |     |
|              |                                      |                 |     |
+--------------+                                      +-----------------+  +--+


分發流程圖:

+-----------------+  +--+
|                 |     |
| Link layer      |     |
|                 |     |
+-----------------+     |
|                 |     |
| Network Layer   |     | no use
|                 |     |
+-----------------+     |
|                 |     |
| Transport layer |     |
|                 |  +--+
+-----------------+                                                           +---------------
|                 |  +--+                  by adding an offset to throw away  |              |
| Network Layer   |     |                  no use data, it is wrapped by      | Network Layer|
|                 |     |                  kernel since we use UDP            |              |
+-----------------+     | data we want    +-------------------------------->  +--------------+
|                 |     |                                                     |              |
| ...             |     |                                                     | ...          |
|                 |     |                                                     |              |
+-----------------+  +--+                                                     +--------------+




                                                              +-----------------+  +--+
                                                              |                 |     | added by kernel
                                                              | Link layer      |     |
                                                              |                 |  +--+
+---------------                                              +-----------------+
|              |    distribute it use RAW IP socket           |                 |  +--+
| Network Layer|    kernel will add link layer                | Network Layer   |     |
|              |                                              |                 |     |
+--------------+   +------------------------------->          +-----------------+     | now we successfully
|              |                                              |                 |     | forward PC1's data to PC2
| ...          |                                              | ...             |     |
|              |                                              |                 |     |
+--------------+                                              +-----------------+  +--+

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章