diff --git a/src/api/servers.go b/src/api/servers.go index 9060f426..d92e27be 100644 --- a/src/api/servers.go +++ b/src/api/servers.go @@ -57,7 +57,7 @@ func attachServers(app *gin.RouterGroup) { return } - if err := manager.Create(name, cfg); err != nil { + if err := manager.Create(name, cfg, make(chan struct{}, 1)); err != nil { c.IndentedJSON(http.StatusConflict, err.Error()) return } diff --git a/src/manager/manager.go b/src/manager/manager.go index a203a6dd..39852128 100644 --- a/src/manager/manager.go +++ b/src/manager/manager.go @@ -61,7 +61,7 @@ func Initialize(cfg config.Config) { // Go through config and start servers for each server for name, serverCfg := range cfg.Servers { - err := Create(name, serverCfg) + err := Create(name, serverCfg, make(chan struct{}, 1)) if err != nil { log.Fatal(err) } @@ -181,7 +181,7 @@ func Get(name string) interface{} { /** * Create new server and launch it */ -func Create(name string, cfg config.Server) error { +func Create(name string, cfg config.Server, completed chan <- struct{}) error { servers.Lock() defer servers.Unlock() @@ -195,7 +195,7 @@ func Create(name string, cfg config.Server) error { return err } - server, err := server.New(name, c) + server, err := server.New(name, c, completed) if err != nil { return err diff --git a/src/server/server.go b/src/server/server.go index 4845e95c..dccc9a88 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -19,12 +19,12 @@ import ( /** * Creates new Server based on cfg.Protocol */ -func New(name string, cfg config.Server) (core.Server, error) { +func New(name string, cfg config.Server, completed chan<- struct{}) (core.Server, error) { switch cfg.Protocol { case "tls", "tcp": - return tcp.New(name, cfg) + return tcp.New(name, cfg, completed) case "udp": - return udp.New(name, cfg) + return udp.New(name, cfg, completed) default: return nil, errors.New("Can't create server for protocol " + cfg.Protocol) } diff --git a/src/server/tcp/server.go b/src/server/tcp/server.go index 6c936771..8368e9e1 100644 --- a/src/server/tcp/server.go +++ b/src/server/tcp/server.go @@ -70,6 +70,9 @@ type Server struct { /* Get certificate filled by external service */ GetCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error) + /* A channel that helps to determine when the server has completed */ + completed chan<- struct{} + /* ----- modules ----- */ /* Access module checks if client is allowed to connect */ @@ -79,7 +82,7 @@ type Server struct { /** * Creates new server instance */ -func New(name string, cfg config.Server) (*Server, error) { +func New(name string, cfg config.Server, completed chan<- struct{}) (*Server, error) { log := logging.For("server") @@ -101,6 +104,7 @@ func New(name string, cfg config.Server) (*Server, error) { Healthcheck: healthcheck.New(cfg.Healthcheck.Kind, *cfg.Healthcheck), StatsHandler: statsHandler, }, + completed: completed, } /* Add access if needed */ @@ -134,7 +138,6 @@ func (this *Server) Cfg() config.Server { * Start server */ func (this *Server) Start() error { - var err error this.tlsConfig, err = tlsutil.MakeTlsConfig(this.cfg.Tls, this.GetCertificate) if err != nil { @@ -270,6 +273,7 @@ func (this *Server) Listen() (err error) { sniEnabled := this.cfg.Sni != nil go func() { + defer func() { this.completed <- struct{}{} }() for { conn, err := this.listener.Accept() diff --git a/src/server/udp/server.go b/src/server/udp/server.go index 1ce1a418..89d29b43 100644 --- a/src/server/udp/server.go +++ b/src/server/udp/server.go @@ -54,6 +54,9 @@ type Server struct { /* Stop channel */ stop chan bool + /* A channel that helps to determine when the server has completed */ + completed chan<- struct{} + /* ----- modules ----- */ /* Access module checks if client is allowed to connect */ @@ -116,7 +119,7 @@ func (cp *connPool) close() { /** * Creates new UDP server */ -func New(name string, cfg config.Server) (*Server, error) { +func New(name string, cfg config.Server, completed chan <- struct{}) (*Server, error) { statsHandler := stats.NewHandler(name) scheduler := &scheduler.Scheduler{ @@ -131,6 +134,7 @@ func New(name string, cfg config.Server) (*Server, error) { cfg: cfg, scheduler: scheduler, stop: make(chan bool), + completed: completed, sessions: make(map[string]*session.Session), } @@ -158,7 +162,6 @@ func (this *Server) Cfg() config.Server { * Starts server */ func (this *Server) Start() error { - // Start listening if err := this.listen(); err != nil { return fmt.Errorf("Could not start listening UDP: %v", err) @@ -241,6 +244,7 @@ func (this *Server) serve() { // Main loop goroutine - reads incoming data and decides what to do go func() { + defer func() { this.completed <- struct{}{} }() defer cp.close()