diff options
author | Mike Perry <mikeperry-git@torproject.org> | 2020-06-08 18:05:34 -0500 |
---|---|---|
committer | Mike Perry <mikeperry-git@torproject.org> | 2020-06-08 18:05:34 -0500 |
commit | 9eb0eeb68e524b03924ea9b1f11e9b75fcdcf37b (patch) | |
tree | 9a36c7018d99bc028af3b30f10a007c25fe729d7 /src/trunnel | |
parent | 1d32c3114fa3ebcd4219eba6ad7bb2a57b878511 (diff) | |
download | tor-9eb0eeb68e524b03924ea9b1f11e9b75fcdcf37b.tar.gz tor-9eb0eeb68e524b03924ea9b1f11e9b75fcdcf37b.zip |
Update Trunnel for new machine_ctr field.
This field area was memset to 0 in old versions, which the code treats as
"match any machine instance", for backward compatibility without a protover
bump.
Diffstat (limited to 'src/trunnel')
-rw-r--r-- | src/trunnel/circpad_negotiation.c | 52 | ||||
-rw-r--r-- | src/trunnel/circpad_negotiation.h | 27 | ||||
-rw-r--r-- | src/trunnel/circpad_negotiation.trunnel | 17 |
3 files changed, 96 insertions, 0 deletions
diff --git a/src/trunnel/circpad_negotiation.c b/src/trunnel/circpad_negotiation.c index 547818f2ec..4e3ee3d5bd 100644 --- a/src/trunnel/circpad_negotiation.c +++ b/src/trunnel/circpad_negotiation.c @@ -112,6 +112,17 @@ circpad_negotiate_set_echo_request(circpad_negotiate_t *inp, uint8_t val) inp->echo_request = val; return 0; } +uint32_t +circpad_negotiate_get_machine_ctr(const circpad_negotiate_t *inp) +{ + return inp->machine_ctr; +} +int +circpad_negotiate_set_machine_ctr(circpad_negotiate_t *inp, uint32_t val) +{ + inp->machine_ctr = val; + return 0; +} const char * circpad_negotiate_check(const circpad_negotiate_t *obj) { @@ -148,6 +159,9 @@ circpad_negotiate_encoded_len(const circpad_negotiate_t *obj) /* Length of u8 echo_request IN [0, 1] */ result += 1; + + /* Length of u32 machine_ctr */ + result += 4; return result; } int @@ -203,6 +217,13 @@ circpad_negotiate_encode(uint8_t *output, const size_t avail, const circpad_nego trunnel_set_uint8(ptr, (obj->echo_request)); written += 1; ptr += 1; + /* Encode u32 machine_ctr */ + trunnel_assert(written <= avail); + if (avail - written < 4) + goto truncated; + trunnel_set_uint32(ptr, trunnel_htonl(obj->machine_ctr)); + written += 4; ptr += 4; + trunnel_assert(ptr == output + written); #ifdef TRUNNEL_CHECK_ENCODED_LEN @@ -263,6 +284,11 @@ circpad_negotiate_parse_into(circpad_negotiate_t *obj, const uint8_t *input, con remaining -= 1; ptr += 1; if (! (obj->echo_request == 0 || obj->echo_request == 1)) goto fail; + + /* Parse u32 machine_ctr */ + CHECK_REMAINING(4, truncated); + obj->machine_ctr = trunnel_ntohl(trunnel_get_uint32(ptr)); + remaining -= 4; ptr += 4; trunnel_assert(ptr + remaining == input + len_in); return len_in - remaining; @@ -372,6 +398,17 @@ circpad_negotiated_set_machine_type(circpad_negotiated_t *inp, uint8_t val) inp->machine_type = val; return 0; } +uint32_t +circpad_negotiated_get_machine_ctr(const circpad_negotiated_t *inp) +{ + return inp->machine_ctr; +} +int +circpad_negotiated_set_machine_ctr(circpad_negotiated_t *inp, uint32_t val) +{ + inp->machine_ctr = val; + return 0; +} const char * circpad_negotiated_check(const circpad_negotiated_t *obj) { @@ -408,6 +445,9 @@ circpad_negotiated_encoded_len(const circpad_negotiated_t *obj) /* Length of u8 machine_type */ result += 1; + + /* Length of u32 machine_ctr */ + result += 4; return result; } int @@ -463,6 +503,13 @@ circpad_negotiated_encode(uint8_t *output, const size_t avail, const circpad_neg trunnel_set_uint8(ptr, (obj->machine_type)); written += 1; ptr += 1; + /* Encode u32 machine_ctr */ + trunnel_assert(written <= avail); + if (avail - written < 4) + goto truncated; + trunnel_set_uint32(ptr, trunnel_htonl(obj->machine_ctr)); + written += 4; ptr += 4; + trunnel_assert(ptr == output + written); #ifdef TRUNNEL_CHECK_ENCODED_LEN @@ -523,6 +570,11 @@ circpad_negotiated_parse_into(circpad_negotiated_t *obj, const uint8_t *input, c CHECK_REMAINING(1, truncated); obj->machine_type = (trunnel_get_uint8(ptr)); remaining -= 1; ptr += 1; + + /* Parse u32 machine_ctr */ + CHECK_REMAINING(4, truncated); + obj->machine_ctr = trunnel_ntohl(trunnel_get_uint32(ptr)); + remaining -= 4; ptr += 4; trunnel_assert(ptr + remaining == input + len_in); return len_in - remaining; diff --git a/src/trunnel/circpad_negotiation.h b/src/trunnel/circpad_negotiation.h index ba9155019e..9004540d43 100644 --- a/src/trunnel/circpad_negotiation.h +++ b/src/trunnel/circpad_negotiation.h @@ -26,6 +26,7 @@ struct circpad_negotiate_st { uint8_t machine_type; /** If true, send a relay_drop reply.. */ uint8_t echo_request; + uint32_t machine_ctr; uint8_t trunnel_error_code_; }; #endif @@ -42,6 +43,14 @@ struct circpad_negotiated_st { /** Machine type is left unbounded because we can specify * new machines in the consensus */ uint8_t machine_type; + /** + * This field is used for shutdown synchronization. It is OK if + * it wraps, because all we need to do is make sure the STOP + * command is actually for the currently active machine. + * For backward-compatibility, though, 0 has special meaning + * (it means match any machine). + */ + uint32_t machine_ctr; uint8_t trunnel_error_code_; }; #endif @@ -118,6 +127,15 @@ uint8_t circpad_negotiate_get_echo_request(const circpad_negotiate_t *inp); * code on 'inp' on failure. */ int circpad_negotiate_set_echo_request(circpad_negotiate_t *inp, uint8_t val); +/** Return the value of the machine_ctr field of the + * circpad_negotiate_t in 'inp' + */ +uint32_t circpad_negotiate_get_machine_ctr(const circpad_negotiate_t *inp); +/** Set the value of the machine_ctr field of the circpad_negotiate_t + * in 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. + */ +int circpad_negotiate_set_machine_ctr(circpad_negotiate_t *inp, uint32_t val); /** Return a newly allocated circpad_negotiated with all elements set * to zero. */ @@ -190,6 +208,15 @@ uint8_t circpad_negotiated_get_machine_type(const circpad_negotiated_t *inp); * -1 and set the error code on 'inp' on failure. */ int circpad_negotiated_set_machine_type(circpad_negotiated_t *inp, uint8_t val); +/** Return the value of the machine_ctr field of the + * circpad_negotiated_t in 'inp' + */ +uint32_t circpad_negotiated_get_machine_ctr(const circpad_negotiated_t *inp); +/** Set the value of the machine_ctr field of the circpad_negotiated_t + * in 'inp' to 'val'. Return 0 on success; return -1 and set the error + * code on 'inp' on failure. + */ +int circpad_negotiated_set_machine_ctr(circpad_negotiated_t *inp, uint32_t val); #endif diff --git a/src/trunnel/circpad_negotiation.trunnel b/src/trunnel/circpad_negotiation.trunnel index abbc929cc5..68fed6a013 100644 --- a/src/trunnel/circpad_negotiation.trunnel +++ b/src/trunnel/circpad_negotiation.trunnel @@ -27,6 +27,13 @@ struct circpad_negotiate { // FIXME-MP-AP: Maybe we just say to transition to the first state // here instead.. Also what about delay before responding? u8 echo_request IN [0,1]; + + // This field is used for shutdown synchronization. It is OK if + // it wraps, because all we need to do is make sure the STOP + // command is actually for the currently active machine. + // For backward-compatibility, though, 0 has special meaning + // (it means match any machine). + u32 machine_ctr; }; /** @@ -41,4 +48,14 @@ struct circpad_negotiated { /** Machine type is left unbounded because we can specify * new machines in the consensus */ u8 machine_type; + + /** + * This field is used for shutdown synchronization. It is OK if + * it wraps, because all we need to do is make sure the STOP + * command is actually for the currently active machine. + * For backward-compatibility, though, 0 has special meaning + * (it means match any machine). + */ + u32 machine_ctr; + }; |