mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-07 00:34:42 +00:00
derp: add Client.LocalAddr method
So magicsock can later ask a DERP connection whether its source IP would've changed if it reconnected. Updates #3619 Change-Id: Ibc8810340c511d6786b60c78c1a61c09f5800e40 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
b09000ad5d
commit
63d9c7b9b3
@ -12,10 +12,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go4.org/mem"
|
"go4.org/mem"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
|
"inet.af/netaddr"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
@ -38,7 +40,7 @@ type Client struct {
|
|||||||
|
|
||||||
// Owned by Recv:
|
// Owned by Recv:
|
||||||
peeked int // bytes to discard on next Recv
|
peeked int // bytes to discard on next Recv
|
||||||
readErr error // sticky read error
|
readErr atomic.Value // of error; sticky (set by Recv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientOpt is an option passed to NewClient.
|
// ClientOpt is an option passed to NewClient.
|
||||||
@ -441,13 +443,14 @@ func (c *Client) Recv() (m ReceivedMessage, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err error) {
|
func (c *Client) recvTimeout(timeout time.Duration) (m ReceivedMessage, err error) {
|
||||||
if c.readErr != nil {
|
readErr, _ := c.readErr.Load().(error)
|
||||||
return nil, c.readErr
|
if readErr != nil {
|
||||||
|
return nil, readErr
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("derp.Recv: %w", err)
|
err = fmt.Errorf("derp.Recv: %w", err)
|
||||||
c.readErr = err
|
c.readErr.Store(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -587,3 +590,22 @@ func (c *Client) setSendRateLimiter(sm ServerInfoMessage) {
|
|||||||
sm.TokenBucketBytesBurst)
|
sm.TokenBucketBytesBurst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LocalAddr returns the TCP connection's local address.
|
||||||
|
//
|
||||||
|
// If the client is broken in some previously detectable way, it
|
||||||
|
// returns an error.
|
||||||
|
func (c *Client) LocalAddr() (netaddr.IPPort, error) {
|
||||||
|
readErr, _ := c.readErr.Load().(error)
|
||||||
|
if readErr != nil {
|
||||||
|
return netaddr.IPPort{}, readErr
|
||||||
|
}
|
||||||
|
if c.nc == nil {
|
||||||
|
return netaddr.IPPort{}, errors.New("nil conn")
|
||||||
|
}
|
||||||
|
a := c.nc.LocalAddr()
|
||||||
|
if a == nil {
|
||||||
|
return netaddr.IPPort{}, errors.New("nil addr")
|
||||||
|
}
|
||||||
|
return netaddr.ParseIPPort(a.String())
|
||||||
|
}
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -283,9 +284,8 @@ type PacketForwarder interface {
|
|||||||
// It is a defined type so that non-net connections can be used.
|
// It is a defined type so that non-net connections can be used.
|
||||||
type Conn interface {
|
type Conn interface {
|
||||||
io.WriteCloser
|
io.WriteCloser
|
||||||
|
LocalAddr() net.Addr
|
||||||
// The *Deadline methods follow the semantics of net.Conn.
|
// The *Deadline methods follow the semantics of net.Conn.
|
||||||
|
|
||||||
SetDeadline(time.Time) error
|
SetDeadline(time.Time) error
|
||||||
SetReadDeadline(time.Time) error
|
SetReadDeadline(time.Time) error
|
||||||
SetWriteDeadline(time.Time) error
|
SetWriteDeadline(time.Time) error
|
||||||
|
Loading…
x
Reference in New Issue
Block a user