]> Cypherpunks.ru repositories - govpn.git/commitdiff
Ability to generate Constant Packet Rate traffic
authorSergey Matveev <stargrave@stargrave.org>
Fri, 1 May 2015 22:26:39 +0000 (01:26 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Fri, 1 May 2015 22:26:39 +0000 (01:26 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
TODO
cmd/govpn-client/main.go
cmd/govpn-server/main.go
cpr.go [new file with mode: 0644]
doc/cpr.texi [new file with mode: 0644]
doc/overview.texi
doc/user.texi
transport.go

diff --git a/TODO b/TODO
index 63d6ef3c18755c3023c77845ad5ec731d2e0afbf..e1d3d3f321528fe8eb111b8d3c2e5450641d0e5e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,4 @@
 * Increase performance
-* Implement rate-control
 * Probably implement alternative Secure Remote Password protocol to allow
   human memorized passphrases to be used
 * Randomize ports usage
-* Fragmentize packets, noise the traffic
index f6ca4b35b44a34cb9b219c50f975b4a7bcd228cf..9d99f080d42ea4f1ebbd11fe0ce05234ae9b710a 100644 (file)
@@ -42,6 +42,7 @@ var (
        nonceDiff  = flag.Int("noncediff", 1, "Allow nonce difference")
        timeoutP   = flag.Int("timeout", 60, "Timeout seconds")
        noisy      = flag.Bool("noise", false, "Enable noise appending")
+       cpr        = flag.Int("cpr", 0, "Enable constant KiB/s out traffic rate")
 )
 
 func main() {
@@ -54,6 +55,7 @@ func main() {
        govpn.Timeout = time.Second * time.Duration(timeout)
        govpn.Noncediff = *nonceDiff
        govpn.NoiseEnable = *noisy
+       govpn.CPRInit(*cpr)
 
        id := govpn.IDDecode(*IDRaw)
        govpn.PeersInitDummy(id)
index 16462b7072907eec28c31ee14496e69bfe2bed50..ffb6d2325bc507c141d42b9fd88d940a1c7d6889 100644 (file)
@@ -40,6 +40,7 @@ var (
        nonceDiff = flag.Int("noncediff", 1, "Allow nonce difference")
        timeoutP  = flag.Int("timeout", 60, "Timeout seconds")
        noisy     = flag.Bool("noise", false, "Enable noise appending")
+       cpr        = flag.Int("cpr", 0, "Enable constant KiB/s out traffic rate")
 )
 
 type PeerReadyEvent struct {
@@ -87,6 +88,7 @@ func main() {
        govpn.Timeout = timeout
        govpn.Noncediff = *nonceDiff
        govpn.NoiseEnable = *noisy
+       govpn.CPRInit(*cpr)
        govpn.PeersInit(*peersPath)
 
        bind, err := net.ResolveUDPAddr("udp", *bindAddr)
diff --git a/cpr.go b/cpr.go
new file mode 100644 (file)
index 0000000..1b3c1a4
--- /dev/null
+++ b/cpr.go
@@ -0,0 +1,24 @@
+package govpn
+
+import (
+       "net"
+       "time"
+)
+
+type UDPCPR net.UDPConn
+
+var (
+       cprCycle  time.Duration
+       cprEnable bool = false
+)
+
+// Initialize Constant Packet Rate. rate is KiB/s.
+func CPRInit(rate int) {
+       if rate <= 0 {
+               return
+       }
+       NoiseEnable = true
+       cprEnable = true
+       cprCycle = time.Second / time.Duration(rate*(1<<10)/MTU)
+       heartbeatPeriod = cprCycle
+}
diff --git a/doc/cpr.texi b/doc/cpr.texi
new file mode 100644 (file)
index 0000000..70572bf
--- /dev/null
@@ -0,0 +1,10 @@
+@node CPR
+@section CPR
+
+Constant Packet Rate is used to hide fact of underlying payload packets
+appearance. In this mode daemon inserts necessary dummy packets and
+delays other ones.
+
+This mode is turned by @code{-cpr} option, where you specify desired
+outgoing traffic rate in KiB/s (kibibytes per second). This option also
+forces using of the @ref{Noise}! It is turned off by default.
index 406ab288fdef1ad8b6344080bb89445d202f0b27..517e0e7f210d93bc4efe0f992078062665068e6d 100644 (file)
@@ -30,6 +30,10 @@ Server can work with several clients simultaneously. Each client is
 @strong{identified} by 128-bit key, that does not leak during handshake
 and each client stays @strong{anonymous} for MiTM and DPI.
 
+Optional ability to hide payload packets lengths by appending
+@strong{noise} to them during transmission. Ability to generate constant
+packet rate traffic (@strong{CPR}) that will hide even the fact of
+packets appearance.
 
 The only platform specific requirement is TAP network interface support.
 API to that kind of device is different, OS dependent and non portable.
@@ -57,6 +61,7 @@ network interfaces on top of UDP entirely
 @item Built-in rehandshake and heartbeat features
 @item Several simultaneous clients support
 @item Hiding of payload packets length by noise appending
+@item Hiding of payload packets appearance with constant packet rate traffic
 @item Optional built-in HTTP-server for retrieving information about
 known connected peers in @url{http://json.org/, JSON} format
 @end itemize
index b5ebd8fdd67af90b99411ad514c0962aba07b25e..075f2991bedea3905cdc0ed736645b0eac41cd2d 100644 (file)
@@ -18,6 +18,7 @@ automate it using up and down shell scripts.
 * Server part::
 * Stats::
 * Noise::
+* CPR::
 * Example usage::
 @end menu
 
@@ -35,4 +36,6 @@ automate it using up and down shell scripts.
 
 @include noise.texi
 
+@include cpr.texi
+
 @include example.texi
index 904d3f1f56f9936c3f1f4d90e38a08fac515a226..7379d680f64fd94e6b6f62d4c9c9930eabb77dce 100644 (file)
@@ -57,6 +57,7 @@ type Peer struct {
        NonceCipher     *xtea.Cipher   `json:"-"`
        LastPing        time.Time
        LastSent        time.Time
+       willSentCycle   time.Time
        buf             []byte
        tag             *[poly1305.TagSize]byte
        keyAuth         *[KeySize]byte
@@ -314,6 +315,14 @@ func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
 
        p.BytesOut += int64(len(p.frame) + poly1305.TagSize)
        p.FramesOut++
+
+       if cprEnable {
+               p.willSentCycle = p.LastSent.Add(cprCycle)
+               if p.willSentCycle.After(now) {
+                       time.Sleep(p.willSentCycle.Sub(now))
+                       now = p.willSentCycle
+               }
+       }
        p.LastSent = now
        if _, err := conn.WriteTo(append(p.frame, p.tag[:]...), p.Addr); err != nil {
                log.Println("Error sending UDP", err)