mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-21 06:01:42 +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/tsweb/varz from tailscale.com/util/usermetric
|
||||
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/empty from tailscale.com/ipn+
|
||||
tailscale.com/types/ipproto from tailscale.com/net/flowtrack+
|
||||
|
@ -49,6 +49,7 @@ import (
|
||||
"tailscale.com/net/socks5"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/tsd"
|
||||
"tailscale.com/types/bools"
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/types/logid"
|
||||
"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
|
||||
// *gonet.TCPConn(nil) instead of a nil interface which trips up
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
@ -611,7 +614,9 @@ func (s *Server) start() (reterr error) {
|
||||
// Note: don't just return ns.DialContextUDP or we'll return
|
||||
// *gonet.UDPConn(nil) instead of a nil interface which trips up
|
||||
// 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 {
|
||||
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)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
remoteAddress := &tcpip.FullAddress{
|
||||
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)
|
||||
}
|
||||
|
||||
// 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
|
||||
// when calling tstun.Wrapper.InjectInboundPacketBuffer(). These are sized with
|
||||
// consideration for MTU and GSO support on ns.linkEP. They should be recycled
|
||||
|
Loading…
x
Reference in New Issue
Block a user