* 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
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() {
govpn.Timeout = time.Second * time.Duration(timeout)
govpn.Noncediff = *nonceDiff
govpn.NoiseEnable = *noisy
+ govpn.CPRInit(*cpr)
id := govpn.IDDecode(*IDRaw)
govpn.PeersInitDummy(id)
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 {
govpn.Timeout = timeout
govpn.Noncediff = *nonceDiff
govpn.NoiseEnable = *noisy
+ govpn.CPRInit(*cpr)
govpn.PeersInit(*peersPath)
bind, err := net.ResolveUDPAddr("udp", *bindAddr)
--- /dev/null
+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
+}
--- /dev/null
+@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.
@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.
@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
* Server part::
* Stats::
* Noise::
+* CPR::
* Example usage::
@end menu
@include noise.texi
+@include cpr.texi
+
@include example.texi
NonceCipher *xtea.Cipher `json:"-"`
LastPing time.Time
LastSent time.Time
+ willSentCycle time.Time
buf []byte
tag *[poly1305.TagSize]byte
keyAuth *[KeySize]byte
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)