Skip to content

Commit

Permalink
listen/bind in deterministic order for consistent error messages, and…
Browse files Browse the repository at this point in the history
… warn if quickstart cannot find public ip's

without public ip's, the generated mox config will try to listen on 0.0.0.0 and
::, but because there is already a listener for 127.0.0.1:80 (and possibly
others), a bind for 0.0.0.0:80 will fail. explicit public ip's are needed.

the public http listener is useful for ACME validation over http.

for issue #52
  • Loading branch information
mjl- committed Aug 10, 2023
1 parent 01bcd98 commit 038b478
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 6 deletions.
15 changes: 13 additions & 2 deletions http/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (

_ "net/http/pprof"

"golang.org/x/exp/maps"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
Expand Down Expand Up @@ -362,7 +364,13 @@ func Listen() {
}
}

for name, l := range mox.Conf.Static.Listeners {
// Initialize listeners in deterministic order for the same potential error
// messages.
names := maps.Keys(mox.Conf.Static.Listeners)
sort.Strings(names)
for _, name := range names {
l := mox.Conf.Static.Listeners[name]

portServe := map[int]*serve{}

var ensureServe func(https bool, port int, kind string) *serve
Expand Down Expand Up @@ -546,7 +554,10 @@ func Listen() {
ensureManagerHosts[m] = hosts
}

for port, srv := range portServe {
ports := maps.Keys(portServe)
sort.Ints(ports)
for _, port := range ports {
srv := portServe[port]
sort.Slice(srv.PathHandlers, func(i, j int) bool {
a := srv.PathHandlers[i].Path
b := srv.PathHandlers[j].Path
Expand Down
11 changes: 8 additions & 3 deletions imapserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ import (
"strings"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/mjl-/bstore"

"github.com/mjl-/mox/config"
Expand Down Expand Up @@ -307,7 +308,11 @@ type msgseq uint32

// Listen initializes all imap listeners for the configuration, and stores them for Serve to start them.
func Listen() {
for name, listener := range mox.Conf.Static.Listeners {
names := maps.Keys(mox.Conf.Static.Listeners)
sort.Strings(names)
for _, name := range names {
listener := mox.Conf.Static.Listeners[name]

var tlsConfig *tls.Config
if listener.TLS != nil {
tlsConfig = listener.TLS.Config
Expand Down
11 changes: 11 additions & 0 deletions quickstart.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,17 @@ listed in more DNS block lists, visit:
fmt.Printf(" OK\n")
}
}

if len(publicIPs) == 0 {
log.Printf(`WARNING: Could not find your public IP address(es). The "public" listener is
configured to listen on 0.0.0.0 (IPv4) and :: (IPv6). If you don't change these
to your actual public IP addresses, you will likely get "address in use" errors
when starting mox because the "internal" listener binds to a specific IP
address on the same port(s).
`)
}

fmt.Printf("\n")

user := "mox"
Expand Down
9 changes: 8 additions & 1 deletion smtpserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ import (
"net"
"os"
"runtime/debug"
"sort"
"strconv"
"strings"
"sync"
"time"

"golang.org/x/exp/maps"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

Expand Down Expand Up @@ -175,7 +178,11 @@ func durationDefault(delay *time.Duration, def time.Duration) time.Duration {
// Listen initializes network listeners for incoming SMTP connection.
// The listeners are stored for a later call to Serve.
func Listen() {
for name, listener := range mox.Conf.Static.Listeners {
names := maps.Keys(mox.Conf.Static.Listeners)
sort.Strings(names)
for _, name := range names {
listener := mox.Conf.Static.Listeners[name]

var tlsConfig *tls.Config
if listener.TLS != nil {
tlsConfig = listener.TLS.Config
Expand Down

0 comments on commit 038b478

Please sign in to comment.