]> Cypherpunks.ru repositories - govpn.git/commitdiff
Merge branch 'develop' 2.2
authorSergey Matveev <stargrave@stargrave.org>
Sun, 15 Mar 2015 16:10:07 +0000 (19:10 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 15 Mar 2015 16:10:07 +0000 (19:10 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
NEWS
cmd/govpn-client/main.go
cmd/govpn-server/main.go
common.go
doc/download.texi
doc/govpn.texi
makefile
tap.go
transport.go

diff --git a/NEWS b/NEWS
index b56beacaddb7e660ecb0a56a59d78e003cd15e62..4500296c5f9358219e153fb49057ef65b2be6b26 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Release 2.2
+-----------
+* Fixed several possible channel deadlocks.
+
 Release 2.1
 -----------
 * Fixed Linux-related building.
index e358d43f8b82dad67ad9c6de2bfc4afeffbf3422..f4a29eb82d2aea2a23d3fdb5eaad906cf41e677d 100644 (file)
@@ -102,7 +102,9 @@ MainCycle:
                        break MainCycle
                case ethPkt = <-ethSink:
                        if peer == nil {
-                               ethReady <- struct{}{}
+                               if len(ethPkt) > 0 {
+                                       ethReady <- struct{}{}
+                               }
                                continue
                        }
                        peer.EthProcess(ethPkt, conn, ethReady)
index f628244189ebe78b4468514443fec795f78ff96f..4fa5c96f8baa184c350e4362178b196dc14f1009 100644 (file)
@@ -172,7 +172,7 @@ MainCycle:
                                }
                        }(state)
                case ethEvent = <-ethSink:
