千家信息网

LINUX中socket与VRF怎么用

发表于:2024-10-08 作者:千家信息网编辑
千家信息网最后更新 2024年10月08日,这篇文章给大家分享的是有关LINUX中socket与VRF怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。LINUX socket与VRF实验环境如下图所示:配置如下:
千家信息网最后更新 2024年10月08日LINUX中socket与VRF怎么用

这篇文章给大家分享的是有关LINUX中socket与VRF怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

LINUX socket与VRF

实验环境如下图所示:

配置如下:

#!/bin/bashsudo ip netns add ns1 sudo ip link add ns1veth2 type veth peer name eth0 netns ns1sudo ip netns add ns2sudo ip link add ns2veth2 type veth peer name eth0 netns ns2sudo ip link set ns1veth2 master vrftestsudo ip link set ns2veth2 master vrftestsudo ip link set ns2veth2 upsudo ip link set ns1veth2 upsudo ip addr add 1.1.1.254/24 dev ns1veth2 sudo ip addr add 2.2.2.254/24 dev ns2veth2 sudo ip netns exec ns2 ip addr add 2.2.2.1/24 dev eth0 sudo ip netns exec ns1 ip addr add 1.1.1.1/24 dev eth0 sudo ip netns exec ns1 ip link set eth0 upsudo ip netns exec ns1 ip link set lo upsudo ip netns exec ns1 ip route add default via 1.1.1.254 dev eth0sudo ip netns exec ns2 ip link set eth0 upsudo ip netns exec ns2 ip link set lo upsudo ip netns exec ns2 ip route add default via 2.2.2.254 dev eth0

实验使用c语言写了两个套接字交互程序:

  • 服务器:vrfs

#include#include#include#include#include#include#include#include #define MAXLINE 4096int main(int argc, char** argv){    int    listenfd, connfd;    struct sockaddr_in     servaddr;    char    buff[4096];    int     n;    int     on = 1;    if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){        printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);        exit(0);    }    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,                         sizeof(on));    setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, (void *)&on,                         sizeof(on));    memset(&servaddr, 0, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    servaddr.sin_port = htons(6666);    if(argc == 2){        printf("vrf device name: %s\r\n", argv[1]);        if(0 > setsockopt(listenfd, SOL_SOCKET, SO_BINDTODEVICE, argv[1], strlen(argv[1])+1)){             printf("bind socket master dev error: %s(errno: %d)\n",strerror(errno),errno);             exit(0);        }    }    if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){        printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);        exit(0);    }    if( listen(listenfd, 10) == -1){        printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);        exit(0);    }    printf("======waiting for client's request======\n");    while(1){        if((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){                printf("accept socket error: %s(errno: %d)",strerror(errno),errno);                continue;        }        n = recv(connfd, buff, MAXLINE, 0);        buff[n] = '\0';        printf("recv msg from client: %s\n", buff);        close(connfd);    }    close(listenfd);}
  • 客户端程序:vrfc

#include#include#include#include#include#include#include#include#define MAXLINE 4096#include int main(int argc, char** argv){    int    sockfd, n;    char   *sendline = "hello vrf";    struct sockaddr_in    servaddr;    if( argc != 2){    printf("usage: ./client  [master device]\n");    exit(0);    }    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){    printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);    exit(0);    }    memset(&servaddr, 0, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(6666);    if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){    printf("inet_pton error for %s\n",argv[1]);    exit(0);    }    if(argc == 3){        printf("vrf device name: %s\r\n", argv[2]);        if(0 > setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, argv[2], strlen(argv[2])+1)){             printf("bind socket master dev error: %s(errno: %d)\n",strerror(errno),errno);             exit(0);        }    }    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){    printf("connect error: %s(errno: %d)\n",strerror(errno),errno);    exit(0);    }    printf("send msg to server: hello vrf\n");        if( send(sockfd, sendline, strlen(sendline), 0) < 0)    {    printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);    exit(0);    }    close(sockfd);    exit(0);}

实验一:惊群效应

在默认VRF环境下,启动两个进程,监听相同的端口和地址:程序中套接口使用了SO_REUSEADDR和SO_REUSEPORT。查看内核如何处理惊群效应。

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do ./vrfc 127.0.0.1; done  send msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfadmin@ubuntu:~/vrfsocket$

console2:

admin@ubuntu:~/vrfsocket$ ./vrfs ======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

console3:

admin@ubuntu:~/vrfsocket$ ./vrfs ======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

结论

新内核似乎已经能够处理惊群效应了,收到请求时不再通知所有监听该端口的服务器程序,而是会进行一定的负载均衡调度处理。

实验二:启动两个服务器,一个绑定VRF,一个不绑定,客户端不绑定VRF

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do sudo ./vrfc 127.0.0.1; donesend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfadmin@ubuntu:~/vrfsocket$

