void Connector::Transmit (Path* path) { if (path == nil) { Path newPath; Retransmit(&newPath); } else { Retransmit(path); } }
void Connector::Retransmit (Path* path) { if (path->Visited(this)) { return; } boolean forking = _cnxns->First() != _cnxns->Last(); // fork if > 1 cnxn path->Visit(this); for (UList* u = _cnxns->First(); u != _cnxns->End(); u = u->Next()) { Connector* peer = Conn(u); if (!path->Visited(peer)) { if (forking) { Path fork(path); Retransmit(peer, &fork); } else { Retransmit(peer, path); } } } }
static bytebuff_t * paa_process(pana_session_t * pacs, bytebuff_t * datain) { paa_ctx_t * ctx = pacs->ctx; bytebuff_t * respData; pana_packet_t * pkt_in = NULL; pana_avp_node_t * tmpavplist = NULL; pana_avp_t * tmp_avp; if (datain != NULL) { dbg_hexdump(PKT_RECVD, "Packet-contents:", bytebuff_data(datain), datain->used); pkt_in = parse_pana_packet(datain); if (pkt_in == NULL) { dbg_printf(MSG_ERROR,"Packet is invalid"); clear_events(); return NULL; } } #define RTX_COUNTER (ctx->rtx_timer.count) #define RTX_MAX_NUM (cfg->rtx_max_count) // ---------- // State: ANY // ---------- // - - - - - - - - - - - - - (Re-transmissions)- - - - - - - - - - // RTX_TIMEOUT && Retransmit(); (no change) // RTX_COUNTER< // RTX_MAX_NUM // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RTX_TIMEOUT && RTX_COUNTER < RTX_MAX_NUM) { clear_events(); Retransmit(pacs); } // - - - - - - - (Reach maximum number of transmissions)- - - - - - // (RTX_TIMEOUT && Disconnect(); CLOSED // RTX_COUNTER>= // RTX_MAX_NUM) || // SESS_TIMEOUT // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if ((RTX_TIMEOUT && RTX_COUNTER >= RTX_MAX_NUM) || SESS_TIMEOUT) { clear_events(); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } if (PKT_RECVD) { // ------------------------- // State: ANY except INITIAL // ------------------------- // - - - - - - - - - - (liveness test initiated by peer)- - - - - - // Rx:PNR[P] Tx:PNA[P](); (no change) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (pacs->cstate != PAA_STATE_INITIAL) { if (RX_PNR_P(pkt_in)) { /* reset the event status */ clear_events(); TX_PNA_P(respData, NULL); } } // ------------------------- // State: ANY except WAIT_PNA_PING // ------------------------- // - - - - - - - - - - - - (liveness test response) - - - - - - - - // Rx:PNA[P] None(); (no change) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (pacs->cstate != PAA_STATE_WAIT_PNA_PING){ if (RX_PNA_P(pkt_in)) { clear_events(); /* just discard the packet because it's not meant occur in this phase */ } } } // ------------------------- // State: CLOSED // ------------------------- // - - - - - - - -(Catch all event on closed state) - - - - - - - - // ANY None(); CLOSED // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (pacs->cstate == PAA_STATE_CLOSED){ clear_events(); /* just discard the packet because it's not meant occur in this phase */ } while(ctx->event_occured) { switch (pacs->cstate) { // ------------------------------ // State: INITIAL (Initial State) // ------------------------------ case PAA_STATE_INITIAL: // ------------------------+--------------------------+------------ // - - - - - - - - (PCI and PAA initiated PANA) - - - - - - - - - // (Rx:PCI[] || if (OPTIMIZED_INIT == INITIAL // PAC_FOUND) Set) { // EAP_Restart(); // SessionTimerReStart // (FAILED_SESS_TIMEOUT); // } // else { // if (generate_pana_sa()) // Tx:PAR[S]("PRF-Algorithm", // "Integrity-Algorithm"); // else // Tx:PAR[S](); // } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PCI(pkt_in)) { clear_events(); if (OPTIMIZED_INIT) { EAP_Restart(pacs); SessionTimerReStart(pacs, FAILED_SESS_TIMEOUT); } else { if (generate_pana_sa()) { tmpavplist = AVPLIST(PAVP_PRF_ALG,"Integrity-Algorithm"); TX_PAR_S(respData, tmpavplist); } else { TX_PAR_S(respData, NULL); } } pacs->cstate = PAA_STATE_INITIAL; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // EAP_REQUEST if (generate_pana_sa()) INITIAL // Tx:PAR[S]("EAP-Payload", // "PRF-Algorithm", // "Integrity-Algorithm"); // else // Tx:PAR[S]("EAP-Payload"); // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_REQUEST) { clear_events(); if (generate_pana_sa()) { tmpavplist = AVPLIST(PAVP_EAP_PAYLOAD,PAVP_PRF_ALG,"Integrity-Algorithm"); TX_PAR_S(respData, tmpavplist); } else{ tmpavplist = AVPLIST(PAVP_EAP_PAYLOAD); TX_PAR_S(respData, tmpavplist); } RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_INITIAL; } // - - - - - - - - - - - - - - (PAN Handling) - - - - - - - - - - // Rx:PAN[S] && if (PAN.exist_avp WAIT_EAP_MSG // ((OPTIMIZED_INIT == ("EAP-Payload")) // Unset) || TxEAP(); // PAN.exist_avp else { // ("EAP-Payload")) EAP_Restart(); // SessionTimerReStart // (FAILED_SESS_TIMEOUT); // } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (RX_PAN_S(pkt_in) && ((!OPTIMIZED_INIT) || exists_avp(pkt_in, PAVP_EAP_PAYLOAD))) { clear_events(); pacs->seq_rx = pkt_in->pp_seq_number; tmp_avp = get_vend_avp_by_code(pkt_in->pp_avp_list, PAVP_PEER_MACADDR, PANA_VENDOR_UPB, AVP_GET_FIRST); if (tmp_avp) { memcpy(ctx->peer_macaddr, tmp_avp->avp_value, MACADDR_LEN); } if (exists_avp(pkt_in, PAVP_EAP_PAYLOAD)) { TxEAP(pacs, pkt_in); } else { EAP_Restart(pacs); SessionTimerReStart(pacs, FAILED_SESS_TIMEOUT); } pacs->cstate = PAA_STATE_WAIT_EAP_MSG; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Rx:PAN[S] && None(); WAIT_PAN_OR_PAR // (OPTIMIZED_INIT == // Set) && // ! PAN.exist_avp // ("EAP-Payload") // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (RX_PAN_S(pkt_in) &&(OPTIMIZED_INIT) && !exists_avp(pkt_in, PAVP_EAP_PAYLOAD)) { clear_events(); pacs->seq_rx = pkt_in->pp_seq_number; // None(); pacs->cstate = PAA_STATE_WAIT_PAN_OR_PAR; } break; // ------------------- // State: WAIT_EAP_MSG // ------------------- case PAA_STATE_WAIT_EAP_MSG: // - - - - - - - - - - - -(Receiving EAP-Request)- - - - - - - - - // EAP_REQUEST if (NONCE_SENT==Unset) { WAIT_PAN_OR_PAR // Tx:PAR[]("Nonce", // "EAP-Payload"); // NONCE_SENT=Set; // } // else // Tx:PAR[]("EAP-Payload"); // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (EAP_REQUEST) { clear_events(); if (!NONCE_SENT) { tmpavplist = AVPLIST(PAVP_NONCE, PAVP_EAP_PAYLOAD); TX_PAR(respData, tmpavplist); NONCE_SENT_Set(); } else { tmpavplist = AVPLIST(PAVP_EAP_PAYLOAD); TX_PAR(respData, tmpavplist); } RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_WAIT_PAN_OR_PAR; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - -(Receiving EAP-Success/Failure) - - - - - // EAP_FAILURE PAR.RESULT_CODE = WAIT_FAIL_PAN // PANA_AUTHENTICATION_ // REJECTED; // Tx:PAR[C]("EAP-Payload"); // RtxTimerStart(); // SessionTimerStop(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_FAILURE) { clear_events(); tmpavplist = AVPLIST(PAVP_RESULT_AUTHENTICATION_REJECTED, PAVP_EAP_PAYLOAD); TX_PAR_C(respData, tmpavplist); RtxTimerStart(pacs, respData); SessionTimerStop(pacs); pacs->cstate = PAA_STATE_WAIT_FAIL_PAN; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // EAP_SUCCESS && PAR.RESULT_CODE = WAIT_SUCC_PAN // Authorize() PANA_SUCCESS; // if (new_key_available()) // Tx:PAR[C]("EAP-Payload", // "Key-Id"); // else // Tx:PAR[C]("EAP-Payload"); // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_SUCCESS && Authorize(pacs)) { clear_events(); if (new_key_available()) { tmpavplist = AVPLIST(PAVP_RESULT_SUCCESS, PAVP_EAP_PAYLOAD,"Key-Id"); TX_PAR_C(respData, tmpavplist); } else{ tmpavplist = AVPLIST(PAVP_RESULT_SUCCESS, PAVP_EAP_PAYLOAD); TX_PAR_C(respData, tmpavplist);} RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_WAIT_SUCC_PAN; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // EAP_SUCCESS && PAR.RESULT_CODE = WAIT_FAIL_PAN // !Authorize() PANA_AUTHORIZATION_ // REJECTED; // if (new_key_available()) // Tx:PAR[C]("EAP-Payload", // "Key-Id"); // else // Tx:PAR[C]("EAP-Payload"); // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_SUCCESS && !Authorize(pacs)) { clear_events(); if (new_key_available()) { tmpavplist = AVPLIST(PAVP_RESULT_AUTHORIZATION_REJECTED ,PAVP_EAP_PAYLOAD,"Key-Id"); TX_PAR_C(respData, tmpavplist); }else{ tmpavplist = AVPLIST(PAVP_RESULT_AUTHORIZATION_REJECTED, PAVP_EAP_PAYLOAD); TX_PAR_C(respData, tmpavplist); } RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_WAIT_FAIL_PAN; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - (Receiving EAP-Timeout or invalid message) - - - - - // EAP_TIMEOUT || SessionTimerStop(); CLOSED // EAP_DISCARD Disconnect(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_TIMEOUT || EAP_DISCARD) { clear_events(); SessionTimerStop(pacs); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -------------------- // State: WAIT_SUCC_PAN // -------------------- case PAA_STATE_WAIT_SUCC_PAN: // - - - - - - - - - - - - - (PAN Processing)- - - - - - - - - - - // Rx:PAN[C] RtxTimerStop(); OPEN // SessionTimerReStart // (LIFETIME_SESS_TIMEOUT); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PAN_C(pkt_in)) { clear_events(); RtxTimerStop(pacs); SessionTimerReStart(pacs, LIFETIME_SESS_TIMEOUT); pacs->cstate = PAA_STATE_OPEN; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -------------------- // State: WAIT_FAIL_PAN // -------------------- case PAA_STATE_WAIT_FAIL_PAN: // - - - - - - - - - - - - - - (PAN Processing)- - - - - - - - - - // Rx:PAN[C] RtxTimerStop(); CLOSED // Disconnect(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PAN_C(pkt_in)) { clear_events(); RtxTimerStop(pacs); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ----------- // State: OPEN // ----------- case PAA_STATE_OPEN: // - - - - - - - - (re-authentication initiated by PaC) - - - - - - // Rx:PNR[A] NONCE_SENT=Unset; WAIT_EAP_MSG // EAP_Restart(); // Tx:PNA[A](); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PNR_A(pkt_in)) { clear_events(); NONCE_SENT_Unset(); EAP_Restart(pacs); TX_PNA_A(respData, NULL); pacs->cstate = PAA_STATE_WAIT_EAP_MSG; } // - - - - - - - - (re-authentication initiated by PAA)- - - - - - // REAUTH || NONCE_SENT=Unset; WAIT_EAP_MSG // REAUTH_TIMEOUT EAP_Restart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* will require the PaC to reauth */ else if (REAUTH ) { clear_events(); NONCE_SENT_Unset(); EAP_Restart(pacs); pacs->cstate = PAA_STATE_WAIT_EAP_MSG; } // - - (liveness test based on PNR-PNA exchange initiated by PAA)- // PANA_PING Tx:PNR[P](); WAIT_PNA_PING // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (PANA_PING) { clear_events(); TX_PNR_P(respData, NULL); RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_WAIT_PNA_PING; } // - - - - - - - - (Session termination initated from PAA) - - - - // TERMINATE Tx:PTR[](); SESS_TERM // SessionTimerStop(); // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (TERMINATE) { clear_events(); TX_PTR(respData, NULL); SessionTimerStop(pacs); RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_SESS_TERM; } // - - - - - - - - (Session termination initated from PaC) - - - - // Rx:PTR[] Tx:PTA[](); CLOSED // SessionTimerStop(); // Disconnect(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (RX_PTR(pkt_in)) { clear_events(); TX_PTA(respData, NULL); SessionTimerStop(pacs); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // -------------------- // State: WAIT_PNA_PING // -------------------- case PAA_STATE_WAIT_PNA_PING: // - - - - - - - - - - - - - -(PNA processing) - - - - - - - - - - // Rx:PNA[P] RtxTimerStop(); OPEN // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PNA_P(pkt_in)) { clear_events(); RtxTimerStop(pacs); pacs->cstate = PAA_STATE_OPEN; } // - - - - - - - - (re-authentication initiated by PaC) - - - - - - // Rx:PNR[A] RtxTimerStop(); WAIT_EAP_MSG // NONCE_SENT=Unset; // EAP_Restart(); // Tx:PNA[A](); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (RX_PNR_A(pkt_in)) { clear_events(); RtxTimerStop(pacs); NONCE_SENT_Unset(); EAP_Restart(pacs); TX_PNA_A(respData, NULL); pacs->cstate = PAA_STATE_WAIT_EAP_MSG; } // - - - - - - - - (Session termination initated from PaC) - - - - // Rx:PTR[] RtxTimerStop(); CLOSED // Tx:PTA[](); // SessionTimerStop(); // Disconnect(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if ( RX_PTR(pkt_in)) { clear_events(); RtxTimerStop(pacs); TX_PTA(respData, NULL); SessionTimerStop(pacs); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ---------------------- // State: WAIT_PAN_OR_PAR // ---------------------- case PAA_STATE_WAIT_PAN_OR_PAR: // - - - - - - - - - - - - - (PAR Processing)- - - - - - - - - - - // Rx:PAR[] TxEAP(); WAIT_EAP_MSG // RtxTimerStop(); // Tx:PAN[](); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PAR(pkt_in)) { clear_events(); TxEAP(pacs, pkt_in); RtxTimerStop(pacs); TX_PAN(respData, NULL); pacs->cstate = PAA_STATE_WAIT_EAP_MSG; } // - - - - - - (Pass EAP Response to the EAP authenticator)- - - - // Rx:PAN[] && TxEAP(); WAIT_EAP_MSG // PAN.exist_avp RtxTimerStop(); // ("EAP-Payload") // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (RX_PAN(pkt_in) && exists_avp(pkt_in, PAVP_EAP_PAYLOAD)) { clear_events(); TxEAP(pacs, pkt_in); RtxTimerStop(pacs); pacs->cstate = PAA_STATE_WAIT_EAP_MSG; } // - - - - - - - - - - (PAN without an EAP response) - - - - - - - // Rx:PAN[] && RtxTimerStop(); WAIT_PAN_OR_PAR // !PAN.exist_avp // ("EAP-Payload") // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (RX_PAN(pkt_in) && !exists_avp(pkt_in, PAVP_EAP_PAYLOAD)) { clear_events(); RtxTimerStop(pacs); pacs->cstate = PAA_STATE_WAIT_PAN_OR_PAR; } // - - - - - - - - - - - -(EAP retransmission) - - - - - - - - - - // EAP_REQUEST RtxTimerStop(); WAIT_PAN_OR_PAR // Tx:PAR[]("EAP-Payload"); // RtxTimerStart(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_REQUEST) { clear_events(); RtxTimerStop(pacs); tmpavplist = AVPLIST(PAVP_EAP_PAYLOAD); TX_PAR(respData, tmpavplist); RtxTimerStart(pacs, respData); pacs->cstate = PAA_STATE_WAIT_PAN_OR_PAR; } // - - - - - - - (EAP authentication timeout or failure)- - - - - // EAP_FAILURE || RtxTimerStop(); CLOSED // EAP_TIMEOUT || SessionTimerStop(); // EAP_DISCARD Disconnect(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else if (EAP_FAILURE || EAP_TIMEOUT ||EAP_DISCARD ) { clear_events(); RtxTimerStop(pacs); SessionTimerStop(pacs); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // ---------------- // State: SESS_TERM // ---------------- case PAA_STATE_SESS_TERM: // - - - - - - - - - - - - - -(PTA processing) - - - - - - - - - - // Rx:PTA[] RtxTimerStop(); CLOSED // Disconnect(); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (RX_PTA(pkt_in)) { clear_events(); RtxTimerStop(pacs); Disconnect(pacs); pacs->cstate = PAA_STATE_CLOSED; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /* End switch */ } } if (respData == NULL) { return NULL; } dbgi_asciihexdump(respData,"replycontents:",bytebuff_data(respData), respData->used); return respData; }