openswan DPD可能引發狀態不一致修改

環境網絡

都開啓了DPDcode

server端DPD探測到client不在線,刪除本身的ISAKMP SAIPsec SA,發送刪除ISAKMP SAIPsec SA兩個通知報文給client端,此時若是client端只收到刪除ISAKMP SA的報文,client端把ISAKMP SA刪除了,但IPsec SA還存在,這就出如今狀態不一致問題,server端狀態爲斷開,client端狀態爲鏈接,實際上隧道已不能互通。同時DPD沒法工做(由於ISAKMP SA不存在)server

理論上這種狀況很難出現,由於兩端DPD都開啓,當server探測到client不在線時,client也應該探測到server不在線了。在真實網絡中,特別是中國的ISP環境下,client收到server DPD報文後已作出迴應,但server就是收不到,這樣client是不可能探測到server不在線的ci

這種狀況我以爲也跟DPD探測機制有關,由於DPD定義只要本端收到對端發送的R_U_THERE報文或R_U_ACK報文都認爲對端是在線的io

修改dpd.c加入BEGIN MODIFYEND MODIFY之間的代碼,當DPD發現ISAKMP SA不存時進行重協商,從而保證隧道連續可用event

void p2_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)
    {
/** BEGIN MODIFY **/
        /*loglog(RC_LOG_SERIOUS, "DPD: could not find newest phase 1 state");*/
#define DELETE_SA_DELAY  EVENT_RETRANSMIT_DELAY_0
        if (p2st->st_event != NULL &&
            p2st->st_event->ev_type == EVENT_SA_REPLACE &&
            p2st->st_event->ev_time <= DELETE_SA_DELAY + now()) {
            loglog(RC_LOG_SERIOUS, "DPD: could not find newest phase 1 state: "
                    "already replacing IPSEC State #%lu in %d seconds"
                    , p2st->st_serialno, (int)(p2st->st_event->ev_time - now()));
        } else {
            loglog(RC_LOG_SERIOUS, "DPD: could not find newest phase 1 state: "
                    "replace IPSEC State #%lu in %d seconds"
                    , p2st->st_serialno, DELETE_SA_DELAY);
            p2st->st_margin = DELETE_SA_DELAY;
            delete_event(p2st);
            event_schedule(EVENT_SA_REPLACE, DELETE_SA_DELAY, p2st);
        }
/** END MODIFY **/
        return;
    }

    dpd_outI(st, p2st, TRUE, delay, timeout);
}
相關文章
相關標籤/搜索