]> 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
 * Increase performance
-* Implement rate-control
 * Probably implement alternative Secure Remote Password protocol to allow
   human memorized passphrases to be used
 * Randomize ports usage
 * 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")
        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() {
 )
 
 func main() {
@@ -54,6 +55,7 @@ func main() {
        govpn.Timeout = time.Second * time.Duration(timeout)
        govpn.Noncediff = *nonceDiff
        govpn.NoiseEnable = *noisy
        govpn.Timeout = time.Second * time.Duration(timeout)
        govpn.Noncediff = *nonceDiff
        govpn.NoiseEnable = *noisy
+       govpn.CPRInit(*cpr)
 
        id := govpn.IDDecode(*IDRaw)
        govpn.PeersInitDummy(id)
 
        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")
        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 {
 )
 
 type PeerReadyEvent struct {
@@ -87,6 +88,7 @@ func main() {
        govpn.Timeout = timeout
        govpn.Noncediff = *nonceDiff
        govpn.NoiseEnable = *noisy
        govpn.Timeout = timeout
        govpn.Noncediff = *nonceDiff
        govpn.NoiseEnable = *noisy
+       govpn.CPRInit(*cpr)
        govpn.PeersInit(*peersPath)
 
        bind, err := net.ResolveUDPAddr("udp", *bindAddr)
        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.
 
 @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.
 
 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 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
 @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::
 * Server part::
 * Stats::
 * Noise::
+* CPR::
 * Example usage::
 @end menu
 
 * Example usage::
 @end menu
 
@@ -35,4 +36,6 @@ automate it using up and down shell scripts.
 
 @include noise.texi
 
 
 @include noise.texi
 
+@include cpr.texi
+
 @include example.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
        NonceCipher     *xtea.Cipher   `json:"-"`
        LastPing        time.Time
        LastSent        time.Time
+       willSentCycle   time.Time
        buf             []byte
        tag             *[poly1305.TagSize]byte
        keyAuth         *[KeySize]byte
        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++
 
        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)
        p.LastSent = now
        if _, err := conn.WriteTo(append(p.frame, p.tag[:]...), p.Addr); err != nil {
                log.Println("Error sending UDP", err)