mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 17:44:35 +03:00
move config-changing code from package mox-/ to admin/
needed for upcoming changes, where (now) package admin needs to import package store. before, because package store imports mox- (for accessing the active config), that would lead to a cyclic import. package mox- keeps its active config, package admin has the higher-level config-changing functions.
This commit is contained in:
109
mox-/ip.go
109
mox-/ip.go
@ -1,6 +1,9 @@
|
||||
package mox
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
)
|
||||
|
||||
@ -19,3 +22,109 @@ func Network(ip string) string {
|
||||
}
|
||||
return "tcp6"
|
||||
}
|
||||
|
||||
// DomainSPFIPs returns IPs to include in SPF records for domains. It includes the
|
||||
// IPs on listeners that have SMTP enabled, and includes IPs configured for SOCKS
|
||||
// transports.
|
||||
func DomainSPFIPs() (ips []net.IP) {
|
||||
for _, l := range Conf.Static.Listeners {
|
||||
if !l.SMTP.Enabled || l.IPsNATed {
|
||||
continue
|
||||
}
|
||||
ipstrs := l.IPs
|
||||
if len(l.NATIPs) > 0 {
|
||||
ipstrs = l.NATIPs
|
||||
}
|
||||
for _, ipstr := range ipstrs {
|
||||
ip := net.ParseIP(ipstr)
|
||||
if ip.IsUnspecified() {
|
||||
continue
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
for _, t := range Conf.Static.Transports {
|
||||
if t.Socks != nil {
|
||||
ips = append(ips, t.Socks.IPs...)
|
||||
}
|
||||
}
|
||||
return ips
|
||||
}
|
||||
|
||||
// IPs returns ip addresses we may be listening/receiving mail on or
|
||||
// connecting/sending from to the outside.
|
||||
func IPs(ctx context.Context, receiveOnly bool) ([]net.IP, error) {
|
||||
log := pkglog.WithContext(ctx)
|
||||
|
||||
// Try to gather all IPs we are listening on by going through the config.
|
||||
// If we encounter 0.0.0.0 or ::, we'll gather all local IPs afterwards.
|
||||
var ips []net.IP
|
||||
var ipv4all, ipv6all bool
|
||||
for _, l := range Conf.Static.Listeners {
|
||||
// If NATed, we don't know our external IPs.
|
||||
if l.IPsNATed {
|
||||
return nil, nil
|
||||
}
|
||||
check := l.IPs
|
||||
if len(l.NATIPs) > 0 {
|
||||
check = l.NATIPs
|
||||
}
|
||||
for _, s := range check {
|
||||
ip := net.ParseIP(s)
|
||||
if ip.IsUnspecified() {
|
||||
if ip.To4() != nil {
|
||||
ipv4all = true
|
||||
} else {
|
||||
ipv6all = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
|
||||
// We'll list the IPs on the interfaces. How useful is this? There is a good chance
|
||||
// we're listening on all addresses because of a load balancer/firewall.
|
||||
if ipv4all || ipv6all {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing network interfaces: %v", err)
|
||||
}
|
||||
for _, iface := range ifaces {
|
||||
if iface.Flags&net.FlagUp == 0 {
|
||||
continue
|
||||
}
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing addresses for network interface: %v", err)
|
||||
}
|
||||
if len(addrs) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
ip, _, err := net.ParseCIDR(addr.String())
|
||||
if err != nil {
|
||||
log.Errorx("bad interface addr", err, slog.Any("address", addr))
|
||||
continue
|
||||
}
|
||||
v4 := ip.To4() != nil
|
||||
if ipv4all && v4 || ipv6all && !v4 {
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if receiveOnly {
|
||||
return ips, nil
|
||||
}
|
||||
|
||||
for _, t := range Conf.Static.Transports {
|
||||
if t.Socks != nil {
|
||||
ips = append(ips, t.Socks.IPs...)
|
||||
}
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user