We now first exchange a very minimal header, consisting of just the
name of the protocol ("weave") and the min and max version (encoded as
a byte each) we support. This leaves all other details of the
protocol, including the contents of of the handshake, open.
Peers agree to communicate using the maximum mutually supported
version. We record this in the LocalConnection, though atm nothing is
making use of that information.
We set a shorter than normal deadline (10s instead of 60s) for the
header exchange, so we detect version mismatches, garbage, or
non-responsive remotes quickly.
We reset the protocol version to '1' since this is a fresh start; old
weaves will not be able to parse the header.
Closes#871.
Instead of erroring when we receive gossip for an unknown channel, we
create a GossipChannel on the fly, with a SurrogateGossiper singleton
as the gossiper.
The SurrogateGossiper ignores unicasts and relays broadcasts and
gossip.
and take extra locks to avoid race conditions.
Also removed the sendPendingGossip() from mockChannelConnection.SendProtocolMsg(),
because waiting in flush now creates a deadlock. Tests will have to
call sendPendingGossip() explicitly if they need it.
This is how fragmentation tests used to happen:
A: conn.stackFrag = false
A->B: StartFragmentationTest
B->A: send large non-DF UDP packet
A->B: FragmentationReceived
B: conn.stackFrag = true
conn.stackFrag = true means "UDP packets sent to the other peer get
correctly fragmented and re-assembled".
Note how A clears its own stackFrag flag, but the test establishes
whether fragmentation works for B->A, and ends up setting stackFrag on
B. Not only is this weird, it also means that if A previously had
stackFrag=true, it will now start fragmenting packets until B
initiates a fragmentation test.
The new sequence is:
A: conn.stackFrag = false
A->B: send large non-DF UDP packet
B->A: FragmentationReceived
A: conn.stackFrag = true
Closes#746.
The main purpose of this is to set an upper bound on the rate at which
an attacker might execute a brute force attack on the weave password.
No need to get clever or precise here.
Closes#837.
The delay d(n) for the nth retry was
d(1) = rand(initial_interval)
d(n+1) = d(n) + rand(d(n))
There are two problem with this:
1) The entire sequence is dominated by the random value for d(1). If
this is a small value, lots of retries at short interval ensue. In
extremis, if d(1) is 0, indefinite immediate retries would ensue.
2) The delay is not a true exponential backoff; the upper bound only
increases exponentially *probabilistically*.
The new algorithm calculates
d(n) = random_value in range [i-i/2,i+i/2],
where i = initial_interval * 1.5^(n-1).
Thus d(1) is at least initial_interval/2, and successive values are
independent of previous values, forming a true exponential sequence of
intervals bounds between which the retry delay is chosen randomly.
Due to the change in algorithm we reduce...
- the initial interval from 5s to 2s. Recall that previously d(1) was
in the range [0,initial_interval=5s]. It is now [2-2/2=1s,2+2/2=3s].
- the max interval from 10 minutes to 6. Previously, once that was
reached, it would stay exactly there. It is now randomly chosen in
the range [6-6/2=3m,6+6/2=9min].
Thus previously delays would range from 0 to 10 minutes, now they
range from 1s to 9 minutes.
Fixes#412.
From the golang spec: 'A "break" statement terminates execution of the
innermost "for", "switch", or "select" statement within the same
function.' But the LocalConnection actorLoop seems to assume it
skips the "select" and terminates the enclosing "for".
As a result, if something did conn.Shutdown(nil), it would not actually
shutdown the connection. It turns out this is never a problem, because
Shutdown is always called with a non-nil error, even though there is code
in a few places to handle the nil case. By cleaning that up, the dubious
"break" is eliminated.
Using the Ring CRDT and Weave gossip, provides an interface
for the weave script to allocate IP addresses in `weave run`,
`weave start` and `weave expose`.
See docs/ipam.md for implementation details, and site/features.md
for user-visible changes.