send empty SDATA batch if no recommendation is available yet, but in order to avoid...
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 11 Jul 2012 10:21:29 +0000 (12:21 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 11 Jul 2012 15:09:05 +0000 (17:09 +0200)
src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c
src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.c
src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.h
src/libcharon/plugins/tnccs_20/tnccs_20.c

index 99f5746..383aa95 100644 (file)
@@ -272,6 +272,8 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
                                                                  PB_ERROR_UNEXPECTED_BATCH_TYPE);
                goto fatal;
        }
+       DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names,
+                                                                                               this->type);
 
        /* Batch Length */
        if (this->encoding.len != batch_len)
@@ -284,6 +286,13 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
        }
 
        this->offset = PB_TNC_BATCH_HEADER_SIZE;
+
+       /* Register an empty CDATA batch with the state machine */
+       if (this->type == PB_BATCH_CDATA)
+       {
+               state_machine->set_empty_cdata(state_machine,
+                                                                          this->offset == this->encoding.len);
+       }
        return SUCCESS;
 
 fatal:
@@ -459,8 +468,7 @@ METHOD(pb_tnc_batch_t, process, status_t,
        {
                return FAILED;
        }
-       DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names,
-                                                                                               this->type);
+
        while (this->offset < this->encoding.len)
        {
                switch (process_tnc_msg(this))
index f0cf14a..5e95131 100644 (file)
@@ -71,6 +71,11 @@ struct private_pb_tnc_state_machine_t {
        bool is_server;
 
        /**
+        * Informs whether last received PB-TNC CDATA Batch was empty
+        */
+       bool empty_cdata;
+
+       /**
         * Current PB-TNC state
         */
        pb_tnc_state_t state;
@@ -265,6 +270,22 @@ METHOD(pb_tnc_state_machine_t, send_batch, bool,
        return TRUE;
 }
 
+METHOD(pb_tnc_state_machine_t, get_empty_cdata, bool,
+       private_pb_tnc_state_machine_t *this)
+{
+       return this->empty_cdata;
+}
+
+METHOD(pb_tnc_state_machine_t, set_empty_cdata, void,
+       private_pb_tnc_state_machine_t *this, bool empty)
+{
+       if (empty)
+       {
+               DBG2(DBG_TNC, "received empty PB-TNC CDATA batch");
+       }
+       this->empty_cdata = empty;
+}
+
 METHOD(pb_tnc_state_machine_t, destroy, void,
        private_pb_tnc_state_machine_t *this)
 {
@@ -283,6 +304,8 @@ pb_tnc_state_machine_t* pb_tnc_state_machine_create(bool is_server)
                        .get_state = _get_state,
                        .receive_batch = _receive_batch,
                        .send_batch = _send_batch,
+                       .get_empty_cdata = _get_empty_cdata,
+                       .set_empty_cdata = _set_empty_cdata,
                        .destroy = _destroy,
                },
                .is_server = is_server,
index 8076b6d..d13f20d 100644 (file)
@@ -73,6 +73,20 @@ struct pb_tnc_state_machine_t {
        bool (*send_batch)(pb_tnc_state_machine_t *this, pb_tnc_batch_type_t type);
 
        /**
+        * Informs whether the last received PB-TNC CDATA Batch was empty
+        *
+        * @result                              TRUE if last received PB-TNC CDATA Batch was empty
+        */
+       bool (*get_empty_cdata)(pb_tnc_state_machine_t *this);
+
+       /**
+        * Store information whether the received PB-TNC CDATA Batch was empty
+        *
+        * @bool empty                  set to TRUE if received PB-TNC CDATA Batch was empty
+        */
+       void (*set_empty_cdata)(pb_tnc_state_machine_t *this, bool empty);
+
+       /**
         * Destroys a pb_tnc_state_machine_t object.
         */
        void (*destroy)(pb_tnc_state_machine_t *this);
index aaceed5..206f446 100644 (file)
@@ -632,7 +632,17 @@ METHOD(tls_t, build, status_t,
        if (this->batch_type == PB_BATCH_NONE && this->is_server &&
                state == PB_STATE_SERVER_WORKING)
        {
-               check_and_build_recommendation(this);
+               if (this->state_machine->get_empty_cdata(this->state_machine) ||
+                       this->recs->have_recommendation(this->recs, NULL, NULL))
+               {
+                       check_and_build_recommendation(this);
+               }
+               else
+               {
+                       DBG2(DBG_TNC, "no recommendation available yet, "
+                                                 "sending empty PB-TNC SDATA batch");
+                       this->batch_type = PB_BATCH_SDATA;
+               }
        }
 
        if (this->batch_type != PB_BATCH_NONE)