adapted state_machine for retry batches
[strongswan.git] / src / libcharon / plugins / tnccs_20 / tnccs_20.c
index d53fd8e..636f525 100644 (file)
@@ -289,14 +289,21 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
  */
 static void build_retry_batch(private_tnccs_20_t *this)
 {
+       pb_tnc_batch_type_t batch_retry_type;
+
+       batch_retry_type = this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY;
        if (this->batch)
        {
+               if (this->batch->get_type(this->batch) == batch_retry_type)
+               {
+                       /* retry batch has already been created */
+                       return;
+               }
                DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
                        pb_tnc_batch_type_names, this->batch->get_type(this->batch));
                this->batch->destroy(this->batch);
         }
-       this->batch = pb_tnc_batch_create(this->is_server,
-                                               this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY);
+       this->batch = pb_tnc_batch_create(this->is_server, batch_retry_type);
 }
 
 METHOD(tls_t, process, status_t,
@@ -319,6 +326,8 @@ METHOD(tls_t, process, status_t,
                }
                charon->imvs->notify_connection_change(charon->imvs,
                                                        this->connection_id, TNC_CONNECTION_STATE_CREATE);
+               charon->imvs->notify_connection_change(charon->imvs,
+                                                       this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
        }
 
        data = chunk_create(buf, buflen);
@@ -463,6 +472,7 @@ METHOD(tls_t, build, status_t,
        private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
 {
        status_t status;
+       pb_tnc_state_t state;
 
        /* Initialize the connection */
        if (!this->is_server && !this->connection_id)
@@ -494,8 +504,9 @@ METHOD(tls_t, build, status_t,
                charon->imcs->begin_handshake(charon->imcs, this->connection_id);
        }
 
-       if (this->is_server && this->fatal_error &&
-               this->state_machine->get_state(this->state_machine) == PB_STATE_END)
+       state = this->state_machine->get_state(this->state_machine);
+
+       if (this->is_server && this->fatal_error && state == PB_STATE_END)
        {
                DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
                return FAILED;
@@ -506,7 +517,10 @@ METHOD(tls_t, build, status_t,
 
        if (this->request_handshake_retry)
        {
-               build_retry_batch(this);
+               if (state != PB_STATE_INIT)
+               {
+                       build_retry_batch(this);
+               }
 
                /* Reset the flag for the next handshake retry request */
                this->request_handshake_retry = FALSE;
@@ -514,9 +528,6 @@ METHOD(tls_t, build, status_t,
 
        if (!this->batch)
        {
-               pb_tnc_state_t state;
-
-               state = this->state_machine->get_state(this->state_machine);
                if (this->is_server)
                {
                        if (state == PB_STATE_SERVER_WORKING)
@@ -606,11 +617,7 @@ METHOD(tls_t, is_complete, bool,
 
        if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
        {
-               DBG2(DBG_TNC, "Final recommendation is '%N' and evaluation is '%N'",
-                        TNC_IMV_Action_Recommendation_names, rec,
-                        TNC_IMV_Evaluation_Result_names, eval);
-
-               return charon->imvs->enforce_recommendation(charon->imvs, rec);
+               return charon->imvs->enforce_recommendation(charon->imvs, rec, eval);
        }
        else
        {
@@ -627,17 +634,8 @@ METHOD(tls_t, get_eap_msk, chunk_t,
 METHOD(tls_t, destroy, void,
        private_tnccs_20_t *this)
 {
-       if (this->is_server)
-       {
-               charon->imvs->notify_connection_change(charon->imvs,
-                                                       this->connection_id, TNC_CONNECTION_STATE_DELETE);
-       }
-       else
-       {
-               charon->imcs->notify_connection_change(charon->imcs,
-                                                       this->connection_id, TNC_CONNECTION_STATE_DELETE);
-       }
-       charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+       charon->tnccs->remove_connection(charon->tnccs, this->connection_id,
+                                                                                                       this->is_server);
        this->state_machine->destroy(this->state_machine);
        this->mutex->destroy(this->mutex);
        DESTROY_IF(this->batch);