diff options
author | Andrea Barberio <insomniac@slackware.it> | 2019-04-29 13:52:22 +0100 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2019-04-29 15:44:25 +0100 |
commit | 03e9ac918544b248cd2d660195934d7c943cb4d7 (patch) | |
tree | a9b43d893419db1d567934dc56f23b2eaaf16e0d /dhcpv6 | |
parent | 5c6ea15a40cc06ac0af833fa3ef883de3f32037b (diff) |
[server6] Server should join multicast address
The previous logic was wrong - there's no "listening" on multicast
address, the server should listen on the given address, and join the
multicast group. This PR fixes it.
Also moved the multicast addresses to a common package.
Tested with unit/integ tests, and with coredhcp.
Signed-off-by: Andrea Barberio <insomniac@slackware.it>
Diffstat (limited to 'dhcpv6')
-rw-r--r-- | dhcpv6/async/client.go | 2 | ||||
-rw-r--r-- | dhcpv6/client6/client.go | 8 | ||||
-rw-r--r-- | dhcpv6/defaults.go | 9 | ||||
-rw-r--r-- | dhcpv6/nclient6/client_test.go | 2 | ||||
-rw-r--r-- | dhcpv6/server6/server.go | 28 | ||||
-rw-r--r-- | dhcpv6/server6/server_test.go | 2 |
6 files changed, 39 insertions, 12 deletions
diff --git a/dhcpv6/async/client.go b/dhcpv6/async/client.go index 4749e70..b2f977f 100644 --- a/dhcpv6/async/client.go +++ b/dhcpv6/async/client.go @@ -197,7 +197,7 @@ func (c *Client) receive(_ dhcpv6.DHCPv6) { func (c *Client) remoteAddr() (*net.UDPAddr, error) { if c.RemoteAddr == nil { - return &net.UDPAddr{IP: client6.AllDHCPRelayAgentsAndServers, Port: dhcpv6.DefaultServerPort}, nil + return &net.UDPAddr{IP: dhcpv6.AllDHCPRelayAgentsAndServers, Port: dhcpv6.DefaultServerPort}, nil } if addr, ok := c.RemoteAddr.(*net.UDPAddr); ok { diff --git a/dhcpv6/client6/client.go b/dhcpv6/client6/client.go index c7bd318..3722579 100644 --- a/dhcpv6/client6/client.go +++ b/dhcpv6/client6/client.go @@ -17,12 +17,6 @@ const ( MaxUDPReceivedPacketSize = 8192 // arbitrary size. Theoretically could be up to 65kb ) -// Broadcast destination IP addresses as defined by RFC 3315 -var ( - AllDHCPRelayAgentsAndServers = net.ParseIP("ff02::1:2") - AllDHCPServers = net.ParseIP("ff05::1:3") -) - // Client implements a DHCPv6 client type Client struct { ReadTimeout time.Duration @@ -119,7 +113,7 @@ func (c *Client) sendReceive(ifname string, packet dhcpv6.DHCPv6, expectedType d // if no RemoteAddr is specified, use AllDHCPRelayAgentsAndServers var raddr net.UDPAddr if c.RemoteAddr == nil { - raddr = net.UDPAddr{IP: AllDHCPRelayAgentsAndServers, Port: dhcpv6.DefaultServerPort} + raddr = net.UDPAddr{IP: dhcpv6.AllDHCPRelayAgentsAndServers, Port: dhcpv6.DefaultServerPort} } else { if addr, ok := c.RemoteAddr.(*net.UDPAddr); ok { raddr = *addr diff --git a/dhcpv6/defaults.go b/dhcpv6/defaults.go index ae14bba..ba25437 100644 --- a/dhcpv6/defaults.go +++ b/dhcpv6/defaults.go @@ -1,6 +1,15 @@ package dhcpv6 +import "net" + +// Default ports const ( DefaultClientPort = 546 DefaultServerPort = 547 ) + +// Default multicast groups +var ( + AllDHCPRelayAgentsAndServers = net.ParseIP("ff02::1:2") + AllDHCPServers = net.ParseIP("ff05::1:3") +) diff --git a/dhcpv6/nclient6/client_test.go b/dhcpv6/nclient6/client_test.go index 49b914e..902c7c5 100644 --- a/dhcpv6/nclient6/client_test.go +++ b/dhcpv6/nclient6/client_test.go @@ -65,7 +65,7 @@ func serveAndClient(ctx context.Context, responses [][]*dhcpv6.Message, opt ...C h := &handler{ responses: responses, } - s, err := server6.NewServer(nil, h.handle, server6.WithConn(serverRawConn)) + s, err := server6.NewServer("", nil, h.handle, server6.WithConn(serverRawConn)) if err != nil { panic(err) } diff --git a/dhcpv6/server6/server.go b/dhcpv6/server6/server.go index e4fcf91..ab9cb32 100644 --- a/dhcpv6/server6/server.go +++ b/dhcpv6/server6/server.go @@ -58,6 +58,7 @@ import ( "net" "github.com/insomniacslk/dhcp/dhcpv6" + "golang.org/x/net/ipv6" ) // Handler is a type that defines the handler function to be called every time a @@ -111,8 +112,12 @@ func WithConn(conn net.PacketConn) ServerOpt { } } -// NewServer initializes and returns a new Server object -func NewServer(addr *net.UDPAddr, handler Handler, opt ...ServerOpt) (*Server, error) { +// NewServer initializes and returns a new Server object, listening on `addr`, +// and joining the multicast group ff02::1:2 . If `addr` is nil, IPv6 unspec is +// used. If `WithConn` is used with a non-nil address, `addr` and `ifname` have +// no effect. In such case, joining the multicast group is the caller's +// responsibility. +func NewServer(ifname string, addr *net.UDPAddr, handler Handler, opt ...ServerOpt) (*Server, error) { s := &Server{ handler: handler, } @@ -122,10 +127,29 @@ func NewServer(addr *net.UDPAddr, handler Handler, opt ...ServerOpt) (*Server, e } if s.conn == nil { + // no connection provided by the user, create a new one conn, err := net.ListenUDP("udp6", addr) if err != nil { return nil, err } + // join multicast group on the specified interface + var iface *net.Interface + if ifname == "" { + iface = nil + } else { + iface, err = net.InterfaceByName(ifname) + if err != nil { + return nil, err + } + } + group := net.UDPAddr{ + IP: dhcpv6.AllDHCPRelayAgentsAndServers, + Port: dhcpv6.DefaultServerPort, + } + p := ipv6.NewPacketConn(conn) + if err := p.JoinGroup(iface, &group); err != nil { + return nil, err + } s.conn = conn } return s, nil diff --git a/dhcpv6/server6/server_test.go b/dhcpv6/server6/server_test.go index 3b204f1..c81525a 100644 --- a/dhcpv6/server6/server_test.go +++ b/dhcpv6/server6/server_test.go @@ -33,7 +33,7 @@ func setUpClientAndServer(handler Handler) (*nclient6.Client, *Server) { IP: net.ParseIP("::1"), Port: 0, } - s, err := NewServer(laddr, handler) + s, err := NewServer("lo", laddr, handler) if err != nil { panic(err) } |