openswan协商流程之(一):main_outI1()

主模式第一包:main_outI1()

1. 序言

main_outI1()作为主模式主动发起连接请求的核心处理函数,我们可以通过学习该函数的处理流程来探究openswan中报文封装的基本思想。如果之前没有学习基本的函数接口(如in_struct, out_struct, out_sa等),那么直接学习main_outI1()流程是比较困难的。如果想快速学习这几个函数接口,可以查看我先前的文章,我把需要的基本知识、思想等做了基本介绍,看完那几个接口再来学习此后的ISAKMP协商流程会容易很多,起到事半功倍的效果。

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

2. main_outI1()流程图

下面两个流程图中主要描述了三个函数的处理流程,后面我会分别附上这三个函数的源码信息。

在这里插入图片描述
在这里插入图片描述

3. main_outI1()源码注释

stf_status
main_outI1(int whack_sock
	   , struct connection *c
	   , struct state *predecessor
           , so_serial_t  *newstateno
	   , lset_t policy
	   , unsigned long try
	   , enum crypto_importance importance
	   , struct xfrm_user_sec_ctx_ike * uctx
	   )
{
   
    struct state *st = new_state();/*创建一个新的状态*/
    struct msg_digest md;   /* use reply/rbody found inside */

    int numvidtosend = 1;  /* we always send DPD VID */
#ifdef NAT_TRAVERSAL
    if (nat_traversal_enabled) {
   
	numvidtosend++;
    }
#endif
#if SEND_PLUTO_VID || defined(openpgp_peer)
    numvidtosend++;
#endif
#ifdef XAUTH
    if(c->spd.this.xauth_client || c->spd.this.xauth_server) {
   
	numvidtosend++;
    }
#endif
/*统计VID个数*/
    /* set up new state *//*根据对端IP地址信息生成一个新的cookie*/
    get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);

   /*初始化新的state结构*/
    initialize_new_state(st, c, policy, try, whack_sock, importance);
	
    if(newstateno) *newstateno = st->st_serialno;

    /* IKE version numbers -- used mostly in logging */
    st->st_ike_maj        = IKEv1_MAJOR_VERSION;
    st->st_ike_min        = IKEv1_MINOR_VERSION;

    change_state(st, STATE_MAIN_I1);/*设置当前的状态为STATE_MAIN_I1*/

    if (HAS_IPSEC_POLICY(policy))
	add_pending(dup_any(whack_sock), st, c, policy, 1
	    , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno
	    , uctx
                    );

#ifdef HAVE_LABELED_IPSEC
    /*For main modes states, sec ctx is always null*/
    st->sec_ctx = NULL;
#endif

    if (predecessor == NULL)
	openswan_log("initiating Main Mode");
    else
	openswan_log("initiating Main Mode to replace #%lu", predecessor->st_serialno);

    /* set up reply */
    zero(reply_buffer);/*初始化应答报文(发送的报文)的结构*/
    init_pbs(&reply_stream, reply_buffer, sizeof(reply_buffer), "reply packet");

    /* HDR out */
    {
   /*添加isakmp头部信息*/
	struct isakmp_hdr hdr;

	zero(&hdr);	/* default to 0 */
	hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
	hdr.isa_np = ISAKMP_NEXT_SA;
	hdr.isa_xchg = ISAKMP_XCHG_IDPROT;
	memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);
	/* R-cookie, flags and MessageID are left zero */
	/*长度字段最后设置: close_output_pbs(&reply_stream);*/
	if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_stream, &md.rbody))
	{
   
	    reset_cur_state();
	    return STF_INTERNAL_ERROR;
	}
    }

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

叨陪鲤

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

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

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

打赏作者

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

抵扣说明:

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

余额充值