implemented send_message() callback function
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 6 Nov 2010 19:13:41 +0000 (20:13 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 9 Nov 2010 19:43:50 +0000 (20:43 +0100)
src/libcharon/plugins/tnc_imc/tnc_imc.c
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libcharon/tnc/tnccs/tnccs.h
src/libcharon/tnc/tnccs/tnccs_manager.c
src/libcharon/tnc/tnccs/tnccs_manager.h

index 6e0b4a5..b3f5717 100644 (file)
@@ -18,7 +18,7 @@
 #include <dlfcn.h>
 
 #include <debug.h>
-#include <library.h>
+#include <daemon.h>
 
 typedef struct private_tnc_imc_t private_tnc_imc_t;
 
@@ -166,42 +166,8 @@ TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
 {
        DBG2(DBG_TNC,"TNCC_SendMessage %u %u '%s' %u %0x", imc_id, connection_id,
                                  message, message_len, message_type);
-
-       /*
-       -----TNCCS 2.0-----
-    tnc_tncc_connection* conn;
-
-    conn = libtnc_array_index(&connections, connectionID);
-    
-    TNC_MessageSubtype message_type = messageType             & TNC_SUBTYPE_ANY;
-    TNC_VendorID       message_vendor_id = (messageType >> 8) & TNC_VENDORID_ANY;
-    
-    chunk_t pa_message = tnc_create_pa_message(FALSE, message_vendor_id,
-                                                                       message_type, 0, 0, message, messageLength); 
-        
-    if(conn->current_batch.len)
-    {
-         chunk_t batch = conn->current_batch;
-         htoun32(batch.ptr + 4,batch.len + pa_message.len);
-         conn->current_batch = chunk_cat("cc", batch, pa_message);
-
-    }
-    else
-    {
-         chunk_t header = tnc_create_batch_header(TNCCS_BATCH_TYPE_CDATA, false);
-         
-         htoun32(header.ptr + 4,header.len + pa_message.len);
-         conn->current_batch = chunk_cat("cc", header, pa_message);
-
-    }
-    -----TNCCS 1.1-----
-    libtnc_mutex_lock();
-    conn = libtnc_array_index(&connections, connectionID);
-    libtnc_mutex_unlock();
-    return libtnc_tncc_add_imc_imv_message(conn, message, messageLength, messageType);
-       */
-    return TNC_RESULT_SUCCESS;
+       return charon->tnccs->send_message(charon->tnccs, connection_id, message,
+                                                                          message_len, message_type);
 }
 
 /**
index 2d6bdf5..5afc6e1 100644 (file)
@@ -41,15 +41,32 @@ struct private_tnccs_20_t {
         * Connection ID assigned to this TNCCS connection
         */
        TNC_ConnectionID connection_id;
+
+       /**
+        * Batch being constructed
+        */
+       chunk_t batch;
 };
 
+METHOD(tnccs_t, send_message, void,
+       private_tnccs_20_t* this, TNC_BufferReference message,
+                                                         TNC_UInt32 message_len,
+                                                         TNC_MessageType message_type)
+{
+       chunk_t msg = { message, message_len },
+                       batch = this->batch;
+
+       DBG1(DBG_TNC, "TNCCS 2.0 send message");
+       this->batch = chunk_cat("mc", batch, msg);
+}
+
 METHOD(tls_t, process, status_t,
        private_tnccs_20_t *this, void *buf, size_t buflen)
 {
        if (this->is_server && !this->connection_id)
        {
                this->connection_id = charon->tnccs->create_connection(charon->tnccs,
-                                                                                                                         (tnccs_t*)this);
+                                                                                               (tnccs_t*)this, _send_message);
                charon->imvs->notify_connection_change(charon->imvs,
                                                        this->connection_id, TNC_CONNECTION_STATE_CREATE);
        }
