aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-01-13 12:25:46 +0800
committerRunxi Yu <me@runxiyu.org>2025-01-13 12:25:46 +0800
commit8724c4b8935aceefdc3cea4e82dfba7d28a36cc6 (patch)
tree3712dbd26f69cea86f85f07751b49d172f6f833c
parentClose connections on QUIT (diff)
downloadmaild-8724c4b8935aceefdc3cea4e82dfba7d28a36cc6.tar.gz
maild-8724c4b8935aceefdc3cea4e82dfba7d28a36cc6.tar.zst
maild-8724c4b8935aceefdc3cea4e82dfba7d28a36cc6.zip
Bug fixes
-rw-r--r--config.go13
-rw-r--r--deliver_local.go3
-rw-r--r--errors.go7
-rw-r--r--mx_recv.go17
4 files changed, 19 insertions, 21 deletions
diff --git a/config.go b/config.go
index 591bcd9..e7d6aa4 100644
--- a/config.go
+++ b/config.go
@@ -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
}
}
diff --git a/errors.go b/errors.go
index 1512b60..7ee429a 100644
--- a/errors.go
+++ b/errors.go
@@ -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), ", ")
}
diff --git a/mx_recv.go b/mx_recv.go
index 8df6cfa..ef8c2cc 100644
--- a/mx_recv.go
+++ b/mx_recv.go
@@ -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)
}