Fix DLEP handling of mandatory TLVs
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Thu, 22 Mar 2018 08:02:05 +0000 (09:02 +0100)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Thu, 22 Mar 2018 08:02:05 +0000 (09:02 +0100)
src-plugins/generic/dlep/dlep_session.c
src-plugins/generic/dlep/dlep_session.h
src-plugins/generic/dlep/ext_base_proto/proto.c
src-plugins/generic/dlep/radio/dlep_radio_interface.c
src-plugins/generic/dlep/router/dlep_router_interface.c

index 16d7fad..14bf837 100644 (file)
@@ -77,7 +77,7 @@ static enum dlep_parser_error _handle_extension(
   struct dlep_session *session, struct dlep_extension *ext, uint32_t signal_type);
 static enum dlep_parser_error _process_tlvs(
   struct dlep_session *, int32_t signal_type, uint16_t signal_length, const uint8_t *tlvs);
-static void _send_terminate(struct dlep_session *session);
+static void _send_terminate(struct dlep_session *session, enum dlep_status status, const char *status_text);
 static void _cb_destination_timeout(struct oonf_timer_instance *);
 
 static struct oonf_class _tlv_class = {
@@ -224,11 +224,13 @@ dlep_session_remove(struct dlep_session *session) {
 /**
  * Send peer termination
  * @param session dlep session
+ * @param status DLEP status code for termination
+ * @param status_text text message for termination
  */
 void
-dlep_session_terminate(struct dlep_session *session) {
+dlep_session_terminate(struct dlep_session *session, enum dlep_status status, const char *status_text) {
   if (session->restrict_signal != DLEP_ALL_SIGNALS) {
-    dlep_session_generate_signal(session, DLEP_SESSION_TERMINATION, NULL);
+    dlep_session_generate_signal_status(session, DLEP_SESSION_TERMINATION, NULL, status, status_text);
     session->cb_send_buffer(session, 0);
   }
   session->restrict_signal = DLEP_SESSION_TERMINATION_ACK;
@@ -441,7 +443,7 @@ dlep_session_process_signal(struct dlep_session *session, const void *ptr, size_
   }
   if (result != DLEP_NEW_PARSER_OKAY) {
     OONF_WARN(session->log_source, "Parser error: %d", result);
-    _send_terminate(session);
+    _send_terminate(session, DLEP_STATUS_INVALID_DATA, "Incoming signal could not be parsed");
   }
   else if (session->next_restrict_signal != DLEP_KEEP_RESTRICTION) {
     session->restrict_signal = session->next_restrict_signal;
@@ -822,11 +824,13 @@ _process_tlvs(struct dlep_session *session, int32_t signal_type, uint16_t signal
 /**
  * terminate a DLEP session
  * @param session dlep session
+ * @param status DLEP status code for termination
+ * @param status_text text message for termination
  */
 static void
-_send_terminate(struct dlep_session *session) {
+_send_terminate(struct dlep_session *session, enum dlep_status status, const char *status_text) {
   if (session->restrict_signal != DLEP_UDP_PEER_DISCOVERY && session->restrict_signal != DLEP_UDP_PEER_OFFER) {
-    dlep_session_generate_signal(session, DLEP_SESSION_TERMINATION, NULL);
+    dlep_session_generate_signal_status(session, DLEP_SESSION_TERMINATION, NULL, status, status_text);
 
     session->restrict_signal = DLEP_SESSION_TERMINATION_ACK;
     session->next_restrict_signal = DLEP_SESSION_TERMINATION_ACK;
index 6f6d50f..4528665 100644 (file)
@@ -340,7 +340,7 @@ int dlep_session_add(struct dlep_session *session, const char *l2_ifname, const
   const struct oonf_layer2_origin *l2_default_origin, struct autobuf *out, bool radio,
   int (*if_changed)(struct os_interface_listener *), enum oonf_log_source);
 void dlep_session_remove(struct dlep_session *session);
-void dlep_session_terminate(struct dlep_session *session);
+void dlep_session_terminate(struct dlep_session *session, enum dlep_status status, const char *status_text);
 
 int dlep_session_update_extensions(struct dlep_session *session, const uint8_t *extvalues, size_t extcount);
 enum oonf_stream_session_state dlep_session_process_tcp(
index f986aa0..281d2c5 100644 (file)
@@ -153,7 +153,6 @@ static const uint16_t _dst_down_tlvs[] = {
 };
 static const uint16_t _dst_down_mandatory[] = {
   DLEP_MAC_ADDRESS_TLV,
-  DLEP_STATUS_TLV,
 };
 
 /* destination down ack */
@@ -163,6 +162,7 @@ static const uint16_t _dst_down_ack_tlvs[] = {
 };
 static const uint16_t _dst_down_ack_mandatory[] = {
   DLEP_MAC_ADDRESS_TLV,
+  DLEP_STATUS_TLV,
 };
 
 /* destination update */
@@ -588,7 +588,7 @@ _cb_remote_heartbeat(struct oonf_timer_instance *ptr) {
   }
   else {
     /* soft-terminate session (send PEER_TERM) */
-    dlep_session_terminate(session);
+    dlep_session_terminate(session, DLEP_STATUS_TIMED_OUT, "Remote heartbeat timed out");
 
     /* set timeout for hard-termination */
     oonf_timer_set(&session->remote_heartbeat_timeout, session->remote_heartbeat_interval * 2);
index 0886274..7c850d1 100644 (file)
@@ -248,7 +248,7 @@ dlep_radio_terminate_all_sessions(void) {
 
   avl_for_each_element(dlep_if_get_tree(true), interf, interf._node) {
     avl_for_each_element(&interf->interf.session_tree, radio_session, _node) {
-      dlep_session_terminate(&radio_session->session);
+      dlep_session_terminate(&radio_session->session, DLEP_STATUS_OKAY, "DLEP radio is shutting down");
     }
   }
 }
index ef406e3..50504de 100644 (file)
@@ -267,7 +267,7 @@ dlep_router_terminate_all_sessions(void) {
 
   avl_for_each_element(dlep_if_get_tree(false), interf, interf._node) {
     avl_for_each_element(&interf->interf.session_tree, router_session, _node) {
-      dlep_session_terminate(&router_session->session);
+      dlep_session_terminate(&router_session->session, DLEP_STATUS_OKAY, "DLEP router is shutting down");
     }
   }
 }