【20】Strongswan sa ——IKE_SA set_state|process_message|
ike_sa_t:IKE_SA 包含与对等体连接相关的密码信息。它通过task manager和itasks管理多个 IPsec CHILD_SA。该对象包含如下:
(1)get_id 获取ike_sa_id_t 对象,该对象标识一个IKE_SA,包含发起方和响应方的SPI(国标是cookie),以及ike主版本,是否发起方等。
(2)get_version 获取ike版本1 ikev1 2 ikev2(国标是 ikev1)。
(3)get_unique_id 获取唯一定义此IKE_SA的数字 ID (国标无)。
(4)set_state/get_state 管理ike状态机状态:
/*** IKE_SA在其生命周期内会传递各种状态。新创建的 SA 处于 CREATED 状态。* +----------------+¦ SA_CREATED ¦+----------------+¦on initiate()---> ¦ <----- on IKE_SA_INIT receivedV+----------------+¦ SA_CONNECTING ¦+----------------+¦¦ <----- on IKE_AUTH successfully completedV+----------------+¦ SA_ESTABLISHED ¦-------------------------+ <-- on rekeying+----------------+ ¦¦ Von delete()---> ¦ <----- on IKE_SA +-------------+¦ delete request ¦ SA_REKEYING ¦¦ received +-------------+V ¦+----------------+ ¦¦ SA_DELETING ¦<------------------------+ <-- after rekeying+----------------+¦¦ <----- after delete() acknowledged¦\V/X/ \*/
enum ike_sa_state_t {//IKE_SA 刚刚创建,但尚未启动或响应。IKE_CREATED,//IKE_SA主动或被动启动IKE_CONNECTING,//IKE_SA 已完全建立IKE_ESTABLISHED,//IKE_SA 在外部进行管理,不处理消息?IKE_PASSIVE,//IKE_SA 正在进行的重新协商IKE_REKEYING,//IKE_SA已重新生成密钥(或冗余)IKE_REKEYED,//IKE_SA 正在删除IKE_DELETING,//IKE_SA对象被销毁IKE_DESTROYING,
};
a.传入的state设置到private_ike_sa_t的state。
b.若是IKE_ESTABLISHED,并且上一个状态为IKE_CONNECTING(发起方)或IKE_PASSIVE(响应方),记录IKE_ESTABLISHED的时间戳,以用于生命周期管理,更新状态机STAT_REKEY、STAT_REAUTH、STAT_DELETE的调度。
//获取配置的rekey重新协商时间,如果设置了且STAT_REKEY状态的时间戳为0,即还没有设置下一次REKEY的时间及调度job
//或者STAT_ESTABLISHED+t小于已有的应该rekey时间,需要更新STAT_REKEY以便于更早及时的rekey。
//STAT_REAUTH类似。
t = this->peer_cfg->get_rekey_time(this->peer_cfg, TRUE);
if (t && (this->stats[STAT_REKEY] == 0 ||(this->stats[STAT_REKEY] > t + this->stats[STAT_ESTABLISHED])))
{this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED];job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);lib->scheduler->schedule_job(lib->scheduler, job, t);DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
}
t = this->peer_cfg->get_reauth_time(this->peer_cfg, TRUE);
if (t && (this->stats[STAT_REAUTH] == 0 ||(this->stats[STAT_REAUTH] > t + this->stats[STAT_ESTABLISHED])))
{this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED];job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);lib->scheduler->schedule_job(lib->scheduler, job, t);DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
}
else if (this->stats[STAT_REAUTH]) /*this->stats[STAT_REAUTH] <= t + this->stats[STAT_ESTABLISHED] 这次函数调用之前,已经向process添加过job*/
{t = this->stats[STAT_REAUTH] - this->stats[STAT_ESTABLISHED];DBG1(DBG_IKE, "reauthentication already scheduled in %ds", t);
}//解决什么时间删除ike_sa: maximum IKE_SA lifetime -> t
//t: Delay before deleting a rekeying/reauthenticating SA
t = this->peer_cfg->get_over_time(this->peer_cfg);
if (this->stats[STAT_REKEY] || this->stats[STAT_REAUTH])
{//STAT_DELETE时间戳(到此时删除)取REKEY、REAUTH中的最小者,要是与rekeying/reauthenticating错开,不是应该用max?if (this->stats[STAT_REAUTH] == 0){this->stats[STAT_DELETE] = this->stats[STAT_REKEY];}else if (this->stats[STAT_REKEY] == 0){this->stats[STAT_DELETE] = this->stats[STAT_REAUTH];}else{this->stats[STAT_DELETE] = min(this->stats[STAT_REKEY],this->stats[STAT_REAUTH]);}//t=配置的删除重新生成密钥/重新验证 SA 之前的延迟 + (stats[STAT_REKEY]-stats[STAT_ESTABLISHED])this->stats[STAT_DELETE] += t;t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED];//到时间(t时间后)执行删除ike_sa的jobjob = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);lib->scheduler->schedule_job(lib->scheduler, job, t);DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
c.对方支持的话发送DPD
d.若上一个状态为IKE_PASSIVE ?,则send_keepalive发送心跳
(5) get_name 连接的名字?
(6)get_statistic/set_statistic ike状态统计信息
(7)get_my_host/set_my_host/get_other_host/set_other_host 主机信息操作
(8)float_ports 4500端口
process_message:
(1)被动状态下不处理消息。
(2)ike版本不对应不处理消息。
(2)task_manager->process_message