@@ -63,12 +80,15 @@ METHOD(tls_t, process, status_t,
 METHOD(tls_t, build, status_t,
        private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
 {
-       char *msg;
+       char *msg = this->is_server ? "|tncs->tncc 2.0|" : "|tncc->tncs 2.0|";
+       size_t len;
+
+       this->batch = chunk_clone(chunk_create(msg, strlen(msg)));
 
        if (!this->is_server && !this->connection_id)
        {
                this->connection_id = charon->tnccs->create_connection(charon->tnccs,
-                                                                                                                         (tnccs_t*)this);
+                                                                                               (tnccs_t*)this, _send_message);
                charon->imcs->notify_connection_change(charon->imcs,
                                                        this->connection_id, TNC_CONNECTION_STATE_CREATE);
                charon->imcs->notify_connection_change(charon->imcs,
@@ -76,13 +96,15 @@ METHOD(tls_t, build, status_t,
                charon->imcs->begin_handshake(charon->imcs, this->connection_id);
        }
 
-       msg = this->is_server ? "tncs-tncc 2.0" : "tncc-tncs 2.0";
+       len = this->batch.len;
+       *msglen = len;
+       *buflen = len;
+       memcpy(buf, this->batch.ptr, len);
+
        DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
-                                  strlen(msg), this->connection_id);
-       DBG3(DBG_TNC, "%s", msg);
-       *msglen = strlen(msg);
-       memcpy(buf, msg, *msglen);
-       *buflen = *msglen;
+                                  len, this->connection_id);
+       DBG3(DBG_TNC, "%.*s", len, buf);
+       chunk_free(&this->batch);
 
        return ALREADY_DONE;
 }
@@ -115,6 +137,7 @@ METHOD(tls_t, destroy, void,
        private_tnccs_20_t *this)
 {
        charon->tnccs->remove_connection(charon->tnccs, this->connection_id);
+       free(this->batch.ptr);
        free(this);
 }
 
index 583512e..443e7e7 100644 (file)
 #ifndef TNCCS_H_
 #define TNCCS_H_
 
-typedef enum tnccs_type_t tnccs_type_t;
-
 #include <library.h>
 
+#include <tnc/tncif.h>
+
+typedef enum tnccs_type_t tnccs_type_t;
+
 /**
  * Type of TNC Client/Server protocol
  */
@@ -49,4 +51,16 @@ typedef struct tnccs_t tnccs_t;
  */
 typedef tnccs_t* (*tnccs_constructor_t)(bool is_server);
 
+/**
+ * Callback function adding a message to a TNCCS batch
+ *
+ * @param message              message to be added
+ * @param message_len  message length
+ * @param message_type message type
+ */
+typedef void (*tnccs_send_message_t)(tnccs_t* tncss,
+                                                                        TNC_BufferReference message,
+                                                                        TNC_UInt32 message_len,
+                                                                        TNC_MessageType message_type);
+
 #endif /** TNC_H_ @}*/
index c0b4969..4d0dc24 100644 (file)
@@ -53,6 +53,11 @@ struct tnccs_connection_entry_t {
         * TNCCS instance
         */
        tnccs_t *tnccs;
+
+       /** TNCCS send message function
+        *
+        */
+       tnccs_send_message_t send_message;
 };
 
 /**
@@ -147,12 +152,14 @@ METHOD(tnccs_manager_t, create_instance, tnccs_t*,
 }
 
 METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
-       private_tnccs_manager_t *this, tnccs_t *tnccs)
+       private_tnccs_manager_t *this, tnccs_t *tnccs,
+       tnccs_send_message_t send_message)
 {
        tnccs_connection_entry_t *entry = malloc_thing(tnccs_connection_entry_t);
 
        entry->id = ++this->connection_id;
        entry->tnccs = tnccs;
+       entry->send_message = send_message;
 
        this->lock->write_lock(this->lock);
        this->connections->insert_last(this->connections, entry);
@@ -183,6 +190,39 @@ METHOD(tnccs_manager_t, remove_connection, void,
        this->lock->unlock(this->lock);
 }
 
+METHOD(tnccs_manager_t, send_message, TNC_Result,
+       private_tnccs_manager_t *this, TNC_ConnectionID id,
+                                                                  TNC_BufferReference message,
+                                                                  TNC_UInt32 message_len,
+                                                                  TNC_MessageType message_type)
+{
+       enumerator_t *enumerator;
+       tnccs_connection_entry_t *entry;
+       tnccs_send_message_t send_message;
+       tnccs_t *tnccs = NULL;
+
+       this->lock->write_lock(this->lock);
+       enumerator = this->connections->create_enumerator(this->connections);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (id == entry->id)
+               {
+                       tnccs = entry->tnccs;
+                       send_message = entry->send_message;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->lock->unlock(this->lock);
+
+       if (tnccs)
+       {
+               send_message(tnccs, message, message_len, message_type);
+               return TNC_RESULT_SUCCESS;
+        }
+       return TNC_RESULT_FATAL;
+}
+
 METHOD(tnccs_manager_t, destroy, void,
        private_tnccs_manager_t *this)
 {
@@ -206,6 +246,7 @@ tnccs_manager_t *tnccs_manager_create()
                                .create_instance = _create_instance,
                                .create_connection = _create_connection,
                                .remove_connection = _remove_connection,
+                               .send_message = _send_message,
                                .destroy = _destroy,
                        },
                        .protocols = linked_list_create(),
index 40c3d0a..127147e 100644 (file)
@@ -65,9 +65,11 @@ struct tnccs_manager_t {
         * Create a TNCCS connection and assign a unique connection ID
         *
         * @param tnccs                 TNCCS connection instance
+        * @param send_message  callback function adding a message to a TNCCS batch
         * @result                              assigned connection ID
         */
-       TNC_ConnectionID (*create_connection)(tnccs_manager_t *this, tnccs_t *tnccs);
+       TNC_ConnectionID (*create_connection)(tnccs_manager_t *this, tnccs_t *tnccs,
+                                                                                 tnccs_send_message_t send_message);
 
        /**
         * Remove a TNCCS connection using its connection ID.
@@ -77,6 +79,20 @@ struct tnccs_manager_t {
        void (*remove_connection)(tnccs_manager_t *this, TNC_ConnectionID id);
 
        /**
+        * Add an IMC/IMV message to the batch of a given connection ID.
+        *
+        * @param id                    target connection ID
+        * @param message               message to be added
+        * @param message_len   message length
+        * @param message_type  message type
+        * @result                              return code
+        */
+       TNC_Result (*send_message)(tnccs_manager_t *this, TNC_ConnectionID id,
+                                                                                               TNC_BufferReference message,
+                                                                                               TNC_UInt32 message_len,
+                                                                                               TNC_MessageType message_type);
+
+       /**
         * Destroy a tnccs_manager instance.
         */
        void (*destroy)(tnccs_manager_t *this);