【22】Strongswan sa ——IKE_SA task_manager_v1
(0)task:
(1)task与exchange的关系是多对多。
(2)任务具有 build() 和 process()接口。build()创建有效负载payload并将其添加到消息message中,process()检查消息并处理其有效负载。交换exchange的发起者initiator首先调用 build() 来构建请求request,并使用 process() 方法处理响应response消息。响应者则相反;它首先调用 process() 来处理传入的请求,然后调用 build() 来构建适当的响应。两种方法都返回 SUCCESS、NEED_MORE 或 FAILED。
(3)SUCCESS 表示任务已完成,即使任务未成功完成也是如此。然后,task manager从列表中删除该任务。当任务需要进一步的 build()/process() 调用才能完成时,将返回一个 NEED_MORE,task manager管理器将任务留在队列中。返回的 FAILED 表示严重失败。每当任务返回 FAILED 时,管理器都会关闭 IKE_SA。
(4)Migrate接口 将任务迁移到新IKE_SA。迁移任务后,它将返回到可以再次用于启动 Exchange 的状态。当任务必须迁移到新IKE_SA时,这非常有用。特殊用法是收到 INVALID_KE_PAYLOAD。调用 reset 会重置任务,但会使用另一个 DH 组进行下一次尝试。ike_sa 是此任务所属并运行的新IKE_SA。
(1)task_manager_v1_create 创建一个private_task_manager_t对象,该对象继承task_manager_v1_t,task_manager_t实现了处理message的task任务接口。
(2)process_message 接收到重复帧处理、针对发起方或响应方分别处理。主要有解析数据帧、验证与处理以及需要的对对方的回应。以及日志记录。作为响应方被动加载ike_cfg_t配置以开启ike。
(3)queue_task 调用queue_task_delayed向queued_tasks队列尾部插入task,如果是IKEv1 Mode Config或IKEv1 XAUTH authentication类型,则如果队列中已存在,清除再添加。
(4)queue_ike IKEv1 检测避免重复添加;创建各类型相应的task添加后调用queue_task添加到任务队列。
(5) queue_ike_reauth 创建一个新的ike_sa_t,旧的sa的host等信息复制到新的sa;管理的所有child_sa,记录日志。initiate初始化一个新的连接,ike_sa_manager_t中签入记录,追踪该sa。
(6)queue_ike_delete flush_queue 根据task_queue_t类型,清空对应的task队列。将所有ike_sa管理的child_sa的删除任务加入队列,将ike_sa删除任务加入队列。
(7)queue_child 创建一个quick_mode_t类型的child task,插入queued_tasks队列。
(8) queue_child_rekey 根据(入站或出站)SPI和协议(AH、ESP)获取ike_sa管理的该child_sa,先尝试用入站SPI,找不到再用出站SPI。如果找到,则判断child_sa的状态机为CHILD_INSTALLED,如果是ikev1_child_sa_is_redundant 冗余的,则根据配置删除,否则创建quick_mode_create 任务添加到任务队列。
(9)queue_dpd 创建一个isakmp_dpd_t ,插入任务队列。根据配置,将DPD timeout job插入scheduler调度队列,超时后调度。
(10)initiate EXCHANGE_TYPE_UNDEFINED或INFORMATIONAL_V1才允许initiate ,根据ike_sa当前所处的状态机,
switch (this->ike_sa->get_state(this->ike_sa))
{case IKE_CREATED:activate_task(this, TASK_ISAKMP_VENDOR);activate_task(this, TASK_ISAKMP_CERT_PRE);if (activate_task(this, TASK_MAIN_MODE)){exchange = ID_PROT;}else if (activate_task(this, TASK_AGGRESSIVE_MODE)){exchange = AGGRESSIVE;}activate_task(this, TASK_ISAKMP_CERT_POST);activate_task(this, TASK_ISAKMP_NATD);break;case IKE_CONNECTING:if (activate_task(this, TASK_ISAKMP_DELETE)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}if (activate_task(this, TASK_XAUTH)){exchange = TRANSACTION;new_mid = TRUE;break;}if (activate_task(this, TASK_INFORMATIONAL)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}break;case IKE_ESTABLISHED:if (activate_task(this, TASK_MODE_CONFIG)){exchange = TRANSACTION;new_mid = TRUE;break;}if (activate_task(this, TASK_QUICK_DELETE)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}if (activate_task(this, TASK_ISAKMP_DELETE)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}if (activate_task(this, TASK_ISAKMP_DPD)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}if (!mode_config_expected(this) &&activate_task(this, TASK_QUICK_MODE)){exchange = QUICK_MODE;new_mid = TRUE;break;}if (activate_task(this, TASK_INFORMATIONAL)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}break;case IKE_REKEYING:if (activate_task(this, TASK_ISAKMP_DELETE)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}if (activate_task(this, TASK_ISAKMP_DPD)){exchange = INFORMATIONAL_V1;new_mid = TRUE;break;}break;default:break;
遍历active_tasks,处理message,根据返回值,SUCCESS则移除task;NEED_MORE则已处理,但 Task 需要再次交换,下文retransmit。ALREADY_DONE则再次initiate?FAILED则输出日志结束,DESTROY_ME则清空队列结束。
//如处理接收到的respons帧,vendor ID 后返回NEED_MORE,还需接着处理其他payload。
METHOD(task_t, build_i, status_t,private_isakmp_vendor_t *this, message_t *message)
{if (this->count++ == 0){build(this, message);}if (message->get_exchange_type(message) == AGGRESSIVE && this->count > 1){return SUCCESS;}return NEED_MORE;
}
generate_message生成给定的消息并将数据包存储在给定的数组中。
send_packets(this, this->initiating.packets);发送。
return initiate(this);?递归调用
(11)retransmit 重传请求或回应