代码版本:

Socket Pool

套接字池(Socket Pool)为虚拟路由冗余协议(VRRP)实例高效管理网络通信,可在合适的情况下允许多个实例共享套接字。

vrrp_dispatcher_init

创建和申请一个 socket pool。

假设有 n 个网卡。每个网卡最多有 2 个 fds(1个用于 VRRP,另一个用于 IPSEC_AH)。所有的 VRRP 实例都通过这些文件描述符(fds)实现多路复用。因此,我们的设计可支持 2×n 个多路复用节点。

1
2
3
4
   fd1  fd2    fd3  fd4          fdi  fdi+1
-----\__/--------\__/---........---\__/---
| ETH0 | | ETH1 | | ETHn |
+------+ +------+ +------+

多个 VRRP 实例不单独占用套接字,而是共享一组 fds 资源,通过操作系统的 I/O 多路复用技术(如 Linux 的epoll、BSD 的kqueue)实现对多个实例通信需求的并发处理,最终达成 “用少量 fds 支持大量实例” 的高效设计目标。

vrrp_create_sockpool

为 VRRP instances 创建 sockets 结构

1
2
3
4
5
vrrp_create_sockpool(vrrp_data->vrrp_socket_pool)
for(e : vrrp_data->vrrp_socket_pool) {
alloc_sock
MALLOC
}

vrrp_open_sockpool

开启物理 sockets

1
2
3
4
5
6
7
8
vrrp_open_sockpool(vrrp_data->vrrp_socket_pool)
for(e : vrrp_data->vrrp_socket_pool) {
sock_obj = ELEMENT_DATA(e);
sock_obj->fd_in = open_vrrp_socket();
socket(AF_INET, SOCK_RAW, proto);
sock_obj->fd_out = open_vrrp_send_socket();
socket(AF_INET, SOCK_RAW, proto);
}

vrrp_set_fds

为 VRRP instances 分配合适的 sockets

1
2
3
4
5
vrrp_set_fds(vrrp_data->vrrp_socket_pool)
for(e : vrrp_data->vrrp_socket_pool) {
vrrp->fd_in = sock_obj->fd_in;
vrrp->fd_out = sock_obj->fd_out;
}