summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrea Barberio <insomniac@slackware.it>2019-04-29 13:52:22 +0100
committerinsomniac <insomniacslk@users.noreply.github.com>2019-04-29 15:44:25 +0100
commit03e9ac918544b248cd2d660195934d7c943cb4d7 (patch)
treea9b43d893419db1d567934dc56f23b2eaaf16e0d
parent5c6ea15a40cc06ac0af833fa3ef883de3f32037b (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>
-rw-r--r--dhcpv6/async/client.go2
-rw-r--r--dhcpv6/client6/client.go8
-rw-r--r--dhcpv6/defaults.go9
-rw-r--r--dhcpv6/nclient6/client_test.go2
-rw-r--r--dhcpv6/server6/server.go28
-rw-r--r--dhcpv6/server6/server_test.go2
-rw-r--r--examples/server6/main.go2
7 files changed, 40 insertions, 13 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)
}
diff --git a/examples/server6/main.go b/examples/server6/main.go
index 318937f..363a3ae 100644
--- a/examples/server6/main.go
+++ b/examples/server6/main.go
@@ -18,7 +18,7 @@ func main() {
IP: net.ParseIP("::1"),
Port: dhcpv6.DefaultServerPort,
}
- server, err := server6.NewServer(laddr, handler)
+ server, err := server6.NewServer("", laddr, handler)
if err != nil {
log.Fatal(err)
}