From 490fd1d63d1f1dfc86ee6228d8d6c2e087ac0d32 Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Sat, 10 Aug 2024 22:46:46 +0300 Subject: [PATCH] core: add `iface` as network type Signed-off-by: Mohammed Al Sahaf --- interface.go | 51 +++++++++++++++++++++++++++++++++++++ modules/caddyhttp/server.go | 4 +++ 2 files changed, 55 insertions(+) create mode 100644 interface.go diff --git a/interface.go b/interface.go new file mode 100644 index 00000000000..35409e7a652 --- /dev/null +++ b/interface.go @@ -0,0 +1,51 @@ +package caddy + +import ( + "context" + "fmt" + "net" + "strings" +) + +func init() { + RegisterNetwork("iface", getInterfaceListener) + RegisterNetwork("iface+tcp", getInterfaceListener) + RegisterNetwork("iface+udp", getInterfaceListener) +} + +func getInterfaceListener(ctx context.Context, network, addr string, config net.ListenConfig) (any, error) { + // assuming addr = "interface+family:port" + // if family is missing, then assume tcp + family := "tcp" + parts := strings.Split(network, "+") + if len(parts) == 2 { + family = parts[1] + } + host, port, _ := net.SplitHostPort(addr) + iface, err := net.InterfaceByName(host) + if err != nil { + return nil, fmt.Errorf("interface %s not found", addr) + } + addrs, err := iface.Addrs() + if err != nil { + return nil, fmt.Errorf("error on obtaining interface %s addresses: %s", iface.Name, err) + } + if len(addrs) == 0 { + return nil, fmt.Errorf("interface %s has no addresses", iface.Name) + } + for _, addr := range addrs { + if face, ok := addr.(*net.IPNet); ok { + if ip4 := face.IP.To4(); ip4 != nil { + switch family { + case "tcp": + return net.Listen(family, net.JoinHostPort(ip4.String(), port)) + case "udp": + return net.ListenPacket(family, net.JoinHostPort(ip4.String(), port)) + default: + return net.Listen(family, net.JoinHostPort(ip4.String(), port)) + } + } + } + } + return nil, fmt.Errorf("interface %s has no IPv4 addresses", iface.Name) +} diff --git a/modules/caddyhttp/server.go b/modules/caddyhttp/server.go index 6caaabcdaf0..a1328bcfaa5 100644 --- a/modules/caddyhttp/server.go +++ b/modules/caddyhttp/server.go @@ -40,6 +40,10 @@ import ( "github.com/caddyserver/caddy/v2/modules/caddytls" ) +func init() { + RegisterNetworkHTTP3("iface", "iface+udp") +} + // Server describes an HTTP server. type Server struct { // Socket addresses to which to bind listeners. Accepts