将PIDcaching到端口映射Windows的安全方法

我使用WinDivert通过Windows上的透明代理pipe道连接(TCP和UDP)。 这是如何工作的,通过使用像GETTcpTable2这样的函数进行端口到pid的查找,然后检查是否匹配代理或其任何subprocess的PID是否匹配。 如果他们不匹配,他们通过代理转发,如果他们这样做,数据包是不变的。

我的问题是,有没有一个安全的方法,或者一个安全的持续时间,我可以“caching”端口到PID查找的结果? 每当我收到大量的数据包,比如在YouTube上观看video时,使用WinDivert的代码突然将所有的CPU都打开了,我假设这是通过对每个接收到的数据包进行TcpTable2查找。 我可以看到UDP没有真正的安全期限,我可以认为它是一个端口相同的进程,但是这可能与TCP?

作为Luis评论的一个补充,我认为缓存端口到pid lookup的应用程序也可以保留进程的句柄(通过OpenProcess获取)。 这个问题,如果关联到一个进程的资源没有被释放,直到所有的句柄关闭。 这是正常的,因为直到你有一个有效的句柄处理,你可以查询系统的各种信息,如使用的内存或时间。 所以你应该定期查看缓存的进程是否终止,以清除缓存中的条目并关闭句柄。

作为替代方案,您可以保留另一个信息,如可通过GetProcessTimes访问的进程的开始时间。 在缓存中查找进程ID时,可以打开进程并控制其启动时间。 如果可以的话,这是正确的过程,如果不是的话,进程ID已被重用,你应该从缓存清除条目。

第一种方法应该更高效,因为您不必为每个数据包重新打开进程,但是您必须更严格地识别终止的进程以释放资源,也许使用在所有进程句柄上使用WaitForMultipleObjectsEx的线程来一旦终止,就会收到提醒。

第二种方法应该更容易实施。

所以,我最终在这里做的是使用两个std :: unordered_maps。 一个映射是存储端口号(作为关键字)和最后系统时间(以毫秒为单位),TCPTable被查询以查找绑定到端口(关键字)的进程ID。 如果密钥不存在或者上一次大于当前系统时间加上2秒,则重新检查到TCPTable是否需要重新检查绑定到端口的PID。 完成检查后,我们更新第二个使用端口#作为键的映射,并返回一个int,它表示使用最后一个查询中有问题的端口找到的PID。 在查找中给我们提供了2秒钟的缓存,这将CPU使用率峰值从50%以上降至3%以下。