summaryrefslogtreecommitdiff
path: root/src/trunnel
diff options
context:
space:
mode:
authorMike Perry <mikeperry-git@torproject.org>2020-06-08 18:05:34 -0500
committerMike Perry <mikeperry-git@torproject.org>2020-06-08 18:05:34 -0500
commit9eb0eeb68e524b03924ea9b1f11e9b75fcdcf37b (patch)
tree9a36c7018d99bc028af3b30f10a007c25fe729d7 /src/trunnel
parent1d32c3114fa3ebcd4219eba6ad7bb2a57b878511 (diff)
downloadtor-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.c52
-rw-r--r--src/trunnel/circpad_negotiation.h27
-rw-r--r--src/trunnel/circpad_negotiation.trunnel17
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;
+
};