Merge branch 'maint-0.2.2' into release-0.2.2

This commit is contained in:
Roger Dingledine 2011-04-01 10:16:57 -04:00
commit c7473adec0
49 changed files with 721 additions and 206 deletions

View File

@ -1,4 +1,4 @@
# Doxyfile 1.5.1
# Doxyfile 1.5.6
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
@ -14,6 +14,14 @@
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
@ -46,23 +54,14 @@ CREATE_SUBDIRS = NO
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
# and Ukrainian.
OUTPUT_LANGUAGE = English
# This tag can be used to specify the encoding used in the generated output.
# The encoding is not always determined by the language that is chosen,
# but also whether or not the output is meant for Windows or non-Windows users.
# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
# forces the Windows encoding (this is the default for the Windows binary),
# whereas setting the tag to NO uses a Unix-style encoding (the default for
# all platforms other than Windows).
USE_WINDOWS_ENCODING = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
@ -135,11 +134,19 @@ SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the JavaDoc
# comments will behave just like the Qt-style comments (thus requiring an
# explicit @brief command for a brief description.
# comments will behave just like regular Qt-style comments
# (thus requiring an explicit @brief command for a brief description.)
JAVADOC_AUTOBRIEF = NO
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
# interpret the first line (until the first dot) of a Qt-style
# comment as the brief description. If set to NO, the comments
# will behave just like regular Qt-style comments (thus requiring
# an explicit \brief command for a brief description.)
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
# comments) as a brief description. This used to be the default behaviour.
@ -153,7 +160,7 @@ MULTILINE_CPP_IS_BRIEF = NO
# If set to NO, the detailed description appears after the member
# documentation.
DETAILS_AT_TOP = NO
# DETAILS_AT_TOP = NO
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
@ -189,14 +196,26 @@ ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
# sources only. Doxygen will then generate output that is more tailored for Java.
# For instance, namespaces will be presented as packages, qualified scopes
# will look different, etc.
# sources only. Doxygen will then generate output that is more tailored for
# Java. For instance, namespaces will be presented as packages, qualified
# scopes will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
# include (a tag file for) the STL sources as input, then you should
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources only. Doxygen will then generate output that is more tailored for
# Fortran.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for
# VHDL.
OPTIMIZE_OUTPUT_VHDL = NO
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should
# set this tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
# func(std::string) {}). This also make the inheritance and collaboration
@ -204,6 +223,26 @@ OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
# Doxygen will parse them like normal C++ but will assume all classes use public
# instead of private inheritance when no explicit protection keyword is present.
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate getter
# and setter methods for a property. Setting this option to YES (the default)
# will make doxygen to replace the get and set methods by a property in the
# documentation. This will only work if the methods are indeed getting or
# setting a simple type. If this is not the case, or you want to show the
# methods anyway, you should set this option to NO.
IDL_PROPERTY_SUPPORT = NO
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES, then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
@ -219,6 +258,16 @@ DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
# is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically
# be useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@ -253,6 +302,14 @@ EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base
# name of the file that contains the anonymous namespace. By default
# anonymous namespace are hidden.
EXTRACT_ANON_NSPACES = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
@ -328,6 +385,12 @@ SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
# hierarchy of group names into alphabetical order. If set to NO (the default)
# the group names will appear in their defined order.
SORT_GROUP_NAMES = NO
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
# sorted by fully-qualified names, including namespaces. If set to
# NO (the default), the class list will be sorted only by class name,
@ -389,9 +452,21 @@ SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
# Folder Tree View (if specified). The default is YES.
SHOW_FILES = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
# Namespaces page. This will remove the Namespaces entry from the Quick Index
# and from the Folder Tree View (if specified). The default is YES.
SHOW_NAMESPACES = YES
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from the
# version control system). Doxygen will invoke the program by executing (via
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command <command> <input-file>, where <command> is the value of
# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
# provided by doxygen. Whatever the program writes to standard output
@ -462,12 +537,20 @@ WARN_LOGFILE =
INPUT = src/common \
src/or
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
# also the default input encoding. Doxygen uses libiconv (or the iconv built
# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
# the list of possible encodings.
INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank the following patterns are tested:
# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
FILE_PATTERNS = *.c \
*.h
@ -498,6 +581,14 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
EXCLUDE_SYMBOLS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
@ -558,7 +649,7 @@ FILTER_SOURCE_FILES = NO
# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER = NO
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
@ -571,13 +662,13 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES (the default)
# If the REFERENCED_BY_RELATION tag is set to YES
# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
# If the REFERENCES_RELATION tag is set to YES (the default)
# If the REFERENCES_RELATION tag is set to YES
# then for each documented function all documented entities
# called/used by that function will be listed.
@ -677,11 +768,44 @@ HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
# integrated development environment, introduced with OSX 10.5 (Leopard).
# To create a documentation set, doxygen will generate a Makefile in the
# HTML output directory. Running make will produce the docset in that
# directory and running "make install" will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
# it at startup.
GENERATE_DOCSET = NO
# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
# feed. A documentation feed provides an umbrella under which multiple
# documentation sets from a single provider (such as a company or product suite)
# can be grouped.
DOCSET_FEEDNAME = "Doxygen generated docs for Tor"
# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
# should uniquely identify the documentation set bundle. This should be a
# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
# will append .docset to the name.
DOCSET_BUNDLE_ID = org.torproject.Tor
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded. For this to work a browser that supports
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
# be used to specify the file name of the resulting .chm file. You
# can add a path in front of the file if the result should not be
@ -702,6 +826,12 @@ HHC_LOCATION =
GENERATE_CHI = NO
# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
# is used to encode HtmlHelp index (hhk), content (hhc) and project file
# content.
CHM_INDEX_ENCODING =
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
@ -724,12 +854,20 @@ DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
# generated containing a tree-like index structure (just like the one that
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information.
# If the tag value is set to FRAME, a side panel will be generated
# containing a tree-like index structure (just like the one that
# is generated for HTML Help). For this to work a browser that supports
# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
# probably better off using the HTML help feature.
# probably better off using the HTML help feature. Other possible values
# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
# and Class Hiererachy pages using a tree view instead of an ordered list;
# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
# disables this behavior completely. For backwards compatibility with previous
# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
# respectively.
GENERATE_TREEVIEW = NO
@ -739,6 +877,14 @@ GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
# Use this tag to change the font size of Latex formulas included
# as images in the HTML documentation. The default is 10. Note that
# when you change the font size after a successful doxygen run you need
# to manually remove any form_*.png images from the HTML output directory
# to force them to be regenerated.
FORMULA_FONTSIZE = 10
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
@ -1087,6 +1233,15 @@ PERL_PATH = /usr/bin/perl
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see
# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
# or is not a class.
@ -1100,6 +1255,24 @@ HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
# By default doxygen will write a font called FreeSans.ttf to the output
# directory and reference it in all dot files that doxygen generates. This
# font does not include all possible unicode characters however, so when you need
# these (or just want a differently looking font) you can specify the font name
# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
# which can be done by putting it in a standard location or by setting the
# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
# containing the font.
DOT_FONTNAME = FreeSans
# By default doxygen will tell dot to use the output directory to look for the
# FreeSans.ttf font (which doxygen will put there itself). If you specify a
# different font using DOT_FONTNAME you can set the path where dot
# can find it using this tag.
DOT_FONTPATH =
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
@ -1144,19 +1317,19 @@ INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
# generate a call dependency graph for every global function or class method.
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable call graphs for selected
# functions only using the \callgraph command.
# If the CALL_GRAPH and HAVE_DOT options are set to YES then
# doxygen will generate a call dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable call graphs
# for selected functions only using the \callgraph command.
CALL_GRAPH = NO
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will
# generate a caller dependency graph for every global function or class method.
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable caller graphs for selected
# functions only using the \callergraph command.
# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
# doxygen will generate a caller dependency graph for every global function
# or class method. Note that enabling this option will significantly increase
# the time of a run. So in most cases it will be better to enable caller
# graphs for selected functions only using the \callergraph command.
CALLER_GRAPH = NO
@ -1189,39 +1362,31 @@ DOT_PATH =
DOTFILE_DIRS =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
# nodes that will be shown in the graph. If the number of nodes in a graph
# becomes larger than this value, doxygen will truncate the graph, which is
# visualized by representing a node as a red box. Note that doxygen if the
# number of direct children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
DOT_GRAPH_MAX_NODES = 50
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
# graphs generated by dot. A depth value of 3 means that only nodes reachable
# from the root by following a path via at most 3 edges will be shown. Nodes
# that lay further from the root node will be omitted. Note that setting this
# option to 1 or 2 may greatly reduce the computation time needed for large
# code bases. Also note that a graph may be further truncated if the graph's
# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH
# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default),
# the graph is not depth-constrained.
# code bases. Also note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, which results in a white background.
# Warning: Depending on the platform used, enabling this option may lead to
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
# read).
# background. This is enabled by default, which results in a transparent
# background. Warning: Depending on the platform used, enabling this option
# may lead to badly anti-aliased labels on the edges of a graph (i.e. they
# become hard to read).
DOT_TRANSPARENT = NO

3
changes/bug2683a Normal file
View File

@ -0,0 +1,3 @@
o Minor features
- Log the source of a rejected POSTed v3 networkstatus vote.

5
changes/bug2696 Normal file
View File

@ -0,0 +1,5 @@
o Minor features:
- Make compilation with clang possible when using
--enable-gcc-warnings by removing two warnings that clang hasn't
implemented yet and by fixing a few warnings. Implements ticket
2696.

