X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcske%2Fsilcske.c;fp=lib%2Fsilcske%2Fsilcske.c;h=a4822e95a505a8cb709d6d63bfb0f4eabf9e8f0f;hb=3192ac4ddd09cd3fabe10a88cd5c885f217650a4;hp=1987ffc279f737dcb91d2ee65f1ff4df4941dec2;hpb=5c43a88e369950a34b1c40d655b598bedd16beda;p=silc.git diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 1987ffc2..a4822e95 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -73,7 +73,41 @@ static SilcBool silc_ske_packet_send(SilcSKE ske, const unsigned char *data, SilcUInt32 data_len); -static void silc_ske_notify_failure(SilcSKE ske); +/* + * Notify the owner of the ske that we failed. Ensures that we don't make the + * same callout twice, as the notification callback routines are not designed + * to handle that case. + */ +static void silc_ske_notify_failure(SilcSKE ske) +{ + SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %lu)", + ske, ske->failure_notified)); + + /* + * First, check if we have already made a failure callout. If so, then we + * will stop here. + */ + if (ske->failure_notified) + return; + + /* + * Mark ourselves as having already sent the failure notification here and + * now. + */ + ske->failure_notified = TRUE; + + SILC_LOG_DEBUG(("Deliver failure notification for SKE %p (%s)", + ske, ske->responder ? "responder" : "initiator")); + + /* + * Finally, make the call to the owner's registered failure callback. + */ + if (ske->responder) + silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure); + else + silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure); +} + /* Packet callback */ static SilcBool silc_ske_packet_receive(SilcPacketEngine engine, @@ -108,9 +142,8 @@ static SilcBool silc_ske_packet_receive(SilcPacketEngine engine, } /* See if received failure from remote */ - if (packet->type == SILC_PACKET_FAILURE) { + if (packet->type == SILC_PACKET_FAILURE) silc_ske_notify_failure(ske); - } /* Handle rekey and SUCCESS packets synchronously. After SUCCESS packets they keys are taken into use immediately, hence the synchronous @@ -968,8 +1001,7 @@ static void silc_ske_finished(SilcFSM fsm, void *fsm_context, void *destructor_context) { SilcSKE ske = fsm_context; - ske->fsm_finished = TRUE; - silc_ske_free(ske); + silc_ske_free(ske); } /* Key exchange timeout task callback */ @@ -1030,28 +1062,28 @@ void silc_ske_free(SilcSKE ske) if (!ske) return; - SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", ske, ske->aborted, ske->refcnt)); - - if (ske->aborted) { - /* - * If already aborted, destroy the session immediately. Only do the - * notification work if we have not already though, as doing so twice - * results in memory corruption. We may have silc_ske_free called - * twice, once when the abort is requested, and then again when the - * FSM finish routine is called. We have to be prepared to handle - * that case. - */ + SILC_LOG_DEBUG(("Freeing Key Exchange object %p: aborted=%u refcount=%hu", + ske, ske->aborted, ske->refcnt)); - ske->packet = NULL; - ske->status = SILC_SKE_STATUS_ERROR; + if (ske->aborted) { + /* + * If already aborted, destroy the session immediately. Only do the + * notification work if we have not already though, as doing so twice + * results in memory corruption. We may have silc_ske_free called + * twice, once when the abort is requested, and then again when the + * FSM finish routine is called. We have to be prepared to handle + * that case. + */ + ske->packet = NULL; + ske->status = SILC_SKE_STATUS_ERROR; - silc_ske_notify_failure(ske); + silc_ske_notify_failure(ske); - if (!ske->fsm_finished) - silc_fsm_continue_sync(&ske->fsm); - else - SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske)); - } + if (silc_fsm_is_started(&ske->fsm)) + silc_fsm_continue_sync(&ske->fsm); + else + SILC_LOG_DEBUG(("Not continuing FSM as it's finished for SKE %p", ske)); + } ske->refcnt--; if (ske->refcnt > 0) @@ -1801,7 +1833,8 @@ SilcAsyncOperation silc_ske_initiator(SilcSKE ske, SilcSKEParams params, SilcSKEStartPayload start_payload) { - SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; start_payload=%p", ske, stream, params, start_payload)); + SILC_LOG_DEBUG(("Start SKE %p as initiator; stream=%p; params=%p; " + "start_payload=%p", ske, stream, params, start_payload)); if (!ske || !stream || !params || !params->version) return NULL; @@ -3497,40 +3530,3 @@ SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske) { return ske->keymat; } - -/* - * Notify the owner of the ske that we failed. Ensures that we don't make the - * same callout twice, as the notification callback routines are not designed - * to handle that case. - */ -static void silc_ske_notify_failure(SilcSKE ske) -{ - SILC_LOG_DEBUG(("Notifying SKE %p owner of failure (failure_notified = %lu)", ske, ske->failure_notified)); - - /* - * First, check if we have already made a failure callout. If so, then we - * will stop here. - */ - - if (ske->failure_notified) - return; - - /* - * Mark ourselves as having already sent the failure notification here and - * now. - */ - - ske->failure_notified = TRUE; - - SILC_LOG_DEBUG(("Actually calling real failure notify callback for SKE %p (responder = %s)", ske, ske->responder ? "TRUE" : "FALSE")); - - /* - * Finally, make the call to the owner's registered failure callback. - */ - - if (ske->responder) - silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure); - else - silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure); -} -