diff options
-rw-r--r-- | config.go | 13 | ||||
-rw-r--r-- | deliver_local.go | 3 | ||||
-rw-r--r-- | errors.go | 7 | ||||
-rw-r--r-- | mx_recv.go | 17 |
4 files changed, 19 insertions, 21 deletions
@@ -22,14 +22,16 @@ var config struct { Conn string `scfg:"conn"` } `scfg:"db"` MX struct { - Net string `scfg:"net"` + Net string `scfg:"net"` Addr string `scfg:"addr"` } `scfg:"mx"` _tls_config *tls.Config } var ( - config_mutex sync.RWMutex // covers things like the database too - global_db *pgxpool.Pool // only call Close() after replacing this global variable + config_mutex sync.RWMutex // covers things like the database too + config_context context.Context + config_context_cancel context.CancelFunc + global_db *pgxpool.Pool // only call Close() after replacing this global variable ) // load_config loads the configuration file and sets up global things according @@ -47,6 +49,7 @@ func load_config(path string) error { if err != nil { return err } + config_context, config_context_cancel = context.WithCancel(context.Background()) // TLS key loading and TLS config creation cer, err := tls.LoadX509KeyPair(config.TLS.Cert, config.TLS.Key) @@ -62,7 +65,7 @@ func load_config(path string) error { if config.DB.Type != "postgres" { return err_unsupported_database_type } - global_db, err = pgxpool.New(context.Background(), config.DB.Conn) + global_db, err = pgxpool.New(config_context, config.DB.Conn) // BUG: Context-related leak: cancel context when the config is invalidated if err != nil { return err @@ -77,7 +80,7 @@ func load_config(path string) error { // config_fetch_one fetches one value from the configuration. // -// Consequtive calls do not guarantee a consistent snapshot of the +// Consecutive calls do not guarantee a consistent snapshot of the // configuration. Use config_consistent_run in these cases. func config_fetch_one[T any](x *T) T { config_mutex.RLock() diff --git a/deliver_local.go b/deliver_local.go index 9a29459..47af7f9 100644 --- a/deliver_local.go +++ b/deliver_local.go @@ -1,8 +1,8 @@ package main import ( - "fmt" "context" + "github.com/jackc/pgx/v5/pgxpool" ) @@ -15,7 +15,6 @@ func deliver_local(ctx context.Context, db *pgxpool.Pool, envelope_from string, for _, address := range addresses { _, err = tx.Exec(ctx, "INSERT INTO mail (mailbox_id, data) SELECT a.mailbox_id, $2::bytea FROM addresses a JOIN mailboxes m ON a.mailbox_id = m.id WHERE a.address = $1;", address, data) if err != nil { - fmt.Printf("%#v\n", err) return err } } @@ -2,16 +2,13 @@ package main import ( "errors" - "fmt" "strings" ) -var ( - err_unsupported_database_type = errors.New("Unsupported database type; only \"postgres\" is currently supported") -) +var err_unsupported_database_type = errors.New("Unsupported database type; only \"postgres\" is currently supported") type err_local_recipients_not_found_t []string func (e *err_local_recipients_not_found_t) Error() string { - return fmt.Sprintf("Local recipients not found: %s", strings.Join([]string(*e), ", ")) + return "Local recipients not found: " + strings.Join([]string(*e), ", ") } @@ -34,10 +34,9 @@ type mx_recv_session struct { current_mail_from string current_rcpt_to []string server_state server_state_t - ctx context.Context } -func (session *mx_recv_session) handle() error { +func (session *mx_recv_session) handle(ctx context.Context) error { session.buf_conn = bufio.NewReadWriter(bufio.NewReader(session.net_conn), bufio.NewWriter(session.net_conn)) config_consistent_run(func() { session.my_server_name = config.Server_name @@ -132,7 +131,7 @@ func (session *mx_recv_session) handle() error { } recipient_address, _, _ := mailkit.Strip_angle_brackets(param[len("TO:"):]) var count int - err := session.db.QueryRow(session.ctx, "SELECT COUNT (*) FROM addresses WHERE address = $1", recipient_address).Scan(&count) + err := session.db.QueryRow(ctx, "SELECT COUNT (*) FROM addresses WHERE address = $1", recipient_address).Scan(&count) if err != nil { _, _ = session.buf_conn.WriteString("451 Internal error: " + err.Error() + "\r\n") _ = session.buf_conn.Flush() @@ -184,13 +183,14 @@ func (session *mx_recv_session) handle() error { if err != nil { return err } - err = deliver_local(session.ctx, session.db, session.current_mail_from, session.current_rcpt_to, current_data, session.current_rcpt_to) + err = deliver_local(ctx, session.db, session.current_mail_from, session.current_rcpt_to, current_data, session.current_rcpt_to) var err_local_recipients_not_found *err_local_recipients_not_found_t - if errors.As(err, &err_local_recipients_not_found) { + switch { + case errors.As(err, &err_local_recipients_not_found): _, _ = session.buf_conn.WriteString("550 5.1.1 Recipient address rejected: " + err_local_recipients_not_found.Error() + "\r\n") - } else if err != nil { + case err != nil: _, _ = session.buf_conn.WriteString("500 2.0.0 Error: " + err.Error() + "\r\n") - } else { + default: _, _ = session.buf_conn.WriteString("250 2.0.0 Ok: Accepted\r\n") } _ = session.buf_conn.Flush() @@ -222,7 +222,6 @@ func (session *mx_recv_session) handle() error { func handle_mx_recv_conn(ctx context.Context, net_conn net.Conn) error { session := mx_recv_session{ net_conn: net_conn, - ctx: ctx, } - return session.handle() + return session.handle(ctx) } |