aboutsummaryrefslogtreecommitdiff
path: root/misc.go
diff options
context:
space:
mode:
authorFlorent Daigniere <nextgens@freenetproject.org>2019-02-23 21:50:04 +0100
committerFlorent Daigniere <nextgens@freenetproject.org>2019-02-25 18:20:23 +0100
commit0c2d06d8a5a6bb61b42857ac2c21c579b11a6f1c (patch)
treeabcd5992aaa3f02f0c0b5e14a4673317b6749fca /misc.go
parent9e686cd714a371ad5f35f356fe88f018fa5e92e6 (diff)
downloadwireguard-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.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/misc.go b/misc.go
index 6786cb5..e5688a5 100644
--- a/misc.go
+++ b/misc.go
@@ -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
+}