]> Cypherpunks.ru repositories - govpn.git/blobdiff - src/cypherpunks.ru/govpn/cmd/govpn-server/main.go
Go language does not like underscores in names
[govpn.git] / src / cypherpunks.ru / govpn / cmd / govpn-server / main.go
index 606caf0ede5ccbb32c0e0e267dbadfc9d6f59793..5f06b33920877b2a461f1e9ebdb0326b8c0deeae 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
@@ -22,13 +22,11 @@ package main
 import (
        "flag"
        "fmt"
-       "log"
-       "net"
-       "os"
-       "os/signal"
-       "time"
+
+       "github.com/Sirupsen/logrus"
 
        "cypherpunks.ru/govpn"
+       "cypherpunks.ru/govpn/server"
 )
 
 var (
@@ -38,106 +36,75 @@ 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")
+       logLevel = flag.String("loglevel", "warning", "Logging level")
 )
 
 func main() {
+       var err error
+       fields := logrus.Fields{"func": "main"}
+
        flag.Parse()
        if *warranty {
                fmt.Println(govpn.Warranty)
                return
        }
-       timeout := time.Second * time.Duration(govpn.TimeoutDefault)
-       log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)
-       log.Println(govpn.VersionGet())
+       if *version {
+               fmt.Println(govpn.VersionGet())
+               return
+       }
 
-       confInit()
-       knownPeers = govpn.KnownPeers(make(map[string]**govpn.Peer))
+       logger, err = govpn.NewLogger(*logLevel, *syslog)
+       if err != nil {
+               logrus.WithFields(
+                       fields,
+               ).WithError(err).Fatal("Can not initialize logging")
+       }
+       govpn.SetLogger(logger)
 
        if *egdPath != "" {
-               log.Println("Using", *egdPath, "EGD")
+               logger.WithField(
+                       "egd_path", *egdPath,
+               ).WithFields(
+                       fields,
+               ).Debug("Init EGD")
                govpn.EGDInit(*egdPath)
        }
 
-       switch *proto {
-       case "udp":
-               startUDP()
-       case "tcp":
-               startTCP()
-       case "all":
-               startUDP()
-               startTCP()
-       default:
-               log.Fatalln("Unknown protocol specified")
-       }
+       confInit()
 
-       termSignal := make(chan os.Signal, 1)
-       signal.Notify(termSignal, os.Interrupt, os.Kill)
+       serverConfig := server.Configuration{
+               BindAddress:  *bindAddr,
+               ProxyAddress: *proxy,
+               Timeout:      govpn.TimeoutDefault,
+       }
+       if serverConfig.Protocol, err = govpn.NewProtocolFromString(*proto); err != nil {
+               logger.WithError(err).WithFields(
+                       fields,
+               ).WithField(
+                       "proto", *proto,
+               ).Fatal("Invalid protocol")
+       }
+       if err = serverConfig.Validate(); err != nil {
+               logger.WithError(err).WithFields(fields).Fatal("Invalid configuration")
+       }
 
-       hsHeartbeat := time.Tick(timeout)
-       go func() { <-hsHeartbeat }()
+       srv := server.NewServer(
+               serverConfig,
+               confs,
+               idsCache,
+               logger,
+               govpn.CatchSignalShutdown(),
+       )
 
        if *stats != "" {
-               log.Println("Stats are going to listen on", *stats)
-               statsPort, err := net.Listen("tcp", *stats)
-               if err != nil {
-                       log.Fatalln("Can not listen on stats port:", err)
-               }
-               go govpn.StatsProcessor(statsPort, &knownPeers)
-       }
-       if *proxy != "" {
-               go proxyStart()
+               go govpn.StatsProcessor(*stats, srv.KnownPeers())
        }
-       log.Println("Server started")
-
-       var needsDeletion bool
-MainCycle:
-       for {
-               select {
-               case <-termSignal:
-                       log.Println("Terminating")
-                       for _, ps := range peers {
-                               govpn.ScriptCall(
-                                       confs[*ps.peer.Id].Down,
-                                       ps.tap.Name,
-                                       ps.peer.Addr,
-                               )
-                       }
-                       break MainCycle
-               case <-hsHeartbeat:
-                       now := time.Now()
-                       hsLock.Lock()
-                       for addr, hs := range handshakes {
-                               if hs.LastPing.Add(timeout).Before(now) {
-                                       log.Println("Deleting handshake state", addr)
-                                       hs.Zero()
-                                       delete(handshakes, addr)
-                               }
-                       }
-                       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()
-                               if needsDeletion {
-                                       log.Println("Deleting peer", ps.peer)
-                                       delete(peers, addr)
-                                       delete(knownPeers, addr)
-                                       delete(peersById, *ps.peer.Id)
-                                       go govpn.ScriptCall(
-                                               confs[*ps.peer.Id].Down,
-                                               ps.tap.Name,
-                                               ps.peer.Addr,
-                                       )
-                                       ps.terminator <- struct{}{}
-                               }
-                       }
-                       hsLock.Unlock()
-                       peersLock.Unlock()
-                       peersByIdLock.Unlock()
-                       kpLock.Unlock()
-               }
+
+       go srv.MainCycle()
+       if err = <-srv.Error; err != nil {
+               logger.WithError(err).Fatal("Fatal error")
        }
 }