Add information about allocated sockets to remotecontrol plugin
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Tue, 14 Feb 2017 13:31:38 +0000 (14:31 +0100)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Tue, 14 Feb 2017 13:31:38 +0000 (14:31 +0100)
src-plugins/generic/remotecontrol/remotecontrol.c
src-plugins/subsystems/oonf_class.c
src-plugins/subsystems/oonf_packet_socket.c
src-plugins/subsystems/oonf_packet_socket.h
src-plugins/subsystems/oonf_socket.c
src-plugins/subsystems/oonf_socket.h
src-plugins/subsystems/oonf_stream_socket.c
src-plugins/subsystems/oonf_stream_socket.h
src-plugins/subsystems/oonf_timer.c
src-plugins/subsystems/os_linux/os_system_linux.c

index c45f943..1954884 100644 (file)
@@ -162,7 +162,8 @@ DECLARE_OONF_PLUGIN(_oonf_remotecontrol_subsystem);
 static struct oonf_telnet_command _telnet_cmds[] = {
   TELNET_CMD("resources", _cb_handle_resource,
       "\"resources memory\": display information about memory usage\n"
-      "\"resources timer\": display information about active timers\n",
+      "\"resources timer\": display information about active timers\n"
+      "\"resources socket\": display information about socket usage\n",
       .acl = &_remotecontrol_config.acl),
   TELNET_CMD("log", _cb_handle_log,
       "\"log\":      continuous output of logging to this console\n"
@@ -280,6 +281,20 @@ _print_timer(struct autobuf *buf) {
   }
 }
 
+/**
+ * Print current sockets
+ * @param buf output buffer
+ */
+static void
+_print_socket(struct autobuf *buf) {
+  struct oonf_socket_entry *sock;
+
+  list_for_each_element(oonf_socket_get_list(), sock, _node) {
+    abuf_appendf(buf, "%-25s (SOCKET) usage_r: %u usage_s: %u usage_long: %u\n",
+        sock->name, sock->usage_r, sock->usage_s, sock->usage_long);
+  }
+}
+
 /**
  * Handle resource command
  * @param data pointer to telnet data
@@ -288,14 +303,20 @@ _print_timer(struct autobuf *buf) {
 static enum oonf_telnet_result
 _cb_handle_resource(struct oonf_telnet_data *data) {
   if (data->parameter == NULL || strcasecmp(data->parameter, "memory") == 0) {
-    abuf_puts(data->out, "Memory cookies:\n");
+    abuf_puts(data->out, "Memory blocks:\n");
     _print_memory(data->out);
   }
 
   if (data->parameter == NULL || strcasecmp(data->parameter, "timer") == 0) {
-    abuf_puts(data->out, "\nTimer cookies:\n");
+    abuf_puts(data->out, "\nTimer Classes:\n");
     _print_timer(data->out);
   }
+
+  if (data->parameter == NULL || strcasecmp(data->parameter, "socket") == 0) {
+    abuf_puts(data->out, "Sockets:\n");
+    _print_socket(data->out);
+  }
+
   return TELNET_RESULT_ACTIVE;
 }
 
index 3783c9d..62ef11a 100644 (file)
@@ -117,6 +117,7 @@ void
 oonf_class_add(struct oonf_class *ci)
 {
   assert (ci->name);
+  assert (ci->name[0]);
 
   /* round up size to make block extendable */
   ci->total_size = _roundup(ci->size);
index 8182297..52b2535 100644 (file)
@@ -175,22 +175,29 @@ oonf_packet_raw_add(struct oonf_packet_socket *pktsocket, int protocol,
 static void
 _packet_add(struct oonf_packet_socket *pktsocket,
     union netaddr_socket *local, struct os_interface *interf) {
+  struct netaddr_str nbuf;
+
   pktsocket->os_if = interf;
+  pktsocket->scheduler_entry.name = pktsocket->socket_name;
   pktsocket->scheduler_entry.process = _cb_packet_event_unicast;
 
-  oonf_socket_add(&pktsocket->scheduler_entry);
-  oonf_socket_set_read(&pktsocket->scheduler_entry, true);
-
   abuf_init(&pktsocket->out);
   list_add_tail(&_packet_sockets, &pktsocket->node);
   memcpy(&pktsocket->local_socket, local, sizeof(pktsocket->local_socket));
 
+  /* generate socket name */
+  snprintf(pktsocket->socket_name, sizeof(pktsocket->socket_name),
+      "udp: %s", netaddr_socket_to_string(&nbuf, &pktsocket->local_socket));
+
   pktsocket->_errno1_measurement_time = oonf_clock_getNow();
 
   if (pktsocket->config.input_buffer_length == 0) {
     pktsocket->config.input_buffer = _input_buffer;
     pktsocket->config.input_buffer_length = sizeof(_input_buffer);
   }
+
+  oonf_socket_add(&pktsocket->scheduler_entry);
+  oonf_socket_set_read(&pktsocket->scheduler_entry, true);
 }
 
 /**
@@ -236,6 +243,7 @@ oonf_packet_send(struct oonf_packet_socket *pktsocket, union netaddr_socket *rem
       OONF_DEBUG(LOG_PACKET, "Sent %d bytes to %s %s",
           result, netaddr_socket_to_string(&buf, remote),
           pktsocket->os_if != NULL ? pktsocket->os_if->name : "");
+      oonf_socket_register_direct_send(&pktsocket->scheduler_entry);
       return 0;
     }
 
index b431517..c8e7b25 100644 (file)
@@ -120,6 +120,9 @@ struct oonf_packet_socket {
   /*! configuration of packet socket */
   struct oonf_packet_config config;
 
+  /*! name of socket */
+  char socket_name[sizeof(struct netaddr_str)+5];
+
   /*! true if errno==1 suppression is active */
   bool _errno1_suppression;
 
index 19b0c69..ef8be27 100644 (file)
@@ -149,6 +149,9 @@ oonf_socket_add(struct oonf_socket_entry *entry)
   OONF_DEBUG(LOG_SOCKET, "Adding socket entry %d to scheduler\n",
       os_fd_get_fd(&entry->fd));
 
+  assert (entry->name);
+  assert (entry->name[0]);
+
   list_add_before(&_socket_head, &entry->_node);
   os_fd_event_socket_add(&_socket_events, &entry->fd);
 }
@@ -169,16 +172,35 @@ oonf_socket_remove(struct oonf_socket_entry *entry)
   }
 }
 
