openswan协商流程之(二):main_inI1_outR1()

主模式第二包:main_inI1_outR1()

1. 序言

main_inI1_outR1()函数是ISAKMP协商过程中第二包的核心处理函数,同时也是响应端口的首包。这里我们主要说明main_inI1_outR1的处理流程,关于main_inI1_outR1的上下文环境暂不叙述,留给后面的文章进行更新。

ISAKMP协商报文的处理流程都比较复杂,一个函数有几百行都是很常见的,因此个人学习期间难免有遗漏和理解错误的地方,请大家多多批评指正。

2. main_inI1_outR1()处理流程图

下面的流程图不仅包括main_inI1_outR1,还包括它其中的一个重要函数:parse_isakmp_sa_body。此函数的作用就是解析对端的SA信息,然后根据对端的建议载荷,选择本地支持的算法,并构造自己的应答SA载荷。
在这里插入图片描述
在这里插入图片描述

3. main_inI1_outR1()源码

/* State Transition Functions.
 *
 * The definition of state_microcode_table in demux.c is a good
 * overview of these routines.
 *
 * - Called from process_packet; result handled by complete_v1_state_transition
 * - struct state_microcode member "processor" points to these
 * - these routine definitionss are in state order
 * - these routines must be restartable from any point of error return:
 *   beware of memory allocated before any error.
 * - output HDR is usually emitted by process_packet (if state_microcode
 *   member first_out_payload isn't ISAKMP_NEXT_NONE).
 *
 * The transition functions' functions include:
 * - process and judge payloads
 * - update st_iv (result of decryption is in st_new_iv)
 * - build reply packet
 */

/* Handle a Main Mode Oakley first packet (responder side).
 * HDR;SA --> HDR;SA
 */

/********************************
*main_inI1_outR1函数被process_packet函数调用
*它的返回结果由complete_v1_state_transition处理
*
*********************************/
stf_status
main_inI1_outR1(struct msg_digest *md)
{
   
#ifdef DMALLOC
     if (_dm_initialized != 0) {
   
	/* log unfreed pointers that have been added to the heap since mark */
	dmalloc_log_changed(_dm_mark, 1, 0, 1);
	dmalloc_log_stats ();
     }
     _dm_mark = dmalloc_mark() ;
     _dm_initialized = 1;
#endif
/*接收到的数据包中的SA载荷部分*/
    struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
    struct state *st;
    struct connection *c;
/*准备作为应答的SA载荷缓冲区*/
    pb_stream r_sa_pbs;
    lset_t policy_hint = 0;

    /* we are looking for an OpenPGP Vendor ID sent by the peer */
    bool openpgp_peer = FALSE;

    /* Determin how many Vendor ID payloads we will be sending */
    int next;
    int numvidtosend = 1;  /* we always send DPD VID */
/*至少会发送DPD的VID,因此初始值为1*/
#ifdef NAT_TRAVERSAL   /*支持NAT-T,则增加一个nat-t探测的VID*/
    if (md->quirks.nat_traversal_vid && nat_traversal_enabled) {
   
	DBG(DBG_NATT, DBG_log("nat-t detected, sending nat-t VID"));
	numvidtosend++;
    }
#endif
/*如果预定义了PLUUO VID 或openpgp 对端, 增加VID 数量*/
#if SEND_PLUTO_VID || defined(openpgp_peer)
    numvidtosend++;
#endif

#if defined(openpgp_peer)
    {
   
	    struct payload_digest *p;
	   /*遍历接收到的数据包中的VID 载荷链表*/
	    for (p = md->chain[ISAKMP_NEXT_VID]; p != NULL; p = p->next)
		{
   
		    int vid_len = sizeof(pgp_vendorid) - 1 < pbs_left(&p->pbs)
			? sizeof(pgp_vendorid) - 1 : pbs_left(&p->pbs);

		    /*检查是否是pgp VID, 是则设置openpgp_peer 标志为TRUE*/
		    if (memcmp(pgp_vendorid, p->pbs.cur, vid_len) == 0)
			{
   
			    openpgp_peer = TRUE;
			    DBG(DBG_PARSING,
				DBG_log("we have an OpenPGP peer")
				)
				}
		}
    }
#endif

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叨陪鲤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值