/*
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
import (
"flag"
+ "fmt"
"log"
"net"
"os"
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()
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
+ })
}
}
}