+/**
+ * @return list of all registered sockets
+ */
+struct list_entity *
+oonf_socket_get_list(void) {
+  return &_socket_head;
+}
+
+/**
+ * @param entry socket entry
+ * @param event_read true to enable read events, false to disable
+ */
 void
 oonf_socket_set_read(struct oonf_socket_entry *entry, bool event_read) {
   os_fd_event_socket_read(&_socket_events, &entry->fd, event_read);
 }
 
+/**
+ * @param entry socket entry
+ * @param event_write true to enable write events, false to disable
+ */
 void
 oonf_socket_set_write(struct oonf_socket_entry *entry, bool event_write) {
   os_fd_event_socket_write(&_socket_events, &entry->fd, event_write);
 }
 
+/**
+ * @return true if scheduler should stop
+ */
 static bool
 _shall_end_scheduler(void) {
   return _scheduler_time_limit == ~0ull && oonf_main_shall_stop_scheduler();
@@ -255,18 +277,28 @@ _handle_scheduling(void)
           continue;
         }
 
-        OONF_DEBUG(LOG_SOCKET, "Socket %d triggered (read=%s, write=%s)",
+        OONF_DEBUG(LOG_SOCKET, "Socket '%s' (%d) triggered (read=%s, write=%s)",
+            sock_entry->name,
             os_fd_get_fd(&sock_entry->fd),
             os_fd_event_is_read(sock) ? "true" : "false",
-            os_fd_event_is_write(sock) ? "true" : "false");
+                os_fd_event_is_write(sock) ? "true" : "false");
 
