[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: stream_bw event



On Wednesday 14 February 2007 05:50, Nick Mathewson wrote:
> On Tue, Feb 06, 2007 at 10:31:19PM +0000, Robert Hogan wrote:
> > Mentioned this on irc the other night and took the attached approach.
> >
> > If you are happy with the general outline, I can prepare a proper
> > patch adding stuff to the docs etc and with proper comments.
>
> Looks good.
>
> > There are probably a couple
> > of house-style solecisms in there too, so please let me know.
>
> Okay!  (Ordinarily, I'd just clean this kind of stuff up myself, but
> you asked.)  First off, here's some stuff you might not know about our
> house style:
>   - we have a whitespace checking script that you can invoke
>     with "make check-spaces"
>   - we try to make everything build warning-free on GCC.  If you're
>     using a Unix-like platform, run configure with
>     --enable-gcc-warnings in order to keep your source squeaky-clean.
>
> The only actual error I found in the code was that you declared a
> no-arguments function as "int fn();" rather than "int fn(void)".  This
> is fine in C++ or Java, but in standard C, it can be confused for an
> old (pre-ANSI) style declaration where instead of saying "this
> function takes no arguments" you're saying "this function might or
> might take arguments; I'm not telling."
>
> Again, this looks like a good and useful feature.  Would you like me
> to tidy up the patch and check it in, or would you like to do it
> yourself?
>

I've cleaned it up as per your advice. changed the logic that decides whether 
to write a event to be slightly more efficient (I think!), and added a note 
for the control-spec.

Hope it doesn't require too much tweaking!

-- 

KlamAV - An Anti-Virus Manager for KDE - http://www.klamav.net
TorK   - A Tor Controller For KDE      - http://tork.sf.net
Index: src/or/control.c
===================================================================
--- src/or/control.c	(revision 9582)
+++ src/or/control.c	(working copy)
@@ -89,7 +89,8 @@
 #define EVENT_STATUS_SERVER    0x0011
 #define EVENT_STATUS_GENERAL   0x0012
 #define EVENT_GUARD            0x0013
-#define _EVENT_MAX             0x0013
+#define EVENT_STREAM_BANDWIDTH_USED   0x0014
+#define _EVENT_MAX             0x0014
 /* If _EVENT_MAX ever hits 0x0020, we need to make the mask wider. */
 
 /** Array mapping from message type codes to human-readable message
@@ -1104,6 +1105,8 @@
           event_code = EVENT_STATUS_SERVER;
         else if (!strcasecmp(ev, "GUARD"))
           event_code = EVENT_GUARD;
+        else if (!strcasecmp(ev, "STREAM_BW"))
+          event_code = EVENT_STREAM_BANDWIDTH_USED;
         else {
           connection_printf_to_buf(conn, "552 Unrecognized event \"%s\"\r\n",
                                    ev);
@@ -3411,6 +3414,44 @@
 }
 
 /** A second or more has elapsed: tell any interested control
+ * connections how much bandwidth streams have used. */
+int
+control_event_stream_bandwidth_used()
+{
+  connection_t **carray;
+  edge_connection_t *conn;
+  int n, i;
+  uint32_t justread, justwritten;
+
+  if (EVENT_IS_INTERESTING1(EVENT_STREAM_BANDWIDTH_USED)) {
+
+    get_connection_array(&carray, &n);
+
+    for (i = 0; i < n; ++i) {
+        if (carray[i]->type != CONN_TYPE_AP)
+          continue;
+        conn = TO_EDGE_CONN(carray[i]);
+        if (conn->p_read == conn->n_read && conn->p_written == conn->n_written)
+          continue;
+
+        justread = conn->n_read - conn->p_read;
+        conn->p_read = conn->n_read;
+        justwritten = conn->n_written - conn->p_written;
+        conn->p_written = conn->n_written;
+
+        send_control1_event(EVENT_STREAM_BANDWIDTH_USED, ALL_NAMES,
+                            "650 STREAM_BW %lu %lu %lu\r\n",
+                            (unsigned long)conn->global_identifier,
+                            (unsigned long)justread,
+                            (unsigned long)justwritten);
+
+    }
+  }
+
+  return 0;
+}
+
+/** A second or more has elapsed: tell any interested control
  * connections how much bandwidth we used. */
 int
 control_event_bandwidth_used(uint32_t n_read, uint32_t n_written)
Index: src/or/or.h
===================================================================
--- src/or/or.h	(revision 9582)
+++ src/or/or.h	(working copy)
@@ -838,6 +838,14 @@
   /* XXXX NM This can get re-used after 2**32 streams */
   uint32_t global_identifier;
 
+  /** Bytes read */
+  uint32_t n_read;
+  uint32_t p_read;
+
+  /** Bytes written */
+  uint32_t n_written;
+  uint32_t p_written;
+
   /** Exit only: a dirserv connection that is tunneled over this connection
    * using a socketpair. */
   struct dir_connection_t *bridge_for_conn;
@@ -2329,6 +2337,7 @@
 int control_event_or_conn_status(or_connection_t *conn,
                                  or_conn_status_event_t e, int reason);
 int control_event_bandwidth_used(uint32_t n_read, uint32_t n_written);
+int control_event_stream_bandwidth_used(void);
 void control_event_logmsg(int severity, unsigned int domain, const char *msg);
 int control_event_descriptors_changed(smartlist_t *routers);
 int control_event_address_mapped(const char *from, const char *to,
Index: src/or/connection.c
===================================================================
--- src/or/connection.c	(revision 9582)
+++ src/or/connection.c	(working copy)
@@ -1571,6 +1571,13 @@
     *max_to_read = at_most - n_read;
   }
 
+  if (CONN_IS_EDGE(conn)) {
+    if (conn->type == CONN_TYPE_AP) {
+        edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+        edge_conn->n_read += n_read;
+    }
+  }
+
   if (connection_is_rate_limited(conn)) {
     /* For non-local IPs, remember if we flushed any bytes over the wire. */
     time_t now = time(NULL);
@@ -1767,6 +1774,13 @@
     n_written = (size_t) result;
   }
 
+  if (CONN_IS_EDGE(conn)) {
+    if (conn->type == CONN_TYPE_AP) {
+      edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+      edge_conn->n_written += n_written;
+    }
+  }
+
   if (connection_is_rate_limited(conn)) {
     /* For non-local IPs, remember if we flushed any bytes over the wire. */
     time_t now = time(NULL);
Index: src/or/main.c
===================================================================
--- src/or/main.c	(revision 9582)
+++ src/or/main.c	(working copy)
@@ -998,6 +998,7 @@
   if (accounting_is_enabled(options) && seconds_elapsed >= 0)
     accounting_add_bytes(bytes_read, bytes_written, seconds_elapsed);
   control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
+  control_event_stream_bandwidth_used();
 
   if (seconds_elapsed > 0)
     connection_bucket_refill(seconds_elapsed);
Index: doc/spec/control-spec.txt
===================================================================
--- doc/spec/control-spec.txt	(revision 9582)
+++ doc/spec/control-spec.txt	(working copy)
@@ -194,7 +194,7 @@
      EventCode = "CIRC" / "STREAM" / "ORCONN" / "BW" / "DEBUG" /
          "INFO" / "NOTICE" / "WARN" / "ERR" / "NEWDESC" / "ADDRMAP" /
          "AUTHDIR_NEWDESCS" / "DESCCHANGED" / "STATUS_GENERAL" /
-         "STATUS_CLIENT" / "STATUS_SERVER" / "GUARDS" / "NS"
+         "STATUS_CLIENT" / "STATUS_SERVER" / "GUARDS" / "NS" / "STREAM_BW"
 
   Any events *not* listed in the SETEVENTS line are turned off; thus, sending
   SETEVENTS with an empty body turns off all event reporting.
@@ -1271,6 +1271,17 @@
 
   [First added in 0.1.2.3-alpha]
 
+4.1.13. Bandwidth used on a stream
+
+  The syntax is:
+     "650" SP "STREAM_BW" SP StreamID SP BytesRead SP BytesWritten
+     BytesRead = 1*DIGIT
+     BytesWritten = 1*DIGIT
+
+  The number of bytes read and written since the last read or write event
+  on a stream.
+
+
 5. Implementation notes
 
 5.1. Authentication