console2:

root@ubuntu:/home/admin/vrfsocket# ./vrfs======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

console3:

root@ubuntu:/home/admin/vrfsocket# ./vrfs vrftestvrf device name: vrftest======waiting for client's request======

结论:服务器监听套接字绑定VRF后,不再处理默认VRF中的请求

实验三:启动两个服务器,一个绑定VRF,一个不绑定,客户端绑定VRF

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do sudo ./vrfc 1.1.1.254 vrftest; donevrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfadmin@ubuntu:~/vrfsocket$

console2:在root用户下运行

root@ubuntu:/home/admin/vrfsocket# ./vrfs======waiting for client's request======

console3:在root用户下运行。

root@ubuntu:/home/admin/vrfsocket# ./vrfs vrftestvrf device name: vrftest======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

结论:服务器监听套接字不绑定VRF,不能处理非默认VRF中的请求

实验四:设置sudo sysctl -w net.ipv4.tcp_l3mdev_accept=1

启动两个服务器,一个绑定VRF,一个不绑定,客户端不绑定VRF

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do sudo ./vrfc 127.0.0.1; donesend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfsend msg to server: hello vrfadmin@ubuntu:~/vrfsocket$

console2:

root@ubuntu:/home/admin/vrfsocket# ./vrfs======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

console3:

root@ubuntu:/home/admin/vrfsocket# ./vrfs vrftestvrf device name: vrftest======waiting for client's request======

启动一个服务器,绑定VRF,客户端不绑定VRF

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do sudo ./vrfc 127.0.0.1; doneconnect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)connect error: Connection refused(errno: 111)admin@ubuntu:~/vrfsocket$

console3:

root@ubuntu:/home/admin/vrfsocket# ./vrfs vrftestvrf device name: vrftest======waiting for client's request======

启动一个服务器,绑定VRF,客户端绑定VRF

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do sudo ./vrfc 1.1.1.254 vrftest; donevrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfadmin@ubuntu:~/vrfsocket$

console3:

root@ubuntu:/home/admin/vrfsocket# ./vrfs vrftestvrf device name: vrftest======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

启动两个服务器,一个绑定VRF,一个不绑定,客户端绑定VRF

console1:

admin@ubuntu:~/vrfsocket$ for i in {0..9}; do sudo ./vrfc 1.1.1.254 vrftest; donevrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfvrf device name: vrftestsend msg to server: hello vrfadmin@ubuntu:~/vrfsocket$

console2:

root@ubuntu:/home/admin/vrfsocket# ./vrfs======waiting for client's request======recv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrfrecv msg from client: hello vrf

console3:

root@ubuntu:/home/admin/vrfsocket# ./vrfs vrftestvrf device name: vrftest======waiting for client's request======

在打开sudo sysctl -w net.ipv4.tcp_l3mdev_accept=1后,默认VRF中的监听套接字能够处理所有VRF中的请求,且优先级高于其它的VRF的监听套接字。

序号结论
1多个服务器器监听同一地址和端口,内核会进行负载均衡,选择唤醒其中一个进程处理请求。
2默认VRF中的服务器进程不能处理非默认VRF中的请求,非默认VRF中的服务器进程不能处理其它VRF中的请求
3开启net.ipv4.tcp_l3mdev_accept=1后,默认VRF中的服务器进程可以处理任意VRF中的请求,且优先级最高
4开启net.ipv4.tcp_l3mdev_accept=1后,非默认VRF中的服务器进程不能处理其它VRF中的请求,在处理本VRF中的流量时,优先级低于默认VRF中的进程。

感谢各位的阅读!关于"LINUX中socket与VRF怎么用"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

服务器 服务 处理 客户 客户端 进程 监听 两个 实验 套接字 程序 结论 优先级 内核 效应 端口 均衡 内容 地址 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中国历代墓志数据库唐李遂墓志 网络安全中的重要性 滨州山东软件开发 大型数据中心服务器数量 白云区网络安全会议 您的网络安全设置 qq代理服务器2018 ipddr网络安全 网络安全等级保护有多少级 开工报告软件开发 数据库表的操作按钮的作用是 博文图书馆管理系统服务器 黑色沙漠季节服务器装备养成 未来之役下载后连接不上服务器 光子云三河网络技术有限公司 能源管理系统数据库ER图 足球经理数据库编辑器官方正式版 运城软件开发培训学校 青山区方便网络安全维护联系人 青岛网络安全产业项目 hp3778如何连接服务器 带网络安全模式杀毒软件 网络安全知识竞赛江西 鼎湖区自然资源网络安全 30岁入行网络安全工程师 阿里大学生网络安全能力大赛 湖北康创科技软件开发公司 表格中部分数据对应数据库 数据库管理技术发展顺序 软件开发需求逻辑
0