Reconcile DHCP with SO_BROADCAST

Now that we have SO_BROADCAST, we don't need (some of) the hackery in the DHCP
client. This also fixes a bizarre regression observed in Fuchsia where DHCP
acquisition was taking over two minutes.

PiperOrigin-RevId: 236661954
Change-Id: Ibcfe5d311fa5df8ff4ff2e40ccedffe91f92daa5
This commit is contained in:
Tamir Duberstein
2019-03-04 09:01:03 -08:00
committed by Shentubot
parent d811c1016d
commit bc70897bb4
2 changed files with 15 additions and 30 deletions
+1
View File
@@ -15,6 +15,7 @@ go_library(
"//pkg/rand",
"//pkg/tcpip",
"//pkg/tcpip/buffer",
"//pkg/tcpip/header",
"//pkg/tcpip/network/ipv4",
"//pkg/tcpip/stack",
"//pkg/tcpip/transport/udp",
+14 -30
View File
@@ -23,6 +23,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/rand"
"gvisor.googlesource.com/gvisor/pkg/tcpip"
tcpipHeader "gvisor.googlesource.com/gvisor/pkg/tcpip/header"
"gvisor.googlesource.com/gvisor/pkg/tcpip/network/ipv4"
"gvisor.googlesource.com/gvisor/pkg/tcpip/stack"
"gvisor.googlesource.com/gvisor/pkg/tcpip/transport/udp"
@@ -119,14 +120,10 @@ func (c *Client) Config() Config {
// If the server sets a lease limit a timer is set to automatically
// renew it.
func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg Config, reterr error) {
if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, "\xff\xff\xff\xff", stack.NeverPrimaryEndpoint); err != nil && err != tcpip.ErrDuplicateAddress {
if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, tcpipHeader.IPv4Any, stack.NeverPrimaryEndpoint); err != nil && err != tcpip.ErrDuplicateAddress {
return Config{}, fmt.Errorf("dhcp: %v", err)
}
if err := c.stack.AddAddressWithOptions(c.nicid, ipv4.ProtocolNumber, "\x00\x00\x00\x00", stack.NeverPrimaryEndpoint); err != nil && err != tcpip.ErrDuplicateAddress {
return Config{}, fmt.Errorf("dhcp: %v", err)
}
defer c.stack.RemoveAddress(c.nicid, "\xff\xff\xff\xff")
defer c.stack.RemoveAddress(c.nicid, "\x00\x00\x00\x00")
defer c.stack.RemoveAddress(c.nicid, tcpipHeader.IPv4Any)
var wq waiter.Queue
ep, err := c.stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
@@ -134,30 +131,20 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg
return Config{}, fmt.Errorf("dhcp: outbound endpoint: %v", err)
}
defer ep.Close()
if err := ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil {
return Config{}, fmt.Errorf("dhcp: setsockopt: %v", err)
}
if err := ep.Bind(tcpip.FullAddress{
Addr: "\x00\x00\x00\x00",
Addr: tcpipHeader.IPv4Any,
Port: ClientPort,
NIC: c.nicid,
}, nil); err != nil {
return Config{}, fmt.Errorf("dhcp: connect failed: %v", err)
return Config{}, fmt.Errorf("dhcp: bind failed: %v", err)
}
if err := ep.SetSockOpt(tcpip.BroadcastOption(1)); err != nil {
return Config{}, fmt.Errorf("dhcp: setsockopt SO_BROADCAST: %v", err)
}
epin, err := c.stack.NewEndpoint(udp.ProtocolNumber, ipv4.ProtocolNumber, &wq)
if err != nil {
return Config{}, fmt.Errorf("dhcp: inbound endpoint: %v", err)
}
defer epin.Close()
if err := epin.Bind(tcpip.FullAddress{
Addr: "\xff\xff\xff\xff",
Port: ClientPort,
NIC: c.nicid,
}, nil); err != nil {
return Config{}, fmt.Errorf("dhcp: connect failed: %v", err)
}
var xid [4]byte
rand.Read(xid[:])
@@ -191,7 +178,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg
h.setOptions(discOpts)
serverAddr := &tcpip.FullAddress{
Addr: "\xff\xff\xff\xff",
Addr: tcpipHeader.IPv4Broadcast,
Port: ServerPort,
NIC: c.nicid,
}
@@ -222,8 +209,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg
// DHCPOFFER
var opts options
for {
var addr tcpip.FullAddress
v, _, err := epin.Read(&addr)
v, _, err := ep.Read(nil)
if err == tcpip.ErrWouldBlock {
select {
case <-ch:
@@ -271,12 +257,11 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg
c.cfg = cfg
c.mu.Unlock()
// Clean up broadcast addresses before calling acquiredFunc
// Clean up addresses before calling acquiredFunc
// so nothing else uses them by mistake.
//
// (The deferred RemoveAddress calls above silently error.)
c.stack.RemoveAddress(c.nicid, "\xff\xff\xff\xff")
c.stack.RemoveAddress(c.nicid, "\x00\x00\x00\x00")
// (The deferred RemoveAddress call above silently errors.)
c.stack.RemoveAddress(c.nicid, tcpipHeader.IPv4Any)
if c.acquiredFunc != nil {
c.acquiredFunc(oldAddr, addr, cfg)
@@ -311,8 +296,7 @@ func (c *Client) Request(ctx context.Context, requestedAddr tcpip.Address) (cfg
// DHCPACK
for {
var addr tcpip.FullAddress
v, _, err := epin.Read(&addr)
v, _, err := ep.Read(nil)
if err == tcpip.ErrWouldBlock {
select {
case <-ch: