最近开发 C++ 的程序在链接阶段发生了一个 LTO 相关的错误。链接时优化(Link Time Optimization, LTO) 是一种编译优化技术,旨在通过在链接阶段执行全程序优化来提升代码性能和减少二进制文件大小。其主要原理是在链接阶段而不是在编译阶段进行更高级的优化,允许跨文件的全局优化。LTO 的基本原理和过程是:
遇到这样一个蛋疼的问题,我有一台服务器,上面部署了一个 web 服务,同时我也想把这个服务器作为客户端连入一个 OpenVPN 虚拟网络,并且我希望服务器上的程序能够通过 OpenVPN 的网关来访问外部网络,这主要是为了隐藏服务器的身份。但是在 OpenVPN 连接之后,原有的 Web 服务将无法访问。通过调试分析可以法线,造成这一现象的原因是 Web 服务的响应包也被路由配置路由到 OpenVPN 的 tun0 接口中。这导致响应无法返回给原来的请求服务器。如何解决这个问题呢?
如果你在网络上搜索这类问题你会发现各种文章给出的方案一般都是为 OpenVPN 的配置文件添加 route-nopull 选项来阻止 OpenVPN 设置客户端路由,但是这会导致客户端的对外访问无法通过 VPN 进行。事实上,从 IP 路由的角度来看,如果我的服务器是 A,而某个访问 Web 服务的 IP 是 B,同时 B 也可能是 A 试图访问的外部的目标服务提供者。对传输层路由而言,A 给 B 的 Web 服务响应和 A 主动发往 B 的请求是无法区分的。从这个角度来看,要达成 inbound 和 outbound 流量分别路由似乎是不可能的。
但是其实我们有一个突破点:那就是 Web 服务总是在本机使用固定的端口和请求者通信,我们可以通过端口来区分 inbound 和 outbound 流量。首先我们输入下面的命令:
1
iptables -t mangle -A OUTPUT -p tcp -m multiport --sports 80,443 -j MARK --set-mark 1