diff options
author | Florent Daigniere <nextgens@freenetproject.org> | 2019-02-23 21:50:04 +0100 |
---|---|---|
committer | Florent Daigniere <nextgens@freenetproject.org> | 2019-02-25 18:20:23 +0100 |
commit | 0c2d06d8a5a6bb61b42857ac2c21c579b11a6f1c (patch) | |
tree | abcd5992aaa3f02f0c0b5e14a4673317b6749fca /receive.go | |
parent | 9e686cd714a371ad5f35f356fe88f018fa5e92e6 (diff) | |
download | wireguard-go-0c2d06d8a5a6bb61b42857ac2c21c579b11a6f1c.tar.gz wireguard-go-0c2d06d8a5a6bb61b42857ac2c21c579b11a6f1c.zip |
net: implement ECN handling, rfc6040 stylefd/propagate-DSCP-bits
To decide whether we should use the compatibility mode or the normal
mode with a peer, we use the handshake messages as a signaling channel.
If we receive the expected ECN bits, it most likely means they're
running a compatible version.
Signed-off-by: Florent Daigniere <nextgens@freenetproject.org>
Diffstat (limited to '')
-rw-r--r-- | receive.go | 19 |
1 files changed, 16 insertions, 3 deletions
@@ -23,6 +23,7 @@ type QueueHandshakeElement struct { packet []byte endpoint Endpoint buffer *[MaxMessageSize]byte + isECNCompatible bool } type QueueInboundElement struct { @@ -33,6 +34,7 @@ type QueueInboundElement struct { counter uint64 keypair *Keypair endpoint Endpoint + tos byte } func (elem *QueueInboundElement) Drop() { @@ -108,6 +110,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) { err error size int endpoint Endpoint + outerTOS byte ) for { @@ -116,9 +119,9 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) { switch IP { case ipv4.Version: - size, endpoint, err = bind.ReceiveIPv4(buffer[:]) + size, endpoint, outerTOS, err = bind.ReceiveIPv4(buffer[:]) case ipv6.Version: - size, endpoint, err = bind.ReceiveIPv6(buffer[:]) + size, endpoint, outerTOS, err = bind.ReceiveIPv6(buffer[:]) default: panic("invalid IP version") } @@ -178,6 +181,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) { elem.endpoint = endpoint elem.counter = 0 elem.Mutex = sync.Mutex{} + elem.tos = outerTOS elem.Lock() // add to decryption queues @@ -213,6 +217,7 @@ func (device *Device) RoutineReceiveIncoming(IP int, bind Bind) { buffer: buffer, packet: packet, endpoint: endpoint, + isECNCompatible: ecn_rfc6040_enabled(outerTOS), }, )) { buffer = device.GetMessageBuffer() @@ -426,7 +431,7 @@ func (device *Device) RoutineHandshake() { peer.SetEndpointFromPacket(elem.endpoint) logDebug.Println(peer, "- Received handshake initiation") - + peer.isECNConfirmed.Set(elem.isECNCompatible) peer.SendHandshakeResponse() case MessageResponseType: @@ -473,6 +478,7 @@ func (device *Device) RoutineHandshake() { peer.timersSessionDerived() peer.timersHandshakeComplete() + peer.isECNConfirmed.Set(elem.isECNCompatible) peer.SendKeepalive() select { case peer.signals.newKeypairArrived <- struct{}{}: @@ -565,6 +571,7 @@ func (peer *Peer) RoutineSequentialReceiver() { } peer.timersDataReceived() + var shouldDrop bool // verify source and strip padding switch elem.packet[0] >> 4 { @@ -595,6 +602,7 @@ func (peer *Peer) RoutineSequentialReceiver() { continue } + elem.tos, shouldDrop = ecn_rfc6040_egress(elem.packet[1], elem.tos) case ipv6.Version: // strip padding @@ -623,10 +631,15 @@ func (peer *Peer) RoutineSequentialReceiver() { continue } + elem.tos, shouldDrop = ecn_rfc6040_egress(elem.packet[1], elem.tos); default: logInfo.Println("Packet with invalid IP version from", peer) continue } + if shouldDrop { + logInfo.Println("ECN/Congestion detected, dropping packet from", peer) + continue + } // write to tun device |