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 /misc.go | |
parent | 9e686cd714a371ad5f35f356fe88f018fa5e92e6 (diff) | |
download | wireguard-go-fd/propagate-DSCP-bits.tar.gz wireguard-go-fd/propagate-DSCP-bits.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 'misc.go')
-rw-r--r-- | misc.go | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -46,3 +46,62 @@ func min(a, b uint) uint { } return a } + +// called from receive +func ecn_rfc6040_egress(inner byte, outer byte) (byte, bool) { + /* + +---------+------------------------------------------------+ + |Arriving | Arriving Outer Header | + | Inner +---------+------------+------------+------------+ + | Header | Not-ECT | ECT(0) | ECT(1) | CE | + +---------+---------+------------+------------+------------+ + | Not-ECT | Not-ECT |Not-ECT(!!!)|Not-ECT(!!!)| <drop>(!!!)| + | ECT(0) | ECT(0) | ECT(0) | ECT(1) | CE | + | ECT(1) | ECT(1) | ECT(1) (!) | ECT(1) | CE | + | CE | CE | CE | CE(!!!)| CE | + +---------+---------+------------+------------+------------+ + */ + innerECN := CongestionExperienced & inner + outerECN := CongestionExperienced & outer + + switch outerECN { + case CongestionExperienced: + switch innerECN { + case NotECNTransport: + return 0, true + } + return (inner & (CongestionExperienced ^ 255)) | CongestionExperienced, false + case ECNTransport1: + switch innerECN { + case ECNTransport0: + return (inner & (CongestionExperienced ^ 255)) | ECNTransport1, false + } + } + return inner, false +} + +// called from send +func ecn_rfc6040_ingress(inner byte, useNormalMode bool) byte { + /* + +-----------------+-------------------------------+ + | Incoming Header | Departing Outer Header | + | (also equal to +---------------+---------------+ + | departing Inner | Compatibility | Normal | + | Header) | Mode | Mode | + +-----------------+---------------+---------------+ + | Not-ECT | Not-ECT | Not-ECT | + | ECT(0) | Not-ECT | ECT(0) | + | ECT(1) | Not-ECT | ECT(1) | + | CE | Not-ECT | CE | + +-----------------+---------------+---------------+ + */ + if !useNormalMode { + inner &= (CongestionExperienced ^ 255) + } + + return inner +} + +func ecn_rfc6040_enabled(tos byte) bool { + return (CongestionExperienced & tos) == ECNTransport0 +} |