6
changes/bug2698 Normal file
View File

@ -0,0 +1,6 @@
o Minor bugfixes:
- Fix an issue that prevented static linking of libevent on
some platforms (notably Linux). Fixes bug 2698, bugfix on
versions 0.2.1.23/0.2.2.8-alpha (the versions introducing
the --with-static-libevent configure option).

11
changes/bug2756 Normal file
View File

@ -0,0 +1,11 @@
o Minor bugfixes (spec conformance, performance):
- We now ask the other side of a stream (the client or the exit)
for more data on that stream when the amount of queued data on
that stream dips low enough. Previously, we wouldn't ask the
other side for more data until either it sent us more data
(which it wasn't supposed to do if it had exhausted its
window!) or until we had completely flushed all our queued
data. Fixing this should improve throughput. Fixes bug 2756;
bugfix on the earliest released versions of Tor (svn commit
r152).

6
changes/bug2757 Normal file
View File

@ -0,0 +1,6 @@
- Minor bugfixes
o Avoid a double-mark-for-free warning when failing to attach a
transparent proxy connection. (We thought we had fixed this in
0.2.2.23-alpha, but it turns out our fix was checking the wrong
connection.) Fixes bug 2757; bugfix on 0.1.2.1-alpha (the original
bug) and 0.2.2.23-alpha (the incorrect fix).

7
changes/cbt_hi_res Normal file
View File

@ -0,0 +1,7 @@
o Minor features
- When expiring circuits, use microsecond timers rather than one-second
timers. This can avoid an unpleasant situation where a circuit is
launched near the end of one second and expired right near the
beginning of the next, and prevent fluctuations in circuit timeout
values.

View File

@ -0,0 +1,4 @@
o Minor features
- Use computed circuit-build timeouts to decide when to launch
parallel introdution circuits. (Previously, we would retry
after 15 seconds.)

6
changes/doxygen Normal file
View File

@ -0,0 +1,6 @@
o Documentation changes
- Modernize the doxygen configuration file slightly. Fixes bug 2707.
- Resolve all doxygen warnings except those for missing documentation.
Fixes bug 2705.
- Add doxygen documentation for more functions, fields, and types.

View File

@ -0,0 +1,3 @@
o Minor bugfixes
- Fix a minor typo in a log message. Bugfix on 0.2.2.6-alpha.

View File

@ -0,0 +1,3 @@
o Minor bugfixes
- When warning about missing zlib development packages, give the
correct package names. Bugfix on 0.2.0.1-alpha.

View File

@ -271,7 +271,19 @@ tor_libevent_pkg_debian="libevent-dev"
tor_libevent_devpkg_redhat="libevent-devel"
tor_libevent_devpkg_debian="libevent-dev"
TOR_SEARCH_LIBRARY(libevent, $trylibeventdir, [-levent $TOR_LIB_WS32], [
dnl On Gnu/Linux or any place we require it, we'll add librt to the Libevent
dnl linking for static builds.
STATIC_LIBEVENT_FLAGS=""
if test "$enable_static_libevent" = "yes"; then
dnl Determine if we have clock_gettime in librt
AC_SEARCH_LIBS([clock_gettime], [rt],
[have_rt=yes])
if test "$have_rt" = yes; then
STATIC_LIBEVENT_FLAGS=" -lrt "
fi
fi
TOR_SEARCH_LIBRARY(libevent, $trylibeventdir, [-levent $STATIC_LIBEVENT_FLAGS $TOR_LIB_WS32], [
#ifdef WIN32
#include <winsock2.h>
#endif
@ -294,7 +306,7 @@ dnl Now check for particular libevent functions.
save_LIBS="$LIBS"
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LIBS="-levent $TOR_LIB_WS32 $LIBS"
LIBS="-levent $STATIC_LIBEVENT_FLAGS $TOR_LIB_WS32 $LIBS"
LDFLAGS="$TOR_LDFLAGS_libevent $LDFLAGS"
CPPFLAGS="$TOR_CPPFLAGS_libevent $CPPFLAGS"
AC_CHECK_FUNCS(event_get_version event_get_version_number event_get_method event_set_log_callback evdns_set_outgoing_bind_address event_base_loopexit)
@ -315,7 +327,7 @@ if test "$enable_static_libevent" = "yes"; then
if test "$tor_cv_library_libevent_dir" = "(system)"; then
AC_MSG_ERROR("You must specify an explicit --with-libevent-dir=x option when using --enable-static-libevent")
else
TOR_LIBEVENT_LIBS="$TOR_LIBDIR_libevent/libevent.a"
TOR_LIBEVENT_LIBS="$TOR_LIBDIR_libevent/libevent.a $STATIC_LIBEVENT_FLAGS"
fi
else
TOR_LIBEVENT_LIBS="-levent"
@ -363,10 +375,10 @@ AC_SUBST(TOR_OPENSSL_LIBS)
dnl ------------------------------------------------------
dnl Where do you live, zlib? And how do we call you?
tor_openssl_pkg_redhat="zlib"
tor_openssl_pkg_debian="zlib1g"
tor_openssl_devpkg_redhat="zlib-devel"
tor_openssl_devpkg_debian="zlib1g-dev"
tor_zlib_pkg_redhat="zlib"
tor_zlib_pkg_debian="zlib1g"
tor_zlib_devpkg_redhat="zlib-devel"
tor_zlib_devpkg_debian="zlib1g-dev"
TOR_SEARCH_LIBRARY(zlib, $tryzlibdir, [-lz],
[#include <zlib.h>],
@ -865,12 +877,13 @@ fi
# Set CFLAGS _after_ all the above checks, since our warnings are stricter
# than autoconf's macros like.
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -g -O2"
# Disable GCC's strict aliasing checks. They are an hours-to-debug
# accident waiting to happen.
CFLAGS="$CFLAGS -fno-strict-aliasing"
CFLAGS="$CFLAGS -Wall -fno-strict-aliasing"
else
CFLAGS="$CFLAGS -g -O"
# Autoconf sets -g -O2 by default. Override optimization level
# for non-gcc compilers
CFLAGS="$CFLAGS -O"
enable_gcc_warnings=no
enable_gcc_warnings_advisory=no
fi
@ -894,6 +907,11 @@ if test x$enable_gcc_warnings = xyes || test x$enable_gcc_warnings_advisory = xy
#error
#endif])], have_gcc43=yes, have_gcc43=no)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
#if !defined(__clang__) || (__clang_major__ > 2) || (__clang_major__ == 2 && __clang_minor__ > 9)
#error
#endif])], have_clang29orlower=yes, have_clang29orlower=no)
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wshorten-64-to-32"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [])], have_shorten64_flag=yes,
@ -924,11 +942,19 @@ if test x$enable_gcc_warnings = xyes || test x$enable_gcc_warnings_advisory = xy
if test x$have_gcc42 = xyes ; then
# These warnings break gcc 4.0.2 and work on gcc 4.2
# XXXX020 See if any of these work with earlier versions.
CFLAGS="$CFLAGS -Waddress -Wmissing-noreturn -Wnormalized=id -Woverride-init -Wstrict-overflow=1"
CFLAGS="$CFLAGS -Waddress -Wmissing-noreturn -Wstrict-overflow=1"
# We used to use -Wstrict-overflow=5, but that breaks us heavily under 4.3.
fi
if test x$have_gcc43 = xyes ; then
if test x$have_gcc42 = xyes && test x$have_clang29orlower = xno; then
# These warnings break gcc 4.0.2 and clang, but work on gcc 4.2
# We only disable these for clang 2.9 and lower, in case they are
# supported in later versions.
CFLAGS="$CFLAGS -Wnormalized=id -Woverride-init"
fi
if test x$have_gcc43 = xyes ; then
# These warnings break gcc 4.2 and work on gcc 4.3
# XXXX020 See if any of these work with earlier versions.
CFLAGS="$CFLAGS -Wextra -Warray-bounds"

View File

@ -508,7 +508,8 @@ tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
tor_assert(s);
tor_assert(addr_out);
/* IP, [], /mask, ports */
/** Longest possible length for an address, mask, and port-range combination.
* Includes IP, [], /mask, :, ports */
#define MAX_ADDRESS_LENGTH (TOR_ADDR_BUF_LEN+2+(1+INET_NTOA_BUF_LEN)+12+1)
if (strlen(s) > MAX_ADDRESS_LENGTH) {
@ -788,7 +789,7 @@ tor_addr_compare(const tor_addr_t *addr1, const tor_addr_t *addr2,
* Reduce over-specific masks (>128 for ipv6, >32 for ipv4) to 128 or 32.
*
* The mask is interpreted relative to <b>addr1</b>, so that if a is
* ::ffff:1.2.3.4, and b is 3.4.5.6,
* \::ffff:1.2.3.4, and b is 3.4.5.6,
* tor_addr_compare_masked(a,b,100,CMP_SEMANTIC) is the same as
* -tor_addr_compare_masked(b,a,4,CMP_SEMANTIC).
*
@ -800,6 +801,8 @@ int
tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
maskbits_t mbits, tor_addr_comparison_t how)
{
/** Helper: Evaluates to -1 if a is less than b, 0 if a equals b, or 1 if a
* is greater than b. May evaluate a and b more than once. */
#define TRISTATE(a,b) (((a)<(b))?-1: (((a)==(b))?0:1))
sa_family_t family1, family2, v_family1, v_family2;

View File

@ -53,8 +53,20 @@ tor_addr_to_in6(const tor_addr_t *a)
return a->family == AF_INET6 ? &a->addr.in6_addr : NULL;
}
/** Given an IPv6 address <b>x</b>, yield it as an array of uint8_t.
*
* Requires that <b>x</b> is actually an IPv6 address.
*/
#define tor_addr_to_in6_addr8(x) tor_addr_to_in6(x)->s6_addr
/** Given an IPv6 address <b>x</b>, yield it as an array of uint16_t.
*
* Requires that <b>x</b> is actually an IPv6 address.
*/
#define tor_addr_to_in6_addr16(x) S6_ADDR16(*tor_addr_to_in6(x))
/** Given an IPv6 address <b>x</b>, yield it as an array of uint32_t.
*
* Requires that <b>x</b> is actually an IPv6 address.
*/
#define tor_addr_to_in6_addr32(x) S6_ADDR32(*tor_addr_to_in6(x))
/** Return an IPv4 address in network order for <b>a</b>, or 0 if
@ -71,7 +83,7 @@ tor_addr_to_ipv4h(const tor_addr_t *a)
{
return ntohl(tor_addr_to_ipv4n(a));
}
/* Given an IPv6 address, return its mapped IPv4 address in host order, or
/** Given an IPv6 address, return its mapped IPv4 address in host order, or
* 0 if <b>a</b> is not an IPv6 address.
*
* (Does not check whether the address is really a mapped address */
@ -102,8 +114,14 @@ tor_addr_eq_ipv4h(const tor_addr_t *a, uint32_t u)
return a->family == AF_INET ? (tor_addr_to_ipv4h(a) == u) : 0;
}
#define TOR_ADDR_BUF_LEN 48 /* [ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]
*/
/** Length of a buffer that you need to allocate to be sure you can encode
* any tor_addr_t.
*
* This allows enough space for
* "[ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255]",
* plus a terminating NUL.
*/
#define TOR_ADDR_BUF_LEN 48
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr_out);
char *tor_dup_addr(const tor_addr_t *addr) ATTR_MALLOC;
@ -154,6 +172,7 @@ void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
#define tor_addr_from_ipv4h(dest, v4addr) \
tor_addr_from_ipv4n((dest), htonl(v4addr))
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes);
/** Set <b>dest</b> to the IPv4 address incoded in <b>in</b>. */
#define tor_addr_from_in(dest, in) \
tor_addr_from_ipv4n((dest), (in)->s_addr);
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);

View File

@ -100,6 +100,9 @@
/* Figure out which AES optimizations to use. */
#ifdef USE_BUILTIN_AES
/** If this is defined, we take advantage of the fact that AES treats its
* input as a set of 4 32-bit words, so that there is no need to encode and
* decode the 128-bit counter before every block encryption */
# define USE_RIJNDAEL_COUNTER_OPTIMIZATION
# if 0 && (defined(__powerpc__) || defined(__powerpc64__))
/* XXXX do more experimentation before concluding this is actually

View File

@ -15,6 +15,8 @@
/* This is required on rh7 to make strptime not complain.
* We also need it to make memmem get defined (where available)
*/
/* XXXX023 We should just use AC_USE_SYSTEM_EXTENSIONS in our autoconf,
* and get this (and other important stuff!) automatically */
#define _GNU_SOURCE
#include "compat.h"
@ -660,7 +662,9 @@ touch_file(const char *fname)
/** Represents a lockfile on which we hold the lock. */
struct tor_lockfile_t {
/** Name of the file */
char *filename;
/** File descriptor used to hold the file open */
int fd;
};
@ -766,7 +770,8 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile)
tor_free(lockfile);
}
/* Some old versions of Unix didn't define constants for these values,
/** @{ */
/** Some old versions of Unix didn't define constants for these values,
* and instead expect you to say 0, 1, or 2. */
#ifndef SEEK_CUR
#define SEEK_CUR 1
@ -774,6 +779,7 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile)
#ifndef SEEK_END
#define SEEK_END 2
#endif
/** @} */
/** Return the position of <b>fd</b> with respect to the start of the file. */
off_t
@ -813,6 +819,7 @@ static int n_sockets_open = 0;
/** Mutex to protect open_sockets, max_socket, and n_sockets_open. */
static tor_mutex_t *socket_accounting_mutex = NULL;
/** Helper: acquire the socket accounting lock. */
static INLINE void
socket_accounting_lock(void)
{
@ -821,6 +828,7 @@ socket_accounting_lock(void)
tor_mutex_acquire(socket_accounting_mutex);
}
/** Helper: release the socket accounting lock. */
static INLINE void
socket_accounting_unlock(void)
{
@ -879,6 +887,7 @@ tor_close_socket(int s)
return r;
}
/** @{ */
#ifdef DEBUG_SOCKET_COUNTING
/** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
* now an open socket. */
@ -903,6 +912,7 @@ mark_socket_open(int s)
#else
#define mark_socket_open(s) STMT_NIL
#endif
/** @} */
/** As socket(), but counts the number of open sockets. */
int
@ -1090,6 +1100,8 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
#endif
}
/** Number of extra file descriptors to keep in reserve beyond those that we
* tell Tor it's allowed to use. */
#define ULIMIT_BUFFER 32 /* keep 32 extra fd's beyond _ConnLimit */
/** Learn the maximum allowed number of file descriptors. (Some systems
@ -1202,6 +1214,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
static int
log_credential_status(void)
{
/** Log level to use when describing non-error UID/GID status. */
#define CREDENTIAL_LOG_LEVEL LOG_INFO
/* Real, effective and saved UIDs */
uid_t ruid, euid, suid;
@ -1983,6 +1996,12 @@ tor_gettimeofday(struct timeval *timeval)
#define TIME_FNS_NEED_LOCKS
#endif
/** @{ */
/** As localtime_r, but defined for platforms that don't have it:
*
* Convert *<b>timep</b> to a struct tm in local time, and store the value in
* *<b>result</b>. Return the result on success, or NULL on failure.
*/
#ifndef HAVE_LOCALTIME_R
#ifdef TIME_FNS_NEED_LOCKS
struct tm *
@ -2010,7 +2029,14 @@ tor_localtime_r(const time_t *timep, struct tm *result)
}
#endif
#endif
/** @} */
/** @{ */
/** As gmtimee_r, but defined for platforms that don't have it:
*
* Convert *<b>timep</b> to a struct tm in UTC, and store the value in
* *<b>result</b>. Return the result on success, or NULL on failure.
*/
#ifndef HAVE_GMTIME_R
#ifdef TIME_FNS_NEED_LOCKS
struct tm *
@ -2038,6 +2064,7 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
}
#endif
#endif
/** @} */
#if defined(USE_WIN32_THREADS)
void

