《openswan》专栏系列文章主要是记录openswan源码学习过程中的笔记。
- Author : 叨陪鲤
- Email : vip_13031075266@163.com
- Date : 2020.11.22
- Copyright : 未经同意不得转载!!!
- Version : openswan-2.6.51.5
- Reference :https://download.openswan.org/openswan/
目录
1. 加密流程状态机实现:
如果还不知道状态机是什么东东的,可以参考文章《C语言实现有限状态机》,该博客里简单的说明了状态机的实现原理和步骤。这里跳过状态机的初级讲解,而是直接进入高阶实现。
下面是IPSec封装流程中的核心:加密状态机
struct {
enum ipsec_xmit_value (*action)(struct ipsec_xmit_state *ixs);
int next_state;
} xmit_state_table[] = {
[IPSEC_XSM_INIT1] = {ipsec_xmit_init1, IPSEC_XSM_INIT2 },
[IPSEC_XSM_INIT2] = {ipsec_xmit_init2, IPSEC_XSM_ENCAP_INIT },
[IPSEC_XSM_ENCAP_INIT] = {ipsec_xmit_encap_init, IPSEC_XSM_ENCAP_SELECT },
[IPSEC_XSM_ENCAP_SELECT] = {ipsec_xmit_encap_select, IPSEC_XSM_DONE },
[IPSEC_XSM_ESP] = {ipsec_xmit_esp, IPSEC_XSM_ESP_AH },
[IPSEC_XSM_ESP_AH] = {ipsec_xmit_esp_ah, IPSEC_XSM_CONT },
[IPSEC_XSM_AH] = {ipsec_xmit_ah, IPSEC_XSM_CONT },
[IPSEC_XSM_IPIP] = {ipsec_xmit_ipip, IPSEC_XSM_CONT },
[IPSEC_XSM_IPCOMP] = {ipsec_xmit_ipcomp, IPSEC_XSM_CONT },
[IPSEC_XSM_CONT] = {ipsec_xmit_cont, IPSEC_XSM_DONE },
[IPSEC_XSM_DONE] = {NULL, IPSEC_XSM_DONE},
};
状态机核心调度处理流程代码:
void
ipsec_xsm(struct ipsec_xmit_state *ixs)
{
enum ipsec_xmit_value stat = IPSEC_XMIT_ENCAPFAIL;
unsigned more_allowed;
if (ixs == NULL) {
return;
}
more_allowed = 1000;
while (ixs->state != IPSEC_XSM_DONE && --more_allowed) {
ixs->next_state = xmit_state_table[ixs->state].next_state;
stat = xmit_state_table[ixs->state].action(ixs);
if (stat == IPSEC_XMIT_OK) {
ixs->state = ixs->next_state;
} else if (stat == IPSEC_XMIT_PENDING) {
return;
} else {
/* bad result, force state change to done */
ixs->state = IPSEC_XSM_DONE;
}
}
ixs->xsm_complete(ixs, stat);
}
2. 各状态函数基本功能总览:
状态 | 对应的动作(函数) | 作用 | 备注 |
IPSEC_XSM_INIT1 | ipsec_xmit_init1 |
根据outgoing_id查找对应的IPsec_sa | |
IPSEC_XSM_INIT2 | ipsec_xmit_init2 |
根据IPsec_sa封装策略确定统计封装需要空间大小 | |
IPSEC_XSM_ENCAP_INIT | ipsec_xmit_encap_init |
开始封装,开辟报文头部、尾部空间 | 真正开始修改报文内容 |
IPSEC_XSM_ENCAP_SELECT | ipsec_xmit_encap_select t |
根据IPsecsa封装协议选择封装套件 | |
IPSEC_XSM_ESP | ipsec_xmit_esp |
ESP封装套件 | |
IPSEC_XSM_ESP_AH | ipsec_xmit_esp_ah |
ESP+AH封装套件 | |
IPSEC_XSM_AH | ipsec_xmit_ah |
AH封装套件 | |
IPSEC_XSM_IPIP | ipsec_xmit_ipip |
隧道模式封装套件 | |
IPSEC_XSM_IPCOMP | ipsec_xmit_ipcomp |
IPcom封装套件 | |
IPSEC_XSM_CONT | ipsec_xmit_cont |
根据IPsecsa封装策略确定是否需要继续封装 | 是否需要继续封装 |
IPSEC_XSM_DONE | NULL |
IPsec封装完毕 |
4. 各状态功能概要
4.1 ipsec_xmit_init1():
此函数最关键的功能便是根据outgoing_said获取到对应的IPSec SA。 outgoing_said是在IPSec匹配流程根据报文五元组找到对应的eroute,其中eroute结构中包含said指针。
- 根据outgoing_said查询ipsec sa