]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Add a 0-pullup version of fetch_from_evbuffer_socks
authorNick Mathewson <nickm@torproject.org>
Tue, 11 Aug 2009 21:44:43 +0000 (17:44 -0400)
committerNick Mathewson <nickm@torproject.org>
Mon, 27 Sep 2010 16:31:13 +0000 (12:31 -0400)
src/or/buffers.c

index 9d667d4b442b3654a5037f7ae605dfe4d1c6e016..b750a0540cf7896b122382335c5ec5caabeb6e43 100644 (file)
@@ -1498,7 +1498,7 @@ int
 fetch_from_evbuffer_socks(struct evbuffer *buf, socks_request_t *req,
                           int log_sockstype, int safe_socks)
 {
-  const char *data;
+  char *data;
   ssize_t n_drain;
   size_t datalen, buflen, want_length;
   int res;
@@ -1507,27 +1507,51 @@ fetch_from_evbuffer_socks(struct evbuffer *buf, socks_request_t *req,
   if (buflen < 2)
     return 0;
 
-  want_length = evbuffer_get_contiguous_space(buf);
+  {
+    struct evbuffer_iovec v;
+    int i;
+    want_length = evbuffer_get_contiguous_space(buf);
+    n_drain = 0;
+    i = evbuffer_peek(buf, want_length, NULL, &v, 1);
+    tor_assert(i == i);
+    data = v.iov_base;
+    datalen = v.iov_len;
 
-  do {
+    res = parse_socks(data, datalen, req, log_sockstype,
+                      safe_socks, &n_drain, &want_length);
+
+    if (n_drain < 0)
+      evbuffer_drain(buf, evbuffer_get_length(buf));
+    else if (n_drain > 0)
+      evbuffer_drain(buf, n_drain);
+
+    if (res)
+      return res;
+  }
+
+  while (evbuffer_get_length(buf) > datalen) {
+    int free_data = 0;
     n_drain = 0;
-    data = (const char*) evbuffer_pullup(buf, want_length);
-    datalen = evbuffer_get_contiguous_space(buf);
-    want_length = 0;
+    data = NULL;
+    datalen = inspect_evbuffer(buf, &data, want_length, &free_data, NULL);
 
     res = parse_socks(data, datalen, req, log_sockstype,
                       safe_socks, &n_drain, &want_length);
 
+    if (free_data)
+      tor_free(data);
+
     if (n_drain < 0)
       evbuffer_drain(buf, evbuffer_get_length(buf));
     else if (n_drain > 0)
       evbuffer_drain(buf, n_drain);
 
-    datalen = evbuffer_get_contiguous_space(buf);
-    buflen = evbuffer_get_length(buf);
+    if (res)
+      return res;
 
-  } while (res == 0 &&
-           want_length > datalen && buflen > datalen);
+    if (want_length <= datalen)
+      break;
+  }
 
   return res;
 }