Skip to content
This repository
Browse code

patches for tor on constrained devices + transparent torrc

  • Loading branch information...
commit ad84ee63ef2462b78a2571c7f3bb2789b5bb01f8 1 parent b267763
the grugq authored
118 feeds/packages/net/tor-alpha/Makefile
... ... @@ -0,0 +1,118 @@
  1 +#
  2 +# Copyright (C) 2008-2012 OpenWrt.org
  3 +#
  4 +# This is free software, licensed under the GNU General Public License v2.
  5 +# See /LICENSE for more information.
  6 +#
  7 +
  8 +include $(TOPDIR)/rules.mk
  9 +
  10 +PKG_NAME:=tor-alpha
  11 +PKG_VERSION:=0.2.3.22-rc
  12 +PKG_RELEASE:=1
  13 +
  14 +PKG_SOURCE:=tor-$(PKG_VERSION).tar.gz
  15 +PKG_SOURCE_URL:=https://www.torproject.org/dist \
  16 + https://archive.torproject.org/tor-package-archive
  17 +PKG_MD5SUM:=c07431ee40a0e16dc1b4d1e8d266680c
  18 +
  19 +PKG_BUILD_DEPENDS:=libminiupnpc libnatpmp
  20 +PKG_BUILD_DIR:=$(BUILD_DIR)/tor-$(PKG_VERSION)
  21 +PKG_INSTALL:=1
  22 +
  23 +include $(INCLUDE_DIR)/package.mk
  24 +
  25 +define Package/tor-alpha/Default
  26 + SECTION:=net
  27 + CATEGORY:=Network
  28 + URL:=https://www.torproject.org/
  29 +endef
  30 +
  31 +define Package/tor-alpha/Default/description
  32 + Tor is a toolset for a wide range of organizations and people that want to
  33 + improve their safety and security on the Internet. Using Tor can help you
  34 + anonymize web browsing and publishing, instant messaging, IRC, SSH, and
  35 + more. Tor also provides a platform on which software developers can build
  36 + new applications with built-in anonymity, safety, and privacy features.
  37 +endef
  38 +
  39 +define Package/tor-alpha
  40 +$(call Package/tor-alpha/Default)
  41 + TITLE:=An anonymous Internet communication system
  42 + DEPENDS:=+libevent2 +libevent2-openssl +libpthread +librt
  43 +endef
  44 +
  45 +define Package/tor-alpha/description
  46 +$(call Package/tor-alpha/Default/description)
  47 + This package contains the tor daemon.
  48 +endef
  49 +
  50 +define Package/tor-alpha-fw-helper
  51 +$(call Package/tor-alpha/Default)
  52 + TITLE:=Firewall helper for tor
  53 + DEPENDS:=+tor-alpha +libminiupnpc +libnatpmp
  54 +endef
  55 +
  56 +define Package/tor-alpha-fw-helper/description
  57 +$(call Package/tor-alpha/Default/description)
  58 + This package contains a helper for automatically configuring port forwarding.
  59 +endef
  60 +
  61 +define Package/tor-alpha-geoip
  62 +$(call Package/tor-alpha/Default)
  63 + TITLE:=GeoIP db for tor
  64 + DEPENDS:=+tor-alpha
  65 +endef
  66 +
  67 +define Package/tor-alpha-geoip/description
  68 +$(call Package/tor-alpha/Default/description)
  69 + This package contains a GeoIP database mapping IP addresses to countries.
  70 +endef
  71 +
  72 +define Package/tor-alpha/conffiles
  73 +/etc/tor/torrc
  74 +endef
  75 +
  76 +CONFIGURE_ARGS += \
  77 + --with-libevent-dir="$(STAGING_DIR)/usr" \
  78 + --with-ssl-dir="$(STAGING_DIR)/usr" \
  79 + --enable-upnp \
  80 + --with-libminiupnpc-dir="$(STAGING_DIR)/usr" \
  81 + --enable-nat-pmp \
  82 + --with-libnatpmp-dir="$(STAGING_DIR)/usr" \
  83 + --disable-asciidoc
  84 +
  85 +ifneq ($(CONFIG_SSP_SUPPORT),y)
  86 + CONFIGURE_ARGS += \
  87 + --disable-gcc-hardening
  88 +endif
  89 +
  90 +CONFIGURE_VARS += \
  91 + CROSS_COMPILE="yes"
  92 +
  93 +# pass CFLAGS again to override -O2 set by configure
  94 +MAKE_FLAGS += \
  95 + CFLAGS="$(TARGET_CFLAGS)"
  96 +
  97 +define Package/tor-alpha/install
  98 + $(INSTALL_DIR) $(1)/usr/sbin
  99 + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/tor $(1)/usr/sbin/
  100 + $(INSTALL_DIR) $(1)/etc/init.d
  101 + $(INSTALL_BIN) ./files/tor.init $(1)/etc/init.d/tor
  102 + $(INSTALL_DIR) $(1)/etc/tor
  103 + $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/tor/torrc.sample $(1)/etc/tor/torrc
  104 +endef
  105 +
  106 +define Package/tor-alpha-fw-helper/install
  107 + $(INSTALL_DIR) $(1)/usr/bin
  108 + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/tor-fw-helper $(1)/usr/bin/
  109 +endef
  110 +
  111 +define Package/tor-alpha-geoip/install
  112 + $(INSTALL_DIR) $(1)/usr/share/tor
  113 + $(CP) $(PKG_INSTALL_DIR)/usr/share/tor/geoip $(1)/usr/share/tor/
  114 +endef
  115 +
  116 +$(eval $(call BuildPackage,tor-alpha))
  117 +$(eval $(call BuildPackage,tor-alpha-fw-helper))
  118 +$(eval $(call BuildPackage,tor-alpha-geoip))
30 feeds/packages/net/tor-alpha/files/tor.init
... ... @@ -0,0 +1,30 @@
  1 +#!/bin/sh /etc/rc.common
  2 +# Copyright (C) 2006-2011 OpenWrt.org
  3 +
  4 +START=50
  5 +STOP=50
  6 +
  7 +SERVICE_USE_PID=1
  8 +
  9 +start() {
  10 + user_exists tor 52 || user_add tor 52 52 /var/lib/tor
  11 + group_exists tor 52 || group_add tor 52
  12 + [ -f /var/run/tor.pid ] || {
  13 + touch /var/run/tor.pid
  14 + chown tor:tor /var/run/tor.pid
  15 + }
  16 + [ -d /var/lib/tor ] || {
  17 + mkdir -m 0755 -p /var/lib/tor
  18 + chmod 0700 /var/lib/tor
  19 + chown tor:tor /var/lib/tor
  20 + }
  21 + [ -d /var/log/tor ] || {
  22 + mkdir -m 0755 -p /var/log/tor
  23 + chown tor:tor /var/log/tor
  24 + }
  25 + service_start /usr/sbin/tor --PidFile /var/run/tor.pid
  26 +}
  27 +
  28 +stop() {
  29 + service_stop /usr/sbin/tor
  30 +}
