]> Cypherpunks.ru repositories - govpn.git/blobdiff - src/cypherpunks.ru/govpn/cmd/govpn-server/main.go
Use convenient simpler Go 1.9's sync.Map
[govpn.git] / src / cypherpunks.ru / govpn / cmd / govpn-server / main.go
index 886b8a812b365dae21960e36232e4d18b0e6618f..0dfd8ab83198f449f7d4148f8e1e11c780eff189 100644 (file)
@@ -1,6 +1,6 @@
 /*
 GoVPN -- simple secure free software virtual private network daemon
-Copyright (C) 2014-2016 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2014-2017 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@ package main
 
 import (
        "flag"
+       "fmt"
        "log"
        "net"
        "os"
@@ -37,22 +38,36 @@ var (
        stats    = flag.String("stats", "", "Enable stats retrieving on host:port")
        proxy    = flag.String("proxy", "", "Enable HTTP proxy on host:port")
        egdPath  = flag.String("egd", "", "Optional path to EGD socket")
+       syslog   = flag.Bool("syslog", false, "Enable logging to syslog")
+       version  = flag.Bool("version", false, "Print version information")
+       warranty = flag.Bool("warranty", false, "Print warranty information")
 )
 
 func main() {
        flag.Parse()
+       if *warranty {
+               fmt.Println(govpn.Warranty)
+               return
+       }
+       if *version {
+               fmt.Println(govpn.VersionGet())
+               return
+       }
        timeout := time.Second * time.Duration(govpn.TimeoutDefault)
        log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
        log.Println(govpn.VersionGet())
 
        confInit()
-       knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer))
 
        if *egdPath != "" {
                log.Println("Using", *egdPath, "EGD")
                govpn.EGDInit(*egdPath)
        }
 
+       if *syslog {
+               govpn.SyslogEnable()
+       }
+
        switch *proto {
        case "udp":
                startUDP()
@@ -82,47 +97,62 @@ func main() {
        if *proxy != "" {
                go proxyStart()
        }
-       log.Println("Server started")
+       govpn.BothPrintf(`[started bind="%s"]`, *bindAddr)
 
        var needsDeletion bool
 MainCycle:
        for {
                select {
                case <-termSignal:
+                       govpn.BothPrintf(`[terminating bind="%s"]`, *bindAddr)
+                       peers.Range(func(_, psI interface{}) bool {
+                               ps := psI.(*PeerState)
+                               govpn.ScriptCall(
+                                       confs[*ps.peer.ID].Down,
+                                       ps.tap.Name,
+                                       ps.peer.Addr,
+                               )
+                               return true
+                       })
                        break MainCycle
                case <-hsHeartbeat:
                        now := time.Now()
-                       hsLock.Lock()
-                       for addr, hs := range handshakes {
+
+                       handshakes.Range(func(addrI, hsI interface{}) bool {
+                               addr := addrI.(string)
+                               hs := hsI.(*govpn.Handshake)
                                if hs.LastPing.Add(timeout).Before(now) {
-                                       log.Println("Deleting handshake state", addr)
+                                       govpn.Printf(`[handshake-delete bind="%s" addr="%s"]`, *bindAddr, addr)
                                        hs.Zero()
-                                       delete(handshakes, addr)
+                                       handshakes.Delete(addr)
                                }
-                       }
-                       peersLock.Lock()
-                       peersByIdLock.Lock()
-                       kpLock.Lock()
-                       for addr, ps := range peers {
+                               return true
+                       })
+
+                       peers.Range(func(addrI, psI interface{}) bool {
+                               addr := addrI.(string)
+                               ps := psI.(*PeerState)
                                ps.peer.BusyR.Lock()
                                needsDeletion = ps.peer.LastPing.Add(timeout).Before(now)
                                ps.peer.BusyR.Unlock()
                                if needsDeletion {
-                                       log.Println("Deleting peer", ps.peer)
-                                       delete(peers, addr)
-                                       delete(knownPeers, addr)
-                                       delete(peersById, *ps.peer.Id)
+                                       govpn.Printf(
+                                               `[peer-delete bind="%s" peer="%s"]`,
+                                               *bindAddr,
+                                               ps.peer.ID.String(),
+                                       )
+                                       peers.Delete(addr)
+                                       knownPeers.Delete(addr)
+                                       peersByID.Delete(*ps.peer.ID)
                                        go govpn.ScriptCall(
-                                               confs[*ps.peer.Id].Down,
+                                               confs[*ps.peer.ID].Down,
                                                ps.tap.Name,
+                                               ps.peer.Addr,
                                        )
                                        ps.terminator <- struct{}{}
                                }
-                       }
-                       hsLock.Unlock()
-                       peersLock.Unlock()
-                       peersByIdLock.Unlock()
-                       kpLock.Unlock()
+                               return true
+                       })
                }
        }
 }