func RunTCP(t TCPService) { l, err := net.ListenTCP("tcp", t.Addr()) if err != nil { log.Error("failed to bind to local address %s", t.Addr()) t.Shutdown() return } defer l.Close() log.Info("listening for connections on %s", t.Addr()) for { conn, err := l.AcceptTCP() if err != nil { log.Error("failed to accept connection: %v", err) continue } if err := t.SetClientOptions(conn); err != nil { conn.Close() continue } log.Trace(func() string { return fmt.Sprintf("%s: client connected to %s", conn.RemoteAddr(), t.Addr()) }) go t.Handle(conn) } }
func trapSignals() chan int { exitChan := make(chan int) signalChan := make(chan os.Signal, 1) go func() { s := <-signalChan log.Info("received signal %d", s) exitChan <- 1 }() signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) return exitChan }
func main() { flag.Parse() cfg, err := LoadConfig(*configPath) if err != nil { log.Error("failed to load config: %s", err) return } log.Info("loaded config: %s", cfg) runtime.GOMAXPROCS(cfg.Cores()) exitChan := trapSignals() go RunTCP(NewSMTPService(cfg, exitChan)) <-exitChan }