[hipl-commit] [tiny] Rev 3766: Modularized dynmaic user message handling.

  • From: Tim Just <tim.just@xxxxxxxxxxxxxx>
  • To: hipl-commit@xxxxxxxxxxxxx
  • Date: Sun, 18 Apr 2010 20:21:28 +0300

Committer: Tim Just <tim.just@xxxxxxxxxxxxxx>
Date: 18/04/2010 at 20:21:28
Revision: 3766
Revision-id: tim.just@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Branch nick: tiny

Log:
  Modularized dynmaic user message handling.
  
  This re-enables manual-update triggering. Also enabled waiting for address
  stabilization on address change.

Modified:
  M  hipd/hip_socket.c
  M  hipd/hipd.c
  M  hipd/init.c
  M  hipd/user.c
  M  hipd/user.h
  M  modules/heartbeat/hipd/heartbeat.c
  M  modules/update/hipd/update.c

=== modified file 'hipd/hip_socket.c'
--- hipd/hip_socket.c   2010-03-31 15:04:18 +0000
+++ hipd/hip_socket.c   2010-04-18 17:20:23 +0000
@@ -82,17 +82,43 @@
 
 static int hip_handle_user_sock(struct hip_packet_context *ctx)
 {
-    int err = 0;
+    int err = 0, send_response = 0, n = 0, len = 0;
+    uint8_t msg_type = 0;
     struct sockaddr_in6 app_src;
 
-    if (hip_read_user_control_msg(hip_user_sock,
-                                  ctx->input_msg,
-                                  &app_src)) {
-        HIP_ERROR("Reading user msg failed\n");
+
+    HIP_IFEL(hip_read_user_control_msg(hip_user_sock,
+                                       ctx->input_msg,
+                                       &app_src),
+             -1,
+             "Reading user msg failed\n");
+
+    msg_type      = hip_get_msg_type(ctx->input_msg);
+    send_response = hip_get_msg_response(ctx->input_msg);
+
+    if (hip_user_run_handles(msg_type, ctx->input_msg, &app_src)) {
+        err = hip_handle_user_msg(ctx->input_msg, &app_src, &send_response);
+    }
+
+    if (send_response) {
+        HIP_DEBUG("Send response\n");
+        if (err) {
+            hip_set_msg_err(ctx->input_msg, 1);
+        }
+        len = hip_get_msg_total_len(ctx->input_msg);
+        HIP_DEBUG("Sending message (type=%d) response to port %d \n",
+                  hip_get_msg_type(ctx->input_msg), ntohs(app_src.sin6_port));
+        HIP_DEBUG_HIT("To address", &app_src.sin6_addr);
+        n   = hip_sendto_user(ctx->input_msg, (struct sockaddr *)  &app_src);
+        if (n != len) {
+            err = -1;
+        } else {
+            HIP_DEBUG("Response sent ok\n");
+        }
     } else {
-        err = hip_handle_user_msg(ctx->input_msg, &app_src);
+        HIP_DEBUG("No response sent\n");
     }
-
+out_err:
     return err;
 }
 

=== modified file 'hipd/hipd.c'
--- hipd/hipd.c 2010-04-13 06:52:09 +0000
+++ hipd/hipd.c 2010-04-18 17:20:23 +0000
@@ -116,7 +116,7 @@
 int hip_shotgun_status                       = HIP_MSG_SHOTGUN_OFF;
 
 int hip_trigger_update_on_heart_beat_failure = 1;
-int hip_wait_addr_changes_to_stabilize       = 0;
+int hip_wait_addr_changes_to_stabilize       = 1;
 
 static void usage(void)
 {

=== modified file 'hipd/init.c'
--- hipd/init.c 2010-04-13 06:52:09 +0000
+++ hipd/init.c 2010-04-18 17:20:23 +0000
@@ -25,6 +25,7 @@
 #include "nsupdate.h"
 #include "pkt_handling.h"
 #include "output.h"
+#include "user.h"
 #include "lib/core/common_defines.h"
 #include "lib/core/debug.h"
 #include "lib/core/hip_capability.h"
@@ -1144,6 +1145,8 @@
 
     hip_uninit_handle_functions();
 
+    hip_user_uninit_handles();
+
     hip_uninit_maint_functions();
 
     lmod_uninit_packet_types();

=== modified file 'hipd/user.c'
--- hipd/user.c 2010-04-13 06:52:09 +0000
+++ hipd/user.c 2010-04-18 17:20:23 +0000
@@ -20,19 +20,170 @@
  * @author  Bing Zhou <bingzhou_cc.hut.fi>
  * @author  Tao Wan  <twan_cc.hut.fi>
  * @author  Rene Hummen
+ * @author  Tim Just
  * @todo split the gigantic hip_handle_user_msg() into an array of handler 
functions
  */
 
 #define _BSD_SOURCE
 
 #include "config.h"
+#include "user.h"
 #include "accessor.h"
-#include "user.h"
 #include "esp_prot_anchordb.h"
+#include "hipd.h"
 #include "nsupdate.h"
+#include "lib/core/hip_udp.h"
 #include "lib/core/hostid.h"
-#include "lib/core/hip_udp.h"
-#include "hipd.h"
+#include "lib/core/icomm.h"
+#include "lib/core/protodefs.h"
+#include "lib/core/state.h"
+#include "lib/modularization/lmod.h"
+
+struct usr_msg_handle {
+    uint16_t priority;
+    int    (*func_ptr)(hip_common_t *msg, struct sockaddr_in6 *src);
+};
+
+static hip_ll_t *hip_user_msg_handles[HIP_MSG_ROOT_MAX];
+
+/**
+ * hip_register_handle_function
+ *
+ * Register a function for handling of the specified combination from packet
+ * type and host association state.
+ *
+ * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
+ * @param ha_state The host association state (RFC 5201, 4.4.1.)
+ * @param *handle_function Pointer to the function which should be called
+ *                         when the combination of packet type and host
+ *                         association state is reached.
+ * @param priority Execution priority for the handle function.
+ *
+ * @return Success =  0
+ *         Error   = -1
+ */
+int hip_user_register_handle(const uint8_t msg_type,
+                             int (*handle_func)(hip_common_t *msg,
+                                                struct sockaddr_in6 *src),
+                             const uint16_t priority)
+{
+    int err = 0;
+    struct usr_msg_handle *new_entry = NULL;
+
+    HIP_IFEL(msg_type > HIP_MSG_ROOT_MAX,
+             -1,
+             "Maximum message type exceeded.\n");
+
+    HIP_IFEL(!(new_entry = malloc(sizeof(struct usr_msg_handle))),
+             -1,
+             "Error on allocating memory for a handle function entry.\n");
+
+    new_entry->priority    = priority;
+    new_entry->func_ptr    = handle_func;
+
+    hip_user_msg_handles[msg_type] =
+            lmod_register_function(hip_user_msg_handles[msg_type],
+                                   new_entry,
+                                   priority);
+    if (!hip_user_msg_handles[msg_type]) {
+        HIP_ERROR("Error on registering a handle function.\n");
+        err = -1;
+    }
+out_err:
+    return err;
+}
+
+/**
+ * hip_unregister_handle_function
+ *
+ * Unregister a function for handling of the specified combination from packet
+ * type and host association state.
+ *
+ * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
+ * @param ha_state The host association state (RFC 5201, 4.4.1.)
+ * @param *handle_function Pointer to the function which should be 
unregistered.
+ *
+ * @return Success =  0
+ *         Error   = -1
+ */
+int hip_user_unregister_handle(const uint8_t msg_type,
+                               const int (*handle_func)(hip_common_t *msg,
+                                                        struct sockaddr_in6 
*src))
+{
+    int err = 0;
+
+    HIP_IFEL(msg_type > HIP_MSG_ROOT_MAX,
+             -1,
+             "Maximum message type exceeded.\n");
+
+    err = lmod_unregister_function(hip_user_msg_handles[msg_type],
+                                   handle_func);
+
+out_err:
+    return err;
+}
+
+/**
+ * hip_run_handle_functions
+ *
+ * Run all handle functions for specified combination from packet type and host
+ * association state.
+ *
+ * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
+ * @param ha_state The host association state (RFC 5201, 4.4.1.)
+ * @param *ctx The packet context containing the received message, source and
+ *             destination address, the ports and the corresponding entry from
+ *             the host association database.
+ *
+ * @return Success =  0
+ *         Error   = -1
+ */
+int hip_user_run_handles(const uint8_t msg_type,
+                         hip_common_t *msg,
+                         struct sockaddr_in6 *src)
+{
+    int            err  = 0;
+    hip_ll_node_t *iter = NULL;
+
+    HIP_IFEL(msg_type > HIP_MSG_ROOT_MAX,
+             -1,
+             "Maximum message type exceeded.\n");
+
+    if (!hip_user_msg_handles[msg_type] ||
+        !hip_ll_get_size(hip_user_msg_handles[msg_type])) {
+        HIP_DEBUG("User message (type: %d) not dynamically handled -> " \
+                  "trigger static handling.\n", msg_type);
+        return 1;
+    }
+
+    while ((iter = hip_ll_iterate(hip_user_msg_handles[msg_type],
+                                  iter))) {
+
+        ((struct usr_msg_handle *) iter->ptr)->func_ptr(msg, src);
+    }
+
+out_err:
+    return err;
+}
+
+/**
+ * hip_uninit_handle_functions
+ *
+ * Free the memory used for storage of handle functions.
+ *
+ */
+void hip_user_uninit_handles(void)
+{
+    int i;
+
+    for (i = 0; i < HIP_MSG_ROOT_MAX; i++) {
+        if (hip_user_msg_handles[i]) {
+            hip_ll_uninit(hip_user_msg_handles[i], free);
+            free(hip_user_msg_handles[i]);
+        }
+    }
+}
+
 
 /**
  * send a response message back to the origin
@@ -58,14 +209,15 @@
  * @param  src the origin of the sender
  * @return zero on success, or negative error value on error.
  */
-int hip_handle_user_msg(hip_common_t *msg, struct sockaddr_in6 *src)
+int hip_handle_user_msg(hip_common_t *msg,
+                        struct sockaddr_in6 *src,
+                        int *send_response)
 {
     hip_hit_t *src_hit           = NULL, *dst_hit = NULL;
     hip_ha_t *entry              = NULL;
-    int err                      = 0, msg_type = 0, n = 0, len = 0, reti = 0;
+    int err                      = 0, msg_type = 0, n = 0, reti = 0;
     int access_ok                = 0, is_root = 0;
     struct hip_tlv_common *param = NULL;
-    int send_response            = 0;
 
     HIP_ASSERT(src->sin6_family == AF_INET6);
     HIP_DEBUG("User message from port %d\n", htons(src->sin6_port));
@@ -77,8 +229,6 @@
         goto out_err;
     }
 
-    send_response = hip_get_msg_response(msg);
-
     msg_type      = hip_get_msg_type(msg);
 
     is_root       = (ntohs(src->sin6_port) < 1024);
@@ -122,7 +272,7 @@
         }
         break;
     case HIP_MSG_RST:
-        //send_response = 0;
+        //*send_response = 0;
         err                = hip_send_close(msg, 1);
         break;
     case HIP_MSG_BOS:
@@ -136,19 +286,6 @@
         HIP_DEBUG("Recreate all R1s\n");
         hip_recreate_all_precreated_r1_packets();
         break;
-        /** @todo Remove dependency to UPDATE code */
-#if 0
-    case HIP_MSG_LOCATOR_GET:
-        HIP_DEBUG("Got a request for locators\n");
-        hip_msg_init(msg);
-        HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_LOCATOR_GET, 0), -1,
-                 "Failed to build user message header.: %s\n",
-                 strerror(err));
-        if ((err = hip_build_locators_old(msg, 0)) < 0) {
-            HIP_DEBUG("LOCATOR parameter building failed\n");
-        }
-#endif
-        break;
     case HIP_MSG_SET_LOCATOR_ON:
         HIP_DEBUG("Setting LOCATOR ON\n");
         hip_locator_status = HIP_MSG_SET_LOCATOR_ON;
