]> Cypherpunks.ru repositories - govpn.git/commitdiff
Per-peer timeout, noncediff, noise, cpr settings
authorSergey Matveev <stargrave@stargrave.org>
Sat, 2 May 2015 11:51:53 +0000 (14:51 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 2 May 2015 13:36:31 +0000 (16:36 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
12 files changed:
cmd/govpn-client/main.go
cmd/govpn-server/main.go
common.go
cpr.go [deleted file]
doc/client.texi
doc/cpr.texi
doc/overview.texi
doc/server.texi
doc/user.texi
identify.go
transport.go
transport_test.go

index 9d99f080d42ea4f1ebbd11fe0ce05234ae9b710a..30ba8e90a76709fdc9556025bb14e7340a18f08b 100644 (file)
@@ -42,7 +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")
+       cpr        = flag.Int("cpr", 0, "Enable constant KiB/sec out traffic rate")
 )
 
 func main() {
 )
 
 func main() {
@@ -52,13 +52,15 @@ func main() {
        log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
 
        govpn.MTU = *mtu
        log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
 
        govpn.MTU = *mtu
-       govpn.Timeout = time.Second * time.Duration(timeout)
-       govpn.Noncediff = *nonceDiff
-       govpn.NoiseEnable = *noisy
-       govpn.CPRInit(*cpr)
 
        id := govpn.IDDecode(*IDRaw)
 
        id := govpn.IDDecode(*IDRaw)
-       govpn.PeersInitDummy(id)
+       govpn.PeersInitDummy(id, govpn.PeerConf{
+               Id:          id,
+               Timeout:     time.Second * time.Duration(timeout),
+               Noncediff:   *nonceDiff,
+               NoiseEnable: *noisy,
+               CPR:         *cpr,
+       })
        key := govpn.KeyRead(*keyPath)
        if id == nil {
                panic("ID is not specified")
        key := govpn.KeyRead(*keyPath)
        if id == nil {
                panic("ID is not specified")
@@ -77,7 +79,11 @@ func main() {
                panic(err)
        }
 
                panic(err)
        }
 
-       tap, ethSink, ethReady, _, err := govpn.TAPListen(*ifaceName)
+       tap, ethSink, ethReady, _, err := govpn.TAPListen(
+               *ifaceName,
+               time.Second*time.Duration(timeout),
+               *cpr,
+       )
        if err != nil {
                panic(err)
        }
        if err != nil {
                panic(err)
        }
index ffb6d2325bc507c141d42b9fd88d940a1c7d6889..6697f2b42351229f4711af3a212ba485f3658585 100644 (file)
@@ -37,10 +37,6 @@ var (
        peersPath = flag.String("peers", "peers", "Path to peers keys directory")
        stats     = flag.String("stats", "", "Enable stats retrieving on host:port")
        mtu       = flag.Int("mtu", 1452, "MTU for outgoing packets")
        peersPath = flag.String("peers", "peers", "Path to peers keys directory")
        stats     = flag.String("stats", "", "Enable stats retrieving on host:port")
        mtu       = flag.Int("mtu", 1452, "MTU for outgoing packets")
-       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 {
@@ -57,7 +53,7 @@ type PeerState struct {
 }
 
 func NewPeerState(peer *govpn.Peer, iface string) *PeerState {
 }
 
 func NewPeerState(peer *govpn.Peer, iface string) *PeerState {
-       tap, sink, ready, terminate, err := govpn.TAPListen(iface)
+       tap, sink, ready, terminate, err := govpn.TAPListen(iface, peer.Timeout, peer.CPR)
        if err != nil {
                log.Println("Unable to create Eth", err)
                return nil
        if err != nil {
                log.Println("Unable to create Eth", err)
                return nil
@@ -80,15 +76,11 @@ type EthEvent struct {
 
 func main() {
        flag.Parse()
 
 func main() {
        flag.Parse()
-       timeout := time.Second * time.Duration(*timeoutP)
+       timeout := time.Second * time.Duration(govpn.TimeoutDefault)
        var err error
        log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
 
        govpn.MTU = *mtu
        var err error
        log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
 
        govpn.MTU = *mtu
-       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)
index e5ff496fac91da78690202993a476cc8c3961c65..b87133a59a2ca80c6c16182b5a0c998ecd18029d 100644 (file)
--- a/common.go
+++ b/common.go
@@ -25,15 +25,15 @@ import (
        "os"
        "os/exec"
        "runtime"
        "os"
        "os/exec"
        "runtime"
-       "time"
+)
+
+const (
+       TimeoutDefault = 60
 )
 
 var (
 )
 
 var (
-       MTU         int
-       Timeout     time.Duration
-       Noncediff   int
-       Version     string
-       NoiseEnable bool = false
+       MTU     int
+       Version string
 )
 
 // Call external program/script.
 )
 
 // Call external program/script.
diff --git a/cpr.go b/cpr.go
deleted file mode 100644 (file)
index 1b3c1a4..0000000
--- a/cpr.go
+++ /dev/null
@@ -1,24 +0,0 @@
-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
-}
index 52f6429888f5071121a0b17a298fab72fb4ee22e..3cb89279101cdf747ae8ceac08daf3e513b7bb6f 100644 (file)
@@ -1,24 +1,43 @@
 @node Client part
 @section Client part
 
 @node Client part
 @section Client part
 
-Except for common @code{-mtu}, @code{-noncediff}, @code{-timeout},
-@code{-stats}, @code{-noise} options client has the following ones:
+Except for common @code{-mtu}, @code{-stats}, options client has the
+following ones:
 
 @table @code
 
 @table @code
+
 @item -remote
 Address (@code{host:port} format) of remote server we need to connect to.
 @item -remote
 Address (@code{host:port} format) of remote server we need to connect to.
+
 @item -iface
 TAP interface name.
 @item -iface
 TAP interface name.
+
 @item -id
 Our client's identification (hexadecimal string).
 @item -id
 Our client's identification (hexadecimal string).
+
 @item -key
 Path to the file with the PSK key.
 @item -key
 Path to the file with the PSK key.
+
+@item -timeout
+@ref{Timeout} setting in seconds.
+
+@item -noncediff
+Allowable @ref{Nonce difference}.
+
+@item -noise
+Enable @ref{Noise}.
+
+@item -cpr
+Enable @ref{CPR} in KiB/sec.
+
 @item -up
 Optional path to script that will be executed after connection is
 established. Interface name will be given to it as a first argument.
 @item -up
 Optional path to script that will be executed after connection is
 established. Interface name will be given to it as a first argument.
+
 @item -down
 Same as @code{-up} above, but it is executed when connection is lost,
 when we exit.
 @item -down
 Same as @code{-up} above, but it is executed when connection is lost,
 when we exit.
+
 @end table
 
 Example up-script that calls DHCP client and IPv6 advertisement
 @end table
 
 Example up-script that calls DHCP client and IPv6 advertisement
index 70572bfeb3f7da0b47d00919b76ae61c4a9078e6..88339dbad43dbbbb1e898d7d39c038dc59a52ac4 100644 (file)
@@ -6,5 +6,5 @@ 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
 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
+outgoing traffic rate in KiB/sec (kibibytes per second). This option also
 forces using of the @ref{Noise}! It is turned off by default.
 forces using of the @ref{Noise}! It is turned off by default.
index 4616af776186dbb195d4e8d3e319d4d4fdca7c3e..1886f0318e0de5bd61e37fe0757da3c75e9eb7c5 100644 (file)
@@ -6,8 +6,10 @@ on @url{http://golang.org/, Go programming language}.
 
 Reviewability, high 128-bit security margin and
 @url{https://en.wikipedia.org/wiki/Deep_packet_inspection, DPI}
 
 Reviewability, high 128-bit security margin and
 @url{https://en.wikipedia.org/wiki/Deep_packet_inspection, DPI}
-resistance in mind in free software solution are the main goals
-for that daemon.
+censorship resistance in mind in free software solution are the main
+goals for that daemon. Most modern widespread protocols and their
+implementations in software are too complex to be reviewed, analyzed and
+modified.
 
 State off art cryptography technologies include:
 @url{http://cr.yp.to/snuffle.html, Salsa20} stream encryption,
 
 State off art cryptography technologies include:
 @url{http://cr.yp.to/snuffle.html, Salsa20} stream encryption,
@@ -28,7 +30,8 @@ one-time keys protects against
 
 Server can work with several clients simultaneously. Each client is
 @strong{identified} by 128-bit key, that does not leak during handshake
 
 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.
+and each client stays @strong{anonymous} for MiTM and DPI. All settings
+are applied per-peer separately.
 
 Optional ability to hide payload packets lengths by appending
 @strong{noise} to them during transmission. Ability to generate constant
 
 Optional ability to hide payload packets lengths by appending
 @strong{noise} to them during transmission. Ability to generate constant
@@ -60,6 +63,7 @@ network interfaces on top of UDP entirely
 @item Zero knowledge authentication
 @item Built-in rehandshake and heartbeat features
 @item Several simultaneous clients support
 @item Zero knowledge authentication
 @item Built-in rehandshake and heartbeat features
 @item Several simultaneous clients support
+@item Per-client configuration options
 @item Hiding of payload packets length with noise
 @item Hiding of payload packets appearance with constant packet rate traffic
 @item Optional built-in HTTP-server for retrieving information about
 @item Hiding of payload packets length with noise
 @item Hiding of payload packets appearance with constant packet rate traffic
 @item Optional built-in HTTP-server for retrieving information about
index 69fee73defacb1319bdb99e56f2eaa46c0694d78..4fd074c0d391d220a6b1b328994c733e1fd3bbb4 100644 (file)
@@ -1,8 +1,8 @@
 @node Server part
 @section Server part
 
 @node Server part
 @section Server part
 
-Except for common @code{-mtu}, @code{-noncediff}, @code{-timeout},
-@code{-stats}, @code{-noise} options server has the following ones:
+Except for common @code{-mtu}, @code{-stats}, options server has the
+following ones:
 
 @table @code
 @item -bind
 
 @table @code
 @item -bind
@@ -11,24 +11,51 @@ Address (@code{host:port} format) we must bind to.
 Path to the directory containing peers information, database.
 @end table
 
 Path to the directory containing peers information, database.
 @end table
 
-Peers directory must contain subdirectories with the names of client's identities
-in hexadecimal notation. Each of those subdirectories must have
-@strong{key} file with the corresponding authentication key,
-@strong{up.sh} script that executes each time connection with the client
-establishes, optional @code{name} file containing human readable
-client's name and optional @code{down.sh} that executes during
-connection lost.
+Peers directory must contain subdirectories with the names of client's
+identities in hexadecimal notation. Each subdirectory has the following
+files:
 
 
-@code{up.sh} script @strong{must} print on the first stdout line the
-name of TAP interface. This script can be simple @code{echo tap10},
-maybe more advanced with dynamic interface creation:
+@table @code
 
 
-@example
-#!/bin/sh
-$tap=$(ifconfig tap create)
-ifconfig $tap inet6 fc00::1/96 mtu 1412 up
-echo $tap
-@end example
+@item key
+@strong{Required}. Contains corresponding authentication PSK key in
+hexadecimal notation.
+
+@item up.sh
+@strong{Required}. up-script executes each time connection with the
+client is established. It's @emph{stdout} output must contain TAP
+interface name on the first string. This script can be simple
+@code{echo tap10}, or maybe more advanced like this:
+    @example
+    #!/bin/sh
+    $tap=$(ifconfig tap create)
+    ifconfig $tap inet6 fc00::1/96 mtu 1412 up
+    echo $tap
+    @end example
+
+@item down.sh
+Optional. Same as @code{up.sh} above, but executes when connection is
+lost.
+
+@item name
+Optional. Contains human readable username. Used to beauty output of
+@ref{Stats}.
+
+@item timeout
+Optional. Contains @ref{Timeout} setting (decimal notation) in seconds.
+Otherwise default minute timeout will be used.
+
+@item noncediff
+Optional. Contains allowable @ref{Nonce difference} setting (decimal
+notation).
+
+@item noise
+Optional. Contains either "1" (enable @ref{Noise} adding), or "0".
+
+@item cpr
+Optional. Contains @ref{CPR} setting (decimal notation) in KiB/sec.
+
+@end table
 
 Each minute server refreshes peers directory contents and adds newly
 appeared identities, deletes an obsolete ones.
 
 Each minute server refreshes peers directory contents and adds newly
 appeared identities, deletes an obsolete ones.
index 075f2991bedea3905cdc0ed736645b0eac41cd2d..a77fd8ad6afcba0ee5031eac83d53c7a72987942 100644 (file)
@@ -14,11 +14,11 @@ automate it using up and down shell scripts.
 * Timeout::
 * Nonce difference::
 * MTU::
 * Timeout::
 * Nonce difference::
 * MTU::
-* Client part::
-* Server part::
 * Stats::
 * Noise::
 * CPR::
 * Stats::
 * Noise::
 * CPR::
+* Client part::
+* Server part::
 * Example usage::
 @end menu
 
 * Example usage::
 @end menu
 
@@ -28,14 +28,14 @@ automate it using up and down shell scripts.
 
 @include mtu.texi
 
 
 @include mtu.texi
 
-@include client.texi
-
-@include server.texi
-
 @include stats.texi
 
 @include noise.texi
 
 @include cpr.texi
 
 @include stats.texi
 
 @include noise.texi
 
 @include cpr.texi
 
+@include client.texi
+
+@include server.texi
+
 @include example.texi
 @include example.texi
index 6c16da08a2a3c1cc124f0b0995b99142e24aad59..d6a324f0ce3d68c7340df1b948fd64f1f69527a2 100644 (file)
@@ -25,6 +25,7 @@ import (
        "log"
        "os"
        "path"
        "log"
        "os"
        "path"
+       "strconv"
        "strings"
        "sync"
        "time"
        "strings"
        "sync"
        "time"
@@ -53,12 +54,21 @@ func (id PeerId) MarshalJSON() ([]byte, error) {
        return []byte(`"` + result + `"`), nil
 }
 
        return []byte(`"` + result + `"`), nil
 }
 
+type PeerConf struct {
+       Id          *PeerId
+       Timeout     time.Duration
+       Noncediff   int
+       NoiseEnable bool
+       CPR         int
+}
+
 type cipherCache map[PeerId]*xtea.Cipher
 
 var (
        PeersPath       string
        IDsCache        cipherCache
        cipherCacheLock sync.RWMutex
 type cipherCache map[PeerId]*xtea.Cipher
 
 var (
        PeersPath       string
        IDsCache        cipherCache
        cipherCacheLock sync.RWMutex
+       dummyConf       *PeerConf
 )
 
 // Initialize (pre-cache) available peers info.
 )
 
 // Initialize (pre-cache) available peers info.
@@ -73,15 +83,15 @@ func PeersInit(path string) {
        }()
 }
 
        }()
 }
 
-// Initialize dummy cache for client-side usage. It will consist only
-// of single key.
-func PeersInitDummy(id *PeerId) {
+// Initialize dummy cache for client-side usage.
+func PeersInitDummy(id *PeerId, conf PeerConf) {
        IDsCache = make(map[PeerId]*xtea.Cipher)
        cipher, err := xtea.NewCipher(id[:])
        if err != nil {
                panic(err)
        }
        IDsCache[*id] = cipher
        IDsCache = make(map[PeerId]*xtea.Cipher)
        cipher, err := xtea.NewCipher(id[:])
        if err != nil {
                panic(err)
        }
        IDsCache[*id] = cipher
+       dummyConf = &conf
 }
 
 // Refresh IDsCache: remove disappeared keys, add missing ones with
 }
 
 // Refresh IDsCache: remove disappeared keys, add missing ones with
@@ -147,6 +157,44 @@ func (cc cipherCache) Find(data []byte) *PeerId {
        return nil
 }
 
        return nil
 }
 
+func readIntFromFile(path string) (int, error) {
+       data, err := ioutil.ReadFile(path)
+       if err != nil {
+               return 0, err
+       }
+       val, err := strconv.Atoi(strings.TrimRight(string(data), "\n"))
+       if err != nil {
+               return 0, err
+       }
+       return val, nil
+}
+
+// Get peer related configuration.
+func (id *PeerId) ConfGet() *PeerConf {
+       if dummyConf != nil {
+               return dummyConf
+       }
+       conf := PeerConf{Id: id, Noncediff: 1, NoiseEnable: false, CPR: 0}
+       peerPath := path.Join(PeersPath, id.String())
+
+       timeout := TimeoutDefault
+       if val, err := readIntFromFile(path.Join(peerPath, "timeout")); err == nil {
+               timeout = val
+       }
+       conf.Timeout = time.Second * time.Duration(timeout)
+
+       if val, err := readIntFromFile(path.Join(peerPath, "noncediff")); err == nil {
+               conf.Noncediff = val
+       }
+       if val, err := readIntFromFile(path.Join(peerPath, "noise")); err == nil && val == 1 {
+               conf.NoiseEnable = true
+       }
+       if val, err := readIntFromFile(path.Join(peerPath, "cpr")); err == nil {
+               conf.CPR = val
+       }
+       return &conf
+}
+
 // Decode identification string.
 // It must be 32 hexadecimal characters long.
 // If it is not the valid one, then return nil.
 // Decode identification string.
 // It must be 32 hexadecimal characters long.
 // If it is not the valid one, then return nil.
index 6065c5eb219f3411664eded9d1f8965b78d2f2aa..f13c50349276977da1fb07c328cd4f562421f6cb 100644 (file)
@@ -49,23 +49,38 @@ type UDPPkt struct {
 }
 
 type Peer struct {
 }
 
 type Peer struct {
-       Addr            *net.UDPAddr
-       Id              PeerId
-       Key             *[KeySize]byte `json:"-"`
-       NonceOur        uint64         `json:"-"`
-       NonceRecv       uint64         `json:"-"`
-       NonceCipher     *xtea.Cipher   `json:"-"`
-       Established     time.Time
-       LastPing        time.Time
-       LastSent        time.Time
-       willSentCycle   time.Time
-       buf             []byte
-       tag             *[poly1305.TagSize]byte
-       keyAuth         *[KeySize]byte
-       nonceRecv       uint64
-       frame           []byte
-       nonce           []byte
-       pktSize         uint64
+       Addr *net.UDPAddr
+       Id   PeerId
+
+       // Traffic behaviour
+       NoiseEnable bool
+       CPR         int
+       CPRCycle    time.Duration `json:"-"`
+
+       // Cryptography related
+       Key         *[KeySize]byte `json:"-"`
+       Noncediff   int
+       NonceOur    uint64       `json:"-"`
+       NonceRecv   uint64       `json:"-"`
+       NonceCipher *xtea.Cipher `json:"-"`
+
+       // Timers
+       Timeout       time.Duration `json:"-"`
+       Established   time.Time
+       LastPing      time.Time
+       LastSent      time.Time
+       willSentCycle time.Time
+
+       // This variables are initialized only once to relief GC
+       buf       []byte
+       tag       *[poly1305.TagSize]byte
+       keyAuth   *[KeySize]byte
+       nonceRecv uint64
+       frame     []byte
+       nonce     []byte
+       pktSize   uint64
+
+       // Statistics
        BytesIn         int64
        BytesOut        int64
        BytesPayloadIn  int64
        BytesIn         int64
        BytesOut        int64
        BytesPayloadIn  int64
@@ -93,25 +108,17 @@ func (p *Peer) Zero() {
 }
 
 var (
 }
 
 var (
-       Emptiness       = make([]byte, 1<<14)
-       taps            = make(map[string]*TAP)
-       heartbeatPeriod time.Duration
+       Emptiness = make([]byte, 1<<14)
+       taps      = make(map[string]*TAP)
 )
 
 )
 
-func heartbeatPeriodGet() time.Duration {
-       if heartbeatPeriod == time.Duration(0) {
-               heartbeatPeriod = Timeout / TimeoutHeartbeat
-       }
-       return heartbeatPeriod
-}
-
 // Create TAP listening goroutine.
 // This function takes required TAP interface name, opens it and allocates
 // a buffer where all frame data will be written, channel where information
 // about number of read bytes is sent to, synchronization channel (external
 // processes tell that read buffer can be used again) and possible channel
 // opening error.
 // Create TAP listening goroutine.
 // This function takes required TAP interface name, opens it and allocates
 // a buffer where all frame data will be written, channel where information
 // about number of read bytes is sent to, synchronization channel (external
 // processes tell that read buffer can be used again) and possible channel
 // opening error.
-func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{}, error) {
+func TAPListen(ifaceName string, timeout time.Duration, cpr int) (*TAP, chan []byte, chan struct{}, chan struct{}, error) {
        var tap *TAP
        var err error
        tap, exists := taps[ifaceName]
        var tap *TAP
        var err error
        tap, exists := taps[ifaceName]
@@ -128,7 +135,13 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{
        sinkSkip := make(chan struct{})
 
        go func() {
        sinkSkip := make(chan struct{})
 
        go func() {
-               heartbeat := time.Tick(heartbeatPeriodGet())
+               cprCycle := cprCycleCalculate(cpr)
+               if cprCycle != time.Duration(0) {
+                       timeout = cprCycle
+               } else {
+                       timeout = timeout / TimeoutHeartbeat
+               }
+               heartbeat := time.Tick(timeout)
                var pkt []byte
        ListenCycle:
                for {
                var pkt []byte
        ListenCycle:
                for {
@@ -211,15 +224,37 @@ func newNonceCipher(key *[KeySize]byte) *xtea.Cipher {
        return ciph
 }
 
        return ciph
 }
 
+func cprCycleCalculate(rate int) time.Duration {
+       if rate == 0 {
+               return time.Duration(0)
+       }
+       return time.Second / time.Duration(rate*(1<<10)/MTU)
+}
+
 func newPeer(addr *net.UDPAddr, id PeerId, nonce int, key *[KeySize]byte) *Peer {
        now := time.Now()
 func newPeer(addr *net.UDPAddr, id PeerId, nonce int, key *[KeySize]byte) *Peer {
        now := time.Now()
+       conf := id.ConfGet()
+       timeout := conf.Timeout
+       cprCycle := cprCycleCalculate(conf.CPR)
+       noiseEnable := conf.NoiseEnable
+       if conf.CPR > 0 {
+               noiseEnable = true
+               timeout = cprCycle
+       } else {
+               timeout = timeout / TimeoutHeartbeat
+       }
        peer := Peer{
                Addr:        addr,
        peer := Peer{
                Addr:        addr,
+               Timeout:     timeout,
                Established: now,
                LastPing:    now,
                Id:          id,
                Established: now,
                LastPing:    now,
                Id:          id,
-               NonceOur:    uint64(Noncediff + nonce),
-               NonceRecv:   uint64(Noncediff + 0),
+               NoiseEnable: noiseEnable,
+               CPR:         conf.CPR,
+               CPRCycle:    cprCycle,
+               Noncediff:   conf.Noncediff,
+               NonceOur:    uint64(conf.Noncediff + nonce),
+               NonceRecv:   uint64(conf.Noncediff + 0),
                Key:         key,
                NonceCipher: newNonceCipher(key),
                buf:         make([]byte, MTU+S20BS),
                Key:         key,
                NonceCipher: newNonceCipher(key),
                buf:         make([]byte, MTU+S20BS),
@@ -254,7 +289,7 @@ func (p *Peer) UDPProcess(udpPkt []byte, tap io.Writer, ready chan struct{}) boo
        }
        p.NonceCipher.Decrypt(p.buf, udpPkt[:NonceSize])
        p.nonceRecv, _ = binary.Uvarint(p.buf[:NonceSize])
        }
        p.NonceCipher.Decrypt(p.buf, udpPkt[:NonceSize])
        p.nonceRecv, _ = binary.Uvarint(p.buf[:NonceSize])
-       if int(p.NonceRecv)-Noncediff >= 0 && int(p.nonceRecv) < int(p.NonceRecv)-Noncediff {
+       if int(p.NonceRecv)-p.Noncediff >= 0 && int(p.nonceRecv) < int(p.NonceRecv)-p.Noncediff {
                ready <- struct{}{}
                p.FramesDup++
                return false
                ready <- struct{}{}
                p.FramesDup++
                return false
@@ -288,7 +323,7 @@ func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
        now := time.Now()
        size := len(ethPkt)
        // If this heartbeat is necessary
        now := time.Now()
        size := len(ethPkt)
        // If this heartbeat is necessary
-       if size == 0 && !p.LastSent.Add(heartbeatPeriodGet()).Before(now) {
+       if size == 0 && !p.LastSent.Add(p.Timeout).Before(now) {
                return
        }
        copy(p.buf, Emptiness)
                return
        }
        copy(p.buf, Emptiness)
@@ -309,7 +344,7 @@ func (p *Peer) EthProcess(ethPkt []byte, conn WriteToer, ready chan struct{}) {
        salsa20.XORKeyStream(p.buf, p.buf, p.nonce, p.Key)
        copy(p.buf[S20BS-NonceSize:S20BS], p.nonce)
        copy(p.keyAuth[:], p.buf[:KeySize])
        salsa20.XORKeyStream(p.buf, p.buf, p.nonce, p.Key)
        copy(p.buf[S20BS-NonceSize:S20BS], p.nonce)
        copy(p.keyAuth[:], p.buf[:KeySize])
-       if NoiseEnable {
+       if p.NoiseEnable {
                p.frame = p.buf[S20BS-NonceSize : S20BS+MTU-NonceSize-poly1305.TagSize]
        } else {
                p.frame = p.buf[S20BS-NonceSize : S20BS+PktSizeSize+size]
                p.frame = p.buf[S20BS-NonceSize : S20BS+MTU-NonceSize-poly1305.TagSize]
        } else {
                p.frame = p.buf[S20BS-NonceSize : S20BS+PktSizeSize+size]
@@ -319,8 +354,8 @@ 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.CPRCycle != time.Duration(0) {
+               p.willSentCycle = p.LastSent.Add(p.CPRCycle)
                if p.willSentCycle.After(now) {
                        time.Sleep(p.willSentCycle.Sub(now))
                        now = p.willSentCycle
                if p.willSentCycle.After(now) {
                        time.Sleep(p.willSentCycle.Sub(now))
                        now = p.willSentCycle
index 11fe2c938eb14f7d8515b4596055e692d88396ec..2a56750dfce6a87a91856e8615fb0270bd003c2e 100644 (file)
@@ -17,7 +17,6 @@ var (
 
 func init() {
        MTU = 1500
 
 func init() {
        MTU = 1500
-       Noncediff = 100
        addr, _ = net.ResolveUDPAddr("udp", "[::1]:1")
        peerId = IDDecode("ffffffffffffffffffffffffffffffff")
        peer = newPeer(addr, *peerId, 128, new([KeySize]byte))
        addr, _ = net.ResolveUDPAddr("udp", "[::1]:1")
        peerId = IDDecode("ffffffffffffffffffffffffffffffff")
        peer = newPeer(addr, *peerId, 128, new([KeySize]byte))