dpd.c

来自「ipsec vpn」· C语言 代码 · 共 581 行 · 第 1/2 页

C
581
字号
    }        seqno = htonl(p1st->st_dpd_seqno);    /* make sure that the timeout occurs. We do this before the send,     * because the send may fail due to network issues, etc, and     * the timeout has to occur anyway     */    dpd_sched_timeout(p1st, tm, timeout);    DBG(DBG_DPD, DBG_log("DPD: Debug: sending R_U_THERE %u to %s:%d (state #%lu)"			 , seqno			 , ip_str(&p1st->st_remoteaddr)			 , p1st->st_remoteport			 , p1st->st_serialno));    if (send_isakmp_notification(p1st, R_U_THERE				 , &seqno, sizeof(seqno)) != STF_IGNORE)    {           loglog(RC_LOG_SERIOUS, "DPD: Serious: could not send R_U_THERE");        return;    }            st->st_last_dpd = tm;    p1st->st_last_dpd = tm;    p1st->st_dpd_expectseqno = p1st->st_dpd_seqno++;}voidp1_dpd_outI1(struct state *p1st){    time_t delay = p1st->st_connection->dpd_delay;    time_t timeout = p1st->st_connection->dpd_timeout;    dpd_outI(p1st, p1st, FALSE, delay, timeout);}voidp2_dpd_outI1(struct state *p2st){    struct state *st;    time_t delay = p2st->st_connection->dpd_delay;    time_t timeout = p2st->st_connection->dpd_timeout;    /* find the related Phase 1 state */    st = find_phase1_state(p2st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);    if (st == NULL)    {        loglog(RC_LOG_SERIOUS, "DPD: Serious: could not find newest phase 1 state");        return;    }    dpd_outI(st, p2st, TRUE, delay, timeout);}voiddpd_event(struct state *st){    if(st==NULL) return;    if(IS_PHASE1(st->st_state)) {	p1_dpd_outI1(st);    } else {	p2_dpd_outI1(st);    }}/** * DPD in Initiator, out Responder * * @param st A state structure (the phase 1 state) * @param n A notification (isakmp_notification) * @param pbs A PB Stream * @return stf_status  */stf_statusdpd_inI_outR(struct state *p1st	     , struct isakmp_notification *const n	     , pb_stream *pbs){    time_t tm = now();    u_int32_t seqno;            if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))    {           loglog(RC_LOG_SERIOUS, "DPD: Warning: received R_U_THERE for unestablished ISKAMP SA");        return STF_IGNORE;    }    if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)    {        loglog(RC_LOG_SERIOUS, "DPD: Error: R_U_THERE has invalid SPI length (%d)", n->isan_spisize);        return STF_FAIL + PAYLOAD_MALFORMED;    }            if (memcmp(pbs->cur, p1st->st_icookie, COOKIE_SIZE) != 0)    {        /* RFC states we *SHOULD* check cookies, not MUST.  So invalid           cookies are technically valid, as per Geoffrey Huang */        loglog(RC_LOG_SERIOUS, "DPD: Warning: R_U_THERE has invalid icookie");    }    pbs->cur += COOKIE_SIZE;        if (memcmp(pbs->cur, p1st->st_rcookie, COOKIE_SIZE) != 0)    {        loglog(RC_LOG_SERIOUS, "DPD: Warning: R_U_THERE has invalid rcookie");          }    pbs->cur += COOKIE_SIZE;    if (pbs_left(pbs) != sizeof(seqno))    {        loglog(RC_LOG_SERIOUS, "DPD: Error: R_U_THERE has invalid data length (%d)", (int) pbs_left(pbs));        return STF_FAIL + PAYLOAD_MALFORMED;    }    seqno = ntohl(*(u_int32_t *)pbs->cur);    if (p1st->st_dpd_peerseqno && seqno <= p1st->st_dpd_peerseqno) {        loglog(RC_LOG_SERIOUS, "DPD Warning: received old or duplicate R_U_THERE");        return STF_IGNORE;    }         DBG(DBG_DPD, DBG_log("DPD: Debug: received R_U_THERE seq:%u time:%lu (state=#%lu name=\"%s\")" , seqno, tm, p1st->st_serialno, p1st->st_connection->name));    p1st->st_dpd_peerseqno = seqno;    if (send_isakmp_notification(p1st, R_U_THERE_ACK				 , pbs->cur, pbs_left(pbs)) != STF_IGNORE)    {        loglog(RC_LOG_SERIOUS, "DPD: Warning: could not send R_U_THERE_ACK");         return STF_IGNORE;    }    /* update the time stamp */    p1st->st_last_dpd = tm;    /*     * since there was activity, kill any EVENT_DPD_TIMEOUT that might     * be waiting.     */    if(p1st->st_dpd_event != NULL       && p1st->st_dpd_event->ev_type == EVENT_DPD_TIMEOUT) {	delete_dpd_event(p1st);    }    return STF_IGNORE;}/** * DPD out Responder * * @param st A state structure (phase 1) * @param n A notification (isakmp_notification) * @param pbs A PB Stream * @return stf_status  */stf_statusdpd_inR(struct state *p1st	, struct isakmp_notification *const n	, pb_stream *pbs){    time_t tm = now();    u_int32_t seqno;         if (!IS_ISAKMP_SA_ESTABLISHED(p1st->st_state))    {        loglog(RC_LOG_SERIOUS, "DPD: Warning: recieved R_U_THERE_ACK for unestablished ISKAMP SA");        return STF_FAIL;    }   if (n->isan_spisize != COOKIE_SIZE * 2 || pbs_left(pbs) < COOKIE_SIZE * 2)    {        loglog(RC_LOG_SERIOUS, "DPD: Error: R_U_THERE_ACK has invalid SPI length (%d)", n->isan_spisize);        return STF_FAIL + PAYLOAD_MALFORMED;    }         if (memcmp(pbs->cur, p1st->st_icookie, COOKIE_SIZE) != 0)    {        /* RFC states we *SHOULD* check cookies, not MUST.  So invalid           cookies are technically valid, as per Geoffrey Huang */        loglog(RC_LOG_SERIOUS, "DPD: Warning: R_U_THERE_ACK has invalid icookie");    }    pbs->cur += COOKIE_SIZE;        if (memcmp(pbs->cur, p1st->st_rcookie, COOKIE_SIZE) != 0)    {        /* RFC states we *SHOULD* check cookies, not MUST.  So invalid           cookies are technically valid, as per Geoffrey Huang */        loglog(RC_LOG_SERIOUS, "DPD: Warning: R_U_THERE_ACK has invalid rcookie ");    }    pbs->cur += COOKIE_SIZE;        if (pbs_left(pbs) != sizeof(seqno))    {        loglog(RC_LOG_SERIOUS, "DPD: Error: R_U_THERE_ACK has invalid data length (%d)", (int) pbs_left(pbs));        return STF_FAIL + PAYLOAD_MALFORMED;    }            seqno = ntohl(*(u_int32_t *)pbs->cur);    DBG(DBG_DPD, DBG_log("DPD: Debug: R_U_THERE_ACK, seqno received: %u expected: %u (state=#%lu)",			 seqno, p1st->st_dpd_expectseqno, p1st->st_serialno));    if (!p1st->st_dpd_expectseqno && seqno != p1st->st_dpd_expectseqno) {        loglog(RC_LOG_SERIOUS, "DPD: Error: R_U_THERE_ACK has unexpected sequence number (expected: %u got: %u", seqno, p1st->st_dpd_expectseqno);	p1st->st_dpd_expectseqno = 0;	/* do not update time stamp, so we'll send a new one sooner */    } else {	/* update the time stamp */	p1st->st_last_dpd = tm;    }    p1st->st_dpd_expectseqno = 0;    /*     * since there was activity, kill any EVENT_DPD_TIMEOUT that might     * be waiting.     */    if(p1st->st_dpd_event != NULL       && p1st->st_dpd_event->ev_type == EVENT_DPD_TIMEOUT) {	delete_dpd_event(p1st);    }    return STF_IGNORE;}           /** * DPD Timeout Function * * This function is called when a timeout DPD_EVENT occurs.  We set clear/trap * both the SA and the eroutes, depending on what the connection definition * tells us (either 'hold' or 'clear') * * @param st A state structure that is fully negotiated  * @return void */voiddpd_timeout(struct state *st){    int action;    struct connection *c = st->st_connection;    action = st->st_connection->dpd_action;        /* probably wrong thing to assert here */    passert(action == DPD_ACTION_HOLD	    || action == DPD_ACTION_CLEAR	    || action == DPD_ACTION_RESTART);            /** delete the state, which is probably in phase 2 */    set_cur_connection(c);    openswan_log("DPD: Info: No response from peer - declaring peer dead");    switch(action) {    case DPD_ACTION_HOLD:	/** dpdaction=hold - Wipe the SA's but %trap the eroute so we don't	    leak traffic.  Also, being in %trap means new packets will	    force an initiation of the conn again.  */	openswan_log("DPD: Info: Putting connection into %%trap");	delete_states_by_connection(c, TRUE);  	break;    case DPD_ACTION_CLEAR:        /** dpdaction=clear - Wipe the SA & eroute - everything */            openswan_log("DPD: Info: Clearing Connection");	delete_states_by_connection(c, TRUE);	DBG(DBG_DPD, DBG_log("DPD: Debug: issuing unroute_connection()"));        unroute_connection(c);        /* --unroute */	break;    case DPD_ACTION_RESTART:	/** dpdaction=restart - immediate renegotiate the connection. */        openswan_log("DPD: Info: Restarting Connection");	/* we replace the SA so that we do it in a rational place */	delete_event(st);	event_schedule(EVENT_SA_REPLACE, 0, st);	break;    }    reset_cur_connection();}/* * Local Variables: * c-basic-offset:4 * c-style: pluto * End: */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?