@@ -164,15 +301,6 @@
                   hip_locator_status, HIP_MSG_SET_LOCATOR_OFF);
         hip_recreate_all_precreated_r1_packets();
         break;
-    /** @todo Modularize user message handling */
-#if 0
-    case HIP_MSG_HEARTBEAT:
-        heartbeat         = hip_get_param(msg, HIP_PARAM_HEARTBEAT);
-        hip_icmp_interval = heartbeat->heartbeat;
-        heartbeat_counter = hip_icmp_interval;
-        HIP_DEBUG("Received heartbeat interval (%d seconds)\n", 
hip_icmp_interval);
-        break;
-#endif
     case HIP_MSG_SET_DEBUG_ALL:
         /* Displays all debugging messages. */
         _HIP_DEBUG("Handling DEBUG ALL user message.\n");
@@ -216,13 +344,13 @@
         err = hip_opp_get_peer_hit(msg, src);
         if (err) {
             _HIP_ERROR("get pseudo hit failed.\n");
-            //send_response = 1;
+            //*send_response = 1;
             if (err == -11) {           /* immediate fallback, do not pass */
                 err = 0;
             }
             goto out_err;
         } else {
-            //send_response = 0;
+            //*send_response = 0;
         }
         /* skip sending of return message; will be sent later in R1 */
         goto out_err;