View File

@ -312,6 +312,7 @@ const char *tor_fix_source_file(const char *fname);
/* ===== Time compatibility */
#if !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_STRUCT_TIMEVAL_TV_SEC)
/** Implementation of timeval for platforms that don't have it. */
struct timeval {
time_t tv_sec;
unsigned int tv_usec;
@ -332,6 +333,48 @@ struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
#endif
#ifndef timeradd
/** Replacement for timeradd on platforms that do not have it: sets tvout to
* the sum of tv1 and tv2. */
#define timeradd(tv1,tv2,tvout) \
do { \
(tvout)->tv_sec = (tv1)->tv_sec + (tv2)->tv_sec; \
(tvout)->tv_usec = (tv2)->tv_usec + (tv2)->tv_usec; \
if ((tvout)->tv_usec >= 1000000) { \
(tvout)->tv_usec -= 1000000; \
(tvout)->tv_sec++; \
} \
} while (0)
#endif
#ifndef timersub
/** Replacement for timersub on platforms that do not have it: sets tvout to
* tv1 minus tv2. */
#define timersub(tv1,tv2,tvout) \
do { \
(tvout)->tv_sec = (tv1)->tv_sec - (tv2)->tv_sec; \
(tvout)->tv_usec = (tv2)->tv_usec - (tv2)->tv_usec; \
if ((tvout)->tv_usec < 0) { \
(tvout)->tv_usec += 1000000; \
(tvout)->tv_sec--; \
} \
} while (0)
#endif
#ifndef timercmp
/** Replacement for timersub on platforms that do not have it: returns true
* iff the relational operator "op" makes the expression tv1 op tv2 true.
*
* Note that while this definition should work for all boolean opeators, some
* platforms' native timercmp definitions do not support >=, <=, or ==. So
* don't use those.
*/
#define timercmp(tv1,tv2,op) \
(((tv1)->tv_sec == (tv2)->tv_sec) ? \
((tv1)->tv_usec op (tv2)->tv_usec) : \
((tv1)->tv_sec op (tv2)->tv_sec))
#endif
/* ===== File compatibility */
int replace_file(const char *from, const char *to);
int touch_file(const char *fname);
@ -364,9 +407,9 @@ int get_n_open_sockets(void);
#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
#define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
/* Define struct in6_addr on platforms that do not have it. Generally,
* these platforms are ones without IPv6 support, but we want to have
* a working in6_addr there anyway, so we can use it to parse IPv6
/** Implementatino of struct in6_addr for platforms that do not have it.
* Generally, these platforms are ones without IPv6 support, but we want to
* have a working in6_addr there anyway, so we can use it to parse IPv6
* addresses. */
#if !defined(HAVE_STRUCT_IN6_ADDR)
struct in6_addr
@ -382,9 +425,10 @@ struct in6_addr
};
#endif
/** @{ */
/** Many BSD variants seem not to define these. */
#if defined(__APPLE__) || defined(__darwin__) || defined(__FreeBSD__) \
|| defined(__NetBSD__) || defined(__OpenBSD__)
/* Many BSD variants seem not to define these. */
#ifndef s6_addr16
#define s6_addr16 __u6_addr.__u6_addr16
#endif
@ -392,12 +436,15 @@ struct in6_addr
#define s6_addr32 __u6_addr.__u6_addr32
#endif
#endif
/** @} */
#ifndef HAVE_SA_FAMILY_T
typedef uint16_t sa_family_t;
#endif
/* Apparently, MS and Solaris don't define s6_addr16 or s6_addr32. */
/** @{ */
/** Apparently, MS and Solaris don't define s6_addr16 or s6_addr32; these
* macros get you a pointer to s6_addr32 or local equivalent. */
#ifdef HAVE_STRUCT_IN6_ADDR_S6_ADDR32
#define S6_ADDR32(x) ((uint32_t*)(x).s6_addr32)
#else
@ -408,9 +455,10 @@ typedef uint16_t sa_family_t;
#else
#define S6_ADDR16(x) ((uint16_t*)((char*)&(x).s6_addr))
#endif
/** @} */
/* Define struct sockaddr_in6 on platforms that do not have it. See notes
* on struct in6_addr. */
/** Implementation of struct sockaddr_in6 on platforms that do not have
* it. See notes on struct in6_addr. */
#if !defined(HAVE_STRUCT_SOCKADDR_IN6)
struct sockaddr_in6 {
sa_family_t sin6_family;
@ -534,10 +582,14 @@ void spawn_exit(void) ATTR_NORETURN;
/** A generic lock structure for multithreaded builds. */
typedef struct tor_mutex_t {
#if defined(USE_WIN32_THREADS)
/** Windows-only: on windows, we implement locks with CRITICAL_SECTIONS. */
CRITICAL_SECTION mutex;
#elif defined(USE_PTHREADS)
/** Pthreads-only: with pthreads, we implement locks with
* pthread_mutex_t. */
pthread_mutex_t mutex;
#else
/** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
int _unused;
#endif
} tor_mutex_t;

View File

@ -36,13 +36,19 @@
*/
typedef uint32_t le_version_t;
/* Macros: returns the number of a libevent version. */
/** @{ */
/** Macros: returns the number of a libevent version as a le_version_t */
#define V(major, minor, patch) \
(((major) << 24) | ((minor) << 16) | ((patch) << 8))
#define V_OLD(major, minor, patch) \
V((major), (minor), (patch)-'a'+1)
/** @} */
/** Represetns a version of libevent so old we can't figure out what version
* it is. */
#define LE_OLD V(0,0,0)
/** Represents a version of libevent so weird we can't figure out what version
* it it. */
#define LE_OTHER V(0,0,99)
static le_version_t tor_get_libevent_version(const char **v_out);
@ -199,8 +205,8 @@ tor_libevent_get_base(void)
}
#ifndef HAVE_EVENT_BASE_LOOPEXIT
/* Replacement for event_base_loopexit on some very old versions of Libevent
that we are not yet brave enough to deprecate. */
/** Replacement for event_base_loopexit on some very old versions of Libevent
* that we are not yet brave enough to deprecate. */
int
tor_event_base_loopexit(struct event_base *base, struct timeval *tv)
{
@ -222,9 +228,9 @@ tor_libevent_get_method(void)
#endif
}
/** Return the le_version_t for the current version of libevent. If the
* version is very new, return LE_OTHER. If the version is so old that it
* doesn't support event_get_version(), return LE_OLD. DOCDOC */
/** Return the le_version_t for the version of libevent specified in the
* string <b>v</b>. If the version is very new or uses an unrecognized
* version, format, return LE_OTHER. */
static le_version_t
tor_decode_libevent_version(const char *v)
{
@ -274,7 +280,7 @@ le_versions_compatibility(le_version_t v)
}
/** Return the version number of the currently running version of Libevent.
See le_version_t for info on the format.
* See le_version_t for info on the format.
*/
static le_version_t
tor_get_libevent_version(const char **v_out)

View File

@ -639,15 +639,27 @@ smartlist_uniq_strings(smartlist_t *sl)
* }
*/
/* For a 1-indexed array, we would use LEFT_CHILD[x] = 2*x and RIGHT_CHILD[x]
* = 2*x + 1. But this is C, so we have to adjust a little. */
/** @{ */
/** Functions to manipulate heap indices to find a node's parent and children.
*
* For a 1-indexed array, we would use LEFT_CHILD[x] = 2*x and RIGHT_CHILD[x]
* = 2*x + 1. But this is C, so we have to adjust a little. */
//#define LEFT_CHILD(i) ( ((i)+1)*2 - 1)
//#define RIGHT_CHILD(i) ( ((i)+1)*2 )
//#define PARENT(i) ( ((i)+1)/2 - 1)
#define LEFT_CHILD(i) ( 2*(i) + 1 )
#define RIGHT_CHILD(i) ( 2*(i) + 2 )
#define PARENT(i) ( ((i)-1) / 2 )
/** }@ */
/** @{ */
/** Helper macros for heaps: Given a local variable <b>idx_field_offset</b>
* set to the offset of an integer index within the heap element structure,
* IDX_OF_ITEM(p) gives you the index of p, and IDXP(p) gives you a pointer to
* where p's index is stored. Given additionally a local smartlist <b>sl</b>,
* UPDATE_IDX(i) sets the index of the element at <b>i</b> to the correct
* value (that is, to <b>i</b>).
*/
#define IDXP(p) ((int*)STRUCT_VAR_P(p, idx_field_offset))
#define UPDATE_IDX(i) do { \
@ -656,6 +668,7 @@ smartlist_uniq_strings(smartlist_t *sl)
} while (0)
#define IDX_OF_ITEM(p) (*IDXP(p))
/** @} */
/** Helper. <b>sl</b> may have at most one violation of the heap property:
* the item at <b>idx</b> may be greater than one or both of its children.

View File

@ -15,6 +15,7 @@
* and macros defined here.
**/
typedef struct smartlist_t {
/** @{ */
/** <b>list</b> has enough capacity to store exactly <b>capacity</b> elements
* before it needs to be resized. Only the first <b>num_used</b> (\<=
* capacity) elements point to valid data.
@ -22,6 +23,7 @@ typedef struct smartlist_t {
void **list;
int num_used;
int capacity;
/** @} */
} smartlist_t;
smartlist_t *smartlist_create(void);
@ -595,9 +597,9 @@ bitarray_is_set(bitarray_t *b, int bit)
/** A set of digests, implemented as a Bloom filter. */
typedef struct {
int mask; /* One less than the number of bits in <b>ba</b>; always one less
int mask; /**< One less than the number of bits in <b>ba</b>; always one less
* than a power of two. */
bitarray_t *ba; /* A bit array to implement the Bloom filter. */
bitarray_t *ba; /**< A bit array to implement the Bloom filter. */
} digestset_t;
#define BIT(n) ((n) & set->mask)

