File govpn-go-1.7-compat.patch of Package govpn
--- a/src/cypherpunks.ru/govpn/client/client.go
+++ b/src/cypherpunks.ru/govpn/client/client.go
@@ -23,7 +23,6 @@ import (
"fmt"
"net"
"os"
- "sync"
"time"
"github.com/agl/ed25519"
@@ -73,7 +72,7 @@ func (c *Configuration) isProxy() bool {
type Client struct {
idsCache *govpn.MACCache
tap *govpn.TAP
- knownPeers sync.Map
+ knownPeers govpn.KnownPeers
statsPort net.Listener
timeouted chan struct{}
rehandshaking chan struct{}
@@ -100,6 +99,7 @@ func (c *Client) MainCycle() {
c.Error <- fmt.Errorf("Can't listen on stats port: %s", err.Error())
return
}
+ c.knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer))
go govpn.StatsProcessor(c.statsPort, &c.knownPeers)
}
--- a/src/cypherpunks.ru/govpn/client/tcp.go
+++ b/src/cypherpunks.ru/govpn/client/tcp.go
@@ -86,7 +86,7 @@ HandshakeCycle:
continue
}
govpn.Printf(`[handshake-completed remote="%s"]`, c.config.RemoteAddress)
- c.knownPeers.Store(c.config.RemoteAddress, &peer)
+ c.knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{c.config.RemoteAddress: &peer})
if c.firstUpCall {
go govpn.ScriptCall(c.config.UpPath, c.config.InterfaceName, c.config.RemoteAddress)
c.firstUpCall = false
--- a/src/cypherpunks.ru/govpn/client/udp.go
+++ b/src/cypherpunks.ru/govpn/client/udp.go
@@ -93,7 +93,7 @@ MainCycle:
continue
}
govpn.Printf(`[handshake-completed remote="%s"]`, c.config.RemoteAddress)
- c.knownPeers.Store(c.config.RemoteAddress, &peer)
+ c.knownPeers = govpn.KnownPeers(map[string]**govpn.Peer{c.config.RemoteAddress: &peer})
if c.firstUpCall {
go govpn.ScriptCall(c.config.UpPath, c.config.InterfaceName, c.config.RemoteAddress)
c.firstUpCall = false
--- a/src/cypherpunks.ru/govpn/cmd/govpn-server/common.go
+++ b/src/cypherpunks.ru/govpn/cmd/govpn-server/common.go
@@ -32,10 +32,17 @@ type PeerState struct {
}
var (
- handshakes sync.Map
- peers sync.Map
- peersByID sync.Map
- knownPeers sync.Map
+ handshakes map[string]*govpn.Handshake = make(map[string]*govpn.Handshake)
+ hsLock sync.RWMutex
+
+ peers = make(map[string]*PeerState)
+ peersLock sync.RWMutex
+
+ peersByID = make(map[govpn.PeerID]string)
+ peersByIDLock sync.RWMutex
+
+ knownPeers govpn.KnownPeers
+ kpLock sync.RWMutex
)
func callUp(peerID *govpn.PeerID, remoteAddr string) (string, error) {
--- a/src/cypherpunks.ru/govpn/cmd/govpn-server/main.go
+++ b/src/cypherpunks.ru/govpn/cmd/govpn-server/main.go
@@ -58,6 +58,7 @@ func main() {
log.Println(govpn.VersionGet())
confInit()
+ knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer))
if *egdPath != "" {
log.Println("Using", *egdPath, "EGD")
@@ -105,33 +106,28 @@ MainCycle:
select {
case <-termSignal:
govpn.BothPrintf(`[terminating bind="%s"]`, *bindAddr)
- peers.Range(func(_, psI interface{}) bool {
- ps := psI.(*PeerState)
+ for _, ps := range peers {
govpn.ScriptCall(
confs[*ps.peer.ID].Down,
ps.tap.Name,
ps.peer.Addr,
)
- return true
- })
+ }
break MainCycle
case <-hsHeartbeat:
now := time.Now()
-
- handshakes.Range(func(addrI, hsI interface{}) bool {
- addr := addrI.(string)
- hs := hsI.(*govpn.Handshake)
+ hsLock.Lock()
+ for addr, hs := range handshakes {
if hs.LastPing.Add(timeout).Before(now) {
govpn.Printf(`[handshake-delete bind="%s" addr="%s"]`, *bindAddr, addr)
hs.Zero()
- handshakes.Delete(addr)
+ delete(handshakes, addr)
}
- return true
- })
-
- peers.Range(func(addrI, psI interface{}) bool {
- addr := addrI.(string)
- ps := psI.(*PeerState)
+ }
+ peersLock.Lock()
+ peersByIDLock.Lock()
+ kpLock.Lock()
+ for addr, ps := range peers {
ps.peer.BusyR.Lock()
needsDeletion = ps.peer.LastPing.Add(timeout).Before(now)
ps.peer.BusyR.Unlock()
@@ -141,9 +137,9 @@ MainCycle:
*bindAddr,
ps.peer.ID.String(),
)
- peers.Delete(addr)
- knownPeers.Delete(addr)
- peersByID.Delete(*ps.peer.ID)
+ delete(peers, addr)
+ delete(knownPeers, addr)
+ delete(peersByID, *ps.peer.ID)
go govpn.ScriptCall(
confs[*ps.peer.ID].Down,
ps.tap.Name,
@@ -151,8 +147,11 @@ MainCycle:
)
ps.terminator <- struct{}{}
}
- return true
- })
+ }
+ hsLock.Unlock()
+ peersLock.Unlock()
+ peersByIDLock.Unlock()
+ kpLock.Unlock()
}
}
}
--- a/src/cypherpunks.ru/govpn/cmd/govpn-server/tcp.go
+++ b/src/cypherpunks.ru/govpn/cmd/govpn-server/tcp.go
@@ -60,9 +60,6 @@ func handleTCP(conn net.Conn) {
var peer *govpn.Peer
var tap *govpn.TAP
var conf *govpn.PeerConf
- var addrPrev string
- var peerPrevI interface{}
- var peerPrev *PeerState
for {
if prev == len(buf) {
break
@@ -99,13 +96,16 @@ func handleTCP(conn net.Conn) {
`[handshake-completed bind="%s" addr="%s" peer="%s"]`,
*bindAddr, addr, peerID.String(),
)
- addrPrevI, exists := peersByID.Load(*peer.ID)
+ peersByIDLock.RLock()
+ addrPrev, exists := peersByID[*peer.ID]
+ peersByIDLock.RUnlock()
+ var peerPrev *PeerState
if exists {
- addrPrev = addrPrevI.(string)
- peerPrevI, exists = peers.Load(addrPrev)
- if exists {
- peerPrev = peerPrevI.(*PeerState)
- exists = peerPrev == nil
+ peersLock.Lock()
+ peerPrev = peers[addrPrev]
+ if peerPrev == nil {
+ exists = false
+ peersLock.Unlock()
}
}
if exists {
@@ -117,11 +117,16 @@ func handleTCP(conn net.Conn) {
terminator: make(chan struct{}),
}
go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
- peers.Delete(addrPrev)
- peers.Store(addr, ps)
- knownPeers.Delete(addrPrev)
- knownPeers.Store(addr, &peer)
- peersByID.Store(*peer.ID, addr)
+ peersByIDLock.Lock()
+ kpLock.Lock()
+ delete(peers, addrPrev)
+ delete(knownPeers, addrPrev)
+ peers[addr] = ps
+ knownPeers[addr] = &peer
+ peersByID[*peer.ID] = addr
+ peersLock.Unlock()
+ peersByIDLock.Unlock()
+ kpLock.Unlock()
govpn.Printf(
`[rehandshake-completed bind="%s" peer="%s"]`,
*bindAddr, peerID.String(),
@@ -147,9 +152,15 @@ func handleTCP(conn net.Conn) {
terminator: make(chan struct{}, 1),
}
go govpn.PeerTapProcessor(ps.peer, ps.tap, ps.terminator)
- peers.Store(addr, ps)
- peersByID.Store(*peer.ID, addr)
- knownPeers.Store(addr, &peer)
+ peersLock.Lock()
+ peersByIDLock.Lock()
+ kpLock.Lock()
+ peers[addr] = ps
+ peersByID[*peer.ID] = addr
+ knownPeers[addr] = &peer
+ peersLock.Unlock()
+ peersByIDLock.Unlock()
+ kpLock.Unlock()
govpn.Printf(`[peer-created bind="%s" peer="%s"]`, *bindAddr, peerID.String())
}
break
--- a/src/cypherpunks.ru/govpn/cmd/govpn-server/udp.go
+++ b/src/cypherpunks.ru/govpn/cmd/govpn-server/udp.go
@@ -57,15 +57,10 @@ func startUDP() {
var addr string
var n int
var err error
- var exists bool
- var psI interface{}
var ps *PeerState
- var hsI interface{}
var hs *govpn.Handshake
- var addrPrevI interface{}
var addrPrev string
- var peerPrevI interface{}
- var peerPrev *PeerState
+ var exists bool
var peerID *govpn.PeerID
var conf *govpn.PeerConf
for {
@@ -77,9 +72,10 @@ func startUDP() {
}
addr = raddr.String()
- psI, exists = peers.Load(addr)
+ peersLock.RLock()
+ ps, exists = peers[addr]
+ peersLock.RUnlock()
if exists {
- ps = psI.(*PeerState)
go func(peer *govpn.Peer, tap *govpn.TAP, buf []byte, n int) {
peer.PktProcess(buf[:n], tap, true)
udpBufs <- buf
@@ -87,7 +83,9 @@ func startUDP() {
continue
}
- hsI, exists = handshakes.Load(addr)
+ hsLock.RLock()
+ hs, exists = handshakes[addr]
+ hsLock.RUnlock()
if !exists {
peerID = idsCache.Find(buf[:n])
if peerID == nil {
@@ -111,11 +109,12 @@ func startUDP() {
)
hs.Server(buf[:n])
udpBufs <- buf
- handshakes.Store(addr, hs)
+ hsLock.Lock()
+ handshakes[addr] = hs
+ hsLock.Unlock()
continue
}
- hs = hsI.(*govpn.Handshake)
peer := hs.Server(buf[:n])
if peer == nil {
udpBufs <- buf
@@ -126,19 +125,24 @@ func startUDP() {
*bindAddr, addr, peerID.String(),
)
hs.Zero()
- handshakes.Delete(addr)
+ hsLock.Lock()
+ delete(handshakes, addr)
+ hsLock.Unlock()
go func() {
udpBufs <- make([]byte, govpn.MTUMax)
udpBufs <- make([]byte, govpn.MTUMax)
}()
- addrPrevI, exists = peersByID.Load(*peer.ID)
+ peersByIDLock.RLock()
+ addrPrev, exists = peersByID[*peer.ID]
+ peersByIDLock.RUnlock()
+ var peerPrev *PeerState
if exists {
- addrPrev = addrPrevI.(string)
- peerPrevI, exists = peers.Load(addrPrev)
- if exists {
- peerPrev = peerPrevI.(*PeerState)
- exists = peerPrev == nil
+ peersLock.Lock()
+ peerPrev = peers[addrPrev]
+ if peerPrev == nil {
+ exists = false
+ peersLock.Unlock()
}
}
if exists {
@@ -153,11 +157,16 @@ func startUDP() {
<-udpBufs
<-udpBufs
}(psNew.peer, psNew.tap, psNew.terminator)
- peers.Delete(addrPrev)
- peers.Store(addr, psNew)
- knownPeers.Delete(addrPrev)
- knownPeers.Store(addr, &peer)
- peersByID.Store(*peer.ID, addr)
+ peersByIDLock.Lock()
+ kpLock.Lock()
+ delete(peers, addrPrev)
+ delete(knownPeers, addrPrev)
+ peers[addr] = psNew
+ knownPeers[addr] = &peer
+ peersByID[*peer.ID] = addr
+ peersLock.Unlock()
+ peersByIDLock.Unlock()
+ kpLock.Unlock()
govpn.Printf(
`[rehandshake-completed bind="%s" peer="%s"]`,
*bindAddr, peer.ID.String(),
@@ -186,9 +195,15 @@ func startUDP() {
<-udpBufs
<-udpBufs
}(psNew.peer, psNew.tap, psNew.terminator)
- peers.Store(addr, psNew)
- knownPeers.Store(addr, &peer)
- peersByID.Store(*peer.ID, addr)
+ peersLock.Lock()
+ peersByIDLock.Lock()
+ kpLock.Lock()
+ peers[addr] = psNew
+ knownPeers[addr] = &peer
+ peersByID[*peer.ID] = addr
+ peersLock.Unlock()
+ peersByIDLock.Unlock()
+ kpLock.Unlock()
govpn.Printf(
`[peer-created bind="%s" peer="%s"]`,
*bindAddr,
--- a/src/cypherpunks.ru/govpn/stats.go
+++ b/src/cypherpunks.ru/govpn/stats.go
@@ -22,7 +22,6 @@ import (
"encoding/json"
"log"
"net"
- "sync"
"time"
)
@@ -30,13 +29,15 @@ const (
RWTimeout = 10 * time.Second
)
+type KnownPeers map[string]**Peer
+
// StatsProcessor is assumed to be run in background. It accepts
// connection on statsPort, reads anything one send to them and show
// information about known peers in serialized JSON format. peers
// argument is a reference to the map with references to the peers as
// values. Map is used here because of ease of adding and removing
// elements in it.
-func StatsProcessor(statsPort net.Listener, peers *sync.Map) {
+func StatsProcessor(statsPort net.Listener, peers *KnownPeers) {
var conn net.Conn
var err error
var data []byte
@@ -51,10 +52,9 @@ func StatsProcessor(statsPort net.Listen
conn.Read(buf)
conn.Write([]byte("HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n"))
var peersList []*Peer
- peers.Range(func(_, peerI interface{}) bool {
- peersList = append(peersList, *peerI.(**Peer))
- return true
- })
+ for _, peer := range *peers {
+ peersList = append(peersList, *peer)
+ }
data, err = json.Marshal(peersList)
if err != nil {
panic(err)