core: add `iface` as network type
This PR allows using the interface name as the network address host when using the iface+?{udp,tcp} network. In other words, user will be able to say:
example.com {
bind iface/eth0
respond "What's up, Doc?"
}
Because an interface may have multiple IPv6 addresses, and I can't come up with a clean up to communicate this using the host part without it being hairy, I limited this to picking up only the IPv4 address of the defined interface.
I tried at first using the format, e.g. iface/en0+tcp, for the protocol selection, but the HTTP3 listener is created by looking up a custom registered network, then using that network to lookup its listener constructor. This makes registering a custom network for UDP the only possible approach to hook our constructor, i.e. doing iface+udp et al.
I'd classify this highly experimental. It's extremely limited for only supporting IPv4 addresses. I don't foresee any possibility of adding IPv6 support without it being convolute and painful. Do we really want this?
This is interesting, but it's a weird violation of abstractions. The bind directive typically describes the socket not the interface. Hence you can bind to tcp/udp/unix and an address, but specifying an interface is like a whole separate thing.
I'm not sure yet what the best solution is... would be nice to avoid funky mini-syntax here.
I put this together as PoC in response to https://github.com/caddyserver/caddy/pull/6504#issuecomment-2281492551. I don't know if it's the best approach or not. It's an experiment.
8 years of discussion about the interface/hostname/ipv6 multicast situation here https://github.com/golang/go/issues/9334 we should make a MultiListener implementation package, add it to Caddy as a PoC, and then rally to get it added into net.go 💪
also with the new optional block for bind, i think we could do
bind tcp/ {
iface en0
}
for protocol selection.
@MayCXC I think I like that more. :thinking: Still a weird concept overall to me :smile:
@MayCXC I think I like that more. 🤔 Still a weird concept overall to me 😄
I think of it like the network host for the specified gateway(s), i.e "0.0.0.0 for my wireguard VPN":
bind tcp/ {
iface wg0
}
or similarly:
bind tcp/ {
iface lo
}
is equivalent to bind tcp/127.0.0.1
Superceded by #7256