首先,本文只涉及如何优化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(CreateIpForwardEntryDeleteIpForwardEntryGetIpForwardTable)接口来实现,深入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的方式,但是使用的是CreateIpForwardEntry2v2版本的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 批量添加删除路由资源性能优化相关推荐

  1. linux小脚本批量添加/删除用户

    批量添加/删除用户,当输入add时,判断用户是否存在,存在则显示存在,不存在则添加:当输入del时,判断用户是否存在,存在则删除用户,不存在则显示不存在. #!/bin/bash if [ $1 == ...

  2. Windows批量添加防火墙例外端口

    Windows下批量添加防火墙例外端口,查了网上资料,基本上都是使用"Netsh命令",循环增加端口,这会导致建立的规则特别多,不便于管理,查了下微软的资料,原来是Netsh命令, ...

  3. Windows设置HTML,windows怎么添加静态路由

    windows添加静态路由的方法:1.按下[win+x]组合键,选择并打开命令提示符:2.执行[route -p add 10.10.10.0 nask 255.255.255.0 172.20.15 ...

  4. windows 2003添加删除windows组件中无iis应用程序服务器项的解决

    文章分类:操作系统 一台windows 2003上,用的上海网管联盟的系统,在 添加删除windows组件 没有应用程序服务器,无法安装iis6. 解决方法如下: 1. 开始 -- 运行 ,输入 c: ...

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

  6. KVM脚本批量添加删除虚拟机

    [背景]最近事情特别多,前段时间搞搞openstack,发现过与复杂,就想把KVM先好好学学,再过来搞它.因为工作关系,又用twisted开发了一个c/s的监控程序,但因还没有写完,所以暂时没有发出来 ...

  7. vs2010 添加删除工具栏资源的上图标按钮

    VS2010 中如果要删除工具栏上多余的图标,直接用DEL 键,或右键菜单中的删除选项,却不能完全删除完,删除后留下了黑块,图标不见命令照常执行,其实正确操作是鼠标左键按住不放,往工具条外一拉就删除了 ...

  8. Android批量添加删除联系人

    项目中的一个小需求,需要批量导入电话号码进入手机里面,号段固定了,可以自己添加号段的选项 XML布局文件 <LinearLayout xmlns:android="http://sch ...

  9. windows批量添加用户

    1.如果您从命令行键入:   FOR /L %i in (1,1,500) DO NET USER MyUser%i /ADD 结果将创建 500 个新用户,分别命名为 MyUser1.MyUser2 ...

最新文章

  1. 20169212 2016-2017-2 《网络攻防实践》第四周学习总结
  2. 妈呀!GitChat 发布 1.9 版本更新公告,这个红色简直亮瞎了我的眼...
  3. Redis 配置文件
  4. Php 删除数组后几个元素
  5. Windows下编译TensorFlow1.3 C++ library及创建一个简单的TensorFlow C++程序
  6. 安卓自定义View进阶-Matrix Camera
  7. 那个在轮胎上考了99分的孩子拒绝再上网课
  8. java poi 导出excel 数字有问题
  9. 更快地重复访问Java的Java类名?
  10. 1.4版本上线(第八次会议)
  11. php的addslashes,PHP addslashes()用法及代码示例
  12. linux 权限mod,linux学习—权限管理
  13. 【Spark】Spark的Kryo序列化
  14. 通过拦截器获取控制类requestMapping注解中的属性值
  15. Java语言实现word转PDF(10分钟解决)
  16. Win:从 Microsoft官方网站下载官方正版ISO镜像文件(以Windows10为例,图文教程)
  17. php安装xmeet,XMeet下载-XMeet官方版下载V1.8.4-99wo下载站
  18. matlab ftt图像压缩,求助 fft图像压缩程序问题
  19. 推荐给初学者:如何学好C语言?
  20. veritas msi_使用适用于AIX 5.3和6.1的Veritas Volume Manager(VxVM)V5管理逻辑卷

热门文章

  1. MATLAB中如何打角标和希腊字母
  2. Windows 11的这19个新功能,你都知道吗?
  3. 从个人网站到淘宝网 仰观Java时代淘宝的技术发展
  4. Android 类似未读短信图标显示数字效果的分析
  5. css尺寸(大小)属性
  6. 王者荣耀 -- 上单及装备
  7. AtCoder Beginner Contest 266(C- G)「判凸包」「dp」「期望」「基环树」「组合数」
  8. 行业步入快速发展期,万亿级“虚拟蛋糕“将被如何瓜分?
  9. react+antd搭建后台管理系统
  10. 第二课 程小奔之辨别颜色