919 feeds/packages/net/tor-alpha/patches/001-anon_mmap.patch
... ... @@ -0,0 +1,919 @@
  1 +diff -uNr tor-0.2.3.19-rc/src/common/util.c tor-0.2.3.19-rc-anon_mmap//src/common/util.c
  2 +--- tor-0.2.3.19-rc/src/common/util.c 2012-07-06 16:32:28.000000000 -0400
  3 ++++ tor-0.2.3.19-rc-anon_mmap//src/common/util.c 2012-07-09 11:39:11.995224656 -0400
  4 +@@ -73,6 +73,9 @@
  5 + #ifdef HAVE_SYS_FCNTL_H
  6 + #include <sys/fcntl.h>
  7 + #endif
  8 ++#ifdef HAVE_SYS_MMAN_H
  9 ++#include <sys/mman.h>
  10 ++#endif
  11 + #ifdef HAVE_TIME_H
  12 + #include <time.h>
  13 + #endif
  14 +@@ -1994,9 +1997,7 @@
  15 + * we can write into a temporary file, and either remove the file on
  16 + * failure, or replace the original file on success. */
  17 + struct open_file_t {
  18 +- char *tempname; /**< Name of the temporary file. */
  19 + char *filename; /**< Name of the original file. */
  20 +- unsigned rename_on_close:1; /**< Are we using the temporary file or not? */
  21 + unsigned binary:1; /**< Did we open in binary mode? */
  22 + int fd; /**< fd for the open file. */
  23 + FILE *stdio_file; /**< stdio wrapper for <b>fd</b>. */
  24 +@@ -2035,18 +2036,15 @@
  25 + #endif
  26 + new_file->fd = -1;
  27 + new_file->filename = tor_strdup(fname);
  28 ++ open_name = fname;
  29 ++
  30 + if (open_flags & O_APPEND) {
  31 +- open_name = fname;
  32 +- new_file->rename_on_close = 0;
  33 + append = 1;
  34 + open_flags &= ~O_APPEND;
  35 + } else {
  36 +- tor_asprintf(&new_file->tempname, "%s.tmp", fname);
  37 +- open_name = new_file->tempname;
  38 +- /* We always replace an existing temporary file if there is one. */
  39 ++ /* We always replace an existing file if not appending. */
  40 + open_flags |= O_CREAT|O_TRUNC;
  41 + open_flags &= ~O_EXCL;
  42 +- new_file->rename_on_close = 1;
  43 + }
  44 + if (open_flags & O_BINARY)
  45 + new_file->binary = 1;
  46 +@@ -2074,7 +2072,6 @@
  47 + close(new_file->fd);
  48 + *data_out = NULL;
  49 + tor_free(new_file->filename);
  50 +- tor_free(new_file->tempname);
  51 + tor_free(new_file);
  52 + return -1;
  53 + }
  54 +@@ -2134,22 +2131,7 @@
  55 + abort_write = r = -1;
  56 + }
  57 +
  58 +- if (file_data->rename_on_close) {
  59 +- tor_assert(file_data->tempname && file_data->filename);
  60 +- if (abort_write) {
  61 +- unlink(file_data->tempname);
  62 +- } else {
  63 +- tor_assert(strcmp(file_data->filename, file_data->tempname));
  64 +- if (replace_file(file_data->tempname, file_data->filename)) {
  65 +- log_warn(LD_FS, "Error replacing \"%s\": %s", file_data->filename,
  66 +- strerror(errno));
  67 +- r = -1;
  68 +- }
  69 +- }
  70 +- }
  71 +-
  72 + tor_free(file_data->filename);
  73 +- tor_free(file_data->tempname);
  74 + tor_free(file_data);
  75 +
  76 + return r;
  77 +@@ -4552,3 +4534,166 @@
  78 + }
  79 + }
  80 +
  81 ++/* =====
  82 ++ * Anonymous mmaps for holding large chunks of data
  83 ++ * ===== */
  84 ++
  85 ++/* Initial size of anonymous mmap and the increase step if we need
  86 ++ * to make it bigger */
  87 ++#define MMAP_INCREASE_SIZE (1<<18)
  88 ++
  89 ++/** Create a new anonymous memory mapping. Return 0 on success. */
  90 ++int
  91 ++tor_mmap_anon(tor_mmap_t *handle)
  92 ++{
  93 ++ char *map;
  94 ++ ssize_t map_size, page_size;
  95 ++
  96 ++ /* round up the initial map size to the next page boundary,
  97 ++ * and allocate an anonymous map */
  98 ++ page_size = getpagesize();
  99 ++ map_size = MMAP_INCREASE_SIZE + (MMAP_INCREASE_SIZE%page_size ? page_size-MMAP_INCREASE_SIZE%page_size : 0);
  100 ++
  101 ++ if (MAP_FAILED == (map = mmap(NULL, map_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0))) {
  102 ++ int save_errno = errno;
  103 ++ log_warn(LD_FS,"Could not create mmap: %s",
  104 ++ strerror(errno));
  105 ++ handle->data = NULL;
  106 ++ handle->size = handle->mapping_size = 0;
  107 ++ errno = save_errno;
  108 ++ return -1;
  109 ++ }
  110 ++
  111 ++ handle->data = map;
  112 ++ handle->size = 0;
  113 ++ handle->mapping_size = map_size;
  114 ++
  115 ++ return 0;
  116 ++}
  117 ++
  118 ++/* Free the mmap referred by the handle. Return 0. */
  119 ++int
  120 ++tor_munmap(tor_mmap_t *handle) {
  121 ++ munmap((void *)handle->data, handle->mapping_size);
  122 ++ handle->data = NULL;
  123 ++ handle->size = handle->mapping_size = 0;
  124 ++ return 0;
  125 ++}
  126 ++
  127 ++/* Make the memory map bigger by MMAP_INCREASE_SIZE. Return 0 on success */
  128 ++int
  129 ++tor_mremap_inc(tor_mmap_t *handle) {
  130 ++ /* Create a new anonymous mmap if we don't have one yet. */
  131 ++ if (handle->data==NULL)
  132 ++ return tor_mmap_anon(handle);
  133 ++
  134 ++ if (handle->size==handle->mapping_size) {
  135 ++ char *new_map;
  136 ++ int new_mapsize;
  137 ++ int page_size = getpagesize();
  138 ++
  139 ++ /* Add the increment and round up to the page boundary */
  140 ++ new_mapsize = handle->mapping_size + MMAP_INCREASE_SIZE + (MMAP_INCREASE_SIZE%page_size ? page_size-MMAP_INCREASE_SIZE%page_size : 0);
  141 ++
  142 ++ if (new_mapsize >= SIZE_T_CEILING) {
  143 ++ errno = ERANGE;
  144 ++ return -1;
  145 ++ }
  146 ++
  147 ++ /* Increase the map size */
  148 ++ if (MAP_FAILED == (new_map = mremap((void *)handle->data, handle->mapping_size, new_mapsize, MREMAP_MAYMOVE)))
  149 ++ return -1;
  150 ++
  151 ++ handle->data = new_map;
  152 ++ handle->mapping_size = new_mapsize;
  153 ++ }
  154 ++ return 0;
  155 ++}
  156 ++
  157 ++/** Read contents of <b>string</b> into a an
  158 ++ * anonymous map; return 0 on success. New data will be appended
  159 ++ * to existing data in the map. The map size will be increased if
  160 ++ * it's too small */
  161 ++int
  162 ++load_string_into_mmap(tor_mmap_t *handle, const char *string, const size_t length)
  163 ++{
  164 ++ char *pos=(char*)string;
  165 ++ ssize_t num;
  166 ++
  167 ++ tor_assert(string);
  168 ++
  169 ++ /* While there's enough data to fill up the map, fill it and increase the map size */
  170 ++ do {
  171 ++ /* When the current map is full, increase its size */
  172 ++ if (handle->size==handle->mapping_size && tor_mremap_inc(handle)) {
  173 ++ int save_errno = errno;
  174 ++ log_err(LD_FS,"Could not increase the anonymous memory mmaping while loading string");
  175 ++ errno = save_errno;
  176 ++ return -1;
  177 ++ }
  178 ++
  179 ++ /* Find out how much data we can handle in this iternation copy */
  180 ++ num = (length > handle->mapping_size-handle->size) ?
  181 ++ handle->mapping_size - handle->size : length;
  182 ++ memcpy((void *)handle->data+handle->size, pos, num);
  183 ++
  184 ++ /* advance the pointer */
  185 ++ pos+=num;
  186 ++ handle->size+=num;
  187 ++
  188 ++ /* Repeat if there was enough data and the map is full */
  189 ++ } while (handle->mapping_size==handle->size);
  190 ++
  191 ++ return 0;
  192 ++}
  193 ++
  194 ++/** Read contents of <b>filename</b> into a an
  195 ++ * anonymous map; return 0 on success. New data will be appended
  196 ++ * to existing data in the map. The map size will be increased if
  197 ++ * it's too small */
  198 ++int
  199 ++load_file_into_mmap(tor_mmap_t *handle, const char *filename)
  200 ++{
  201 ++ int fd; /* router file */
  202 ++ ssize_t r;
  203 ++
  204 ++ tor_assert(filename);
  205 ++
  206 ++ fd = tor_open_cloexec(filename,O_RDONLY|O_TEXT,0);
  207 ++ if (fd<0) {
  208 ++ int save_errno = errno;
  209 ++ log_info(LD_FS,"Could not open \"%s\": %s",filename,
  210 ++ strerror(errno));
  211 ++ errno = save_errno;
  212 ++ return -1;
  213 ++ }
  214 ++
  215 ++ /* While there's enough data to fill up the map, fill it and increase the map size */
  216 ++ do {
  217 ++ /* When the current map is full, increase its size */
  218 ++ if (handle->size==handle->mapping_size && tor_mremap_inc(handle)) {
  219 ++ int save_errno = errno;
  220 ++ log_err(LD_FS,"Could not increase the anonymous memory mmaping while reading from file \"%s\"", filename);
  221 ++ close(fd);
  222 ++ errno = save_errno;
  223 ++ return -1;
  224 ++ }
  225 ++
  226 ++ /* Fill the map with data */
  227 ++ r = read(fd,(void *)handle->data+handle->size,handle->mapping_size-handle->size);
  228 ++ if (r<0) {
  229 ++ int save_errno = errno;
  230 ++ log_warn(LD_FS,"Error reading from file \"%s\": %s", filename,
  231 ++ strerror(errno));
  232 ++ close(fd);
  233 ++ errno = save_errno;
  234 ++ return -1;
  235 ++ }
  236 ++ handle->size+=r;
  237 ++
  238 ++ /* Repeat if we haven't reached the end of the file */
  239 ++ } while (r);
  240 ++
  241 ++ close(fd);
  242 ++ return 0;
  243 ++}
  244 +diff -uNr tor-0.2.3.19-rc/src/common/util.h tor-0.2.3.19-rc-anon_mmap//src/common/util.h
  245 +--- tor-0.2.3.19-rc/src/common/util.h 2012-07-06 16:32:28.000000000 -0400
  246 ++++ tor-0.2.3.19-rc-anon_mmap//src/common/util.h 2012-07-09 11:39:11.995224656 -0400
  247 +@@ -366,6 +366,12 @@
  248 + struct smartlist_t *tor_listdir(const char *dirname);
  249 + int path_is_relative(const char *filename);
  250 +
  251 ++int tor_mmap_anon(tor_mmap_t *handle);
  252 ++int tor_mremap_inc(tor_mmap_t *handle);
  253 ++int load_string_into_mmap(tor_mmap_t *handle, const char *string, const size_t length);
  254 ++int load_file_into_mmap(tor_mmap_t *handle, const char *filename);
  255 ++int tor_munmap(tor_mmap_t *handle);
  256 ++
  257 + /* Process helpers */
  258 + void start_daemon(void);
  259 + void finish_daemon(const char *desired_cwd);
  260 +diff -uNr tor-0.2.3.19-rc/src/or/control.c tor-0.2.3.19-rc-anon_mmap//src/or/control.c
  261 +--- tor-0.2.3.19-rc/src/or/control.c 2012-07-06 16:32:28.000000000 -0400
  262 ++++ tor-0.2.3.19-rc-anon_mmap//src/or/control.c 2012-07-09 11:39:12.003224655 -0400
  263 +@@ -34,6 +34,7 @@
  264 + #include "router.h"
  265 + #include "routerlist.h"
  266 + #include "routerparse.h"
  267 ++#include "microdesc.h"
  268 +
  269 + #ifndef _WIN32
  270 + #include <pwd.h>
  271 +@@ -1666,8 +1667,8 @@
  272 + const microdesc_t *md = NULL;
  273 + if (node) md = node->md;
  274 + if (md) {
  275 +- tor_assert(md->body);
  276 +- *answer = tor_strndup(md->body, md->bodylen);
  277 ++ tor_assert(microdesc_get_body(md));
  278 ++ *answer = tor_strndup(microdesc_get_body(md), md->bodylen);
  279 + }
  280 + } else if (!strcmpstart(question, "md/name/")) {
  281 + /* XXX023 Setting 'warn_if_unnamed' here is a bit silly -- the
  282 +@@ -1677,8 +1678,8 @@
  283 + const microdesc_t *md = NULL;
  284 + if (node) md = node->md;
  285 + if (md) {
  286 +- tor_assert(md->body);
  287 +- *answer = tor_strndup(md->body, md->bodylen);
  288 ++ tor_assert(microdesc_get_body(md));
  289 ++ *answer = tor_strndup(microdesc_get_body(md), md->bodylen);
  290 + }
  291 + } else if (!strcmpstart(question, "desc-annotations/id/")) {
  292 + ri = router_get_by_hexdigest(question+
  293 +diff -uNr tor-0.2.3.19-rc/src/or/microdesc.c tor-0.2.3.19-rc-anon_mmap//src/or/microdesc.c
  294 +--- tor-0.2.3.19-rc/src/or/microdesc.c 2012-07-06 16:31:36.000000000 -0400
  295 ++++ tor-0.2.3.19-rc-anon_mmap//src/or/microdesc.c 2012-07-09 11:39:12.011224656 -0400
  296 +@@ -65,6 +65,16 @@
  297 + _microdesc_hash, _microdesc_eq, 0.6,
  298 + malloc, realloc, free);
  299 +
  300 ++/** Return the pointer to the body of <b>md</b>. */
  301 ++char *
  302 ++microdesc_get_body(const microdesc_t *md)
  303 ++{
  304 ++ return md->saved_location==SAVED_IN_CACHE?
  305 ++ (void*)get_microdesc_cache()->cache_content->data
  306 ++ + md->cache_offset
  307 ++ : md->body;
  308 ++}
  309 ++
  310 + /** Write the body of <b>md</b> into <b>f</b>, with appropriate annotations.
  311 + * On success, return the total number of bytes written, and set
  312 + * *<b>annotation_len_out</b> to the number of bytes written as
  313 +@@ -92,8 +102,7 @@
  314 + *annotation_len_out = 0;
  315 + }
  316 +
  317 +- md->off = (off_t) ftell(f);
  318 +- written = fwrite(md->body, 1, md->bodylen, f);
  319 ++ written = fwrite(microdesc_get_body(md), 1, md->bodylen, f);
  320 + if (written != md->bodylen) {
  321 + log_warn(LD_DIR,
  322 + "Couldn't dump microdescriptor (wrote %lu out of %lu): %s",
  323 +@@ -115,6 +124,9 @@
  324 + {
  325 + if (PREDICT_UNLIKELY(the_microdesc_cache==NULL)) {
  326 + microdesc_cache_t *cache = tor_malloc_zero(sizeof(microdesc_cache_t));
  327 ++ cache->cache_content = tor_malloc_zero(sizeof(tor_mmap_t));
  328 ++ cache->cache_content->data = NULL;
  329 ++ cache->cache_content->size = cache->cache_content->mapping_size = 0;
  330 + HT_INIT(microdesc_map, &cache->map);
  331 + cache->cache_fname = get_datadir_fname("cached-microdescs");
  332 + cache->journal_fname = get_datadir_fname("cached-microdescs.new");
  333 +@@ -215,6 +227,7 @@
  334 + added = smartlist_new();
  335 + SMARTLIST_FOREACH_BEGIN(descriptors, microdesc_t *, md) {
  336 + microdesc_t *md2;
  337 ++ md->saved_location = where;
  338 + md2 = HT_FIND(microdesc_map, &cache->map, md);
  339 + if (md2) {
  340 + /* We already had this one. */
  341 +@@ -229,6 +242,7 @@
  342 + /* Okay, it's a new one. */
  343 + if (f) {
  344 + size_t annotation_len;
  345 ++ /* Write it to the file */
  346 + size = dump_microdescriptor(f, md, &annotation_len);
  347 + if (size < 0) {
  348 + /* we already warned in dump_microdescriptor; */
  349 +@@ -236,10 +250,20 @@
  350 + smartlist_clear(added);
  351 + return added;
  352 + }
  353 +- md->saved_location = SAVED_IN_JOURNAL;
  354 ++ md->off = cache->journal_len + annotation_len;
  355 ++ /* Append in the anonymous mmap of microdescriptors */
  356 ++ size_t new_offset = cache->cache_content->size;
  357 ++ if (load_string_into_mmap(cache->cache_content,
  358 ++ md->body, md->bodylen))
  359 ++ /* Loading into mmap failed, so leave it as a heap chunk */
  360 ++ md->saved_location = SAVED_IN_JOURNAL;
  361 ++ else {
  362 ++ /* Body is now in mmap */
  363 ++ tor_free(md->body);
  364 ++ md->cache_offset = new_offset;
  365 ++ md->saved_location = SAVED_IN_CACHE;
  366 ++ }
  367 + cache->journal_len += size;
  368 +- } else {
  369 +- md->saved_location = where;
  370 + }
  371 +
  372 + md->no_save = no_save;
  373 +@@ -278,9 +302,8 @@
  374 + microdesc_free(md);
  375 + }
  376 + HT_CLEAR(microdesc_map, &cache->map);
  377 +- if (cache->cache_content) {
  378 +- tor_munmap_file(cache->cache_content);
  379 +- cache->cache_content = NULL;
  380 ++ if (cache->cache_content->data) {
  381 ++ tor_munmap(cache->cache_content);
  382 + }
  383 + cache->total_len_seen = 0;
  384 + cache->n_seen = 0;
  385 +@@ -292,36 +315,25 @@
  386 + int
  387 + microdesc_cache_reload(microdesc_cache_t *cache)
  388 + {
  389 +- struct stat st;
  390 +- char *journal_content;
  391 + smartlist_t *added;
  392 +- tor_mmap_t *mm;
  393 + int total = 0;
  394 +
  395 + microdesc_cache_clear(cache);
  396 +
  397 +- mm = cache->cache_content = tor_mmap_file(cache->cache_fname);
  398 +- if (mm) {
  399 +- added = microdescs_add_to_cache(cache, mm->data, mm->data+mm->size,
  400 +- SAVED_IN_CACHE, 0, -1, NULL);
  401 +- if (added) {
  402 +- total += smartlist_len(added);
  403 +- smartlist_free(added);
  404 +- }
  405 +- }
  406 ++ load_file_into_mmap(cache->cache_content, cache->cache_fname);
  407 ++ size_t cache_size = cache->cache_content->size;
  408 +
  409 +- journal_content = read_file_to_str(cache->journal_fname,
  410 +- RFTS_IGNORE_MISSING, &st);
  411 +- if (journal_content) {
  412 +- cache->journal_len = (size_t) st.st_size;
  413 +- added = microdescs_add_to_cache(cache, journal_content,
  414 +- journal_content+st.st_size,
  415 +- SAVED_IN_JOURNAL, 0, -1, NULL);
  416 ++ load_file_into_mmap(cache->cache_content, cache->journal_fname);
  417 ++ cache->journal_len = cache->cache_content->size - cache_size;
  418 ++
  419 ++ if (cache->cache_content->size) {
  420 ++ added = microdescs_add_to_cache(cache, cache->cache_content->data,
  421 ++ cache->cache_content->data+cache->cache_content->size,
  422 ++ SAVED_IN_CACHE, 0, -1, NULL);
  423 + if (added) {
  424 + total += smartlist_len(added);
  425 + smartlist_free(added);
  426 + }
  427 +- tor_free(journal_content);
  428 + }
  429 + log_notice(LD_DIR, "Reloaded microdescriptor cache. Found %d descriptors.",
  430 + total);
  431 +@@ -427,7 +439,6 @@
  432 + log_info(LD_DIR, "Rebuilding the microdescriptor cache...");
  433 +
  434 + orig_size = (int)(cache->cache_content ? cache->cache_content->size : 0);
  435 +- orig_size += (int)cache->journal_len;
  436 +
  437 + f = start_writing_to_stdio_file(cache->cache_fname,
  438 + OPEN_FLAGS_REPLACE|O_BINARY,
  439 +@@ -459,14 +470,12 @@
  440 + smartlist_add(wrote, md);
  441 + }
  442 +
  443 +- if (cache->cache_content)
  444 +- tor_munmap_file(cache->cache_content);
  445 ++ if (cache->cache_content->data)
  446 ++ tor_munmap(cache->cache_content);
  447 +
  448 + finish_writing_to_file(open_file); /*XXX Check me.*/
  449 +
  450 +- cache->cache_content = tor_mmap_file(cache->cache_fname);
  451 +-
  452 +- if (!cache->cache_content && smartlist_len(wrote)) {
  453 ++ if (load_file_into_mmap(cache->cache_content, cache->cache_fname) && smartlist_len(wrote)) {
  454 + log_err(LD_DIR, "Couldn't map file that we just wrote to %s!",
  455 + cache->cache_fname);
  456 + smartlist_free(wrote);
  457 +@@ -474,21 +483,21 @@
  458 + }
  459 + SMARTLIST_FOREACH_BEGIN(wrote, microdesc_t *, md) {
  460 + tor_assert(md->saved_location == SAVED_IN_CACHE);
  461 +- md->body = (char*)cache->cache_content->data + md->off;
  462 ++ md->cache_offset = md->off;
  463 + if (PREDICT_UNLIKELY(
  464 +- md->bodylen < 9 || fast_memneq(md->body, "onion-key", 9) != 0)) {
  465 ++ md->bodylen < 9 || fast_memneq(microdesc_get_body(md), "onion-key", 9) != 0)) {
  466 + /* XXXX once bug 2022 is solved, we can kill this block and turn it
  467 + * into just the tor_assert(!memcmp) */
  468 + off_t avail = cache->cache_content->size - md->off;
  469 + char *bad_str;
  470 + tor_assert(avail >= 0);
  471 +- bad_str = tor_strndup(md->body, MIN(128, (size_t)avail));
  472 ++ bad_str = tor_strndup(microdesc_get_body(md), MIN(128, (size_t)avail));
  473 + log_err(LD_BUG, "After rebuilding microdesc cache, offsets seem wrong. "
  474 + " At offset %d, I expected to find a microdescriptor starting "
  475 + " with \"onion-key\". Instead I got %s.",
  476 + (int)md->off, escaped(bad_str));
  477 + tor_free(bad_str);
  478 +- tor_assert(fast_memeq(md->body, "onion-key", 9));
  479 ++ tor_assert(fast_memeq(microdesc_get_body(md), "onion-key", 9));
  480 + }
  481 + } SMARTLIST_FOREACH_END(md);
  482 +
  483 +@@ -498,7 +507,7 @@
  484 + cache->journal_len = 0;
  485 + cache->bytes_dropped = 0;
  486 +
  487 +- new_size = cache->cache_content ? (int)cache->cache_content->size : 0;
  488 ++ new_size = (int)cache->cache_content->size;
  489 + log_info(LD_DIR, "Done rebuilding microdesc cache. "
  490 + "Saved %d bytes; %d still used.",
  491 + orig_size-new_size, new_size);
  492 +@@ -594,6 +603,7 @@
  493 + microdesc_cache_clear(the_microdesc_cache);
  494 + tor_free(the_microdesc_cache->cache_fname);
  495 + tor_free(the_microdesc_cache->journal_fname);
  496 ++ tor_free(the_microdesc_cache->cache_content);
  497 + tor_free(the_microdesc_cache);
  498 + }
  499 + }
  500 +diff -uNr tor-0.2.3.19-rc/src/or/microdesc.h tor-0.2.3.19-rc-anon_mmap//src/or/microdesc.h
  501 +--- tor-0.2.3.19-rc/src/or/microdesc.h 2012-07-06 16:31:36.000000000 -0400
  502 ++++ tor-0.2.3.19-rc-anon_mmap//src/or/microdesc.h 2012-07-09 11:39:12.011224656 -0400
  503 +@@ -14,6 +14,8 @@
  504 +
  505 + microdesc_cache_t *get_microdesc_cache(void);
  506 +
  507 ++char* microdesc_get_body(const microdesc_t *md);
  508 ++
  509 + void microdesc_check_counts(void);
  510 +
  511 + smartlist_t *microdescs_add_to_cache(microdesc_cache_t *cache,
  512 +diff -uNr tor-0.2.3.19-rc/src/or/or.h tor-0.2.3.19-rc-anon_mmap//src/or/or.h
  513 +--- tor-0.2.3.19-rc/src/or/or.h 2012-07-06 16:31:36.000000000 -0400
  514 ++++ tor-0.2.3.19-rc-anon_mmap//src/or/or.h 2012-07-09 11:39:12.015224656 -0400
  515 +@@ -1633,16 +1633,14 @@
  516 + /** The descriptor isn't stored on disk at all: the copy in memory is
  517 + * canonical; the saved_offset field is meaningless. */
  518 + SAVED_NOWHERE=0,
  519 +- /** The descriptor is stored in the cached_routers file: the
  520 ++ /** The descriptor is stored in the cached_routers file or in the journal.
  521 ++ * In both cases the body is kept in the anonymous mmap: the
  522 + * signed_descriptor_body is meaningless; the signed_descriptor_len and
  523 +- * saved_offset are used to index into the mmaped cache file. */
  524 ++ * saved_offset are used to index into the memory map. */
  525 + SAVED_IN_CACHE,
  526 +- /** The descriptor is stored in the cached_routers.new file: the
  527 ++ /** The descriptor is stored in the cached_routers.new file but we've
  528 ++ * failed to get space in the anonymous mmap (memory error). The
  529 + * signed_descriptor_body and saved_offset fields are both set. */
  530 +- /* FFFF (We could also mmap the file and grow the mmap as needed, or
  531 +- * lazy-load the descriptor text by using seek and read. We don't, for
  532 +- * now.)
  533 +- */
  534 + SAVED_IN_JOURNAL
  535 + } saved_location_t;
  536 +
  537 +@@ -1696,8 +1694,8 @@
  538 + download_status_t ei_dl_status;
  539 + /** Where is the descriptor saved? */
  540 + saved_location_t saved_location;
  541 +- /** If saved_location is SAVED_IN_CACHE or SAVED_IN_JOURNAL, the offset of
  542 +- * this descriptor in the corresponding file. */
  543 ++ /** The position of the body in anonymous memory map dedicated to holding
  544 ++ * descriptors that are saved in files. */
  545 + off_t saved_offset;
  546 + /** What position is this descriptor within routerlist->routers or
  547 + * routerlist->old_routers? -1 for none. */
  548 +@@ -1949,9 +1947,13 @@
  549 + unsigned int held_by_nodes;
  550 +
  551 + /** If saved_location == SAVED_IN_CACHE, this field holds the offset of the
  552 +- * microdescriptor in the cache. */
  553 ++ * microdescriptor in the file that holds it cache. */
  554 + off_t off;
  555 +
  556 ++ /** If saved_location == SAVED_IN_CACHE, this field holds the offset to the
  557 ++ * microdescriptor body in the anonymous memory map */
  558 ++ size_t cache_offset;
  559 ++
  560 + /* The string containing the microdesc. */
  561 +
  562 + /** A pointer to the encoded body of the microdescriptor. If the
  563 +diff -uNr tor-0.2.3.19-rc/src/or/routerlist.c tor-0.2.3.19-rc-anon_mmap//src/or/routerlist.c
  564 +--- tor-0.2.3.19-rc/src/or/routerlist.c 2012-07-06 16:31:36.000000000 -0400
  565 ++++ tor-0.2.3.19-rc-anon_mmap//src/or/routerlist.c 2012-07-09 11:39:12.019224656 -0400
  566 +@@ -627,8 +627,9 @@
  567 + }
  568 +
  569 + /** Add the signed_descriptor_t in <b>desc</b> to the router
  570 +- * journal; change its saved_location to SAVED_IN_JOURNAL and set its
  571 +- * offset appropriately. */
  572 ++ * journal; change its saved_location to SAVED_IN_CACHE and set its
  573 ++ * offset appropriately. The location is set to SAVED_IN_JOURNAL
  574 ++ * only if we can't move the body to the cache memory map */
  575 + static int
  576 + signed_desc_append_to_journal(signed_descriptor_t *desc,
  577 + desc_store_t *store)
  578 +@@ -642,10 +643,18 @@
  579 + tor_free(fname);
  580 + return -1;
  581 + }
  582 +- desc->saved_location = SAVED_IN_JOURNAL;
  583 + tor_free(fname);
  584 +
  585 +- desc->saved_offset = store->journal_len;
  586 ++ size_t mmap_offset = store->mmap->size;
  587 ++ /* If we can't move the body into the map, leave it where it is */
  588 ++ if (load_string_into_mmap(store->mmap, desc->signed_descriptor_body,
  589 ++ desc->signed_descriptor_len + desc->annotations_len))
  590 ++ desc->saved_location = SAVED_IN_JOURNAL;
  591 ++ else {
  592 ++ tor_free(desc->signed_descriptor_body);
  593 ++ desc->saved_offset = mmap_offset;
  594 ++ desc->saved_location = SAVED_IN_CACHE;
  595 ++ }
  596 + store->journal_len += len;
  597 +
  598 + return 0;
  599 +@@ -674,7 +683,7 @@
  600 + router_rebuild_store(int flags, desc_store_t *store)
  601 + {
  602 + smartlist_t *chunk_list = NULL;
  603 +- char *fname = NULL, *fname_tmp = NULL;
  604 ++ char *fname = NULL;
  605 + int r = -1;
  606 + off_t offset = 0;
  607 + smartlist_t *signed_descriptors = NULL;
  608 +@@ -705,7 +714,6 @@
  609 + log_info(LD_DIR, "Rebuilding %s cache", store->description);
  610 +
  611 + fname = get_datadir_fname(store->fname_base);
  612 +- fname_tmp = get_datadir_fname_suffix(store->fname_base, ".tmp");
  613 +
  614 + chunk_list = smartlist_new();
  615 +
  616 +@@ -750,25 +758,19 @@
  617 + smartlist_add(chunk_list, c);
  618 + });
  619 +
  620 +- if (write_chunks_to_file(fname_tmp, chunk_list, 1)<0) {
  621 ++ if (write_chunks_to_file(fname, chunk_list, 1)<0) {
  622 + log_warn(LD_FS, "Error writing router store to disk.");
  623 + goto done;
  624 + }
  625 +
  626 + /* Our mmap is now invalid. */
  627 + if (store->mmap) {
  628 +- tor_munmap_file(store->mmap);
  629 +- store->mmap = NULL;
  630 +- }
  631 +-
  632 +- if (replace_file(fname_tmp, fname)<0) {
  633 +- log_warn(LD_FS, "Error replacing old router store: %s", strerror(errno));
  634 +- goto done;
  635 ++ tor_munmap(store->mmap);
  636 + }
  637 +
  638 + errno = 0;
  639 +- store->mmap = tor_mmap_file(fname);
  640 +- if (! store->mmap) {
  641 ++ load_file_into_mmap(store->mmap, fname);
  642 ++ if (!store->mmap) {
  643 + if (errno == ERANGE) {
  644 + /* empty store.*/
  645 + if (total_expected_len) {
  646 +@@ -811,7 +813,6 @@
  647 + done:
  648 + smartlist_free(signed_descriptors);
  649 + tor_free(fname);
  650 +- tor_free(fname_tmp);
  651 + if (chunk_list) {
  652 + SMARTLIST_FOREACH(chunk_list, sized_chunk_t *, c, tor_free(c));
  653 + smartlist_free(chunk_list);
  654 +@@ -826,10 +827,11 @@
  655 + static int
  656 + router_reload_router_list_impl(desc_store_t *store)
  657 + {
  658 +- char *fname = NULL, *altname = NULL, *contents = NULL;
  659 +- struct stat st;
  660 ++ char *fname = NULL, *altname = NULL;
  661 + int read_from_old_location = 0;
  662 + int extrainfo = (store->type == EXTRAINFO_STORE);
  663 ++ int r;
  664 ++ size_t cache_size;
  665 + time_t now = time(NULL);
  666 + store->journal_len = store->store_len = 0;
  667 +
  668 +@@ -837,60 +839,56 @@
  669 + if (store->fname_alt_base)
  670 + altname = get_datadir_fname(store->fname_alt_base);
  671 +
  672 +- if (store->mmap) /* get rid of it first */
  673 +- tor_munmap_file(store->mmap);
  674 +- store->mmap = NULL;
  675 +-
  676 +- store->mmap = tor_mmap_file(fname);
  677 +- if (!store->mmap && altname && file_status(altname) == FN_FILE) {
  678 +- read_from_old_location = 1;
  679 ++ if (store->mmap->size) /* get rid of it first */
  680 ++ tor_munmap(store->mmap);
  681 ++
  682 ++ /* Load the cache file into an anonymous map first */
  683 ++ if (load_file_into_mmap(store->mmap, fname) &&
  684 ++ altname && file_status(altname) == FN_FILE) {
  685 + log_notice(LD_DIR, "Couldn't read %s; trying to load routers from old "
  686 + "location %s.", fname, altname);
  687 +- if ((store->mmap = tor_mmap_file(altname)))
  688 ++ if (!(load_file_into_mmap(store->mmap, altname)))
  689 + read_from_old_location = 1;
  690 + }
  691 + if (altname && !read_from_old_location) {
  692 + remove_file_if_very_old(altname, now);
  693 + }
  694 +- if (store->mmap) {
  695 +- store->store_len = store->mmap->size;
  696 +- if (extrainfo)
  697 +- router_load_extrainfo_from_string(store->mmap->data,
  698 +- store->mmap->data+store->mmap->size,
  699 +- SAVED_IN_CACHE, NULL, 0);
  700 +- else
  701 +- router_load_routers_from_string(store->mmap->data,
  702 +- store->mmap->data+store->mmap->size,
  703 +- SAVED_IN_CACHE, NULL, 0, NULL);
  704 +- }
  705 +
  706 ++ /* Remeber the size of the current data, so we can determine
  707 ++ * whether we've read anything from the journal */
  708 ++ cache_size = store->mmap->size;
  709 + tor_free(fname);
  710 + fname = get_datadir_fname_suffix(store->fname_base, ".new");
  711 +- if (file_status(fname) == FN_FILE)
  712 +- contents = read_file_to_str(fname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  713 ++ r = 0;
  714 ++ if ((file_status(fname) == FN_FILE) && (r = load_file_into_mmap(store->mmap, fname)))
  715 ++ log_warn(LD_DIR, "Couldn't read journal %s", fname);
  716 + if (read_from_old_location) {
  717 + tor_free(altname);
  718 + altname = get_datadir_fname_suffix(store->fname_alt_base, ".new");
  719 +- if (!contents)
  720 +- contents = read_file_to_str(altname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  721 ++ if (r)
  722 ++ load_file_into_mmap(store->mmap, altname);
  723 + else
  724 + remove_file_if_very_old(altname, now);
  725 + }
  726 +- if (contents) {
  727 ++
  728 ++ /* Load router data from the map */
  729 ++ if (store->mmap->size) {
  730 ++ store->store_len = store->mmap->size;
  731 + if (extrainfo)
  732 +- router_load_extrainfo_from_string(contents, NULL,SAVED_IN_JOURNAL,
  733 +- NULL, 0);
  734 ++ router_load_extrainfo_from_string(store->mmap->data,
  735 ++ store->mmap->data+store->mmap->size,
  736 ++ SAVED_IN_CACHE, NULL, 0);
  737 + else
  738 +- router_load_routers_from_string(contents, NULL, SAVED_IN_JOURNAL,
  739 +- NULL, 0, NULL);
  740 +- store->journal_len = (size_t) st.st_size;
  741 +- tor_free(contents);
  742 ++ router_load_routers_from_string(store->mmap->data,
  743 ++ store->mmap->data+store->mmap->size,
  744 ++ SAVED_IN_CACHE, NULL, 0, NULL);
  745 + }
  746 +
  747 + tor_free(fname);
  748 + tor_free(altname);
  749 +
  750 +- if (store->journal_len || read_from_old_location) {
  751 ++ /* rebuild if journal was not empty or we used old locations */
  752 ++ if ((store->mmap->size-cache_size>0) || read_from_old_location) {
  753 + /* Always clear the journal on startup.*/
  754 + router_rebuild_store(RRS_FORCE, store);
  755 + } else if (!extrainfo) {
  756 +@@ -2691,6 +2689,13 @@
  757 +
  758 + routerlist->desc_store.description = "router descriptors";
  759 + routerlist->extrainfo_store.description = "extra-info documents";
  760 ++
  761 ++ routerlist->desc_store.mmap = tor_malloc_zero(sizeof(tor_mmap_t));
  762 ++ routerlist->desc_store.mmap->data = NULL;
  763 ++ routerlist->desc_store.mmap->size = routerlist->desc_store.mmap->mapping_size = 0;
  764 ++ routerlist->extrainfo_store.mmap = tor_malloc_zero(sizeof(tor_mmap_t));
  765 ++ routerlist->extrainfo_store.mmap->data = NULL;
  766 ++ routerlist->extrainfo_store.mmap->size = routerlist->extrainfo_store.mmap->mapping_size = 0;
  767 + }
  768 + return routerlist;
  769 + }
  770 +@@ -2787,10 +2792,14 @@
  771 + signed_descriptor_free(sd));
  772 + smartlist_free(rl->routers);
  773 + smartlist_free(rl->old_routers);
  774 +- if (routerlist->desc_store.mmap)
  775 +- tor_munmap_file(routerlist->desc_store.mmap);
  776 +- if (routerlist->extrainfo_store.mmap)
  777 +- tor_munmap_file(routerlist->extrainfo_store.mmap);
  778 ++ if (routerlist->desc_store.mmap) {
  779 ++ tor_munmap(routerlist->desc_store.mmap);
  780 ++ tor_free(routerlist->desc_store.mmap);
  781 ++ }
  782 ++ if (routerlist->extrainfo_store.mmap) {
  783 ++ tor_munmap(routerlist->extrainfo_store.mmap);
  784 ++ free(routerlist->extrainfo_store.mmap);
  785 ++ }
  786 + tor_free(rl);
  787 +
  788 + router_dir_info_changed();
  789 +diff -uNr tor-0.2.3.19-rc/src/or/routerparse.c tor-0.2.3.19-rc-anon_mmap//src/or/routerparse.c
  790 +--- tor-0.2.3.19-rc/src/or/routerparse.c 2012-07-06 16:31:36.000000000 -0400
  791 ++++ tor-0.2.3.19-rc-anon_mmap//src/or/routerparse.c 2012-07-09 11:39:12.023224656 -0400
  792 +@@ -4387,18 +4387,19 @@
  793 + }
  794 +
  795 + md = tor_malloc_zero(sizeof(microdesc_t));
  796 +- {
  797 +- const char *cp = tor_memstr(s, start_of_next_microdesc-s,
  798 ++ const char *cp = tor_memstr(s, start_of_next_microdesc-s,
  799 + "onion-key");
  800 +- tor_assert(cp);
  801 ++ tor_assert(cp);
  802 +
  803 +- md->bodylen = start_of_next_microdesc - cp;
  804 +- if (copy_body)
  805 +- md->body = tor_strndup(cp, md->bodylen);
  806 +- else
  807 +- md->body = (char*)cp;
  808 +- md->off = cp - start;
  809 ++ md->bodylen = start_of_next_microdesc - cp;
  810 ++ if (copy_body)
  811 ++ md->body = tor_strndup(cp, md->bodylen);
  812 ++ else {
  813 ++ /* we're parsing the cache */
  814 ++ md->body = NULL;
  815 ++ md->cache_offset = cp - start;
  816 + }
  817 ++ md->off = cp - start;
  818 +
  819 + if ((tok = find_opt_by_keyword(tokens, A_LAST_LISTED))) {
  820 + if (parse_iso_time(tok->args[0], &md->last_listed)) {
  821 +@@ -4433,7 +4434,7 @@
  822 + md->exit_policy = parse_short_policy(tok->args[0]);
  823 + }
  824 +
  825 +- crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256);
  826 ++ crypto_digest256(md->digest, cp, md->bodylen, DIGEST_SHA256);
  827 +
  828 + smartlist_add(result, md);
  829 +
  830 +diff -uNr tor-0.2.3.19-rc/src/test/test_microdesc.c tor-0.2.3.19-rc-anon_mmap//src/test/test_microdesc.c
  831 +--- tor-0.2.3.19-rc/src/test/test_microdesc.c 2012-07-06 16:31:36.000000000 -0400
  832 ++++ tor-0.2.3.19-rc-anon_mmap//src/test/test_microdesc.c 2012-07-09 11:39:12.023224656 -0400
  833 +@@ -55,6 +55,7 @@
  834 + time_t time1, time2, time3;
  835 + char *fn = NULL, *s = NULL;
  836 + (void)data;
  837 ++ tor_mmap_t *map;
  838 +
  839 + options = get_options_mutable();
  840 + tt_assert(options);
  841 +@@ -134,25 +135,25 @@
  842 + tt_int_op(md2->last_listed, ==, time2);
  843 + tt_int_op(md3->last_listed, ==, time3);
  844 +
  845 +- tt_int_op(md1->saved_location, ==, SAVED_IN_JOURNAL);
  846 +- tt_int_op(md2->saved_location, ==, SAVED_IN_JOURNAL);
  847 +- tt_int_op(md3->saved_location, ==, SAVED_IN_JOURNAL);
  848 ++ tt_int_op(md1->saved_location, ==, SAVED_IN_CACHE);
  849 ++ tt_int_op(md2->saved_location, ==, SAVED_IN_CACHE);
  850 ++ tt_int_op(md3->saved_location, ==, SAVED_IN_CACHE);
  851 +
  852 + tt_int_op(md1->bodylen, ==, strlen(test_md1));
  853 + tt_int_op(md2->bodylen, ==, strlen(test_md2));
  854 + tt_int_op(md3->bodylen, ==, strlen(test_md3_noannotation));
  855 +- test_mem_op(md1->body, ==, test_md1, strlen(test_md1));
  856 +- test_mem_op(md2->body, ==, test_md2, strlen(test_md2));
  857 +- test_mem_op(md3->body, ==, test_md3_noannotation,
  858 ++ test_mem_op(microdesc_get_body(md1), ==, test_md1, strlen(test_md1));
  859 ++ test_mem_op(microdesc_get_body(md2), ==, test_md2, strlen(test_md2));
  860 ++ test_mem_op(microdesc_get_body(md3), ==, test_md3_noannotation,
  861 + strlen(test_md3_noannotation));
  862 +
  863 + tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new",
  864 + options->DataDirectory);
  865 + s = read_file_to_str(fn, RFTS_BIN, NULL);
  866 + tt_assert(s);
  867 +- test_mem_op(md1->body, ==, s + md1->off, md1->bodylen);
  868 +- test_mem_op(md2->body, ==, s + md2->off, md2->bodylen);
  869 +- test_mem_op(md3->body, ==, s + md3->off, md3->bodylen);
  870 ++ test_mem_op(microdesc_get_body(md1), ==, s + md1->off, md1->bodylen);
  871 ++ test_mem_op(microdesc_get_body(md2), ==, s + md2->off, md2->bodylen);
  872 ++ test_mem_op(microdesc_get_body(md3), ==, s + md3->off, md3->bodylen);
  873 +
  874 + tt_ptr_op(md1->family, ==, NULL);
  875 + tt_ptr_op(md3->family, !=, NULL);
  876 +@@ -175,11 +176,15 @@
  877 +
  878 + /* read the cache. */
  879 + tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
  880 +- options->DataDirectory);
  881 +- s = read_file_to_str(fn, RFTS_BIN, NULL);
  882 +- test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
  883 +- test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
  884 +- test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
  885 ++ options->DataDirectory);
  886 ++ map = tor_malloc(sizeof(tor_mmap_t));
  887 ++ map->data = NULL;
  888 ++ map->size = map->mapping_size = 0;
  889 ++ load_file_into_mmap(map, fn);
  890 ++ s = (char*)map->data;
  891 ++ test_mem_op(microdesc_get_body(md1), ==, s + md1->off, strlen(test_md1));
  892 ++ test_mem_op(microdesc_get_body(md2), ==, s + md2->off, strlen(test_md2));
  893 ++ test_mem_op(microdesc_get_body(md3), ==, s + md3->off, strlen(test_md3_noannotation));
  894 +
  895 + /* Okay, now we are going to forget about the cache entirely, and reload it
  896 + * from the disk. */
  897 +@@ -191,9 +196,9 @@
  898 + test_assert(md1);
  899 + test_assert(md2);
  900 + test_assert(md3);
  901 +- test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
  902 +- test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
  903 +- test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));
  904 ++ test_mem_op(microdesc_get_body(md1), ==, s + md1->off, strlen(test_md1));
  905 ++ test_mem_op(microdesc_get_body(md2), ==, s + md2->off, strlen(test_md2));
  906 ++ test_mem_op(microdesc_get_body(md3), ==, s + md3->off, strlen(test_md3_noannotation));
  907 +
  908 + tt_int_op(md1->last_listed, ==, time1);
  909 + tt_int_op(md2->last_listed, ==, time2);
  910 +@@ -222,7 +227,8 @@
  911 + if (wanted)
  912 + SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
  913 + smartlist_free(wanted);
  914 +- tor_free(s);
  915 ++ tor_munmap(map);
  916 ++ tor_free(map);
  917 + tor_free(fn);
  918 + }
  919 +
39 feeds/packages/net/tor-alpha/patches/001-persistent_keys_in_etc.patch
... ... @@ -0,0 +1,39 @@
  1 +diff -uNr tor-0.2.3.15-alpha/src/or/config.c tor-0.2.3.15-alpha-persistent_keys_in_etc/src/or/config.c
  2 +--- tor-0.2.3.15-alpha/src/or/config.c 2012-04-29 17:07:09.000000000 -0400
  3 ++++ tor-0.2.3.15-alpha-persistent_keys_in_etc/src/or/config.c 2012-05-21 13:05:10.332574460 -0400
  4 +@@ -1458,17 +1458,13 @@
  5 +
  6 + /* If needed, generate a new TLS DH prime according to the current torrc. */
  7 + if (server_mode(options) && options->DynamicDHGroups) {
  8 +- char *keydir = get_datadir_fname("keys");
  9 +- if (check_private_dir(keydir, CPD_CREATE, options->User)) {
  10 +- tor_free(keydir);
  11 ++ char *keydir = "/etc/tor/var";
  12 ++ if (check_private_dir(keydir, CPD_CREATE, options->User))
  13 + return -1;
  14 +- }
  15 +- tor_free(keydir);
  16 +
  17 + if (!old_options || !old_options->DynamicDHGroups) {
  18