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) } }
// Process an incoming admin service connection. func (a *AdminService) Handle(conn *net.TCPConn) { defer func() { log.Trace(func() string { return fmt.Sprintf("%s: client disconnected", conn.RemoteAddr()) }) conn.Close() }() if a.draining { return } }
// Process an incoming SMTP connection. func (s *SMTPService) Handle(conn *net.TCPConn) { defer func() { log.Trace(func() string { return fmt.Sprintf("%s: client disconnected", conn.RemoteAddr()) }) conn.Close() }() // Send a 421 error response if the server is in the process of shutting // down when the client connects. if s.draining { conn.Write(ResponseMap[421]) return } session := NewSMTPSession(conn, s.cfg) if verdict := session.Greet(); verdict == Terminate { return } for { if verdict := session.Process(); verdict == Terminate { return } } }