提问人:fadedbee 提问时间:11/10/2023 最后编辑:fadedbee 更新时间:11/10/2023 访问量:44
为什么使用来自多个进程的 tun 接口会导致它卡顿?
Why does using a tun interface from multiple processes cause it to stutter?
问:
我已经编写了一个有效的用户空间隧道协议,它打开了 tun0。
void peer_tun_open(struct peer *peer) {
struct ifreq ifr;
int err;
proc_assert_master();
if ((peer->tun_fd = open("/dev/net/tun", O_RDWR)) == -1) {
LOG_ERROR_1("%s", "open /dev/net/tun");
exit(1);
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
if ((err = ioctl(peer->tun_fd, TUNSETIFF, (void *) &ifr)) == -1) {
LOG_ERROR_1("%s", "ioctl TUNSETIFF");
close(peer->tun_fd);
exit(1);
}
...
只要我只从一个进程的 epoll 中使用 tun0,一切正常。
(我能够使用来自多个进程的 UDP 套接字,没有问题,带有 SO_REUSEPORT 等。 UDP 端口由子级打开,但 tun 文件描述符是通过 继承的。fork()
当我将 tun0 fd 添加到多个进程的 epoll 中时,100-3000 毫秒的随机延迟会影响到达 tun0 上的所有数据包。
static void proc_epoll_callback(const char *key, void *ob, size_t index, void *extra) {
struct peer *peer = (struct peer *)ob;
int epoll_fd = *(int *) extra;
struct epoll_event event = {0};
if (peer->worker_id != state.proc_worker_id) return; // only one process must listen to a each tun interface, otherwise 100-3000ms delays occur
event.events = EPOLLIN;
event.data.fd = peer->tun_fd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, event.data.fd, &event)) {
LOG_ERROR_1("failed to add fd: %d to epoll fd: %d for peer %s", event.data.fd, epoll_fd, peer->name);
} else {
LOG_DEBUG_1("added fd: %d to epoll fd: %d for peer %s", event.data.fd, epoll_fd, peer->name);
}
}
是什么导致了这些延误?
如何在没有这些延迟的情况下从多个工作进程中使用 tun0?
答: 暂无答案
评论