From b3b711b2bc24996ca491d5b93d37035c999a3fe9 Mon Sep 17 00:00:00 2001 From: Aaron Paterson Date: Fri, 5 Dec 2025 00:05:19 -0700 Subject: [PATCH] to_device --- caddyconfig/httpcaddyfile/addresses.go | 133 +++++++++++++------------ caddyconfig/httpcaddyfile/builtins.go | 18 ++-- caddyconfig/httpcaddyfile/options.go | 18 ++-- 3 files changed, 86 insertions(+), 83 deletions(-) diff --git a/caddyconfig/httpcaddyfile/addresses.go b/caddyconfig/httpcaddyfile/addresses.go index 7a7a8b9cf..1bbbcd862 100644 --- a/caddyconfig/httpcaddyfile/addresses.go +++ b/caddyconfig/httpcaddyfile/addresses.go @@ -320,9 +320,9 @@ func (st *ServerType) listenersForServerBlockAddress(sblock serverBlock, addr Ad } } else { lnCfgVals = []bindOptions{{ - addresses: []string{""}, - interfaces: nil, - protocols: nil, + addresses: []string{""}, + protocols: nil, + to_device: false, }} } } @@ -332,76 +332,79 @@ func (st *ServerType) listenersForServerBlockAddress(sblock serverBlock, addr Ad interfaces := map[string][]net.Addr{} for _, lnCfgVal := range lnCfgVals { lnAddresses := make([]string, 0, len(lnCfgVal.addresses)) - lnAddresses = append(lnAddresses, lnCfgVal.addresses...) - for _, lnIface := range lnCfgVal.interfaces { - lnNetw, lnDevice, _, err := caddy.SplitNetworkAddress(lnIface) - if err != nil { - return nil, fmt.Errorf("splitting listener interface: %v", err) - } - - ifaceAddresses, ok := interfaces[lnDevice] - if !ok { - iface, err := net.InterfaceByName(lnDevice) + for _, lnAddress := range lnCfgVal.addresses { + if lnCfgVal.to_device { + lnNetw, lnDevice, _, err := caddy.SplitNetworkAddress(lnAddress) if err != nil { - return nil, fmt.Errorf("querying listener interface: %v: %v", lnDevice, err) + return nil, fmt.Errorf("splitting listener interface: %v", err) } - if iface == nil { - return nil, fmt.Errorf("querying listener interface: %v", lnDevice) - } - ifaceAddresses, err := iface.Addrs() - if err != nil { - return nil, fmt.Errorf("querying listener interface addresses: %v: %v", lnDevice, err) - } - interfaces[lnDevice] = ifaceAddresses - } - lnIfaceAddresses := []string{} - for _, ifaceAddress := range ifaceAddresses { - if caddy.IsReservedNetwork(lnNetw) { - var addrok, netwok bool - - var ip net.IP - switch ifaceAddressValue := ifaceAddress.(type) { - case *net.IPAddr: - ip, addrok, netwok = ifaceAddressValue.IP, true, true - case *net.IPNet: - ip, addrok, netwok = ifaceAddressValue.IP, true, true - case *net.TCPAddr: - ip, addrok, netwok = ifaceAddressValue.IP, true, caddy.IsTCPNetwork(lnNetw) - case *net.UDPAddr: - ip, addrok, netwok = ifaceAddressValue.IP, true, caddy.IsUDPNetwork(lnNetw) + ifaceAddresses, ok := interfaces[lnDevice] + if !ok { + iface, err := net.InterfaceByName(lnDevice) + if err != nil { + return nil, fmt.Errorf("querying listener interface: %v: %v", lnDevice, err) } + if iface == nil { + return nil, fmt.Errorf("querying listener interface: %v", lnDevice) + } + ifaceAddresses, err := iface.Addrs() + if err != nil { + return nil, fmt.Errorf("querying listener interface addresses: %v: %v", lnDevice, err) + } + interfaces[lnDevice] = ifaceAddresses + } - if addrok { - if netwok { - if caddy.IsIPv4Network(lnNetw) && len(ip) == net.IPv4len || caddy.IsIPv6Network(lnNetw) && len(ip) == net.IPv6len { - lnIfaceAddresses = append(lnIfaceAddresses, ip.String()) + lnIfaceAddresses := []string{} + for _, ifaceAddress := range ifaceAddresses { + if caddy.IsReservedNetwork(lnNetw) { + var addrok, netwok bool + + var ip net.IP + switch ifaceAddressValue := ifaceAddress.(type) { + case *net.IPAddr: + ip, addrok, netwok = ifaceAddressValue.IP, true, true + case *net.IPNet: + ip, addrok, netwok = ifaceAddressValue.IP, true, true + case *net.TCPAddr: + ip, addrok, netwok = ifaceAddressValue.IP, true, caddy.IsTCPNetwork(lnNetw) + case *net.UDPAddr: + ip, addrok, netwok = ifaceAddressValue.IP, true, caddy.IsUDPNetwork(lnNetw) + } + + if addrok { + if netwok { + if caddy.IsIPv4Network(lnNetw) && len(ip) == net.IPv4len || caddy.IsIPv6Network(lnNetw) && len(ip) == net.IPv6len { + lnIfaceAddresses = append(lnIfaceAddresses, ip.String()) + } } + continue } - continue - } - var name string - switch ifaceAddressValue := ifaceAddress.(type) { - case *net.UnixAddr: - name, addrok, netwok = ifaceAddressValue.Name, true, caddy.IsUnixNetwork(lnNetw) - } - - if addrok { - if netwok { - lnIfaceAddresses = append(lnIfaceAddresses, name) + var name string + switch ifaceAddressValue := ifaceAddress.(type) { + case *net.UnixAddr: + name, addrok, netwok = ifaceAddressValue.Name, true, caddy.IsUnixNetwork(lnNetw) } - continue + + if addrok { + if netwok { + lnIfaceAddresses = append(lnIfaceAddresses, name) + } + continue + } + } else { + lnIfaceAddresses = append(lnIfaceAddresses, ifaceAddress.String()) } - } else { - lnIfaceAddresses = append(lnIfaceAddresses, ifaceAddress.String()) } - } - if len(lnIfaceAddresses) == 0 { - return nil, fmt.Errorf("no available listener interface addresses for network: %v: %v", lnDevice, lnNetw) - } - for _, lnIfaceAddress := range lnIfaceAddresses { - lnAddresses = append(lnAddresses, caddy.JoinNetworkAddress(lnNetw, lnIfaceAddress, "")) + if len(lnIfaceAddresses) == 0 { + return nil, fmt.Errorf("no available listener interface addresses for network: %v: %v", lnDevice, lnNetw) + } + for _, lnIfaceAddress := range lnIfaceAddresses { + lnAddresses = append(lnAddresses, caddy.JoinNetworkAddress(lnNetw, lnIfaceAddress, "")) + } + } else { + lnAddresses = append(lnAddresses, lnAddress) } } for _, lnAddr := range lnAddresses { @@ -426,9 +429,9 @@ func (st *ServerType) listenersForServerBlockAddress(sblock serverBlock, addr Ad } type bindOptions struct { - addresses []string - interfaces []string - protocols []string + addresses []string + protocols []string + to_device bool } // Address represents a site address. It contains diff --git a/caddyconfig/httpcaddyfile/builtins.go b/caddyconfig/httpcaddyfile/builtins.go index a0eb77047..13b4fef9b 100644 --- a/caddyconfig/httpcaddyfile/builtins.go +++ b/caddyconfig/httpcaddyfile/builtins.go @@ -63,30 +63,30 @@ func init() { // }] func parseBind(h Helper) ([]ConfigValue, error) { h.Next() // consume directive name - var addresses, interfaces, protocols []string + var ( + addresses, protocols []string + to_device bool + ) addresses = h.RemainingArgs() for h.NextBlock(0) { switch h.Val() { - case "interfaces": - interfaces = h.RemainingArgs() - if len(interfaces) == 0 { - return nil, h.Errf("interfaces requires one or more arguments") - } case "protocols": protocols = h.RemainingArgs() if len(protocols) == 0 { return nil, h.Errf("protocols requires one or more arguments") } + case "to_device": + to_device = true default: return nil, h.Errf("unknown subdirective: %s", h.Val()) } } return []ConfigValue{{Class: "bind", Value: bindOptions{ - addresses: addresses, - interfaces: interfaces, - protocols: protocols, + addresses: addresses, + protocols: protocols, + to_device: to_device, }}}, nil } diff --git a/caddyconfig/httpcaddyfile/options.go b/caddyconfig/httpcaddyfile/options.go index c605ff211..02772f813 100644 --- a/caddyconfig/httpcaddyfile/options.go +++ b/caddyconfig/httpcaddyfile/options.go @@ -307,7 +307,10 @@ func parseOptSingleString(d *caddyfile.Dispenser, _ any) (any, error) { func parseOptDefaultBind(d *caddyfile.Dispenser, _ any) (any, error) { d.Next() // consume option name - var addresses, interfaces, protocols []string + var ( + addresses, protocols []string + to_device bool + ) addresses = d.RemainingArgs() if len(addresses) == 0 { @@ -316,25 +319,22 @@ func parseOptDefaultBind(d *caddyfile.Dispenser, _ any) (any, error) { for d.NextBlock(0) { switch d.Val() { - case "interfaces": - interfaces = d.RemainingArgs() - if len(interfaces) == 0 { - return nil, d.Errf("interfaces requires one or more arguments") - } case "protocols": protocols = d.RemainingArgs() if len(protocols) == 0 { return nil, d.Errf("protocols requires one or more arguments") } + case "to_device": + to_device = true default: return nil, d.Errf("unknown subdirective: %s", d.Val()) } } return []ConfigValue{{Class: "bind", Value: bindOptions{ - addresses: addresses, - interfaces: interfaces, - protocols: protocols, + addresses: addresses, + protocols: protocols, + to_device: to_device, }}}, nil }