Currently we cannot distinguish bi-directional and uni-directional connectivity between peers. This is what currently happens for a connection from A to B... A: remoteUDPAddr=X B: remoteUDPAddr=nil A: send fast heartbeats over UDP B: receive heartbeat; remoteUDPAddr is nil remoteUDPAddr=Y send 'established' over TCP established=true send slow heartbeats over UDP A: receive 'established' over TCP established=true send slow heartbeats over UDP If udp packets make it through from A to B but not B to A then both ends mark the connection as 'established'. Conversely, if udp packets make it through from B to A but not A to B then the connection is not marked as 'established' at either end. In the new scheme, this is what happens... A: receivedHeartbeat=false, remoteUDPAddr=X B: receivedHeartbeat=false, remoteUDPAddr=nil A: send fast heartbeats over UDP B: receive heartbeat; receivedHeartbeat is false remoteUDPAddr=Y receivedHeartbeat=true send 'established' over TCP send fast heartbeats over UDP A: receive 'established' over TCP (*) established=true send slow heartbeats over UDP A: receive heartbeat; receivedHeartbeat is false (*) receivedHeartbeat=true send 'established' over TCP B: receive 'established' over TCP established=true send slow heartbeats over UDP (*) either of these may occur first Now, if udp packets make it through from A to B not not B to A then A marks the connection as 'established' but B doesn't. Conversely, if udp packets make it through from B to A but not A to B then B marks the connection as 'established' but A doesn't.
52 lines
1.5 KiB
Go
52 lines
1.5 KiB
Go
package router
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
Protocol = "weave"
|
|
ProtocolVersion = 9
|
|
EthernetOverhead = 14
|
|
UDPOverhead = 28 // 20 bytes for IPv4, 8 bytes for UDP
|
|
Port = 6783
|
|
HttpPort = Port + 1
|
|
DefaultPMTU = 65535
|
|
MaxUDPPacketSize = 65536
|
|
ChannelSize = 16
|
|
UDPNonceSendAt = 8192
|
|
FragTestSize = 60001
|
|
PMTUDiscoverySize = 60000
|
|
FastHeartbeat = 500 * time.Millisecond
|
|
SlowHeartbeat = 10 * time.Second
|
|
FetchAllInterval = 30 * time.Second
|
|
FragTestInterval = 5 * time.Minute
|
|
ReadTimeout = 2 * FetchAllInterval
|
|
PMTUVerifyAttempts = 8
|
|
PMTUVerifyTimeout = 10 * time.Millisecond // gets doubled with every attempt
|
|
MaxDuration = time.Duration(math.MaxInt64)
|
|
)
|
|
|
|
const (
|
|
ProtocolConnectionEstablished = iota
|
|
ProtocolFragmentationReceived
|
|
ProtocolStartFragmentationTest
|
|
ProtocolNonce
|
|
ProtocolFetchAll
|
|
ProtocolUpdate
|
|
ProtocolPMTUVerified
|
|
)
|
|
|
|
var (
|
|
FragTest = make([]byte, FragTestSize)
|
|
PMTUDiscovery = make([]byte, PMTUDiscoverySize)
|
|
ProtocolConnectionEstablishedByte = []byte{ProtocolConnectionEstablished}
|
|
ProtocolFragmentationReceivedByte = []byte{ProtocolFragmentationReceived}
|
|
ProtocolStartFragmentationTestByte = []byte{ProtocolStartFragmentationTest}
|
|
ProtocolNonceByte = []byte{ProtocolNonce}
|
|
ProtocolFetchAllByte = []byte{ProtocolFetchAll}
|
|
ProtocolUpdateByte = []byte{ProtocolUpdate}
|
|
ProtocolPMTUVerifiedByte = []byte{ProtocolPMTUVerified}
|
|
)
|