Windows 批量添加删除路由资源性能优化
首先,本文只涉及如何优化Windows批量添加删除路由资源的速度优化。
基于虚拟网卡来实现虚拟网络的组建的架构图如下所示:
图片来自网络
起因:
一般来说,私有网络的一个资源对应本地的一条路由(比如:www.example.com,就是一条或者多条ip地址的路由资源),当然,你也可以推送一个网段,这样操作比较简单,但是存在一定的安全隐患,因为你将整个私有网络的网段推送到客户端,这样客户端连上之后就可以访问整个网段的资源,为了安全起见,一般不会推送单个资源地址。
在早些的开源的代码实现中,可以看到,拨号客户端通过调用本地系统的route.exe进程来控制路由资源的增删操作。
拨号客户端在连接到服务器之后,调用系统route.exe进程,根据服务端推送的资源依次添加路由,资源少的时候建立连接的速度还可以,但是随着这些资源的壮大,建立连接时的耗时就变得无法忍受了。
通过查找资源,找到了一个号称秒级别的添加千条路由的方案:
rundll32.exe cmroute.dll,SetRoutes /STATIC_FILE_NAME addchnroutes.txt
传送门
通过测试发现,这个方式添加路由的速度相当快,本着对未知技术的探索,对cmroute代码实现进行深究 cmroute源码实现
深入探索:
从源码中发现,cmroute.dll中使用的添加路由的方式是通过调用iphlpapi.dll(CreateIpForwardEntry、DeleteIpForwardEntry和GetIpForwardTable)接口来实现,深入iphlpapi.dll这些个接口的实现,这些接口直接操作系统的驱动程序
#define DD_TCP_DEVICE_NAME L"\\Device\\Tcp
来实现路由资源的增删。
调用接口和进程两者的调用方式,相信大家不需要测试也知道哪个性能更好一些,在这里还是简单的进行了一下对路由表操作的性能对比分析, 详细如下对254条路由表进行添加测试操作分析:
测试类型 | 测试数量 | 总耗时(s) | 平均耗时(t/s) |
命令行 | 254 | 43.4505 | 0.171065 |
API | 254 | 0.011989 | 4.72008e-05 |
从上面的比对上来看,命令行方式1秒大概添加5~6条策略,而api方式1秒大概添加2.5w左右相差几个数量级,可以看出使用api方式添加路由策略还是很有优势的。
后续:
在看了最新的开源的代码后发现,2020年9月份已经支持api的方式,但是使用的是CreateIpForwardEntry2,v2版本的api在vista及以后版本之后才支持。
代码片段实现参考(需要管理员权限运行):
//测试耗时计算
struct time_overhead {time_overhead(const int times): times(times), start(std::chrono::high_resolution_clock::now()) {}~time_overhead() {std::chrono::duration<double> elapsed =std::chrono::high_resolution_clock::now() - start;std::cout << "run " << times << " times in " << elapsed.count()<< "s, average speed "<< static_cast<double>(elapsed.count() / times) << "t/s \n";}private:const int times;std::chrono::steady_clock::time_point start;
};// 为了获取默认路由下一条地址
{unsigned int i;dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {buffer.resize(dwSize);if (!(pIpForwardTable =reinterpret_cast<PMIB_IPFORWARDTABLE>(&buffer[0]))) {return -1;}dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);}if (dwStatus != ERROR_SUCCESS) {return -1;}std::string nethop;for (i = 0; i < pIpForwardTable->dwNumEntries; i++) {if (pIpForwardTable->table[i].dwForwardDest == 0) { //找到默认网关地址in_addr tmp;tmp.S_un.S_addr = pIpForwardTable->table[i].dwForwardNextHop;nethop = inet_ntoa(tmp);break;}}if (nethop.empty()) {return -1;}
}// 命令行添加路由
{std::vector<std::string> route_cmds;for (int i = 1; i < 255; i++) {route_cmds.emplace_back("route.exe ADD 192.168.1." + std::to_string(i) +" mask MASK 255.255.255.255 " + nethop +" > NUL 2>&1");}{time_overhead to(route_cmds.size());for (auto &item : route_cmds) {system(item.c_str()); //命令行方式添加}}
}// api方式添加
{int mask = ConvertSzToIP("255.255.255.255"); // from cmrouteint next_hop = ConvertSzToIP(nethop); // from cmroutefor (int i = 1; i < api_dests.size(); i++) {MIB_IPFORWARDROW route = {0};route.dwForwardDest = api_dests[i];route.dwForwardIfIndex = 7;route.dwForwardMask = mask;route.dwForwardMetric1 = 281;route.dwForwardNextHop = next_hop;route.dwForwardPolicy = 0;route.dwForwardNextHopAS = 0;route.dwForwardType = 3;route.dwForwardProto = 3;route.dwForwardAge = INFINITE;route.dwForwardMetric2 = 0xFFFFFFFF;route.dwForwardMetric3 = 0xFFFFFFFF;route.dwForwardMetric4 = 0xFFFFFFFF;route.dwForwardMetric5 = 0xFFFFFFFF;DWORD r = DeleteIpForwardEntry(&route);if (ERROR_SUCCESS != r) {std::cout << r << "\n";return -1;}}
}
注:如有侵权,请联系作者
Windows 批量添加删除路由资源性能优化相关推荐
- linux小脚本批量添加/删除用户
批量添加/删除用户,当输入add时,判断用户是否存在,存在则显示存在,不存在则添加:当输入del时,判断用户是否存在,存在则删除用户,不存在则显示不存在. #!/bin/bash if [ $1 == ...
- Windows批量添加防火墙例外端口
Windows下批量添加防火墙例外端口,查了网上资料,基本上都是使用"Netsh命令",循环增加端口,这会导致建立的规则特别多,不便于管理,查了下微软的资料,原来是Netsh命令, ...
- Windows设置HTML,windows怎么添加静态路由
windows添加静态路由的方法:1.按下[win+x]组合键,选择并打开命令提示符:2.执行[route -p add 10.10.10.0 nask 255.255.255.0 172.20.15 ...
- windows 2003添加删除windows组件中无iis应用程序服务器项的解决
文章分类:操作系统 一台windows 2003上,用的上海网管联盟的系统,在 添加删除windows组件 没有应用程序服务器,无法安装iis6. 解决方法如下: 1. 开始 -- 运行 ,输入 c: ...
- linux 删除路由条目,linux添加删除路由条目笔记!
简单操作笔记: 1. 查看 route -n 2. 添加 route add -net x.x.x.x netmask x.x.x.x gw x.x.x.x route add -net x.x.x. ...
- KVM脚本批量添加删除虚拟机
[背景]最近事情特别多,前段时间搞搞openstack,发现过与复杂,就想把KVM先好好学学,再过来搞它.因为工作关系,又用twisted开发了一个c/s的监控程序,但因还没有写完,所以暂时没有发出来 ...
- vs2010 添加删除工具栏资源的上图标按钮
VS2010 中如果要删除工具栏上多余的图标,直接用DEL 键,或右键菜单中的删除选项,却不能完全删除完,删除后留下了黑块,图标不见命令照常执行,其实正确操作是鼠标左键按住不放,往工具条外一拉就删除了 ...
- Android批量添加删除联系人
项目中的一个小需求,需要批量导入电话号码进入手机里面,号段固定了,可以自己添加号段的选项 XML布局文件 <LinearLayout xmlns:android="http://sch ...
- windows批量添加用户
1.如果您从命令行键入: FOR /L %i in (1,1,500) DO NET USER MyUser%i /ADD 结果将创建 500 个新用户,分别命名为 MyUser1.MyUser2 ...
最新文章
- 20169212 2016-2017-2 《网络攻防实践》第四周学习总结
- 妈呀!GitChat 发布 1.9 版本更新公告,这个红色简直亮瞎了我的眼...
- Redis 配置文件
- Php 删除数组后几个元素
- Windows下编译TensorFlow1.3 C++ library及创建一个简单的TensorFlow C++程序
- 安卓自定义View进阶-Matrix Camera
- 那个在轮胎上考了99分的孩子拒绝再上网课
- java poi 导出excel 数字有问题
- 更快地重复访问Java的Java类名?
- 1.4版本上线(第八次会议)
- php的addslashes,PHP addslashes()用法及代码示例
- linux 权限mod,linux学习—权限管理
- 【Spark】Spark的Kryo序列化
- 通过拦截器获取控制类requestMapping注解中的属性值
- Java语言实现word转PDF(10分钟解决)
- Win:从 Microsoft官方网站下载官方正版ISO镜像文件(以Windows10为例,图文教程)
- php安装xmeet,XMeet下载-XMeet官方版下载V1.8.4-99wo下载站
- matlab ftt图像压缩,求助 fft图像压缩程序问题
- 推荐给初学者:如何学好C语言?
- veritas msi_使用适用于AIX 5.3和6.1的Veritas Volume Manager(VxVM)V5管理逻辑卷