+        /* handle statistics */
+        if (os_fd_event_is_read(sock)) {
+          sock_entry->usage_r++;
+        }
+        if (os_fd_event_is_write(sock)) {
+          sock_entry->usage_s++;
+        }
         os_clock_gettime64(&start_time);
         sock_entry->process(sock_entry);
         os_clock_gettime64(&end_time);
 
         if (end_time - start_time > OONF_TIMER_SLICE) {
-          OONF_WARN(LOG_SOCKET, "Socket %d scheduling took %"PRIu64" ms",
+          OONF_WARN(LOG_SOCKET, "Socket '%s' (%d) scheduling took %"PRIu64" ms",
+              sock_entry->name,
               os_fd_get_fd(&sock_entry->fd), end_time - start_time);
+          sock_entry->usage_long++;
         }
       }
     }
index dbb1521..1b2f956 100644 (file)
@@ -59,6 +59,9 @@
  * registered socket handler
  */
 struct oonf_socket_entry {
+  /*! name of socket handler */
+  const char *name;
+
   /*! file descriptor of the socket */
   struct os_fd fd;
 
@@ -68,6 +71,18 @@ struct oonf_socket_entry {
    */
   void (*process) (struct oonf_socket_entry *entry);
 
+  /*! usage counter, will be increased every times the socket receives data */
+  uint32_t usage_r;
+
+  /*! usage counter, will be increased every times the socket sends data */
+  uint32_t usage_s;
+
+  /*!
+   * usage counter, will be increased every times a socket processing takes
+   * more than a TIMER slice
+   */
+  uint32_t usage_long;
+
   /*! list of socket handlers */
   struct list_entity _node;
 };
@@ -78,13 +93,33 @@ EXPORT void oonf_socket_set_read(
     struct oonf_socket_entry *entry, bool event_read);
 EXPORT void oonf_socket_set_write(
     struct oonf_socket_entry *entry, bool event_write);
+EXPORT struct list_entity *oonf_socket_get_list(void);
 
+/**
+ * @param entry socket entry
+ * @return true if socket has a read event, false otherwise
+ */
 static INLINE bool
 oonf_socket_is_read(struct oonf_socket_entry *entry) {
   return os_fd_event_is_read(&entry->fd);
 }
+
+/**
+ * @param entry socket entry
+ * @return true if socket has a write event, false otherwise
+ */
 static INLINE bool
 oonf_socket_is_write(struct oonf_socket_entry *entry) {
   return os_fd_event_is_write(&entry->fd);
 }
+
+/**
+ * Registers a direct send (without select) to a socket
+ * @param entry socket entry
+ */
+static INLINE void
+oonf_socket_register_direct_send(struct oonf_socket_entry *entry) {
+  entry->usage_s++;
+}
+
 #endif /* OONF_SOCKET_H_ */
index c941ebe..ce8895f 100644 (file)
@@ -178,9 +178,11 @@ oonf_stream_add(struct oonf_stream_socket *stream_socket,
           netaddr_socket_to_string(&buf, local), strerror(errno), errno);
       goto add_stream_error;
     }
-
+    stream_socket->scheduler_entry.name = stream_socket->socket_name;
     stream_socket->scheduler_entry.process = _cb_parse_request;
 
+    snprintf(stream_socket->socket_name, sizeof(stream_socket->socket_name),
+        "tcp-server: %s", netaddr_socket_to_string(&buf, local));
     oonf_socket_add(&stream_socket->scheduler_entry);
     oonf_socket_set_read(&stream_socket->scheduler_entry, true);
   }