View File

@ -68,13 +68,15 @@
#endif
#if OPENSSL_VERSION_NUMBER < 0x00908000l
/* On OpenSSL versions before 0.9.8, there is no working SHA256
/** @{ */
/** On OpenSSL versions before 0.9.8, there is no working SHA256
* implementation, so we use Tom St Denis's nice speedy one, slightly adapted
* to our needs */
* to our needs. These macros make it usable by us. */
#define SHA256_CTX sha256_state
#define SHA256_Init sha256_init
#define SHA256_Update sha256_process
#define LTC_ARGCHK(x) tor_assert(x)
/** @} */
#include "sha256.c"
#define SHA256_Final(a,b) sha256_done(b,a)
@ -104,21 +106,22 @@ static int _n_openssl_mutexes = 0;
/** A public key, or a public/private key-pair. */
struct crypto_pk_env_t
{
int refs; /* reference counting so we don't have to copy keys */
RSA *key;
int refs; /**< reference count, so we don't have to copy keys */
RSA *key; /**< The key itself */
};
/** Key and stream information for a stream cipher. */
struct crypto_cipher_env_t
{
char key[CIPHER_KEY_LEN];
aes_cnt_cipher_t *cipher;
char key[CIPHER_KEY_LEN]; /**< The raw key. */
aes_cnt_cipher_t *cipher; /**< The key in format usable for counter-mode AES
* encryption */
};
/** A structure to hold the first half (x, g^x) of a Diffie-Hellman handshake
* while we're waiting for the second.*/
struct crypto_dh_env_t {
DH *dh;
DH *dh; /**< The openssl DH object */
};
static int setup_openssl_threading(void);
@ -1470,7 +1473,7 @@ crypto_cipher_decrypt_with_iv(crypto_cipher_env_t *cipher,
/* SHA-1 */
/** Compute the SHA1 digest of <b>len</b> bytes in data stored in
/** Compute the SHA1 digest of the <b>len</b> bytes on data stored in
* <b>m</b>. Write the DIGEST_LEN byte result into <b>digest</b>.
* Return 0 on success, -1 on failure.
*/
@ -1482,6 +1485,9 @@ crypto_digest(char *digest, const char *m, size_t len)
return (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL);
}
/** Compute a 256-bit digest of <b>len</b> bytes in data stored in <b>m</b>,
* using the algorithm <b>algorithm</b>. Write the DIGEST_LEN256-byte result
* into <b>digest</b>. Return 0 on success, -1 on failure. */
int
crypto_digest256(char *digest, const char *m, size_t len,
digest_algorithm_t algorithm)
@ -1541,13 +1547,14 @@ crypto_digest_algorithm_parse_name(const char *name)
/** Intermediate information about the digest of a stream of data. */
struct crypto_digest_env_t {
union {
SHA_CTX sha1;
SHA256_CTX sha2;
} d;
digest_algorithm_t algorithm : 8;
SHA_CTX sha1; /**< state for SHA1 */
SHA256_CTX sha2; /**< state for SHA256 */
} d; /**< State for the digest we're using. Only one member of the
* union is usable, depending on the value of <b>algorithm</b>. */
digest_algorithm_t algorithm : 8; /**< Which algorithm is in use? */
};
/** Allocate and return a new digest object.
/** Allocate and return a new digest object to compute SHA1 digests.
*/
crypto_digest_env_t *
crypto_new_digest_env(void)
@ -1559,6 +1566,8 @@ crypto_new_digest_env(void)
return r;
}
/** Allocate and return a new digest object to compute 256-bit digests
* using <b>algorithm</b>. */
crypto_digest_env_t *
crypto_new_digest256_env(digest_algorithm_t algorithm)
{
@ -1732,6 +1741,10 @@ init_dh_param(void)
dh_param_g = g;
}
/** Number of bits to use when choosing the x or y value in a Diffie-Hellman
* handshake. Since we exponentiate by this value, choosing a smaller one
* lets our handhake go faster.
*/
#define DH_PRIVATE_KEY_BITS 320
/** Allocate and return a new DH object for a key exchange.
@ -1983,15 +1996,22 @@ crypto_dh_free(crypto_dh_env_t *dh)
/* random numbers */
/* This is how much entropy OpenSSL likes to add right now, so maybe it will
/** How many bytes of entropy we add at once.
*
* This is how much entropy OpenSSL likes to add right now, so maybe it will
* work for us too. */
#define ADD_ENTROPY 32
/* Use RAND_poll if OpenSSL is 0.9.6 release or later. (The "f" means
"release".) */
/** True iff we should use OpenSSL's RAND_poll function to add entropy to its
* pool.
*
* Use RAND_poll if OpenSSL is 0.9.6 release or later. (The "f" means
*"release".) */
#define HAVE_RAND_POLL (OPENSSL_VERSION_NUMBER >= 0x0090600fl)
/* Versions of OpenSSL prior to 0.9.7k and 0.9.8c had a bug where RAND_poll
/** True iff it's safe to use RAND_poll after setup.
*
* Versions of OpenSSL prior to 0.9.7k and 0.9.8c had a bug where RAND_poll
* would allocate an fd_set on the stack, open a new file, and try to FD_SET
* that fd without checking whether it fit in the fd_set. Thus, if the
* system has not just been started up, it is unsafe to call */
@ -2000,6 +2020,7 @@ crypto_dh_free(crypto_dh_env_t *dh)
OPENSSL_VERSION_NUMBER <= 0x00907fffl) || \
(OPENSSL_VERSION_NUMBER >= 0x0090803fl))
/** Set the seed of the weak RNG to a random value. */
static void
seed_weak_rng(void)
{
@ -2253,9 +2274,12 @@ base64_encode(char *dest, size_t destlen, const char *src, size_t srclen)
return ret;
}
/** @{ */
/** Special values used for the base64_decode_table */
#define X 255
#define SP 64
#define PAD 65
/** @} */
/** Internal table mapping byte values to what they represent in base64.
* Numbers 0..63 are 6-bit integers. SPs are spaces, and should be
* skipped. Xs are invalid and must not appear in base64. PAD indicates
@ -2659,6 +2683,7 @@ _openssl_dynlock_destroy_cb(struct CRYPTO_dynlock_value *v,
tor_free(v);
}
/** @{ */
/** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being
* multithreaded. */
static int
@ -2684,4 +2709,5 @@ setup_openssl_threading(void)
return 0;
}
#endif
/** @} */

