mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-21 14:11:56 +00:00
tsnet,wgengine: fix src to primary Tailscale IP for TCP dials
Ensure that the src address for a connection is one of the primary addresses assigned by Tailscale. Not, for example, a virtual IP address. Updates #14667 Signed-off-by: Fran Bull <fran@tailscale.com>
This commit is contained in:
parent
8f0080c7a4
commit
5ebc135397
@ -904,6 +904,7 @@ tailscale.com/cmd/k8s-operator dependencies: (generated by github.com/tailscale/
|
|||||||
tailscale.com/tstime/rate from tailscale.com/derp+
|
tailscale.com/tstime/rate from tailscale.com/derp+
|
||||||
tailscale.com/tsweb/varz from tailscale.com/util/usermetric
|
tailscale.com/tsweb/varz from tailscale.com/util/usermetric
|
||||||
tailscale.com/types/appctype from tailscale.com/ipn/ipnlocal
|
tailscale.com/types/appctype from tailscale.com/ipn/ipnlocal
|
||||||
|
tailscale.com/types/bools from tailscale.com/tsnet
|
||||||
tailscale.com/types/dnstype from tailscale.com/ipn/ipnlocal+
|
tailscale.com/types/dnstype from tailscale.com/ipn/ipnlocal+
|
||||||
tailscale.com/types/empty from tailscale.com/ipn+
|
tailscale.com/types/empty from tailscale.com/ipn+
|
||||||
tailscale.com/types/ipproto from tailscale.com/net/flowtrack+
|
tailscale.com/types/ipproto from tailscale.com/net/flowtrack+
|
||||||
|
@ -49,6 +49,7 @@ import (
|
|||||||
"tailscale.com/net/socks5"
|
"tailscale.com/net/socks5"
|
||||||
"tailscale.com/net/tsdial"
|
"tailscale.com/net/tsdial"
|
||||||
"tailscale.com/tsd"
|
"tailscale.com/tsd"
|
||||||
|
"tailscale.com/types/bools"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
"tailscale.com/types/nettype"
|
"tailscale.com/types/nettype"
|
||||||
@ -601,7 +602,9 @@ func (s *Server) start() (reterr error) {
|
|||||||
// Note: don't just return ns.DialContextTCP or we'll return
|
// Note: don't just return ns.DialContextTCP or we'll return
|
||||||
// *gonet.TCPConn(nil) instead of a nil interface which trips up
|
// *gonet.TCPConn(nil) instead of a nil interface which trips up
|
||||||
// callers.
|
// callers.
|
||||||
tcpConn, err := ns.DialContextTCP(ctx, dst)
|
v4, v6 := s.TailscaleIPs()
|
||||||
|
src := bools.IfElse(dst.Addr().Is6(), v6, v4)
|
||||||
|
tcpConn, err := ns.DialContextTCPWithBind(ctx, src, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -611,7 +614,9 @@ func (s *Server) start() (reterr error) {
|
|||||||
// Note: don't just return ns.DialContextUDP or we'll return
|
// Note: don't just return ns.DialContextUDP or we'll return
|
||||||
// *gonet.UDPConn(nil) instead of a nil interface which trips up
|
// *gonet.UDPConn(nil) instead of a nil interface which trips up
|
||||||
// callers.
|
// callers.
|
||||||
udpConn, err := ns.DialContextUDP(ctx, dst)
|
v4, v6 := s.TailscaleIPs()
|
||||||
|
src := bools.IfElse(dst.Addr().Is6(), v6, v4)
|
||||||
|
udpConn, err := ns.DialContextUDPWithBind(ctx, src, dst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -843,6 +843,27 @@ func (ns *Impl) DialContextTCP(ctx context.Context, ipp netip.AddrPort) (*gonet.
|
|||||||
return gonet.DialContextTCP(ctx, ns.ipstack, remoteAddress, ipType)
|
return gonet.DialContextTCP(ctx, ns.ipstack, remoteAddress, ipType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialContextTCPWithBind creates a new gonet.TCPConn connected to the specified
|
||||||
|
// remoteAddress with its local address bound to localAddr on an available port.
|
||||||
|
func (ns *Impl) DialContextTCPWithBind(ctx context.Context, localAddr netip.Addr, remoteAddr netip.AddrPort) (*gonet.TCPConn, error) {
|
||||||
|
remoteAddress := tcpip.FullAddress{
|
||||||
|
NIC: nicID,
|
||||||
|
Addr: tcpip.AddrFromSlice(remoteAddr.Addr().AsSlice()),
|
||||||
|
Port: remoteAddr.Port(),
|
||||||
|
}
|
||||||
|
localAddress := tcpip.FullAddress{
|
||||||
|
NIC: nicID,
|
||||||
|
Addr: tcpip.AddrFromSlice(localAddr.AsSlice()),
|
||||||
|
}
|
||||||
|
var ipType tcpip.NetworkProtocolNumber
|
||||||
|
if remoteAddr.Addr().Is4() {
|
||||||
|
ipType = ipv4.ProtocolNumber
|
||||||
|
} else {
|
||||||
|
ipType = ipv6.ProtocolNumber
|
||||||
|
}
|
||||||
|
return gonet.DialTCPWithBind(ctx, ns.ipstack, localAddress, remoteAddress, ipType)
|
||||||
|
}
|
||||||
|
|
||||||
func (ns *Impl) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.UDPConn, error) {
|
func (ns *Impl) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.UDPConn, error) {
|
||||||
remoteAddress := &tcpip.FullAddress{
|
remoteAddress := &tcpip.FullAddress{
|
||||||
NIC: nicID,
|
NIC: nicID,
|
||||||
@ -859,6 +880,28 @@ func (ns *Impl) DialContextUDP(ctx context.Context, ipp netip.AddrPort) (*gonet.
|
|||||||
return gonet.DialUDP(ns.ipstack, nil, remoteAddress, ipType)
|
return gonet.DialUDP(ns.ipstack, nil, remoteAddress, ipType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DialContextUDPWithBind creates a new gonet.UDPConn. Connected to remoteAddr.
|
||||||
|
// With its local address bound to localAddr on an available port.
|
||||||
|
func (ns *Impl) DialContextUDPWithBind(ctx context.Context, localAddr netip.Addr, remoteAddr netip.AddrPort) (*gonet.UDPConn, error) {
|
||||||
|
remoteAddress := &tcpip.FullAddress{
|
||||||
|
NIC: nicID,
|
||||||
|
Addr: tcpip.AddrFromSlice(remoteAddr.Addr().AsSlice()),
|
||||||
|
Port: remoteAddr.Port(),
|
||||||
|
}
|
||||||
|
localAddress := &tcpip.FullAddress{
|
||||||
|
NIC: nicID,
|
||||||
|
Addr: tcpip.AddrFromSlice(localAddr.AsSlice()),
|
||||||
|
}
|
||||||
|
var ipType tcpip.NetworkProtocolNumber
|
||||||
|
if remoteAddr.Addr().Is4() {
|
||||||
|
ipType = ipv4.ProtocolNumber
|
||||||
|
} else {
|
||||||
|
ipType = ipv6.ProtocolNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
return gonet.DialUDP(ns.ipstack, localAddress, remoteAddress, ipType)
|
||||||
|
}
|
||||||
|
|
||||||
// getInjectInboundBuffsSizes returns packet memory and a sizes slice for usage
|
// getInjectInboundBuffsSizes returns packet memory and a sizes slice for usage
|
||||||
// when calling tstun.Wrapper.InjectInboundPacketBuffer(). These are sized with
|
// when calling tstun.Wrapper.InjectInboundPacketBuffer(). These are sized with
|
||||||
// consideration for MTU and GSO support on ns.linkEP. They should be recycled
|
// consideration for MTU and GSO support on ns.linkEP. They should be recycled
|
||||||
|
Loading…
x
Reference in New Issue
Block a user