@@ -616,14 +618,12 @@ _create_session(struct oonf_stream_socket *stream_socket,
     struct os_fd *sock, const struct netaddr *remote_addr,
     const union netaddr_socket *remote_socket) {
   struct oonf_stream_session *session;
-#ifdef OONF_LOG_DEBUG_INFO
-  struct netaddr_str buf;
-#endif
+  struct netaddr_str nbuf1, nbuf2;
 
   /* put socket into non-blocking mode */
   if (os_fd_set_nonblocking(sock)) {
-    OONF_WARN(LOG_STREAM, "Cannot read comport socket status: %s (%d)",
-        strerror(errno), errno);
+    OONF_WARN(LOG_STREAM, "Cannot set socket %d nonblocking: %s (%d)",
+        os_fd_get_fd(sock), strerror(errno), errno);
     return NULL;
   }
 
@@ -643,16 +643,20 @@ _create_session(struct oonf_stream_socket *stream_socket,
   }
 
   os_fd_copy(&session->scheduler_entry.fd, sock);
+  session->scheduler_entry.name = session->socket_name;
   session->scheduler_entry.process = _cb_parse_connection;
-  oonf_socket_add(&session->scheduler_entry);
-  oonf_socket_set_read(&session->scheduler_entry, true);
-  oonf_socket_set_write(&session->scheduler_entry, true);
   session->send_first = stream_socket->config.send_first;
   session->stream_socket = stream_socket;
 
   session->remote_address = *remote_addr;
   session->remote_socket = *remote_socket;
 
+  /* generate socket name */
+  snprintf(session->socket_name, sizeof(session->socket_name),
+      "tcp: %s,%s",
+      netaddr_socket_to_string(&nbuf1, &stream_socket->local_socket),
+      netaddr_socket_to_string(&nbuf2, &session->remote_socket));
+
   if (stream_socket->session_counter < stream_socket->config.allowed_sessions) {
     /* create active session */
     session->state = STREAM_SESSION_ACTIVE;
@@ -670,6 +674,10 @@ _create_session(struct oonf_stream_socket *stream_socket,
     oonf_timer_start(&session->timeout, stream_socket->config.session_timeout);
   }
 
+  oonf_socket_add(&session->scheduler_entry);
+  oonf_socket_set_read(&session->scheduler_entry, true);
+  oonf_socket_set_write(&session->scheduler_entry, true);
+
   if (stream_socket->config.init) {
     if (stream_socket->config.init(session)) {
       goto parse_request_error;
@@ -677,7 +685,7 @@ _create_session(struct oonf_stream_socket *stream_socket,
   }
 
   OONF_DEBUG(LOG_STREAM, "Got connection through socket %d with %s.\n",
-      os_fd_get_fd(sock), netaddr_to_string(&buf, remote_addr));
+      os_fd_get_fd(sock), netaddr_to_string(&nbuf1, remote_addr));
 
   list_add_tail(&stream_socket->session, &session->node);
   return session;
index 4ecebe1..9f6adaf 100644 (file)
@@ -111,6 +111,9 @@ struct oonf_stream_session {
    */
   struct os_fd copy_fd;
 
+  /*! name of socket */
+  char socket_name[sizeof(struct netaddr_str)*2 + 10];
+
   /*! number of bytes already copied in file upload */
   size_t copy_bytes_sent;
 
@@ -249,6 +252,9 @@ struct oonf_stream_socket {
   /*! optional back pointer for managed tcp sockets */
   struct oonf_stream_managed *managed;
 
+  /*! name of socket */
+  char socket_name[sizeof(struct netaddr_str)+14];
+
   /*! number of currently active sessions */
   int32_t session_counter;
 
index 61304ce..b01b395 100644 (file)
@@ -129,6 +129,7 @@ void
 oonf_timer_add(struct oonf_timer_class *ti) {
   assert (ti->callback);
   assert (ti->name);
+  assert (ti->name[0]);
   list_add_tail(&_timer_info_list, &ti->_node);
 }
 
index 53591b8..8424b3b 100644 (file)
@@ -327,6 +327,7 @@ os_system_linux_netlink_add(struct os_system_netlink *nl, int protocol) {
     goto os_add_netlink_fail;
   }
 
+  nl->socket.name = "os_system_netlink";
   nl->socket.process = _netlink_handler;
   oonf_socket_add(&nl->socket);
   oonf_socket_set_read(&nl->socket, true);