diff options
-rw-r--r-- | .travis.yml | 10 | ||||
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | ReleaseNotes | 2 | ||||
-rw-r--r-- | changes/bug12399 | 3 | ||||
-rw-r--r-- | changes/bug23507 | 5 | ||||
-rw-r--r-- | changes/bug23818_v2 | 6 | ||||
-rw-r--r-- | changes/bug23818_v3 | 6 | ||||
-rw-r--r-- | changes/bug31442 | 3 | ||||
-rw-r--r-- | changes/ticket31314 | 18 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rwxr-xr-x | scripts/git/git-merge-forward.sh | 281 | ||||
-rwxr-xr-x | scripts/git/git-push-all.sh | 219 | ||||
-rw-r--r-- | src/feature/hs/hs_circuit.c | 33 | ||||
-rw-r--r-- | src/feature/hs/hs_circuit.h | 3 | ||||
-rw-r--r-- | src/feature/hs/hs_service.c | 30 | ||||
-rw-r--r-- | src/feature/nodelist/routerset.c | 2 | ||||
-rw-r--r-- | src/feature/rend/rendcommon.c | 18 | ||||
-rw-r--r-- | src/feature/rend/rendmid.c | 3 | ||||
-rw-r--r-- | src/feature/rend/rendservice.c | 19 |
19 files changed, 556 insertions, 117 deletions
diff --git a/.travis.yml b/.travis.yml index fe9266dffa..94d9bf9cce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,8 @@ env: - HARDENING_OPTIONS="--enable-expensive-hardening" ## We turn off asciidoc by default, because it's slow - ASCIIDOC_OPTIONS="--disable-asciidoc" + ## Our default rust version is the minimum supported version + - RUST_VERSION="1.31.0" matrix: ## We want to use each build option at least once ## @@ -55,9 +57,9 @@ matrix: # We clone our stem repo and run `make test-stem` - env: TEST_STEM="yes" SKIP_MAKE_CHECK="yes" ## Check rust online with distcheck, to make sure we remove rust products - - env: DISTCHECK="yes" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode" + - env: DISTCHECK="yes" RUST_VERSION="beta" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode" ## Check disable module dirauth with and without rust - - env: MODULES_OPTIONS="--disable-module-dirauth" RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true + - env: MODULES_OPTIONS="--disable-module-dirauth" RUST_VERSION="nightly" RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true - env: MODULES_OPTIONS="--disable-module-dirauth" ## Check NSS - env: NSS_OPTIONS="--enable-nss" @@ -173,8 +175,8 @@ install: - if [[ "$ASCIIDOC_OPTIONS" == "" ]] && [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export XML_CATALOG_FILES="/usr/local/etc/xml/catalog"; fi ## If we're using Rust, download rustup - if [[ "$RUST_OPTIONS" != "" ]]; then curl -Ssf -o rustup.sh https://sh.rustup.rs; fi - ## Install the nightly channels of rustc and cargo and setup our toolchain environment - - if [[ "$RUST_OPTIONS" != "" ]]; then sh rustup.sh -y --default-toolchain nightly; fi + ## Install the stable channels of rustc and cargo and setup our toolchain environment + - if [[ "$RUST_OPTIONS" != "" ]]; then sh rustup.sh -y --default-toolchain $RUST_VERSION; fi - if [[ "$RUST_OPTIONS" != "" ]]; then source $HOME/.cargo/env; fi ## If we're testing rust builds in offline-mode, then set up our vendored dependencies - if [[ "$TOR_RUST_DEPENDENCIES" == "true" ]]; then export TOR_RUST_DEPENDENCIES=$PWD/src/ext/rust/crates; fi @@ -306,7 +306,7 @@ Changes in version 0.4.1.1-alpha - 2019-05-22 circuits. This feature is only enabled when also supported by the circuit's middle node. (Clients may specify fixed middle nodes with the MiddleNodes option, and may force-disable this feature - with the CircuitPadding torrc.) Closes ticket 28634. + with the CircuitPadding option.) Closes ticket 28634. o Major features (code organization): - Tor now includes a generic publish-subscribe message-passing @@ -490,7 +490,7 @@ Changes in version 0.4.1.1-alpha - 2019-05-22 o Minor bugfixes (directory authority, ipv6): - Directory authorities with IPv6 support now always mark themselves - as reachable via IPv6. Fixes bug 24338; bugfix on 0.4.0.2-alpha. + as reachable via IPv6. Fixes bug 24338; bugfix on 0.2.4.1-alpha. Patch by Neel Chauhan. o Minor bugfixes (documentation): @@ -528,7 +528,7 @@ Changes in version 0.4.1.1-alpha - 2019-05-22 Neel Chauhan. - When relaunching a circuit to a rendezvous service, mark the circuit as needing high-uptime routers as appropriate. Fixes bug - 17357; bugfix on 0.4.0.2-alpha. Patch by Neel Chauhan. + 17357; bugfix on 0.1.0.1-rc. Patch by Neel Chauhan. - Stop ignoring IPv6 link specifiers sent to v3 onion services. (IPv6 support for v3 onion services is still incomplete: see ticket 23493 for details.) Fixes bug 23588; bugfix on @@ -1462,7 +1462,7 @@ Changes in version 0.4.0.1-alpha - 2019-01-18 we had added up the sum of all nodes with a descriptor, but that could cause us to build failing circuits when we had either too many bridges or not enough guard nodes. Fixes bug 25885; bugfix on - 0.3.6.1-alpha. Patch by Neel Chauhan. + 0.2.3.1-alpha. Patch by Neel Chauhan. o Minor bugfixes (IPv6): - Fix tor_ersatz_socketpair on IPv6-only systems. Previously, the diff --git a/ReleaseNotes b/ReleaseNotes index b378fd07a9..aa88c5321e 100644 --- a/ReleaseNotes +++ b/ReleaseNotes @@ -911,7 +911,7 @@ Changes in version 0.4.0.5 - 2019-05-02 we had added up the sum of all nodes with a descriptor, but that could cause us to build failing circuits when we had either too many bridges or not enough guard nodes. Fixes bug 25885; bugfix on - 0.3.6.1-alpha. Patch by Neel Chauhan. + 0.2.3.1-alpha. Patch by Neel Chauhan. o Minor bugfixes (IPv6): - Fix tor_ersatz_socketpair on IPv6-only systems. Previously, the diff --git a/changes/bug12399 b/changes/bug12399 new file mode 100644 index 0000000000..922c08c5e3 --- /dev/null +++ b/changes/bug12399 @@ -0,0 +1,3 @@ + o Minor bugfixes (logging): + - Change log level of message "Hash of session info was not as expected" + to LOG_PROTOCOL_WARN. Fixes bug 12399; bugfix on 0.1.1.10-alpha. diff --git a/changes/bug23507 b/changes/bug23507 new file mode 100644 index 0000000000..de18273fdb --- /dev/null +++ b/changes/bug23507 @@ -0,0 +1,5 @@ + o Minor bugfixes (v3 single onion services): + - Make v3 single onion services fall back to a 3-hop intro, when there + all intro points are unreachable via a 1-hop path. Previously, v3 + single onion services failed when all intro nodes were unreachable + via a 1-hop path. Fixes bug 23507; bugfix on 0.3.2.1-alpha. diff --git a/changes/bug23818_v2 b/changes/bug23818_v2 new file mode 100644 index 0000000000..0219a20f49 --- /dev/null +++ b/changes/bug23818_v2 @@ -0,0 +1,6 @@ + o Minor bugfixes (v2 single onion services): + - Always retry v2 single onion service intro and rend circuits with a + 3-hop path. Previously, v2 single onion services used a 3-hop path + when rend circuits were retried after a remote or delayed failure, + but a 1-hop path for immediate retries. Fixes bug 23818; + bugfix on 0.2.9.3-alpha. diff --git a/changes/bug23818_v3 b/changes/bug23818_v3 new file mode 100644 index 0000000000..c430144d81 --- /dev/null +++ b/changes/bug23818_v3 @@ -0,0 +1,6 @@ + o Minor bugfixes (v3 single onion services): + - Always retry v3 single onion service intro and rend circuits with a + 3-hop path. Previously, v3 single onion services used a 3-hop path + when rend circuits were retried after a remote or delayed failure, + but a 1-hop path for immediate retries. Fixes bug 23818; + bugfix on 0.3.2.1-alpha. diff --git a/changes/bug31442 b/changes/bug31442 new file mode 100644 index 0000000000..4df9fc6dfb --- /dev/null +++ b/changes/bug31442 @@ -0,0 +1,3 @@ + o Minor bugfixes (rust): + - Raise the minimum rustc version to 1.31.0, as checked by configure + and CI. Fixes bug 31442; bugfix on 0.3.5.4-alpha. diff --git a/changes/ticket31314 b/changes/ticket31314 new file mode 100644 index 0000000000..7ce96e96cf --- /dev/null +++ b/changes/ticket31314 @@ -0,0 +1,18 @@ + o Minor features (git scripts): + - Add a -t <test-branch-prefix> argument to git-merge-forward.sh and + git-push-all.sh, which makes these scripts create, merge forward, and + push test branches. Closes ticket 31314. + - Add a -r <remote-name> argument to git-push-all.sh, so the script can + push test branches to a personal remote. Closes ticket 31314. + - Add a -u argument to git-merge-forward.sh, so that the script can re-use + existing test branches after a merge failure and fix. + Closes ticket 31314. + - Add a TOR_GIT_PUSH env var, which sets the default git push command and + arguments for git-push-all.sh. Closes ticket 31314. + - Add a "--" command-line argument, to + separate git-push-all.sh script arguments from arguments that are passed + through to git push. Closes ticket 31314. + - Skip pushing test branches that are the same as a remote + maint/release/master branch in git-push-all.sh by default. Add a -s + argument, so git-push-all.sh can push all test branches. + Closes ticket 31314. diff --git a/configure.ac b/configure.ac index 9ec123f51e..f90a0c09b1 100644 --- a/configure.ac +++ b/configure.ac @@ -558,8 +558,8 @@ if test "x$enable_rust" = "xyes"; then if test "x$RUSTC_VERSION_MAJOR" = "x" -o "x$RUSTC_VERSION_MINOR" = "x"; then AC_MSG_ERROR([rustc version couldn't be identified]) fi - if test "$RUSTC_VERSION_MAJOR" -lt 2 -a "$RUSTC_VERSION_MINOR" -lt 14; then - AC_MSG_ERROR([rustc must be at least version 1.14]) + if test "$RUSTC_VERSION_MAJOR" -lt 2 -a "$RUSTC_VERSION_MINOR" -lt 31; then + AC_MSG_ERROR([rustc must be at least version 1.31.0]) fi AC_MSG_RESULT([$RUSTC_VERSION]) fi diff --git a/scripts/git/git-merge-forward.sh b/scripts/git/git-merge-forward.sh index ba29983284..cbd2f3c3bd 100755 --- a/scripts/git/git-merge-forward.sh +++ b/scripts/git/git-merge-forward.sh @@ -1,9 +1,23 @@ #!/usr/bin/env bash -############################## -# Configuration (change me!) # -############################## - +# Usage: git-merge-forward.sh -n -t <test-branch-prefix> -u +# arguments: +# -n: dry run mode +# -t: test branch mode: create new branches from the commits checked +# out in each maint directory. Call these branches prefix_029, +# prefix_035, ... , prefix_master. +# -u: in test branch mode, if a prefix_* branch exists, skip creating +# that branch. Use after a merge error, to restart the merge +# forward at the first unmerged branch. +# env vars: +# See the Configuration section for env vars and their default values. + +################# +# Configuration # +################# + +# Don't change this configuration - set the env vars in your .profile +# # The general setup that is suggested here is: # # GIT_PATH = /home/<user>/git/ @@ -21,27 +35,55 @@ TOR_MASTER_NAME=${TOR_MASTER_NAME:-"tor"} # The worktrees location (directory). TOR_WKT_NAME=${TOR_WKT_NAME:-"tor-wkt"} -######################### -# End of configuration. # -######################### +########################## +# Git branches to manage # +########################## + +# The branches and worktrees need to be modified when there is a new branch, +# and when an old branch is no longer supported. # Configuration of the branches that needs merging. The values are in order: -# (1) Branch name that we merge onto. -# (2) Branch name to merge from. In other words, this is merge into (1) -# (3) Full path of the git worktree. +# (0) current maint/release branch name +# (1) previous maint/release name to merge into (0) +# (only used in merge forward mode) +# (2) Full path of the git worktree +# (3) current branch suffix +# (maint branches only, only used in test branch mode) +# (4) previous test branch suffix to merge into (3) +# (maint branches only, only used in test branch mode) # -# As an example: -# $ cd <PATH/TO/WORKTREE> (3) -# $ git checkout maint-0.3.5 (1) +# Merge forward example: +# $ cd <PATH/TO/WORKTREE> (2) +# $ git checkout maint-0.3.5 (0) # $ git pull -# $ git merge maint-0.3.4 (2) +# $ git merge maint-0.3.4 (1) +# +# Test branch example: +# $ cd <PATH/TO/WORKTREE> (2) +# $ git checkout -b ticket99999_035 (3) +# $ git checkout maint-0.3.5 (0) +# $ git pull +# $ git checkout ticket99999_035 +# $ git merge maint-0.3.5 +# $ git merge ticket99999_034 (4) # # First set of arrays are the maint-* branch and then the release-* branch. # New arrays need to be in the WORKTREE= array else they aren't considered. -MAINT_035=( "maint-0.3.5" "maint-0.2.9" "$GIT_PATH/$TOR_WKT_NAME/maint-0.3.5" ) -MAINT_040=( "maint-0.4.0" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" ) -MAINT_041=( "maint-0.4.1" "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" ) -MAINT_MASTER=( "master" "maint-0.4.1" "$GIT_PATH/$TOR_MASTER_NAME" ) +# +# Only used in test branch mode +# There is no previous branch to merge forward, so the second and fifth items +# must be blank ("") +MAINT_029_TB=( "maint-0.2.9" "" "$GIT_PATH/$TOR_WKT_NAME/maint-0.2.9" \ + "_029" "") +# Used in maint/release merge and test branch modes +MAINT_035=( "maint-0.3.5" "maint-0.2.9" "$GIT_PATH/$TOR_WKT_NAME/maint-0.3.5" \ + "_035" "_029") +MAINT_040=( "maint-0.4.0" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.0" \ + "_040" "_035") +MAINT_041=( "maint-0.4.1" "maint-0.4.0" "$GIT_PATH/$TOR_WKT_NAME/maint-0.4.1" \ + "_041" "_040") +MAINT_MASTER=( "master" "maint-0.4.1" "$GIT_PATH/$TOR_MASTER_NAME" \ + "_master" "_041") RELEASE_029=( "release-0.2.9" "maint-0.2.9" "$GIT_PATH/$TOR_WKT_NAME/release-0.2.9" ) RELEASE_035=( "release-0.3.5" "maint-0.3.5" "$GIT_PATH/$TOR_WKT_NAME/release-0.3.5" ) @@ -55,6 +97,7 @@ ORIGIN_PATH="$GIT_PATH/$TOR_MASTER_NAME" # SC2034 -- shellcheck thinks that these are unused. We know better. ACTUALLY_THESE_ARE_USED=<<EOF +${MAINT_029_TB[0]} ${MAINT_035[0]} ${MAINT_040[0]} ${MAINT_041[0]} @@ -65,31 +108,88 @@ ${RELEASE_040[0]} ${RELEASE_041[0]} EOF -########################## -# Git Worktree to manage # -########################## +####################### +# Argument processing # +####################### + +# Controlled by the -n option. The dry run option will just output the command +# that would have been executed for each worktree. +DRY_RUN=0 + +# Controlled by the -t <test-branch-prefix> option. The test branch base +# name option makes git-merge-forward.sh create new test branches: +# <tbbn>_029, <tbbn>_035, ... , <tbbn>_master, and merge forward. +TEST_BRANCH_PREFIX= + +# Controlled by the -u option. The use existing option checks for existing +# branches with the <test-branch-prefix>, and checks them out, rather than +# creating a new branch. +USE_EXISTING=0 + +while getopts "nt:u" opt; do + case "$opt" in + n) DRY_RUN=1 + echo " *** DRY RUN MODE ***" + ;; + t) TEST_BRANCH_PREFIX="$OPTARG" + echo " *** CREATING TEST BRANCHES: ${TEST_BRANCH_PREFIX}_nnn ***" + ;; + u) USE_EXISTING=1 + echo " *** USE EXISTING TEST BRANCHES MODE ***" + ;; + *) + exit 1 + ;; + esac +done + +########################### +# Git worktrees to manage # +########################### + +if [ -z "$TEST_BRANCH_PREFIX" ]; then + + # maint/release merge mode + # + # List of all worktrees to work on. All defined above. Ordering is important. + # Always the maint-* branch BEFORE then the release-*. + WORKTREE=( + RELEASE_029[@] + + MAINT_035[@] + RELEASE_035[@] + + MAINT_040[@] + RELEASE_040[@] + + MAINT_041[@] + RELEASE_041[@] + + MAINT_MASTER[@] + ) + +else -# List of all worktrees to work on. All defined above. Ordering is important. -# Always the maint-* branch BEFORE then the release-*. -WORKTREE=( - RELEASE_029[@] + # Test branch mode: merge to maint only, and create a new branch for 0.2.9 + WORKTREE=( + MAINT_029_TB[@] - MAINT_035[@] - RELEASE_035[@] + MAINT_035[@] - MAINT_040[@] - RELEASE_040[@] + MAINT_040[@] - MAINT_041[@] - RELEASE_041[@] + MAINT_041[@] + + MAINT_MASTER[@] + ) + +fi - MAINT_MASTER[@] -) COUNT=${#WORKTREE[@]} -# Controlled by the -n option. The dry run option will just output the command -# that would have been executed for each worktree. -DRY_RUN=0 +############# +# Constants # +############# # Control characters CNRM=$'\x1b[0;0m' # Clear color @@ -127,7 +227,7 @@ function validate_ret # Switch to the given branch name. function switch_branch { - local cmd="git checkout $1" + local cmd="git checkout '$1'" printf " %s Switching branch to %s..." "$MARKER" "$1" if [ $DRY_RUN -eq 0 ]; then msg=$( eval "$cmd" 2>&1 ) @@ -137,6 +237,45 @@ function switch_branch fi } +# Checkout a new branch with the given branch name. +function new_branch +{ + local cmd="git checkout -b '$1'" + printf " %s Creating new branch %s..." "$MARKER" "$1" + if [ $DRY_RUN -eq 0 ]; then + msg=$( eval "$cmd" 2>&1 ) + validate_ret $? "$msg" + else + printf "\\n %s\\n" "${IWTH}$cmd${CNRM}" + fi +} + +# Switch to an existing branch, or checkout a new branch with the given +# branch name. +function switch_or_new_branch +{ + local cmd="git rev-parse --verify '$1'" + if [ $DRY_RUN -eq 0 ]; then + # Call switch_branch if there is a branch, or new_branch if there is not + msg=$( eval "$cmd" 2>&1 ) + RET=$? + if [ $RET -eq 0 ]; then + # Branch: (commit id) + switch_branch "$1" + elif [ $RET -eq 128 ]; then + # Not a branch: "fatal: Needed a single revision" + new_branch "$1" + else + # Unexpected return value + validate_ret $RET "$msg" + fi + else + printf "\\n %s\\n" "${IWTH}$cmd${CNRM}, then depending on the result:" + switch_branch "$1" + new_branch "$1" + fi +} + # Pull the given branch name. function pull_branch { @@ -150,10 +289,10 @@ function pull_branch fi } -# Merge the given branch name ($2) into the current branch ($1). +# Merge the given branch name ($1) into the current branch ($2). function merge_branch { - local cmd="git merge --no-edit $1" + local cmd="git merge --no-edit '$1'" printf " %s Merging branch %s into %s..." "$MARKER" "$1" "$2" if [ $DRY_RUN -eq 0 ]; then msg=$( eval "$cmd" 2>&1 ) @@ -166,7 +305,7 @@ function merge_branch # Pull the given branch name. function merge_branch_origin { - local cmd="git merge --ff-only origin/$1" + local cmd="git merge --ff-only 'origin/$1'" printf " %s Merging branch origin/%s..." "$MARKER" "$1" if [ $DRY_RUN -eq 0 ]; then msg=$( eval "$cmd" 2>&1 ) @@ -203,16 +342,6 @@ function fetch_origin # Entry point # ############### -while getopts "n" opt; do - case "$opt" in - n) DRY_RUN=1 - echo " *** DRY DRUN MODE ***" - ;; - *) - ;; - esac -done - # First, fetch the origin. goto_repo "$ORIGIN_PATH" fetch_origin @@ -222,15 +351,57 @@ for ((i=0; i<COUNT; i++)); do current=${!WORKTREE[$i]:0:1} previous=${!WORKTREE[$i]:1:1} repo_path=${!WORKTREE[$i]:2:1} + # default to merge forward mode + test_current= + test_previous= + target_current="$current" + target_previous="$previous" + if [ "$TEST_BRANCH_PREFIX" ]; then + test_current_suffix=${!WORKTREE[$i]:3:1} + test_current=${TEST_BRANCH_PREFIX}${test_current_suffix} + # the current test branch, if present, or maint/release branch, if not + target_current="$test_current" + test_previous_suffix=${!WORKTREE[$i]:4:1} + if [ "$test_previous_suffix" ]; then + test_previous=${TEST_BRANCH_PREFIX}${test_previous_suffix} + # the previous test branch, if present, or maint/release branch, if not + target_previous="$test_previous" + fi + fi - printf "%s Handling branch \\n" "$MARKER" "${BYEL}$current${CNRM}" + printf "%s Handling branch \\n" "$MARKER" "${BYEL}$target_current${CNRM}" # Go into the worktree to start merging. goto_repo "$repo_path" - # Checkout the current branch + if [ "$test_current" ]; then + if [ $USE_EXISTING -eq 0 ]; then + # Create a test branch from the currently checked-out branch/commit + # Fail if it already exists + new_branch "$test_current" + else + # Switch if it exists, or create if it does not + switch_or_new_branch "$test_current" + fi + fi + # Checkout the current maint/release branch switch_branch "$current" - # Update the current branch with an origin merge to get the latest. + # Update the current maint/release branch with an origin merge to get the + # latest updates merge_branch_origin "$current" - # Merge the previous branch. Ex: merge maint-0.2.5 into maint-0.2.9. - merge_branch "$previous" "$current" + if [ "$test_current" ]; then + # Checkout the test branch + switch_branch "$test_current" + # Merge the updated maint branch into the test branch + merge_branch "$current" "$test_current" + fi + # Merge the previous branch into the target branch + # Merge Forward Example: + # merge maint-0.2.9 into maint-0.3.5. + # Test Branch Example: + # merge bug99999_029 into bug99999_035. + # Skip the merge if the previous branch does not exist + # (there's nothing to merge forward into the oldest test branch) + if [ "$target_previous" ]; then + merge_branch "$target_previous" "$target_current" + fi done diff --git a/scripts/git/git-push-all.sh b/scripts/git/git-push-all.sh index 469d6fe570..8e49e81b9d 100755 --- a/scripts/git/git-push-all.sh +++ b/scripts/git/git-push-all.sh @@ -1,19 +1,133 @@ #!/usr/bin/env bash -# Usage: git-push-all.sh -# env vars: TOR_UPSTREAM_REMOTE_NAME=upstream TOR_PUSH_DELAY=0 -# options: --no-atomic --dry-run (any other git push option) -# -# TOR_PUSH_DELAY pushes the master and maint branches separately, so that CI -# runs in a sensible order. -# push --atomic is the default when TOR_PUSH_DELAY=0, and for release branches. +# Usage: git-push-all.sh -t <test-branch-prefix> -r <remote-name> -s +# -- <git-opts> +# arguments: +# -t: test branch mode: Push test branches, rather than maint and +# release branches. Pushes the branches called prefix_029, +# prefix_035, ... , prefix_master. +# -r: push to remote-name, rather than $TOR_UPSTREAM_REMOTE_NAME. +# -s: push branches whose tips match upstream maint, release, or +# master branches. The default is to skip these branches. Use +# -s when testing for CI environment failures with old code. +# --: pass any other arguments to git, rather than the script. +# env vars: +# TOR_GIT_PUSH: the git push command and arguments +# TOR_UPSTREAM_REMOTE_NAME: the default upstream, overridden by -r +# TOR_PUSH_DELAY: pushes the master and maint branches separately, +# so that CI runs in a sensible order. +# TOR_PUSH_SAME: push branches whose tips match upstream maint, +# release, or master branches. Inverted by -s. +# See the Configuration section for env var default values. +# git-opts: +# --no-atomic --dry-run (and any other git push option) set -e +################# +# Configuration # +################# + +# Don't change this configuration - set the env vars in your .profile +# +# git push command and default arguments +GIT_PUSH=${TOR_GIT_PUSH:-"git push --atomic"} # The upstream remote which git.torproject.org/tor.git points to. -UPSTREAM_REMOTE=${TOR_UPSTREAM_REMOTE_NAME:-"upstream"} +DEFAULT_UPSTREAM_REMOTE=${TOR_UPSTREAM_REMOTE_NAME:-"upstream"} +# Push to a different upstream remote using -r <remote-name> +UPSTREAM_REMOTE=${DEFAULT_UPSTREAM_REMOTE} # Add a delay between pushes, so CI runs on the most important branches first PUSH_DELAY=${TOR_PUSH_DELAY:-0} +# Push (1) or skip (0) test branches that are the same as an upstream +# maint/master branch. Push if you are testing that the CI environment still +# works on old code, skip if you are testing new code in the branch. +# Default: skip unchanged branches. +# Inverted by the -s option. +PUSH_SAME=${TOR_PUSH_SAME:-0} + +####################### +# Argument processing # +####################### + +# Controlled by the -t <test-branch-prefix> option. The test branch base +# name option makes git-merge-forward.sh create new test branches: +# <tbbn>_029, <tbbn>_035, ... , <tbbn>_master, and merge forward. +TEST_BRANCH_PREFIX= + +while getopts ":r:st:" opt; do + case "$opt" in + r) UPSTREAM_REMOTE="$OPTARG" + echo " *** PUSHING TO REMOTE: ${UPSTREAM_REMOTE} ***" + shift + shift + OPTIND=$((OPTIND - 2)) + ;; + s) PUSH_SAME=$((! PUSH_SAME)) + if [ "$PUSH_SAME" -eq 0 ]; then + echo " *** SKIPPING UNCHANGED TEST BRANCHES ***" + else + echo " *** PUSHING UNCHANGED TEST BRANCHES ***" + fi + shift + OPTIND=$((OPTIND - 1)) + ;; + t) TEST_BRANCH_PREFIX="$OPTARG" + echo " *** PUSHING TEST BRANCHES: ${TEST_BRANCH_PREFIX}_nnn ***" + shift + shift + OPTIND=$((OPTIND - 2)) + ;; + *) + # Assume we're done with script arguments, + # and git push will handle the option + break + ;; + esac +done + +# getopts doesn't allow "-" as an option character, +# so we have to handle -- manually +if [ "$1" = "--" ]; then + shift +fi + +echo "Calling $GIT_PUSH" "$@" "<branches>" + +if [ "$TEST_BRANCH_PREFIX" ]; then + if [ "$UPSTREAM_REMOTE" = "${TOR_UPSTREAM_REMOTE_NAME:-upstream}" ]; then + echo "Pushing test branches ${TEST_BRANCH_PREFIX}_nnn to " \ + "$UPSTREAM_REMOTE is not allowed." + echo "Usage: $0 -r <remote-name> -t <test-branch-prefix> <git-opts>" + exit 1 + fi +fi + +################################ +# Git upstream remote branches # +################################ + +DEFAULT_UPSTREAM_BRANCHES= +if [ "$DEFAULT_UPSTREAM_REMOTE" != "$UPSTREAM_REMOTE" ]; then + DEFAULT_UPSTREAM_BRANCHES=$(echo \ + "$DEFAULT_UPSTREAM_REMOTE"/master \ + "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.1 \ + "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.4.0 \ + "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.3.5 \ + "$DEFAULT_UPSTREAM_REMOTE"/{release,maint}-0.2.9 \ + ) +fi + +UPSTREAM_BRANCHES=$(echo \ + "$UPSTREAM_REMOTE"/master \ + "$UPSTREAM_REMOTE"/{release,maint}-0.4.1 \ + "$UPSTREAM_REMOTE"/{release,maint}-0.4.0 \ + "$UPSTREAM_REMOTE"/{release,maint}-0.3.5 \ + "$UPSTREAM_REMOTE"/{release,maint}-0.2.9 \ + ) + +######################## +# Git branches to push # +######################## PUSH_BRANCHES=$(echo \ master \ @@ -23,29 +137,98 @@ PUSH_BRANCHES=$(echo \ {release,maint}-0.2.9 \ ) +if [ -z "$TEST_BRANCH_PREFIX" ]; then + + # maint/release push mode + # + # List of branches to push. Ordering is not important. + PUSH_BRANCHES=$(echo \ + master \ + {release,maint}-0.4.1 \ + {release,maint}-0.4.0 \ + {release,maint}-0.3.5 \ + {release,maint}-0.2.9 \ + ) +else + + # Test branch mode: merge to maint only, and create a new branch for 0.2.9 + # + # List of branches to push. Ordering is not important. + PUSH_BRANCHES=" \ + ${TEST_BRANCH_PREFIX}_master \ + ${TEST_BRANCH_PREFIX}_041 \ + ${TEST_BRANCH_PREFIX}_040 \ + ${TEST_BRANCH_PREFIX}_035 \ + ${TEST_BRANCH_PREFIX}_029 \ + " +fi + +############### +# Entry point # +############### + +# Skip the test branches that are the same as the upstream branches +if [ "$PUSH_SAME" -eq 0 ] && [ "$TEST_BRANCH_PREFIX" ]; then + NEW_PUSH_BRANCHES= + for b in $PUSH_BRANCHES; do + PUSH_COMMIT=$(git rev-parse "$b") + SKIP_UPSTREAM= + for u in $DEFAULT_UPSTREAM_BRANCHES $UPSTREAM_BRANCHES; do + UPSTREAM_COMMIT=$(git rev-parse "$u") + if [ "$PUSH_COMMIT" = "$UPSTREAM_COMMIT" ]; then + SKIP_UPSTREAM="$u" + fi + done + if [ "$SKIP_UPSTREAM" ]; then + printf "Skipping unchanged: %s remote: %s\n" \ + "$b" "$SKIP_UPSTREAM" + else + if [ "$NEW_PUSH_BRANCHES" ]; then + NEW_PUSH_BRANCHES="${NEW_PUSH_BRANCHES} ${b}" + else + NEW_PUSH_BRANCHES="${b}" + fi + fi + done + PUSH_BRANCHES=${NEW_PUSH_BRANCHES} +fi + if [ "$PUSH_DELAY" -le 0 ]; then echo "Pushing $PUSH_BRANCHES" # We know that there are no spaces in any branch within $PUSH_BRANCHES, so # it is safe to use it unquoted. (This also applies to the other shellcheck # exceptions below.) # + # Push all the branches at the same time # shellcheck disable=SC2086 - git push --atomic "$@" "$UPSTREAM_REMOTE" $PUSH_BRANCHES + $GIT_PUSH "$@" "$UPSTREAM_REMOTE" $PUSH_BRANCHES else + # Push the branches in optimal CI order, with a delay between each push PUSH_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | sort -V) MASTER_BRANCH=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep master) - MAINT_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep maint) - RELEASE_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep release | \ - tr "\n" " ") - printf "Pushing with %ss delays, so CI runs in this order:\n%s\n%s\n%s\n" \ - "$PUSH_DELAY" "$MASTER_BRANCH" "$MAINT_BRANCHES" "$RELEASE_BRANCHES" - git push "$@" "$UPSTREAM_REMOTE" "$MASTER_BRANCH" + if [ -z "$TEST_BRANCH_PREFIX" ]; then + MAINT_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep maint) + RELEASE_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep release | \ + tr "\n" " ") + printf "Pushing with %ss delays, so CI runs in this order:\n%s\n%s\n%s\n" \ + "$PUSH_DELAY" "$MASTER_BRANCH" "$MAINT_BRANCHES" "$RELEASE_BRANCHES" + else + # Actually test branches based on maint branches + MAINT_BRANCHES=$(echo "$PUSH_BRANCHES" | tr " " "\n" | grep -v master) + printf "Pushing with %ss delays, so CI runs in this order:\n%s\n%s\n" \ + "$PUSH_DELAY" "$MASTER_BRANCH" "$MAINT_BRANCHES" + # No release branches + RELEASE_BRANCHES= + fi + $GIT_PUSH "$@" "$UPSTREAM_REMOTE" "$MASTER_BRANCH" sleep "$PUSH_DELAY" # shellcheck disable=SC2086 for b in $MAINT_BRANCHES; do - git push "$@" "$UPSTREAM_REMOTE" $b + $GIT_PUSH "$@" "$UPSTREAM_REMOTE" "$b" sleep "$PUSH_DELAY" done - # shellcheck disable=SC2086 - git push --atomic "$@" "$UPSTREAM_REMOTE" $RELEASE_BRANCHES + if [ "$RELEASE_BRANCHES" ]; then + # shellcheck disable=SC2086 + $GIT_PUSH "$@" "$UPSTREAM_REMOTE" $RELEASE_BRANCHES + fi fi diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index 259ffb1441..a5aa2fb228 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -387,10 +387,7 @@ launch_rendezvous_point_circuit(const hs_service_t *service, &data->onion_pk, service->config.is_single_onion); if (info == NULL) { - /* We are done here, we can't extend to the rendezvous point. - * If you're running an IPv6-only v3 single onion service on 0.3.2 or with - * 0.3.2 clients, and somehow disable the option check, it will fail here. - */ + /* We are done here, we can't extend to the rendezvous point. */ log_fn(LOG_PROTOCOL_WARN, LD_REND, "Not enough info to open a circuit to a rendezvous point for " "%s service %s.", @@ -404,8 +401,12 @@ launch_rendezvous_point_circuit(const hs_service_t *service, if (circ_needs_uptime) { circ_flags |= CIRCLAUNCH_NEED_UPTIME; } - /* Firewall and policies are checked when getting the extend info. */ - if (service->config.is_single_onion) { + /* Firewall and policies are checked when getting the extend info. + * + * We only use a one-hop path on the first attempt. If the first attempt + * fails, we use a 3-hop path for reachability / reliability. + * See the comment in retry_service_rendezvous_point() for details. */ + if (service->config.is_single_onion && i == 0) { circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL; } @@ -677,13 +678,16 @@ hs_circ_retry_service_rendezvous_point(origin_circuit_t *circ) } /* For a given service and a service intro point, launch a circuit to the - * extend info ei. If the service is a single onion, a one-hop circuit will be - * requested. Return 0 if the circuit was successfully launched and tagged + * extend info ei. If the service is a single onion, and direct_conn is true, + * a one-hop circuit will be requested. + * + * Return 0 if the circuit was successfully launched and tagged * with the correct identifier. On error, a negative value is returned. */ int hs_circ_launch_intro_point(hs_service_t *service, const hs_service_intro_point_t *ip, - extend_info_t *ei) + extend_info_t *ei, + bool direct_conn) { /* Standard flags for introduction circuit. */ int ret = -1, circ_flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL; @@ -695,7 +699,16 @@ hs_circ_launch_intro_point(hs_service_t *service, /* Update circuit flags in case of a single onion service that requires a * direct connection. */ - if (service->config.is_single_onion) { + tor_assert_nonfatal(ip->circuit_retries > 0); + /* Only single onion services can make direct conns */ + if (BUG(!service->config.is_single_onion && direct_conn)) { + goto end; + } + /* We only use a one-hop path on the first attempt. If the first attempt + * fails, we use a 3-hop path for reachability / reliability. + * (Unlike v2, retries is incremented by the caller before it calls this + * function.) */ + if (direct_conn && ip->circuit_retries == 1) { circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL; } diff --git a/src/feature/hs/hs_circuit.h b/src/feature/hs/hs_circuit.h index b8d8b25add..e168b301f1 100644 --- a/src/feature/hs/hs_circuit.h +++ b/src/feature/hs/hs_circuit.h @@ -26,7 +26,8 @@ void hs_circ_service_rp_has_opened(const hs_service_t *service, origin_circuit_t *circ); int hs_circ_launch_intro_point(hs_service_t *service, const hs_service_intro_point_t *ip, - extend_info_t *ei); + extend_info_t *ei, + bool direct_conn); int hs_circ_launch_rendezvous_point(const hs_service_t *service, const curve25519_public_key_t *onion_key, const uint8_t *rendezvous_cookie); diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index 8a4f1efb16..2835912742 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -2071,6 +2071,7 @@ build_all_descriptors(time_t now) static hs_service_intro_point_t * pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes) { + const or_options_t *options = get_options(); const node_t *node; hs_service_intro_point_t *ip = NULL; /* Normal 3-hop introduction point flags. */ @@ -2078,11 +2079,19 @@ pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes) /* Single onion flags. */ router_crn_flags_t direct_flags = flags | CRN_PREF_ADDR | CRN_DIRECT_CONN; - node = router_choose_random_node(exclude_nodes, get_options()->ExcludeNodes, + node = router_choose_random_node(exclude_nodes, options->ExcludeNodes, direct_conn ? direct_flags : flags); - /* Unable to find a node. When looking for a node for a direct connection, - * we could try a 3-hop path instead. We'll add support for this in a later - * release. */ + + /* If we are in single onion mode, retry node selection for a 3-hop + * path */ + if (direct_conn && !node) { + log_info(LD_REND, + "Unable to find an intro point that we can connect to " + "directly, falling back to a 3-hop path."); + node = router_choose_random_node(exclude_nodes, options->ExcludeNodes, + flags); + } + if (!node) { goto err; } @@ -2583,7 +2592,7 @@ launch_intro_point_circuits(hs_service_t *service) * circuits using the current map. */ FOR_EACH_DESCRIPTOR_BEGIN(service, desc) { /* Keep a ref on if we need a direct connection. We use this often. */ - unsigned int direct_conn = service->config.is_single_onion; + bool direct_conn = service->config.is_single_onion; DIGEST256MAP_FOREACH_MODIFY(desc->intro_points.map, key, hs_service_intro_point_t *, ip) { @@ -2594,8 +2603,15 @@ launch_intro_point_circuits(hs_service_t *service) if (hs_circ_service_get_intro_circ(ip)) { continue; } - ei = get_extend_info_from_intro_point(ip, direct_conn); + + /* If we can't connect directly to the intro point, get an extend_info + * for a multi-hop path instead. */ + if (ei == NULL && direct_conn) { + direct_conn = false; + ei = get_extend_info_from_intro_point(ip, 0); + } + if (ei == NULL) { /* This is possible if we can get a node_t but not the extend info out * of it. In this case, we remove the intro point and a new one will @@ -2607,7 +2623,7 @@ launch_intro_point_circuits(hs_service_t *service) /* Launch a circuit to the intro point. */ ip->circuit_retries++; - if (hs_circ_launch_intro_point(service, ip, ei) < 0) { + if (hs_circ_launch_intro_point(service, ip, ei, direct_conn) < 0) { log_info(LD_REND, "Unable to launch intro circuit to node %s " "for service %s.", safe_str_client(extend_info_describe(ei)), diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c index 0b89167806..73c2b1b1de 100644 --- a/src/feature/nodelist/routerset.c +++ b/src/feature/nodelist/routerset.c @@ -1,5 +1,5 @@ /* Copyright (c) 2001 Matej Pfajfar. -n * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ diff --git a/src/feature/rend/rendcommon.c b/src/feature/rend/rendcommon.c index 777de2984c..0a606a9f02 100644 --- a/src/feature/rend/rendcommon.c +++ b/src/feature/rend/rendcommon.c @@ -786,39 +786,39 @@ rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint, switch (command) { case RELAY_COMMAND_ESTABLISH_INTRO: if (or_circ) - r = hs_intro_received_establish_intro(or_circ,payload,length); + r = hs_intro_received_establish_intro(or_circ, payload, length); break; case RELAY_COMMAND_ESTABLISH_RENDEZVOUS: if (or_circ) - r = rend_mid_establish_rendezvous(or_circ,payload,length); + r = rend_mid_establish_rendezvous(or_circ, payload, length); break; case RELAY_COMMAND_INTRODUCE1: if (or_circ) - r = hs_intro_received_introduce1(or_circ,payload,length); + r = hs_intro_received_introduce1(or_circ, payload, length); break; case RELAY_COMMAND_INTRODUCE2: if (origin_circ) - r = hs_service_receive_introduce2(origin_circ,payload,length); + r = hs_service_receive_introduce2(origin_circ, payload, length); break; case RELAY_COMMAND_INTRODUCE_ACK: if (origin_circ) - r = hs_client_receive_introduce_ack(origin_circ,payload,length); + r = hs_client_receive_introduce_ack(origin_circ, payload, length); break; case RELAY_COMMAND_RENDEZVOUS1: if (or_circ) - r = rend_mid_rendezvous(or_circ,payload,length); + r = rend_mid_rendezvous(or_circ, payload, length); break; case RELAY_COMMAND_RENDEZVOUS2: if (origin_circ) - r = hs_client_receive_rendezvous2(origin_circ,payload,length); + r = hs_client_receive_rendezvous2(origin_circ, payload, length); break; case RELAY_COMMAND_INTRO_ESTABLISHED: if (origin_circ) - r = hs_service_receive_intro_established(origin_circ,payload,length); + r = hs_service_receive_intro_established(origin_circ, payload, length); break; case RELAY_COMMAND_RENDEZVOUS_ESTABLISHED: if (origin_circ) - r = hs_client_receive_rendezvous_acked(origin_circ,payload,length); + r = hs_client_receive_rendezvous_acked(origin_circ, payload, length); break; default: tor_fragile_assert(); diff --git a/src/feature/rend/rendmid.c b/src/feature/rend/rendmid.c index ef2a44c40d..bc86df632c 100644 --- a/src/feature/rend/rendmid.c +++ b/src/feature/rend/rendmid.c @@ -71,7 +71,8 @@ rend_mid_establish_intro_legacy(or_circuit_t *circ, const uint8_t *request, goto err; } if (tor_memneq(expected_digest, request+2+asn1len, DIGEST_LEN)) { - log_warn(LD_PROTOCOL, "Hash of session info was not as expected."); + log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, + "Hash of session info was not as expected."); reason = END_CIRC_REASON_TORPROTOCOL; goto err; } diff --git a/src/feature/rend/rendservice.c b/src/feature/rend/rendservice.c index 98c7253bcc..119a6f9c89 100644 --- a/src/feature/rend/rendservice.c +++ b/src/feature/rend/rendservice.c @@ -2123,8 +2123,12 @@ rend_service_receive_introduction(origin_circuit_t *circuit, int flags = CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_IS_INTERNAL; if (circ_needs_uptime) flags |= CIRCLAUNCH_NEED_UPTIME; /* A Single Onion Service only uses a direct connection if its - * firewall rules permit direct connections to the address. */ - if (rend_service_use_direct_connection(options, rp)) { + * firewall rules permit direct connections to the address. + * + * We only use a one-hop path on the first attempt. If the first attempt + * fails, we use a 3-hop path for reachability / reliability. + * See the comment in rend_service_relauch_rendezvous() for details. */ + if (rend_service_use_direct_connection(options, rp) && i == 0) { flags = flags | CIRCLAUNCH_ONEHOP_TUNNEL; } launched = circuit_launch_by_extend_info( @@ -3086,8 +3090,15 @@ rend_service_launch_establish_intro(rend_service_t *service, extend_info_t *launch_ei = intro->extend_info; extend_info_t *direct_ei = NULL; - /* Are we in single onion mode? */ - if (rend_service_allow_non_anonymous_connection(options)) { + /* Are we in single onion mode? + * + * We only use a one-hop path on the first attempt. If the first attempt + * fails, we use a 3-hop path for reachability / reliability. + * (Unlike v3, retries is incremented by the caller after it calls this + * function.) + */ + if (rend_service_allow_non_anonymous_connection(options) && + intro->circuit_retries == 0) { /* Do we have a descriptor for the node? * We've either just chosen it from the consensus, or we've just reviewed * our intro points to see which ones are still valid, and deleted the ones |