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
| ...          |                                              | ...             |     |
|              |                                              |                 |     |
+--------------+                                              +-----------------+  +--+

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