mirror of
https://github.com/coredhcp/coredhcp.git
synced 2026-05-05 12:06:13 +02:00
Allow listening on multiple addresses at once
This extends both the configuration and the server, to allow binding the
server(s) to multiple addresses at once.
The `listen` stanza can now accept either a string (for a single address) or
a list to listen to multiple addresses, ie all of these are valid:
```yaml
server6:
...
server6:
listen: "[2001:db8:🅰️2]"
...
server6:
listen:
- "[2001:db8:🅰️2]:530"
- "%eth0"
```
and the equivalent for server4
Signed-off-by: Anatole Denis <anatole@unverle.fr>
This commit is contained in:
parent
3806733ad7
commit
ca2b5ac2d6
@ -41,8 +41,7 @@ func New() *Config {
|
||||
// ServerConfig holds a server configuration that is specific to either the
|
||||
// DHCPv6 server or the DHCPv4 server.
|
||||
type ServerConfig struct {
|
||||
Listener *net.UDPAddr
|
||||
Interface string
|
||||
Addresses []*net.UDPAddr
|
||||
Plugins []*PluginConfig
|
||||
}
|
||||
|
||||
@ -136,12 +135,11 @@ func splitHostPort(hostport string) (ip string, zone string, port string, err er
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Config) getListenAddress(ver protocolVersion) (*net.UDPAddr, error) {
|
||||
func (c *Config) getListenAddress(addr string, ver protocolVersion) (*net.UDPAddr, error) {
|
||||
if err := protoVersionCheck(ver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := c.v.GetString(fmt.Sprintf("server%d.listen", ver))
|
||||
ipStr, ifname, portStr, err := splitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, ConfigErrorFromString("dhcpv%d: %v", ver, err)
|
||||
@ -154,13 +152,15 @@ func (c *Config) getListenAddress(ver protocolVersion) (*net.UDPAddr, error) {
|
||||
ip = net.IPv4zero
|
||||
case protocolV6:
|
||||
ip = net.IPv6unspecified
|
||||
default:
|
||||
panic("BUG: Unknown protocol version")
|
||||
}
|
||||
}
|
||||
if ip == nil {
|
||||
return nil, ConfigErrorFromString("dhcpv%d: invalid IP address in `listen` directive: %s", ver, ipStr)
|
||||
}
|
||||
if ip4 := ip.To4(); (ver == protocolV6 && ip4 != nil) || (ver == protocolV4 && ip4 == nil) {
|
||||
return nil, ConfigErrorFromString("dhcpv%d: not a valid IPv%d address in `listen` directive", ver, ver)
|
||||
return nil, ConfigErrorFromString("dhcpv%d: not a valid IPv%d address in `listen` directive: '%s'", ver, ver, ipStr)
|
||||
}
|
||||
|
||||
var port int
|
||||
@ -170,11 +170,13 @@ func (c *Config) getListenAddress(ver protocolVersion) (*net.UDPAddr, error) {
|
||||
port = dhcpv4.ServerPort
|
||||
case protocolV6:
|
||||
port = dhcpv6.DefaultServerPort
|
||||
default:
|
||||
panic("BUG: Unknown protocol version")
|
||||
}
|
||||
} else {
|
||||
port, err = strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return nil, ConfigErrorFromString("dhcpv%d: invalid `listen` port", ver)
|
||||
return nil, ConfigErrorFromString("dhcpv%d: invalid `listen` port '%s'", ver, portStr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,16 +207,6 @@ func (c *Config) parseConfig(ver protocolVersion) error {
|
||||
// it is valid to have no server configuration defined
|
||||
return nil
|
||||
}
|
||||
listenAddr, err := c.getListenAddress(ver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if listenAddr == nil {
|
||||
// no listener is configured, so `c.Server6` (or `c.Server4` if v4)
|
||||
// will stay nil.
|
||||
log.Warnf("DHCPv%d: server%d present but no listen address defined. The server will not be started", ver, ver)
|
||||
return nil
|
||||
}
|
||||
// read plugin configuration
|
||||
plugins, err := c.getPlugins(ver)
|
||||
if err != nil {
|
||||
@ -223,9 +215,24 @@ func (c *Config) parseConfig(ver protocolVersion) error {
|
||||
for _, p := range plugins {
|
||||
log.Printf("DHCPv%d: found plugin `%s` with %d args: %v", ver, p.Name, len(p.Args), p.Args)
|
||||
}
|
||||
|
||||
listen := c.v.Get(fmt.Sprintf("server%d.listen", ver))
|
||||
addrs, err := cast.ToStringSliceE(listen)
|
||||
if err != nil {
|
||||
addrs = []string{cast.ToString(listen)}
|
||||
}
|
||||
|
||||
listeners := []*net.UDPAddr{}
|
||||
for _, a := range addrs {
|
||||
listenAddr, err := c.getListenAddress(a, ver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listeners = append(listeners, listenAddr)
|
||||
}
|
||||
|
||||
sc := ServerConfig{
|
||||
Listener: listenAddr,
|
||||
Interface: listenAddr.Zone,
|
||||
Addresses: listeners,
|
||||
Plugins: plugins,
|
||||
}
|
||||
if ver == protocolV6 {
|
||||
|
||||
52
coredhcp.go
52
coredhcp.go
@ -27,8 +27,8 @@ type Server struct {
|
||||
Handlers6 []handler.Handler6
|
||||
Handlers4 []handler.Handler4
|
||||
Config *config.Config
|
||||
Server6 *server6.Server
|
||||
Server4 *server4.Server
|
||||
Servers6 []*server6.Server
|
||||
Servers4 []*server4.Server
|
||||
errors chan error
|
||||
}
|
||||
|
||||
@ -240,25 +240,33 @@ func (s *Server) Start() error {
|
||||
|
||||
// listen
|
||||
if s.Config.Server6 != nil {
|
||||
log.Printf("Starting DHCPv6 listener on %v", s.Config.Server6.Listener)
|
||||
s.Server6, err = server6.NewServer(s.Config.Server6.Interface, s.Config.Server6.Listener, s.MainHandler6)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Println("Starting DHCPv6 server")
|
||||
for _, l := range s.Config.Server6.Addresses {
|
||||
s6, err := server6.NewServer(l.Zone, l, s.MainHandler6)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Servers6 = append(s.Servers6, s6)
|
||||
log.Infof("Listen %s", l)
|
||||
go func() {
|
||||
s.errors <- s6.Serve()
|
||||
}()
|
||||
}
|
||||
go func() {
|
||||
s.errors <- s.Server6.Serve()
|
||||
}()
|
||||
}
|
||||
|
||||
if s.Config.Server4 != nil {
|
||||
log.Printf("Starting DHCPv4 listener on %v", s.Config.Server4.Listener)
|
||||
s.Server4, err = server4.NewServer(s.Config.Server4.Interface, s.Config.Server4.Listener, s.MainHandler4)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Println("Starting DHCPv4 server")
|
||||
for _, l := range s.Config.Server4.Addresses {
|
||||
s4, err := server4.NewServer(l.Zone, l, s.MainHandler4)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Servers4 = append(s.Servers4, s4)
|
||||
log.Infof("Listen %s", l)
|
||||
go func() {
|
||||
s.errors <- s4.Serve()
|
||||
}()
|
||||
}
|
||||
go func() {
|
||||
s.errors <- s.Server4.Serve()
|
||||
}()
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -268,11 +276,15 @@ func (s *Server) Start() error {
|
||||
func (s *Server) Wait() error {
|
||||
log.Print("Waiting")
|
||||
err := <-s.errors
|
||||
if s.Server6 != nil {
|
||||
s.Server6.Close()
|
||||
for _, s6 := range s.Servers6 {
|
||||
if s6 != nil {
|
||||
s6.Close()
|
||||
}
|
||||
}
|
||||
if s.Server4 != nil {
|
||||
s.Server4.Close()
|
||||
for _, s4 := range s.Servers4 {
|
||||
if s4 != nil {
|
||||
s4.Close()
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user