[or-cvs] Try to extract as many descriptors as possible from truncat...

Nick Mathewson nickm at seul.org
Fri Oct 14 02:26:15 UTC 2005


Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv8460/src/or

Modified Files:
	buffers.c connection_or.c directory.c main.c or.h 
	routerparse.c 
Log Message:
Try to extract as many descriptors as possible from truncated http responses. (when DIR_PURPOSE_FETCH_ROUTERDESC)

Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/buffers.c,v
retrieving revision 1.173
retrieving revision 1.174
diff -u -d -r1.173 -r1.174
--- buffers.c	6 Oct 2005 04:33:40 -0000	1.173
+++ buffers.c	14 Oct 2005 02:26:12 -0000	1.174
@@ -788,13 +788,16 @@
  *  - If a headers or body doesn't fit in the arg, return -1.
  *  (We ensure that the headers or body don't exceed max len,
  *   _even if_ we're planning to discard them.)
+ *  - If force_complete is true, then succeed even if not all of the
+ *    content has arrived.
  *
  * Else, change nothing and return 0.
  */
 int
 fetch_from_buf_http(buf_t *buf,
                     char **headers_out, size_t max_headerlen,
-                    char **body_out, size_t *body_used, size_t max_bodylen)
+                    char **body_out, size_t *body_used, size_t max_bodylen,
+                    int force_complete)
 {
   char *headers, *body, *p;
   size_t headerlen, bodylen, contentlen;
@@ -840,8 +843,10 @@
     /* if content-length is malformed, then our body length is 0. fine. */
     log_fn(LOG_DEBUG,"Got a contentlen of %d.",(int)contentlen);
     if (bodylen < contentlen) {
-      log_fn(LOG_DEBUG,"body not all here yet.");
-      return 0; /* not all there yet */
+      if (!force_complete) {
+        log_fn(LOG_DEBUG,"body not all here yet.");
+        return 0; /* not all there yet */
+      }
     }
     if (bodylen > contentlen) {
       bodylen = contentlen;

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.189
retrieving revision 1.190
diff -u -d -r1.189 -r1.190
--- connection_or.c	6 Oct 2005 05:08:00 -0000	1.189
+++ connection_or.c	14 Oct 2005 02:26:12 -0000	1.190
@@ -69,7 +69,7 @@
 
   switch (fetch_from_buf_http(conn->inbuf,
                               &headers, MAX_HEADERS_SIZE,
-                              NULL, NULL, 10000)) {
+                              NULL, NULL, 10000, 0)) {
     case -1: /* overflow */
       log_fn(LOG_WARN,"Your https proxy sent back an oversized response. Closing.");
       return -1;

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.305
retrieving revision 1.306
diff -u -d -r1.305 -r1.306
--- directory.c	13 Oct 2005 22:48:09 -0000	1.305
+++ directory.c	14 Oct 2005 02:26:12 -0000	1.306
@@ -806,10 +806,12 @@
   int compression;
   int plausible;
   int skewed=0;
+  int allow_partial = conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC;
 
   switch (fetch_from_buf_http(conn->inbuf,
                               &headers, MAX_HEADERS_SIZE,
-                              &body, &body_len, MAX_DIR_SIZE)) {
+                              &body, &body_len, MAX_DIR_SIZE,
+                              allow_partial)) {
     case -1: /* overflow */
       log_fn(LOG_WARN,"'fetch' response too large (server '%s:%d'). Closing.", conn->address, conn->port);
       return -1;
@@ -878,11 +880,13 @@
     }
     /* Try declared compression first if we can. */
     if (compression > 0)
-      tor_gzip_uncompress(&new_body, &new_len, body, body_len, compression, 1);
+      tor_gzip_uncompress(&new_body, &new_len, body, body_len, compression,
+                          allow_partial);
     /* Okay, if that didn't work, and we think that it was compressed
      * differently, try that. */
     if (!new_body && guessed > 0 && compression != guessed)
-      tor_gzip_uncompress(&new_body, &new_len, body, body_len, guessed, 1);
+      tor_gzip_uncompress(&new_body, &new_len, body, body_len, guessed,
+                          allow_partial);
     /* If we're pretty sure that we have a compressed directory, and
      * we didn't manage to uncompress it, then warn and bail. */
     if (!plausible && !new_body) {
@@ -1510,7 +1514,7 @@
 
   switch (fetch_from_buf_http(conn->inbuf,
                               &headers, MAX_HEADERS_SIZE,
-                              &body, &body_len, MAX_BODY_SIZE)) {
+                              &body, &body_len, MAX_BODY_SIZE, 0)) {
     case -1: /* overflow */
       log_fn(LOG_WARN,"Invalid input from address '%s'. Closing.", conn->address);
       return -1;

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.576
retrieving revision 1.577
diff -u -d -r1.576 -r1.577
--- main.c	12 Oct 2005 22:41:16 -0000	1.576
+++ main.c	14 Oct 2005 02:26:12 -0000	1.577
@@ -580,9 +580,9 @@
     /* This check is temporary; it's to let us know whether we should consider
      * parsing partial serverdesc responses. */
     if (conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
-        buf_datalen(conn->inbuf)>=(24*1024)) {
-      log_fn(LOG_NOTICE, "Expired a wedged directory connection that had already downloaded %d bytes of descriptors.  If this happens often, please file a bug report.",
-             (int)buf_datalen(conn->inbuf));
+        buf_datalen(conn->inbuf)>=1024) {
+      log_fn(LOG_INFO,"Trying to extract information from wedged server desc downoad");
+      connection_dir_reached_eof(conn);
     }
     connection_mark_for_close(conn);
     return;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.713
retrieving revision 1.714
diff -u -d -r1.713 -r1.714
--- or.h	12 Oct 2005 22:41:16 -0000	1.713
+++ or.h	14 Oct 2005 02:26:13 -0000	1.714
@@ -1362,7 +1362,8 @@
 int fetch_from_buf(char *string, size_t string_len, buf_t *buf);
 int fetch_from_buf_http(buf_t *buf,
                         char **headers_out, size_t max_headerlen,
-                        char **body_out, size_t *body_used, size_t max_bodylen);
+                        char **body_out, size_t *body_used, size_t max_bodylen,
+                        int force_complete);
 int fetch_from_buf_socks(buf_t *buf, socks_request_t *req);
 int fetch_from_buf_control0(buf_t *buf, uint32_t *len_out, uint16_t *type_out,
                             char **body_out, int check_for_v1);

Index: routerparse.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerparse.c,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -d -r1.152 -r1.153
--- routerparse.c	7 Oct 2005 18:33:30 -0000	1.152
+++ routerparse.c	14 Oct 2005 02:26:13 -0000	1.153
@@ -636,13 +636,14 @@
 /** Given a string *<b>s</b> containing a concatenated sequence of router
  * descriptors, parses them and stores the result in <b>dest</b>.  All routers
  * are marked running and verified.  Advances *s to a point immediately
- * following the last router entry.  Returns 0 on success and -1 on failure.
+ * following the last router entry.  Ignore any trailing router entries that
+ * are not complete. Returns 0 on success and -1 on failure.
  */
 int
 router_parse_list_from_string(const char **s, smartlist_t *dest)
 {
   routerinfo_t *router;
-  const char *end;
+  const char *end, *cp;
 
   tor_assert(s);
   tor_assert(*s);
@@ -654,20 +655,36 @@
     if (strcmpstart(*s, "router ")!=0)
       break;
     if ((end = strstr(*s+1, "\nrouter "))) {
+      cp = end;
       end++;
     } else if ((end = strstr(*s+1, "\ndirectory-signature"))) {
+      cp = end;
       end++;
     } else {
-      end = *s+strlen(*s);
+      cp = end = *s+strlen(*s);
+    }
+
+    while (cp > *s && (!*cp || TOR_ISSPACE(*cp)))
+      --cp;
+    /* cp now points to the last non-space character in this descriptor. */
+
+    while (cp > *s  && *cp != '\n')
+      --cp;
+    /* cp now points to the first \n before the last non-bank line in this
+     * descriptor */
+
+    if (strcmpstart(cp, "\n-----END SIGNATURE-----\n")) {
+      log_fn(LOG_INFO, "Ignoring truncated router descriptor.");
+      continue;
     }
 
     router = router_parse_entry_from_string(*s, end);
+
     *s = end;
     if (!router) {
       log_fn(LOG_WARN, "Error reading router; skipping");
       continue;
     }
-
     smartlist_add(dest, router);
   }
 



More information about the tor-commits mailing list