diff --git a/doc/TODO b/doc/TODO index c330d9240f..b077956e3f 100644 --- a/doc/TODO +++ b/doc/TODO @@ -73,10 +73,14 @@ N . Improve memory usage on tight-memory machines. - "bandwidth classes", for incoming vs initiated-here conns. o Asynchronous DNS - . And test it + o And test it . Make it work on windows. o Implement + . Enable - Test + - Make the Nameservers option documented, and make it work right on + reload. + - Fail when we have no configured nameservers! - Make it the default on platforms where it works - Security improvements diff --git a/src/common/compat.c b/src/common/compat.c index 9ab5d8fb46..944640e2a7 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -24,8 +24,9 @@ const char compat_c_id[] = #ifdef MS_WINDOWS #include - +#include #endif + #ifdef HAVE_UNAME #include #endif @@ -107,16 +108,22 @@ const char compat_c_id[] = #define INADDR_NONE ((unsigned long) -1) #endif -#ifdef HAVE_SYS_MMAN -const char * -tor_mmap_file(const char *filename, size_t *size) +#ifdef HAVE_SYS_MMAN_H +struct tor_mmap_t { + char *data; + size_t size; +}; +tor_mmap_t * +tor_mmap_file(const char *filename, const char **data, size_t *size_out) { int fd; /* router file */ char *string; int page_size; + tor_mmap_t *res; + size_t size; tor_assert(filename); - tor_assert(size); + tor_assert(size_out); fd = open(filename, O_RDONLY, 0); if (fd<0) { @@ -124,13 +131,13 @@ tor_mmap_file(const char *filename, size_t *size) return NULL; } - *size = lseek(fd, 0, SEEK_END); + size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); /* ensure page alignment */ page_size = getpagesize(); - *size += (page_size + (page_size-(*size%page_size))); + size += (page_size + (page_size-(size%page_size))); - string = mmap(0, *size, PROT_READ, MAP_PRIVATE, fd, 0); + string = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0); if (string == MAP_FAILED) { log_warn(LD_FS,"Could not mmap file \"%s\": %s", filename, strerror(errno)); @@ -139,30 +146,88 @@ tor_mmap_file(const char *filename, size_t *size) close(fd); - return string; -} + res = tor_malloc_zero(sizeof(tor_mmap_t)); + *data = res->data = string; + *size_out = res->size = size; -void -tor_munmap_file(const char *memory, size_t size) -{ - munmap((char*)memory, size); -} -#else -const char * -tor_mmap_file(const char *filename, size_t *size) -{ - char *res = read_file_to_str(filename, 1); - if (res) - *size = strlen(res) + 1; return res; } +void +tor_munmap_file(tor_mmap_t *handle) +{ + munmap(handle->data, handle->size); +} +#elif defined(MS_WINDOWS) +typdef struct tor_mmap_t { + char *data; + HANDLE file_handle; + HANDLE mmap_handle; + size_t size; +} tor_mmap_t; +tor_mmap_t * +tor_mmap_file(const char *filename, const char **data, size_t *size) +{ + win_mmap_t *res = tor_malloc_zero(res); + res->mmap_handle = res->file_handle = INVALID_HANDLE_VALUE; + /* What's this about tags? */ + + /* Open the file. */ + res->file_handle = XXXXX; + res->size = GetFileSize(res->file_handle, NULL); + + res->mmap_handle = CreateFileMapping(res->file_handle, + NULL, + PAGE_READONLY, + 0, + size, + tagname); + if (res->mmap_handle != INVALID_HANDLE_VALUE) + goto err; + res->data = (char*) MapViewOfFile(res->mmap_handle, + access, + 0, 0, 0); + if (!res->data) + goto err; + + *size = res->size; + *data = res->data; + + return res; + err: + tor_munmap_file(res); + return NULL; +} +void +tor_munmap_file(tor_mmap_t *handle) +{ + if (handle->data) + UnmapViewOfFile(handle->data); + if (res->mmap_handle != INVALID_HANDLE_VALUE) + CloseHandle(res->mmap_handle); + if (res->file_handle != INVALID_HANDLE_VALUE) + CloseHandle(self->file_handle); + tor_free(res); +} +#else +struct tor_mmap_t { + char *data; +}; +tor_mmap_t * +tor_mmap_file(const char *filename, const char **data, size_t *size) +{ + char *res = read_file_to_str(filename, 1); + tor_mmap_t *handle; + if (res) + *size = strlen(res) + 1; + handle = tor_malloc_zero(sizeof(tor_mmap_t)); + *data = handle->data = res; + return handle; +} void -tor_munmap_file(const char *memory, size_t size) +tor_munmap_file(tor_mmap_t *handle) { - char *mem = (char*) memory; - (void)size; - tor_free(mem); + tor_free(handle->data); } #endif diff --git a/src/common/compat.h b/src/common/compat.h index 5b76cfe02a..eb72e2e663 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -114,8 +114,12 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #define U64_LITERAL(n) (n ## llu) #endif -const char *tor_mmap_file(const char *filename, size_t *size); -void tor_munmap_file(const char *memory, size_t size); +/** Opaque bookkeeping type used for mmap accounting. */ +typedef struct tor_mmap_t tor_mmap_t; + +tor_mmap_t *tor_mmap_file(const char *filename, + const char **data, size_t *size); +void tor_munmap_file(tor_mmap_t *handle); int tor_snprintf(char *str, size_t size, const char *format, ...) CHECK_PRINTF(3,4); diff --git a/src/or/or.h b/src/or/or.h index 7e3f96eaf8..b1a213a8d3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1020,6 +1020,7 @@ typedef struct { /** DOCDOC */ const char *mmap_descriptors; size_t mmap_descriptors_len; + tor_mmap_t *mmap_handle; } routerlist_t; /** Information on router used when extending a circuit. (We don't need a diff --git a/src/or/routerlist.c b/src/or/routerlist.c index de98ac52f5..e9819ddd83 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -276,12 +276,12 @@ router_rebuild_store(int force) goto done; } /* Our mmap is now invalid. */ - if (routerlist->mmap_descriptors) { - tor_munmap_file(routerlist->mmap_descriptors, - routerlist->mmap_descriptors_len); - routerlist->mmap_descriptors = - tor_mmap_file(fname, &routerlist->mmap_descriptors_len); - if (! routerlist->mmap_descriptors) + if (routerlist->mmap_handle) { + tor_munmap_file(routerlist->mmap_handle); + routerlist->mmap_handle = tor_mmap_file(fname, + &routerlist->mmap_descriptors, + &routerlist->mmap_descriptors_len); + if (! routerlist->mmap_handle) log_warn(LD_FS, "Unable to mmap new descriptor file at '%s'.",fname); } @@ -340,8 +340,9 @@ router_reload_router_list(void) router_journal_len = router_store_len = 0; tor_snprintf(fname, fname_len, "%s/cached-routers", options->DataDirectory); - routerlist->mmap_descriptors = - tor_mmap_file(fname, &routerlist->mmap_descriptors_len); + routerlist->mmap_handle = tor_mmap_file(fname, + &routerlist->mmap_descriptors, + &routerlist->mmap_descriptors_len); if (routerlist->mmap_descriptors) { router_store_len = routerlist->mmap_descriptors_len; router_load_routers_from_string(routerlist->mmap_descriptors,