strongswan--对等体封装模式不一致的处理
ipsec的封装模式有两种:transport模式和tunnel模式。当对等体的封装模式不一致(即一方为transport模式,另一方为tunnel模式)时,双方协商的结果是建立tunnel模式的ipsec会话。
DUTA(transport) ------- DUTB(tunnel)
以IKEv2为例分析。在上图中,假设DUTA是会话的发起方,DUTA配置的封装模式为transport,在IKE_AUTH的请求报文中会携带N(USE_TRANSP)载荷。DUTB在解析到该载荷时会与自己配置的封装模式比较,因为配置为tunnel模式,故保持自己的封装模式不变,DUTB发送的IKE_AUTH回应报文中不携带N(USE_TRANSP)载荷。DUTA创建的child SA的封装模式为默认值tunnel模式,并将该模式下发协议栈。需要注意的是,child SA创建时,封装模式没有使用配置值,而是默认赋值为tunnel模式。
代码如下:
DUTA构造IKE_AUTH请求报文,调用child_create.c的build_i函数:
其封装模式是从配置中读出来的:
然后构造IKE_AUTH请求报文的载荷
注意区分两个结构:private_child_create_t和private_child_sa_t。
-----------------------------------------------------------------------------------------------
DUTB收到N(USE_TRANSP)载荷,先将mode设置为transport:
DUTB在回复IKE_AUTH响应报文之前会先按照child_sa到内核:
此时发现自己配置的封装模式不是transport,于是将封装模式的值改为tunnel:
后续便不会发送N(USE_TRANSP)载荷。
疑问???
为什么DUTA发送N(USE_TRANSP)载荷时,private_child_create_t中的mode是transport,后来没收到DUTB的N(USE_TRANSP)载荷,而mode值又变成tunnel了?
原因是,DUTA在处理DUTB的IKE_AUTH响应报文中的载荷时,将mode值改成了tunnel。代码如下:
代码处理上的细节太多,不多问自己几个为什么,真不敢说自己搞懂了
总结一下,private_child_create_t中的mode是由配置值和N(USE_TRANSP)载荷按照一定的逻辑共同决定的。而private_child_sa_t中的mode,是在child sa下发协议栈之前,先将private_child_create_t中的mode拷贝过去,然后下发的。而决定ipsec会话封装模式的,是private_child_create_t中的mode。