View File

@ -36,8 +36,12 @@
#include "torlog.h"
#include "container.h"
/** @{ */
/** The string we stick at the end of a log message when it is too long,
* and its length. */
#define TRUNCATED_STR "[...truncated]"
#define TRUNCATED_STR_LEN 14
/** @} */
/** Information for a single logfile; only used in log.c */
typedef struct logfile_t {
@ -109,17 +113,19 @@ static int syslog_count = 0;
/** Represents a log message that we are going to send to callback-driven
* loggers once we can do so in a non-reentrant way. */
typedef struct pending_cb_message_t {
int severity;
log_domain_mask_t domain;
char *msg;
int severity; /**< The severity of the message */
log_domain_mask_t domain; /**< The domain of the message */
char *msg; /**< The content of the message */
} pending_cb_message_t;
/** Log messages waiting to be replayed onto callback-based logs */
static smartlist_t *pending_cb_messages = NULL;
/** Lock the log_mutex to prevent others from changing the logfile_t list */
#define LOCK_LOGS() STMT_BEGIN \
tor_mutex_acquire(&log_mutex); \
STMT_END
/** Unlock the log_mutex */
#define UNLOCK_LOGS() STMT_BEGIN tor_mutex_release(&log_mutex); STMT_END
/** What's the lowest log level anybody cares about? Checking this lets us
@ -382,7 +388,10 @@ logv(int severity, log_domain_mask_t domain, const char *funcname,
UNLOCK_LOGS();
}
/** Output a message to the log. */
/** Output a message to the log. It gets logged to all logfiles that
* care about messages with <b>severity</b> in <b>domain</b>. The content
* is formatted printf style basedc on <b>format</b> and extra arguments.
* */
void
tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
{
@ -396,6 +405,9 @@ tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
/** Output a message to the log, prefixed with a function name <b>fn</b>. */
#ifdef __GNUC__
/** GCC-based implementation of the log_fn backend, used when we have
* variadic macros. All arguments are as for log_fn, except for
* <b>fn</b>, which is the name of the calling functions. */
void
_log_fn(int severity, log_domain_mask_t domain, const char *fn,
const char *format, ...)
@ -408,6 +420,11 @@ _log_fn(int severity, log_domain_mask_t domain, const char *fn,
va_end(ap);
}
#else
/** @{ */
/** Variant implementation of log_fn, log_debug, log_info,... for C compilers
* without variadic macros. In this case, the calling function sets
* _log_fn_function_name to the name of the function, then invokes the
* appropriate _log_fn, _log_debug, etc. */
const char *_log_fn_function_name=NULL;
void
_log_fn(int severity, log_domain_mask_t domain, const char *format, ...)
@ -476,6 +493,7 @@ _log_err(log_domain_mask_t domain, const char *format, ...)
va_end(ap);
_log_fn_function_name = NULL;
}
/** @} */
#endif
/** Free all storage held by <b>victim</b>. */

View File

@ -30,12 +30,18 @@
#endif
#ifdef USE_SENTINELS
/** Magic value that we stick at the end of a memarea so we can make sure
* there are no run-off-the-end bugs. */
#define SENTINEL_VAL 0x90806622u
/** How many bytes per area do we devote to the sentinel? */
#define SENTINEL_LEN sizeof(uint32_t)
/** Given a mem_area_chunk_t with SENTINEL_LEN extra bytes allocated at the
* end, set those bytes. */
#define SET_SENTINEL(chunk) \
STMT_BEGIN \
set_uint32( &(chunk)->u.mem[chunk->mem_size], SENTINEL_VAL ); \
STMT_END
/** Assert that the sentinel on a memarea is set correctly. */
#define CHECK_SENTINEL(chunk) \
STMT_BEGIN \
uint32_t sent_val = get_uint32(&(chunk)->u.mem[chunk->mem_size]); \
@ -73,8 +79,11 @@ typedef struct memarea_chunk_t {
} u;
} memarea_chunk_t;
/** How many bytes are needed for overhead before we get to the memory part
* of a chunk? */
#define CHUNK_HEADER_SIZE STRUCT_OFFSET(memarea_chunk_t, u)
/** What's the smallest that we'll allocate a chunk? */
#define CHUNK_SIZE 4096
/** A memarea_t is an allocation region for a set of small memory requests

View File

@ -79,6 +79,7 @@ method_bits(compress_method_t method)
return method == GZIP_METHOD ? 15+16 : 15;
}
/** @{ */
/* These macros define the maximum allowable compression factor. Anything of
* size greater than CHECK_FOR_COMPRESSION_BOMB_AFTER is not allowed to
* have an uncompression factor (uncompressed size:compressed size ratio) of
@ -94,6 +95,7 @@ method_bits(compress_method_t method)
*/
#define MAX_UNCOMPRESSION_FACTOR 25
#define CHECK_FOR_COMPRESSION_BOMB_AFTER (1024*64)
/** @} */
/** Return true if uncompressing an input of size <b>in_size</b> to an input
* of size at least <b>size_out</b> looks like a compression bomb. */
@ -389,12 +391,12 @@ detect_compression_method(const char *in, size_t in_len)
/** Internal state for an incremental zlib compression/decompression. The
* body of this struct is not exposed. */
struct tor_zlib_state_t {
struct z_stream_s stream;
int compress;
struct z_stream_s stream; /**< The zlib stream */
int compress; /**< True if we are compressing; false if we are inflating */
/* Number of bytes read so far. Used to detect zlib bombs. */
/** Number of bytes read so far. Used to detect zlib bombs. */
size_t input_so_far;
/* Number of bytes written so far. Used to detect zlib bombs. */
/** Number of bytes written so far. Used to detect zlib bombs. */
size_t output_so_far;
};

View File