-                       if _, exists := peers[ethEvent.peer.Addr.String()]; !exists {
+                       if s, exists := peers[ethEvent.peer.Addr.String()]; !exists || s.peer != ethEvent.peer {
                                continue
                        }
                        ethEvent.peer.EthProcess(ethEvent.data, conn, ethEvent.ready)
index b38f52b1d282035c6390daa22e6681dd7f84627a..b42673c98925f32be3b63948f7eaf30eccb186e9 100644 (file)
--- a/common.go
+++ b/common.go
@@ -23,6 +23,7 @@ import (
        "encoding/hex"
        "io/ioutil"
        "log"
+       "os"
        "os/exec"
 )
 
@@ -41,6 +42,9 @@ func ScriptCall(path, ifaceName string) ([]byte, error) {
        if path == "" {
                return nil, nil
        }
+       if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
+               return nil, err
+       }
        cmd := exec.Command(path, ifaceName)
        var out bytes.Buffer
        cmd.Stdout = &out
index d2ad657bf8368bad5538dc21b5ca769a979a439f..e0ae00d035748093430cc91ed148a72436adb406 100644 (file)
@@ -8,8 +8,8 @@ or by downloading prepared tarballs below.
 @tab @url{download/govpn-1.5.tar.xz, link} @url{download/govpn-1.5.tar.xz.sig, sign}
 @item 2.0 @tab 31 KiB
 @tab @url{download/govpn-2.0.tar.xz, link} @url{download/govpn-2.0.tar.xz.sig, sign}
-@item 2.1 @tab 32 KiB
-@tab @url{download/govpn-2.1.tar.xz, link} @url{download/govpn-2.1.tar.xz.sig, sign}
+@item 2.2 @tab 32 KiB
+@tab @url{download/govpn-2.2.tar.xz, link} @url{download/govpn-2.2.tar.xz.sig, sign}
 @end multitable
 
 Sourceforge.net also provides mirror for the files above:
index 9c53ba5b4214804d1ce44dec01b648ae8f704de6..3bdf72faddc3ccb254c9dfed48cad765bcec2600 100644 (file)
@@ -17,13 +17,11 @@ GNU General Public License for more details.
 @end quotation
 @end copying
 
-@ifnottex
 @node Top
 @top GoVPN
 
 This manual is for GoVPN -- simple secure free software virtual private
 network (VPN) daemon, written entirely on Go programming language.
-@end ifnottex
 
 @menu
 * Overview::
@@ -202,6 +200,9 @@ transport. MTU for that wlan0 is 1500 bytes. GoVPN will say that maximum
 MTU for the link is 1476, however it does not take in account TAP's
 Ethernet frame header length, that in my case is 14 bytes long (1476 - 14).
 
+Do not forget about setting @code{GOMAXPROC} environment variable for
+using more than one CPU.
+
 GNU/Linux IPv4 client-server example:
 
 @example
@@ -216,7 +217,7 @@ server% tunctl -t tap10
 server% ip link set mtu 1462 dev tap10
 server% ip addr add 172.16.0.1/24 dev tap10
 server% ip link set up dev tap10
-server% govpn -bind 192.168.0.1:1194
+server% GOMAXPROC=4 govpn-server -bind 192.168.0.1:1194
 @end example
 
 @example
@@ -228,8 +229,9 @@ client% ip link set mtu 1462 dev tap10
 client% ip addr add 172.16.0.2/24 dev tap10
 client% ip link set up dev tap10
 client% ip route add default via 172.16.0.1
+client% export GOMAXPROC=4
 client% while :; do
-    govpn -key key.txt -id CLIENTID -iface tap10 -remote 192.168.0.1:1194
+    govpn-client -key key.txt -id CLIENTID -iface tap10 -remote 192.168.0.1:1194
 done
 @end example
 
@@ -248,7 +250,7 @@ echo $tap
 EOF
 server% chmod 500 peers/CLIENTID/up.sh
 server% ifconfig em0 inet6 fe80::1/64
-server% govpn -bind fe80::1%em0
+server% GOMAXPROC=4 govpn-server -bind fe80::1%em0
 @end example
 
 @example
@@ -256,8 +258,9 @@ client% ifconfig me0 inet6 -ifdisabled auto_linklocal
 client% ifconfig tap10
 client% ifconfig tap10 inet6 fc00::2/96 mtu 1462 up
 client% route -6 add default fc00::1
+client% export GOMAXPROC=4
 client% while :; do
-    govpn -key key.txt -id CLIENTID -iface tap10 -remote [fe80::1%me0]:1194
+    govpn-client -key key.txt -id CLIENTID -iface tap10 -remote [fe80::1%me0]:1194
 done
 @end example
 
index b1e4229e7ceed501f81973c4850a07d3b0c9326b..59f148ee059bce4cdc7fa51580febd630f065e7f 100644 (file)
--- a/makefile
+++ b/makefile
@@ -1,6 +1,6 @@
 .PHONY: govpn-client govpn-server
 
-VERSION=2.0
+VERSION=2.2
 LDFLAGS=-X govpn.Version $(VERSION)
 
 all: govpn-client govpn-server
diff --git a/tap.go b/tap.go
index 85926d7df9d1c4d290f85c77408251de0e50f417..4fee83a28c3ea920cb619da22a1a9ddc984d71e7 100644 (file)
--- a/tap.go
+++ b/tap.go
@@ -26,11 +26,12 @@ import (
 )
 
 type TAP struct {
-       Name  string
-       dev   io.ReadWriter
-       buf   []byte
-       sink  chan []byte
-       ready chan struct{}
+       Name   string
+       dev    io.ReadWriter
+       buf    []byte
+       sink   chan []byte
+       ready  chan struct{}
+       synced bool
 }
 
 func NewTAP(ifaceName string) (*TAP, error) {
@@ -40,11 +41,12 @@ func NewTAP(ifaceName string) (*TAP, error) {
                return nil, err
        }
        tap := TAP{
-               Name:  ifaceName,
-               dev:   tapRaw,
-               buf:   make([]byte, maxIfacePktSize),
-               sink:  make(chan []byte),
-               ready: make(chan struct{}),
+               Name:   ifaceName,
+               dev:    tapRaw,
+               buf:    make([]byte, maxIfacePktSize),
+               sink:   make(chan []byte),
+               ready:  make(chan struct{}),
+               synced: false,
        }
        go func() {
                var n int
index 3c460e61926c44d1c812f16a0c5377fac6ee25de..d72fcc15ea140c74584514dd380fbc3fe6dea607 100644 (file)
@@ -102,6 +102,7 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{
        sink := make(chan []byte)
        sinkReady := make(chan struct{})
        sinkTerminate := make(chan struct{})
+       sinkSkip := make(chan struct{})
 
        go func() {
                heartbeat := time.Tick(heartbeatPeriodGet())
@@ -112,29 +113,34 @@ func TAPListen(ifaceName string) (*TAP, chan []byte, chan struct{}, chan struct{
                        case <-sinkTerminate:
                                break ListenCycle
                        case <-heartbeat:
-                               sink <- make([]byte, 0)
+                               go func() { sink <- make([]byte, 0) }()
                                continue
+                       case <-sinkSkip:
                        case <-sinkReady:
-                               if exists {
-                                       exists = false
-                                       break
-                               }
                                tap.ready <- struct{}{}
+                               tap.synced = true
                        }
                HeartbeatCatched:
                        select {
                        case <-heartbeat:
-                               sink <- make([]byte, 0)
+                               go func() { sink <- make([]byte, 0) }()
                                goto HeartbeatCatched
                        case <-sinkTerminate:
                                break ListenCycle
                        case pkt = <-tap.sink:
+                               tap.synced = false
                                sink <- pkt
                        }
                }
                close(sink)
+               close(sinkReady)
+               close(sinkTerminate)
        }()
-       sinkReady <- struct{}{}
+       if exists && tap.synced {
+               sinkSkip <- struct{}{}
+       } else {
+               sinkReady <- struct{}{}
+       }
        return tap, sink, sinkReady, sinkTerminate, nil
 }