@@ -648,7 +776,7 @@
             HIP_DEBUG("hipconf datapacket ok (sent %d bytes)\n", n);
             break;
         }
-        send_response = 1;
+        *send_response = 1;
         break;
     }
 
@@ -672,7 +800,7 @@
         } else {
             HIP_DEBUG("hipconf datapacket ok (sent %d bytes)\n", n);
         }
-        send_response = 1;
+        *send_response = 1;
         break;
     }
 
@@ -694,7 +822,7 @@
         err           = hip_build_host_id_and_signature(msg, &data_hit);
         msg->type_hdr = original_type;
 
-        send_response = 1;
+        *send_response = 1;
         goto out_err;
     }
     break;
@@ -707,7 +835,7 @@
         break;
     case HIP_MSG_USERSPACE_IPSEC:
         HIP_DUMP_MSG(msg);
-        //send_response = 0;
+        //*send_response = 0;
         err = hip_userspace_ipsec_activate(msg);
         break;
     case HIP_MSG_RESTART_DUMMY_INTERFACE:
@@ -896,37 +1024,11 @@
                  -1, "Build param failed\n");
         break;
     }
-        /** @todo Remove dependency to UPDATE code */
-#if 0
-    case HIP_MSG_MANUAL_UPDATE_PACKET:
-        /// @todo : 13.11.2009: Should we use the msg?
-        err = hip_send_locators_to_all_peers();
-        break;
-#endif
     default:
         HIP_ERROR("Unknown socket option (%d)\n", msg_type);
         err = -ESOCKTNOSUPPORT;
     }
 
 out_err:
-    if (send_response) {
-        HIP_DEBUG("Send response\n");
-        if (err) {
-            hip_set_msg_err(msg, 1);
-        }
-        len = hip_get_msg_total_len(msg);
-        HIP_DEBUG("Sending message (type=%d) response to port %d \n",
-                  hip_get_msg_type(msg), ntohs(src->sin6_port));
-        HIP_DEBUG_HIT("To address", &src->sin6_addr);
-        n   = hip_sendto_user(msg, (struct sockaddr *)  src);
-        if (n != len) {
-            err = -1;
-        } else {
-            HIP_DEBUG("Response sent ok\n");
-        }
-    } else {
-        HIP_DEBUG("No response sent\n");
-    }
-
     return err;
 }

=== modified file 'hipd/user.h'
--- hipd/user.h 2010-03-19 14:29:54 +0000
+++ hipd/user.h 2010-04-18 17:20:23 +0000
@@ -25,7 +25,20 @@
 #include "esp_prot_hipd_msg.h"
 #include "user_ipsec_hipd_msg.h"
 
+int hip_user_register_handle(const uint8_t msg_type,
+                             int (*handle_func)(hip_common_t *msg,
+                                                struct sockaddr_in6 *src),
+                             const uint16_t priority);
+int hip_user_unregister_handle(const uint8_t msg_type,
+                               const int (*handle_func)(hip_common_t *msg,
+                                                        struct sockaddr_in6 
*src));
+int hip_user_run_handles(const uint8_t msg_type,
+                         hip_common_t *msg,
+                         struct sockaddr_in6 *src);
+void hip_user_uninit_handles(void);
 int hip_sendto_user(const struct hip_common *msg, const struct sockaddr *dst);
-int hip_handle_user_msg(hip_common_t *msg, struct sockaddr_in6 *src);
+int hip_handle_user_msg(hip_common_t *msg,
+                        struct sockaddr_in6 *src,
+                        int *send_response);
 
 #endif /* HIP_HIPD_USER_H */