@ -329,7 +329,7 @@ typedef uint32_t uintptr_t;
#endif
#endif
/* Any size_t larger than this amount is likely to be an underflow. */
/** Any size_t larger than this amount is likely to be an underflow. */
#define SIZE_T_CEILING (SSIZE_T_MAX-16)
#endif /* __TORINT_H */

View File

@ -5,7 +5,7 @@
/* See LICENSE for licensing information */
/**
* \file log.h
* \file torlog.h
*
* \brief Headers for log.c
**/
@ -99,6 +99,7 @@
* immediately. Used as a flag, not a log domain. */
#define LD_NOCB (1u<<31)
/** Mask of zero or more log domains, OR'd together. */
typedef uint32_t log_domain_mask_t;
/** Configures which severities are logged for each logging domain for a given

View File

@ -457,7 +457,7 @@ circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n)
* Add a new build time value <b>time</b> to the set of build times. Time
* units are milliseconds.
*
* circuit_build_times <b>cbt</a> is a circular array, so loop around when
* circuit_build_times <b>cbt</b> is a circular array, so loop around when
* array is full.
*/
int
@ -655,7 +655,7 @@ circuit_build_times_update_state(circuit_build_times_t *cbt,
/**
* Shuffle the build times array.
*
* Stolen from http://en.wikipedia.org/wiki/Fisher\u2013Yates_shuffle
* Adapted from http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
*/
static void
circuit_build_times_shuffle_and_store_array(circuit_build_times_t *cbt,
@ -2041,7 +2041,7 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
struct timeval end;
long timediff;
tor_gettimeofday(&end);
timediff = tv_mdiff(&circ->_base.highres_created, &end);
timediff = tv_mdiff(&circ->_base.timestamp_created, &end);
/*
* If the circuit build time is much greater than we would have cut

View File

@ -398,8 +398,7 @@ circuit_initial_package_window(void)
static void
init_circuit_base(circuit_t *circ)
{
circ->timestamp_created = time(NULL);
tor_gettimeofday(&circ->highres_created);
tor_gettimeofday(&circ->timestamp_created);
circ->package_window = circuit_initial_package_window();
circ->deliver_window = CIRCWINDOW_START;
@ -609,9 +608,10 @@ circuit_dump_details(int severity, circuit_t *circ, int conn_array_index,
const char *type, int this_circid, int other_circid)
{
log(severity, LD_CIRC, "Conn %d has %s circuit: circID %d (other side %d), "
"state %d (%s), born %d:",
"state %d (%s), born %ld:",
conn_array_index, type, this_circid, other_circid, circ->state,
circuit_state_to_string(circ->state), (int)circ->timestamp_created);
circuit_state_to_string(circ->state),
(long)circ->timestamp_created.tv_sec);
if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
circuit_log_path(severity, LD_CIRC, TO_ORIGIN_CIRCUIT(circ));
}

View File

@ -31,7 +31,7 @@ extern circuit_t *global_circuitlist; /* from circuitlist.c */
/********* END VARIABLES ************/
static void circuit_expire_old_circuits_clientside(time_t now);
static void circuit_expire_old_circuits_clientside(void);
static void circuit_increment_failure_count(void);
/** Return 1 if <b>circ</b> could be returned by circuit_get_best().
@ -162,7 +162,7 @@ circuit_is_better(circuit_t *a, circuit_t *b, uint8_t purpose)
return 1;
} else {
if (a->timestamp_dirty ||
a->timestamp_created > b->timestamp_created)
timercmp(&a->timestamp_created, &b->timestamp_created, >))
return 1;
if (CIRCUIT_IS_ORIGIN(b) &&
TO_ORIGIN_CIRCUIT(b)->build_state->is_internal)
@ -204,7 +204,7 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose,
int need_uptime, int need_internal)
{
circuit_t *circ, *best=NULL;
time_t now = time(NULL);
struct timeval now;
int intro_going_on_but_too_old = 0;
tor_assert(conn);
@ -213,17 +213,16 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose,
purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT ||
purpose == CIRCUIT_PURPOSE_C_REND_JOINED);
tor_gettimeofday(&now);
for (circ=global_circuitlist;circ;circ = circ->next) {
if (!circuit_is_acceptable(circ,conn,must_be_open,purpose,
need_uptime,need_internal,now))
need_uptime,need_internal,now.tv_sec))
continue;
/* XXX022 make this 15 be a function of circuit finishing times we've
* seen lately, a la Fallon Chen's GSoC work -RD */
#define REND_PARALLEL_INTRO_DELAY 15
if (purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT &&
!must_be_open && circ->state != CIRCUIT_STATE_OPEN &&
circ->timestamp_created + REND_PARALLEL_INTRO_DELAY < now) {
!must_be_open && circ->state != CIRCUIT_STATE_OPEN &&
tv_mdiff(&now, &circ->timestamp_created) > circ_times.timeout_ms) {
intro_going_on_but_too_old = 1;
continue;
}
@ -275,22 +274,38 @@ circuit_conforms_to_options(const origin_circuit_t *circ,
* at least CircuitBuildTimeout seconds ago.
*/
void
circuit_expire_building(time_t now)
circuit_expire_building(void)
{
circuit_t *victim, *next_circ = global_circuitlist;
/* circ_times.timeout_ms and circ_times.close_ms are from
* circuit_build_times_get_initial_timeout() if we haven't computed
* custom timeouts yet */
time_t general_cutoff = now - tor_lround(circ_times.timeout_ms/1000);
time_t begindir_cutoff = now - tor_lround(circ_times.timeout_ms/2000);
time_t fourhop_cutoff = now - tor_lround(4*circ_times.timeout_ms/3000);
time_t cannibalize_cutoff = now - tor_lround(circ_times.timeout_ms/2000);
time_t close_cutoff = now - tor_lround(circ_times.close_ms/1000);
time_t introcirc_cutoff = begindir_cutoff;
struct timeval general_cutoff, begindir_cutoff, fourhop_cutoff,
cannibalize_cutoff, close_cutoff, extremely_old_cutoff;
struct timeval now;
struct timeval introcirc_cutoff;
cpath_build_state_t *build_state;
tor_gettimeofday(&now);
#define SET_CUTOFF(target, msec) do { \
long ms = tor_lround(msec); \
struct timeval diff; \
diff.tv_sec = ms / 1000; \
diff.tv_usec = (ms % 1000) * 1000; \
timersub(&now, &diff, &target); \
} while (0)
SET_CUTOFF(general_cutoff, circ_times.timeout_ms);
SET_CUTOFF(begindir_cutoff, circ_times.timeout_ms / 2.0);
SET_CUTOFF(fourhop_cutoff, circ_times.timeout_ms * (4/3.0));
SET_CUTOFF(cannibalize_cutoff, circ_times.timeout_ms / 2.0);
SET_CUTOFF(close_cutoff, circ_times.close_ms);
SET_CUTOFF(extremely_old_cutoff, circ_times.close_ms*2 + 1000);
introcirc_cutoff = begindir_cutoff;
while (next_circ) {
time_t cutoff;
struct timeval cutoff;
victim = next_circ;
next_circ = next_circ->next;
if (!CIRCUIT_IS_ORIGIN(victim) || /* didn't originate here */
@ -312,7 +327,7 @@ circuit_expire_building(time_t now)
else
cutoff = general_cutoff;
if (victim->timestamp_created > cutoff)
if (timercmp(&victim->timestamp_created, &cutoff, >))
continue; /* it's still young, leave it alone */
#if 0
@ -358,7 +373,7 @@ circuit_expire_building(time_t now)
* because that's set when they switch purposes
*/
if (TO_ORIGIN_CIRCUIT(victim)->rend_data ||
victim->timestamp_dirty > cutoff)
victim->timestamp_dirty > cutoff.tv_sec)
continue;
break;
case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
@ -367,7 +382,7 @@ circuit_expire_building(time_t now)
* make an introduction attempt. so timestamp_dirty
* will reflect the time since the last attempt.
*/
if (victim->timestamp_dirty > cutoff)
if (victim->timestamp_dirty > cutoff.tv_sec)
continue;
break;
}
@ -407,15 +422,15 @@ circuit_expire_building(time_t now)
* it off at, we probably had a suspend event along this codepath,
* and we should discard the value.
*/
if (now - victim->timestamp_created > 2*circ_times.close_ms/1000+1) {
if (timercmp(&victim->timestamp_created, &extremely_old_cutoff, <)) {
log_notice(LD_CIRC,
"Extremely large value for circuit build timeout: %lds. "
"Assuming clock jump. Purpose %d",
(long)(now - victim->timestamp_created),
(long)(now.tv_sec - victim->timestamp_created.tv_sec),
victim->purpose);
} else if (circuit_build_times_count_close(&circ_times,
first_hop_succeeded,
victim->timestamp_created)) {
victim->timestamp_created.tv_sec)) {
circuit_build_times_set_timeout(&circ_times);
}
}
@ -636,7 +651,7 @@ circuit_build_needed_circs(time_t now)
time_to_new_circuit = now + options->NewCircuitPeriod;
if (proxy_mode(get_options()))
addressmap_clean(now);
circuit_expire_old_circuits_clientside(now);
circuit_expire_old_circuits_clientside();
#if 0 /* disable for now, until predict-and-launch-new can cull leftovers */
circ = circuit_get_youngest_clean_open(CIRCUIT_PURPOSE_C_GENERAL);
@ -725,17 +740,20 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
* for too long and has no streams on it: mark it for close.
*/
static void
circuit_expire_old_circuits_clientside(time_t now)
circuit_expire_old_circuits_clientside(void)
{
circuit_t *circ;
time_t cutoff;
struct timeval cutoff, now;
tor_gettimeofday(&now);
cutoff = now;
if (circuit_build_times_needs_circuits(&circ_times)) {
/* Circuits should be shorter lived if we need more of them
* for learning a good build timeout */
cutoff = now - IDLE_TIMEOUT_WHILE_LEARNING;
cutoff.tv_sec -= IDLE_TIMEOUT_WHILE_LEARNING;
} else {
cutoff = now - get_options()->CircuitIdleTimeout;
cutoff.tv_sec -= get_options()->CircuitIdleTimeout;
}
for (circ = global_circuitlist; circ; circ = circ->next) {
@ -745,15 +763,15 @@ circuit_expire_old_circuits_clientside(time_t now)
* on it, mark it for close.
*/
if (circ->timestamp_dirty &&
circ->timestamp_dirty + get_options()->MaxCircuitDirtiness < now &&
circ->timestamp_dirty + get_options()->MaxCircuitDirtiness < now.tv_sec &&
!TO_ORIGIN_CIRCUIT(circ)->p_streams /* nothing attached */ ) {
log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %d secs ago, "
log_debug(LD_CIRC, "Closing n_circ_id %d (dirty %ld sec ago, "
"purpose %d)",
circ->n_circ_id, (int)(now - circ->timestamp_dirty),
circ->n_circ_id, (long)(now.tv_sec - circ->timestamp_dirty),
circ->purpose);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
} else if (!circ->timestamp_dirty && circ->state == CIRCUIT_STATE_OPEN) {
if (circ->timestamp_created < cutoff) {
if (timercmp(&circ->timestamp_created, &cutoff, <)) {
if (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL ||
circ->purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT ||
circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
@ -762,8 +780,8 @@ circuit_expire_old_circuits_clientside(time_t now)
circ->purpose <= CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) ||
circ->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) {
log_debug(LD_CIRC,
"Closing circuit that has been unused for %ld seconds.",
(long)(now - circ->timestamp_created));
"Closing circuit that has been unused for %ld msec.",
tv_mdiff(&circ->timestamp_created, &now));
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
} else if (!TO_ORIGIN_CIRCUIT(circ)->is_ancient) {
/* Server-side rend joined circuits can end up really old, because
@ -775,9 +793,9 @@ circuit_expire_old_circuits_clientside(time_t now)
circ->purpose != CIRCUIT_PURPOSE_S_INTRO) {
log_notice(LD_CIRC,
"Ancient non-dirty circuit %d is still around after "
"%ld seconds. Purpose: %d",
"%ld milliseconds. Purpose: %d",
TO_ORIGIN_CIRCUIT(circ)->global_identifier,
(long)(now - circ->timestamp_created),
tv_mdiff(&circ->timestamp_created, &now),
circ->purpose);
/* FFFF implement a new circuit_purpose_to_string() so we don't
* just print out a number for circ->purpose */
@ -1123,7 +1141,7 @@ circuit_launch_by_extend_info(uint8_t purpose,
/* reset the birth date of this circ, else expire_building
* will see it and think it's been trying to build since it
* began. */
circ->_base.timestamp_created = time(NULL);
tor_gettimeofday(&circ->_base.timestamp_created);
switch (purpose) {
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:

View File

@ -12,7 +12,7 @@
#ifndef _TOR_CIRCUITUSE_H
#define _TOR_CIRCUITUSE_H
void circuit_expire_building(time_t now);
void circuit_expire_building(void);
void circuit_remove_handled_ports(smartlist_t *needed_ports);
int circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port,
int min);

View File

@ -4770,10 +4770,10 @@ options_save_current(void)
}
/** Mapping from a unit name to a multiplier for converting that unit into a
* base unit. */
* base unit. Used by config_parse_unit. */
struct unit_table_t {
const char *unit;
uint64_t multiplier;
const char *unit; /**< The name of the unit */
uint64_t multiplier; /**< How many of the base unit appear in this unit */
};
/** Table to map the names of memory units to the number of bytes they

View File

@ -1178,7 +1178,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
}
if (connection_init_accepted_conn(newconn, conn->type) < 0) {
if (! conn->marked_for_close)
if (! newconn->marked_for_close)
connection_mark_for_close(newconn);
return 0;
}
@ -3245,6 +3245,8 @@ connection_flushed_some(connection_t *conn)
r = connection_dirserv_flushed_some(TO_DIR_CONN(conn));
} else if (conn->type == CONN_TYPE_OR) {
r = connection_or_flushed_some(TO_OR_CONN(conn));
} else if (CONN_IS_EDGE(conn)) {
r = connection_edge_flushed_some(TO_EDGE_CONN(conn));
}
conn->in_flushed_some = 0;
return r;

View File

@ -301,6 +301,23 @@ connection_edge_end_errno(edge_connection_t *conn)
return connection_edge_end(conn, reason);
}
/** We just wrote some data to <b>conn</b>; act appropriately.
*
* (That is, if it's open, consider sending a stream-level sendme cell if we
* have just flushed enough.)
*/
int
connection_edge_flushed_some(edge_connection_t *conn)
{
switch (conn->_base.state) {
case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN:
connection_edge_consider_sending_sendme(conn);
break;
}
return 0;
}
/** Connection <b>conn</b> has finished writing and has no bytes left on
* its outbuf.
*

View File

@ -23,6 +23,7 @@ int connection_edge_process_inbuf(edge_connection_t *conn,
int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn);
int connection_edge_end(edge_connection_t *conn, uint8_t reason);
int connection_edge_end_errno(edge_connection_t *conn);
int connection_edge_flushed_some(edge_connection_t *conn);
int connection_edge_finished_flushing(edge_connection_t *conn);
int connection_edge_finished_connecting(edge_connection_t *conn);

View File

@ -467,7 +467,7 @@ connection_or_init_conn_from_address(or_connection_t *conn,
* Requires that both input connections are open; not is_bad_for_new_circs,
* and not impossibly non-canonical.
*
* If </b>forgive_new_connections</b> is true, then we do not call
* If <b>forgive_new_connections</b> is true, then we do not call
* <b>a</b>better than <b>b</b> simply because b has no circuits,
* unless b is also relatively old.
*/

View File

@ -3259,6 +3259,8 @@ directory_handle_command_post(dir_connection_t *conn, const char *headers,
write_http_status_line(conn, status, "Vote stored");
} else {
tor_assert(msg);
log_warn(LD_DIRSERV, "Rejected vote from %s (\"%s\").",
conn->_base.address, msg);
write_http_status_line(conn, status, msg);
}
goto done;

View File

@ -284,11 +284,18 @@ geoip_is_loaded(void)
typedef struct clientmap_entry_t {
HT_ENTRY(clientmap_entry_t) node;
uint32_t ipaddr;
/** Time when we last saw this IP address, in MINUTES since the epoch.
*
* (This will run out of space around 4011 CE. If Tor is still in use around
* 4000 CE, please remember to add more bits to last_seen_in_minutes.) */
unsigned int last_seen_in_minutes:30;
unsigned int action:2;
} clientmap_entry_t;
#define ACTION_MASK 3
/** Largest allowable value for last_seen_in_minutes. (It's a 30-bit field,
* so it can hold up to (1u<<30)-1, or 0x3fffffffu.
*/
#define MAX_LAST_SEEN_IN_MINUTES 0X3FFFFFFFu
/** Map from client IP address to last time seen. */
static HT_HEAD(clientmap, clientmap_entry_t) client_history =
@ -413,15 +420,16 @@ geoip_note_client_seen(geoip_client_action_t action,
lookup.ipaddr = addr;
lookup.action = (int)action;
ent = HT_FIND(clientmap, &client_history, &lookup);
if (ent) {
ent->last_seen_in_minutes = now / 60;
} else {
if (! ent) {
ent = tor_malloc_zero(sizeof(clientmap_entry_t));
ent->ipaddr = addr;
ent->last_seen_in_minutes = now / 60;
ent->action = (int)action;
HT_INSERT(clientmap, &client_history, ent);
}
if (now / 60 <= (int)MAX_LAST_SEEN_IN_MINUTES && now >= 0)
ent->last_seen_in_minutes = (unsigned)(now/60);
else
ent->last_seen_in_minutes = 0;
if (action == GEOIP_CLIENT_NETWORKSTATUS ||
action == GEOIP_CLIENT_NETWORKSTATUS_V2) {

View File

@ -1150,7 +1150,9 @@ run_scheduled_events(time_t now)
* We do this before step 4, so it can try building more if
* it's not comfortable with the number of available circuits.
*/
circuit_expire_building(now);
/* XXXX022 If our circuit build timeout is much lower than a second, maybe
we should do this more often? */
circuit_expire_building();
/** 3b. Also look at pending streams and prune the ones that 'began'
* a long time ago but haven't gotten a 'connected' yet.

View File

@ -23,9 +23,11 @@ int connection_is_on_closeable_list(connection_t *conn);
smartlist_t *get_connection_array(void);
/** Bitmask for events that we can turn on and off with
* connection_watch_events. */
typedef enum watchable_events {
READ_EVENT=0x02,
WRITE_EVENT=0x04
READ_EVENT=0x02, /**< We want to know when a connection is readable */
WRITE_EVENT=0x04 /**< We want to know when a connection is writable */
} watchable_events_t;
void connection_watch_events(connection_t *conn, watchable_events_t events);
int connection_is_reading(connection_t *conn);

View File

@ -54,6 +54,11 @@ static int nt_service_cmd_stop(void);
struct service_fns {
int loaded;
/** @{ */
/** Function pointers for Windows API functions related to service
* management. These are NULL, or they point to the . They're set by
* calling the LOAD macro below. */
BOOL (WINAPI *ChangeServiceConfig2A_fn)(
SC_HANDLE hService,
DWORD dwInfoLevel,
@ -122,6 +127,7 @@ struct service_fns {
LPTSTR ReferencedDomainName,
LPDWORD cchReferencedDomainName,
PSID_NAME_USE peUse);
/** @} */
} service_fns = { 0,
NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL,
@ -144,6 +150,10 @@ nt_service_loadlibrary(void)
goto err;
}
/* Helper macro: try to load a function named <b>f</b> from "library" into
* service_functions.<b>f</b>_fn. On failure, log an error message, and goto
* err.
*/
#define LOAD(f) STMT_BEGIN \
if (!(fn = GetProcAddress(library, #f))) { \
log_err(LD_BUG, \

View File

@ -848,9 +848,13 @@ typedef struct cell_t {
/** Parsed variable-length onion routing cell. */
typedef struct var_cell_t {
/** Type of the cell: CELL_VERSIONS, etc. */
uint8_t command;
/** Circuit thich received the cell */
circid_t circ_id;
/** Number of bytes actually stored in <b>payload</b> */
uint16_t payload_len;
/** Payload of this cell */
uint8_t payload[1];
} var_cell_t;
@ -1679,8 +1683,13 @@ typedef struct networkstatus_v2_t {
* sorted by identity_digest. */
} networkstatus_v2_t;
/** Linked list of microdesc hash lines for a single router in a directory
* vote.
*/
typedef struct vote_microdesc_hash_t {
/** Next element in the list, or NULL. */
struct vote_microdesc_hash_t *next;
/** The raw contents of the microdesc hash line, excluding the "m". */
char *microdesc_hash_line;
} vote_microdesc_hash_t;
@ -1692,6 +1701,7 @@ typedef struct vote_routerstatus_t {
* networkstatus_t.known_flags. */
char *version; /**< The version that the authority says this router is
* running. */
/** The hash or hashes that the authority claims this microdesc has. */
vote_microdesc_hash_t *microdesc;
} vote_routerstatus_t;
@ -2116,10 +2126,9 @@ typedef struct circuit_t {
* length ONIONSKIN_CHALLENGE_LEN. */
char *n_conn_onionskin;
time_t timestamp_created; /**< When was this circuit created? */
struct timeval timestamp_created; /**< When was the circuit created? */
time_t timestamp_dirty; /**< When the circuit was first used, or 0 if the
* circuit is clean. */
struct timeval highres_created; /**< When exactly was the circuit created? */
uint16_t marked_for_close; /**< Should we close this circuit at the end of
* the main loop? (If true, holds the line number
@ -3218,8 +3227,19 @@ typedef struct {
} fp_pair_t;
/********************************* dirserv.c ***************************/
/** An enum to describe what format we're generating a routerstatus line in.
*/
typedef enum {
NS_V2, NS_V3_CONSENSUS, NS_V3_VOTE, NS_CONTROL_PORT,
/** For use in a v2 opinion */
NS_V2,
/** For use in a consensus networkstatus document (ns flavor) */
NS_V3_CONSENSUS,
/** For use in a vote networkstatus document */
NS_V3_VOTE,
/** For passing to the controlport in response to a GETINFO request */
NS_CONTROL_PORT,
/** For use in a consensus networkstatus document (microdesc flavor) */
NS_V3_CONSENSUS_MICRODESC
} routerstatus_format_type_t;
@ -3236,9 +3256,14 @@ typedef struct measured_bw_line_t {
/** Describes the schedule by which votes should be generated. */
typedef struct vote_timing_t {
/** Length in seconds between one consensus becoming valid and the next
* becoming valid. */
int vote_interval;
/** For how many intervals is a consensus valid? */
int n_intervals_valid;
/** Time in seconds allowed to propagate votes */
int vote_delay;
/** Time in seconds allowed to propagate signatures */
int dist_delay;
} vote_timing_t;

View File

@ -52,9 +52,9 @@ static int circuit_consider_stop_edge_reading(circuit_t *circ,
crypt_path_t *layer_hint);
static int circuit_queue_streams_are_blocked(circuit_t *circ);
/* XXXX023 move this all to compat_libevent */
/** Cache the current hi-res time; the cache gets reset when libevent
* calls us. */
static struct timeval cached_time_hires = {0, 0};
/** Stop reading on edge connections when we have this many cells
@ -76,7 +76,7 @@ tor_gettimeofday_cached(struct timeval *tv)
void
tor_gettimeofday_cache_clear(void)
{
cached_time_hires.tv_sec = 0;
cached_time_hires.tv_sec = 0;
}
/** Stats: how many relay cells have originated at this hop, or have
@ -1409,8 +1409,9 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
goto repeat_connection_edge_package_raw_inbuf;
}
/** Called when we've just received a relay data cell, or when
* we've just finished flushing all bytes to stream <b>conn</b>.
/** Called when we've just received a relay data cell, when
* we've just finished flushing all bytes to stream <b>conn</b>,
* or when we've flushed *some* bytes to the stream <b>conn</b>.
*
* If conn->outbuf is not too full, and our deliver window is
* low, send back a suitable number of stream-level sendme cells.

View File

@ -64,5 +64,7 @@ void cell_ewma_set_scale_factor(or_options_t *options,
networkstatus_t *consensus);
void circuit_clear_cell_queue(circuit_t *circ, or_connection_t *orconn);
void tor_gettimeofday_cache_clear(void);
#endif

View File

@ -403,7 +403,7 @@ directory_get_from_hs_dir(const char *desc_id, const rend_data_t *rend_query)
tor_assert(rend_query);
/* Determine responsible dirs. Even if we can't get all we want,
* work with the ones we have. If it's empty, we'll notice below. */
(int) hid_serv_get_responsible_directories(responsible_dirs, desc_id);
hid_serv_get_responsible_directories(responsible_dirs, desc_id);
base32_encode(desc_id_base32, sizeof(desc_id_base32),
desc_id, DIGEST_LEN);

View File

@ -2337,7 +2337,6 @@ typedef struct circ_buffer_stats_t {
uint32_t local_circ_id;
} circ_buffer_stats_t;
/** Holds stats. */
smartlist_t *circuits_for_buffer_stats = NULL;
/** Remember cell statistics for circuit <b>circ</b> at time
@ -2357,9 +2356,9 @@ rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval)
return;
if (!circuits_for_buffer_stats)
circuits_for_buffer_stats = smartlist_create();
start_of_interval = circ->timestamp_created >
start_of_interval = circ->timestamp_created.tv_sec >
start_of_buffer_stats_interval ?
circ->timestamp_created :
circ->timestamp_created.tv_sec :
start_of_buffer_stats_interval;
interval_length = (int) (end_of_interval - start_of_interval);
stat = tor_malloc_zero(sizeof(circ_buffer_stats_t));

View File

@ -2822,7 +2822,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
ns->flavor = flav = flavor;
}
if (flav != FLAV_NS && ns_type != NS_TYPE_CONSENSUS) {
log_warn(LD_DIR, "Flavor found on non-consenus networkstatus.");
log_warn(LD_DIR, "Flavor found on non-consensus networkstatus.");
goto err;
}

View File

@ -5,7 +5,7 @@
/* See LICENSE for licensing information */
/**
* \file routerpase.h
* \file routerparse.h
* \brief Header file for routerparse.c.
**/
@ -82,7 +82,5 @@ int rend_parse_introduction_points(rend_service_descriptor_t *parsed,
size_t intro_points_encoded_size);
int rend_parse_client_keys(strmap_t *parsed_clients, const char *str);
void tor_gettimeofday_cache_clear(void);
#endif

View File

@ -384,12 +384,14 @@ test_crypto_pk(void)
/* Now try signing. */
strlcpy(data1, "Ossifrage", 1024);
test_eq(128, crypto_pk_private_sign(pk1, data2, sizeof(data2), data1, 10));
test_eq(10, crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128));
test_eq(10,
crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128));
test_streq(data3, "Ossifrage");
/* Try signing digests. */
test_eq(128, crypto_pk_private_sign_digest(pk1, data2, sizeof(data2),
data1, 10));
test_eq(20, crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128));
test_eq(20,
crypto_pk_public_checksig(pk1, data3, sizeof(data3), data2, 128));
test_eq(0, crypto_pk_public_checksig_digest(pk1, data1, 10, data2, 128));
test_eq(-1, crypto_pk_public_checksig_digest(pk1, data1, 11, data2, 128));

View File

@ -748,11 +748,11 @@ test_dir_v3_networkstatus(void)
sign_skey_leg1 = pk_generate(4);
test_assert(!crypto_pk_read_private_key_from_string(sign_skey_1,
AUTHORITY_SIGNKEY_1, -1));
AUTHORITY_SIGNKEY_1, -1));
test_assert(!crypto_pk_read_private_key_from_string(sign_skey_2,
AUTHORITY_SIGNKEY_2, -1));
AUTHORITY_SIGNKEY_2, -1));
test_assert(!crypto_pk_read_private_key_from_string(sign_skey_3,
AUTHORITY_SIGNKEY_3, -1));
AUTHORITY_SIGNKEY_3, -1));
test_assert(!crypto_pk_cmp_keys(sign_skey_1, cert1->signing_key));
test_assert(!crypto_pk_cmp_keys(sign_skey_2, cert2->signing_key));