mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-24 09:51:41 +00:00
wgengine/magicsock: retry failed single packet ops across rebinds (#6990)
The single packet WriteTo() through RebindingUDPConn.WriteBatch() was not checking for a rebind between loading the PacketConn and writing to it. Same with ReadFrom()/ReadBatch(). Fixes #6989 Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
parent
6edf357b96
commit
fec888581a
@ -3258,19 +3258,23 @@ func (c *RebindingUDPConn) currentConn() nettype.PacketConn {
|
|||||||
return c.pconn
|
return c.pconn
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadFrom reads a packet from c into b.
|
func (c *RebindingUDPConn) readFromWithInitPconn(pconn nettype.PacketConn, b []byte) (int, net.Addr, error) {
|
||||||
// It returns the number of bytes copied and the source address.
|
|
||||||
func (c *RebindingUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
|
||||||
for {
|
for {
|
||||||
pconn := *c.pconnAtomic.Load()
|
|
||||||
n, addr, err := pconn.ReadFrom(b)
|
n, addr, err := pconn.ReadFrom(b)
|
||||||
if err != nil && pconn != c.currentConn() {
|
if err != nil && pconn != c.currentConn() {
|
||||||
|
pconn = *c.pconnAtomic.Load()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return n, addr, err
|
return n, addr, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadFrom reads a packet from c into b.
|
||||||
|
// It returns the number of bytes copied and the source address.
|
||||||
|
func (c *RebindingUDPConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
|
return c.readFromWithInitPconn(*c.pconnAtomic.Load(), b)
|
||||||
|
}
|
||||||
|
|
||||||
// ReadFromNetaddr reads a packet from c into b.
|
// ReadFromNetaddr reads a packet from c into b.
|
||||||
// It returns the number of bytes copied and the return address.
|
// It returns the number of bytes copied and the return address.
|
||||||
// It is identical to c.ReadFrom, except that it returns a netip.AddrPort instead of a net.Addr.
|
// It is identical to c.ReadFrom, except that it returns a netip.AddrPort instead of a net.Addr.
|
||||||
@ -3321,7 +3325,7 @@ func (c *RebindingUDPConn) WriteBatch(msgs []ipv6.Message, flags int) (int, erro
|
|||||||
bw, ok := pconn.(batchWriter)
|
bw, ok := pconn.(batchWriter)
|
||||||
if !ok {
|
if !ok {
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
_, err = pconn.WriteTo(msg.Buffers[0], msg.Addr)
|
_, err = c.writeToWithInitPconn(pconn, msg.Buffers[0], msg.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
@ -3350,7 +3354,7 @@ func (c *RebindingUDPConn) ReadBatch(msgs []ipv6.Message, flags int) (int, error
|
|||||||
br, ok := pconn.(batchReader)
|
br, ok := pconn.(batchReader)
|
||||||
if !ok {
|
if !ok {
|
||||||
var err error
|
var err error
|
||||||
msgs[0].N, msgs[0].Addr, err = c.ReadFrom(msgs[0].Buffers[0])
|
msgs[0].N, msgs[0].Addr, err = c.readFromWithInitPconn(pconn, msgs[0].Buffers[0])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
@ -3398,17 +3402,21 @@ func (c *RebindingUDPConn) closeLocked() error {
|
|||||||
return c.pconn.Close()
|
return c.pconn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *RebindingUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
func (c *RebindingUDPConn) writeToWithInitPconn(pconn nettype.PacketConn, b []byte, addr net.Addr) (int, error) {
|
||||||
for {
|
for {
|
||||||
pconn := *c.pconnAtomic.Load()
|
|
||||||
n, err := pconn.WriteTo(b, addr)
|
n, err := pconn.WriteTo(b, addr)
|
||||||
if err != nil && pconn != c.currentConn() {
|
if err != nil && pconn != c.currentConn() {
|
||||||
|
pconn = *c.pconnAtomic.Load()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *RebindingUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
|
||||||
|
return c.writeToWithInitPconn(*c.pconnAtomic.Load(), b, addr)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *RebindingUDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) {
|
func (c *RebindingUDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) {
|
||||||
for {
|
for {
|
||||||
pconn := *c.pconnAtomic.Load()
|
pconn := *c.pconnAtomic.Load()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user