From 486c8612a71ba5e1f251fbbbf08a91e3d8f77bfa Mon Sep 17 00:00:00 2001 From: Anatole Denis Date: Tue, 15 Oct 2019 10:16:05 +0200 Subject: server4: Respect listen address NewIPv4UDPConn doesn't support listening on a specific address, only on the wildcard address. This extends it to allow listening on an address, and at the same time homogenizes the function signature with the NewIPv6UDPConn server6 equivalent. It modifies NewServer() to pass the full address given to it instead of just the port as well Note that listening on a non-wildcard interface is seldom useful as the socket won't receive broadcasts, so it is useless in a direct-attached server. It can be useful in a server only used behind relays This breaks API compatibility for NewIPv4UDPConn, which as far as I know nobody uses (yet) Signed-off-by: Anatole Denis --- dhcpv4/server4/conn.go | 12 +++++++++--- dhcpv4/server4/server.go | 2 +- dhcpv4/server4/server_test.go | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/dhcpv4/server4/conn.go b/dhcpv4/server4/conn.go index 0a4c73a..d62a5ac 100644 --- a/dhcpv4/server4/conn.go +++ b/dhcpv4/server4/conn.go @@ -14,7 +14,7 @@ import ( // given based on a IPv4 DGRAM socket. The UDP connection allows broadcasting. // // The interface must already be configured. -func NewIPv4UDPConn(iface string, port int) (*net.UDPConn, error) { +func NewIPv4UDPConn(iface string, addr *net.UDPAddr) (*net.UDPConn, error) { fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_UDP) if err != nil { return nil, fmt.Errorf("cannot get a UDP socket: %v", err) @@ -37,9 +37,15 @@ func NewIPv4UDPConn(iface string, port int) (*net.UDPConn, error) { return nil, fmt.Errorf("cannot bind to interface %s: %v", iface, err) } } + + if addr == nil { + addr = &net.UDPAddr{Port: dhcpv4.ServerPort} + } // Bind to the port. - if err := unix.Bind(fd, &unix.SockaddrInet4{Port: port}); err != nil { - return nil, fmt.Errorf("cannot bind to port %d: %v", port, err) + saddr := unix.SockaddrInet4{Port: addr.Port} + copy(saddr.Addr[:], addr.IP.To4()) + if err := unix.Bind(fd, &saddr); err != nil { + return nil, fmt.Errorf("cannot bind to port %d: %v", addr.Port, err) } conn, err := net.FilePacketConn(f) diff --git a/dhcpv4/server4/server.go b/dhcpv4/server4/server.go index fe4ef09..8bf7924 100644 --- a/dhcpv4/server4/server.go +++ b/dhcpv4/server4/server.go @@ -133,7 +133,7 @@ func NewServer(ifname string, addr *net.UDPAddr, handler Handler, opt ...ServerO } if s.conn == nil { var err error - conn, err := NewIPv4UDPConn(ifname, addr.Port) + conn, err := NewIPv4UDPConn(ifname, addr) if err != nil { return nil, err } diff --git a/dhcpv4/server4/server_test.go b/dhcpv4/server4/server_test.go index a596d04..e64be09 100644 --- a/dhcpv4/server4/server_test.go +++ b/dhcpv4/server4/server_test.go @@ -81,7 +81,7 @@ func setUpClientAndServer(t *testing.T, iface net.Interface, handler Handler) (* _ = s.Serve() }() - clientConn, err := NewIPv4UDPConn("", caddr.Port) + clientConn, err := NewIPv4UDPConn("", &caddr) if err != nil { t.Fatal(err) } -- cgit v1.2.3