=== modified file 'modules/heartbeat/hipd/heartbeat.c'
--- modules/heartbeat/hipd/heartbeat.c  2010-04-13 06:52:09 +0000
+++ modules/heartbeat/hipd/heartbeat.c  2010-04-18 17:20:23 +0000
@@ -389,6 +389,21 @@
     return 0;
 }
 
+static int hip_heartbeat_handle_usr_msg(hip_common_t *msg,
+                                        struct sockaddr_in6 *src)
+{
+    int err = 0;
+
+#if 0
+    heartbeat         = hip_get_param(msg, HIP_PARAM_HEARTBEAT);
+    hip_icmp_interval = heartbeat->heartbeat;
+    heartbeat_counter = hip_icmp_interval;
+    HIP_DEBUG("Received heartbeat interval (%d seconds)\n", hip_icmp_interval);
+#endif
+
+    return err;
+}
+
 static int hip_heartbeat_init_state(struct modular_state *state)
 {
     int err = 0;
@@ -445,6 +460,12 @@
              -1,
              "Error on registration of hip_heartbeat_init_state().\n");
 
+    HIP_IFEL(hip_user_register_handle(HIP_MSG_HEARTBEAT,
+                                      &hip_heartbeat_handle_usr_msg,
+                                      20000),
+             -1,
+             "Error on registering HEARTBEAT user message handle function.\n");
+
 out_err:
     return err;
 }

=== modified file 'modules/update/hipd/update.c'
--- modules/update/hipd/update.c        2010-04-13 06:52:09 +0000
+++ modules/update/hipd/update.c        2010-04-18 17:20:23 +0000
@@ -20,6 +20,7 @@
 #include "hipd/netdev.h"
 #include "hipd/nsupdate.h"
 #include "hipd/pkt_handling.h"
+#include "hipd/user.h"
 #include "update_legacy.h"
 #include "hipd/esp_prot_hipd_msg.h"
 
@@ -577,7 +578,6 @@
     }
 
 out_err:
-
     /* Update DNS data in hit-to-ip domain name. This is done after
      * sending UPDATE packets. See the discussion for the reasoning:
      * 
http://www.freelists.org/post/hipl-users/HIP-UPDATE-select-error-Interrupted-system-call,2
 */
@@ -774,6 +774,23 @@
     ipv6_addr_copy(&ha->peer_addr, dst_addr);
 }
 
+/**
+ * hip_update_manual_update
+ *
+ * Thin wrapper function around hip_send_locators_to_all_peers. Needed for
+ * registration as user message handle function.
+ *
+ * @param *msg unused, needed due to type check of handle functions
+ * @param *src unused, needed due to type check of handle functions
+ *
+ * @return zero on success or negative on failure
+ */
+static int hip_update_manual_update(hip_common_t *msg, struct sockaddr_in6 
*src)
+{
+    HIP_DEBUG("Manual UPDATE triggered.\n");
+    return hip_send_locators_to_all_peers();
+}
+
 static int hip_update_maintenance(void)
 {
     int err = 0;
@@ -1126,6 +1143,23 @@
                                           30000),
              -1, "Error on registering UPDATE handle function.\n");
 
+    HIP_IFEL(hip_user_register_handle(HIP_MSG_MANUAL_UPDATE_PACKET,
+                                      &hip_update_manual_update,
+                                      20000),
+             -1, "Error on registering UPDATE user message handle 
function.\n");
+#if 0
+    case HIP_MSG_LOCATOR_GET:
+        HIP_DEBUG("Got a request for locators\n");
+        hip_msg_init(msg);
+        HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_LOCATOR_GET, 0), -1,
+                 "Failed to build user message header.: %s\n",
+                 strerror(err));
+        if ((err = hip_build_locators_old(msg, 0)) < 0) {
+            HIP_DEBUG("LOCATOR parameter building failed\n");
+        }
+
+#endif
+
     HIP_IFEL(hip_register_maint_function(&hip_update_maintenance, 40000),
              -1,
              "Error on registering UPDATE maintenance function.\n");

Other related posts:

  • » [hipl-commit] [tiny] Rev 3766: Modularized dynmaic user message handling. - Tim Just