tailscale: update tailfs functions and vars to use drive naming (#11597)

This change updates all tailfs functions and the majority of the tailfs
variables to use the new drive naming.

Updates tailscale/corp#16827

Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This commit is contained in:
Charlotte Brandhorst-Satzkorn
2024-04-03 10:09:58 -07:00
committed by GitHub
parent 2409661a0d
commit 93618a3518
27 changed files with 233 additions and 233 deletions

View File

@@ -68,7 +68,7 @@ const (
NotifyInitialNetMap // if set, the first Notify message (sent immediately) will contain the current NetMap
NotifyNoPrivateKeys // if set, private keys that would normally be sent in updates are zeroed out
NotifyInitialTailFSShares // if set, the first Notify message (sent immediately) will contain the current TailFS Shares
NotifyInitialDriveShares // if set, the first Notify message (sent immediately) will contain the current Taildrive Shares
NotifyInitialOutgoingFiles // if set, the first Notify message (sent immediately) will contain the current Taildrop OutgoingFiles
)
@@ -130,13 +130,13 @@ type Notify struct {
// is available.
ClientVersion *tailcfg.ClientVersion `json:",omitempty"`
// TailFSShares tracks the full set of current TailFSShares that we're
// DriveShares tracks the full set of current DriveShares that we're
// publishing. Some client applications, like the MacOS and Windows clients,
// will listen for updates to this and handle serving these shares under
// the identity of the unprivileged user that is running the application. A
// nil value here means that we're not broadcasting shares information, an
// empty value means that there are no shares.
TailFSShares views.SliceView[*drive.Share, drive.ShareView]
DriveShares views.SliceView[*drive.Share, drive.ShareView]
// type is mirrored in xcode/Shared/IPN.swift
}

View File

@@ -25,10 +25,10 @@ func (src *Prefs) Clone() *Prefs {
*dst = *src
dst.AdvertiseTags = append(src.AdvertiseTags[:0:0], src.AdvertiseTags...)
dst.AdvertiseRoutes = append(src.AdvertiseRoutes[:0:0], src.AdvertiseRoutes...)
if src.TailFSShares != nil {
dst.TailFSShares = make([]*drive.Share, len(src.TailFSShares))
for i := range dst.TailFSShares {
dst.TailFSShares[i] = src.TailFSShares[i].Clone()
if src.DriveShares != nil {
dst.DriveShares = make([]*drive.Share, len(src.DriveShares))
for i := range dst.DriveShares {
dst.DriveShares[i] = src.DriveShares[i].Clone()
}
}
dst.Persist = src.Persist.Clone()
@@ -63,7 +63,7 @@ var _PrefsCloneNeedsRegeneration = Prefs(struct {
AppConnector AppConnectorPrefs
PostureChecking bool
NetfilterKind string
TailFSShares []*drive.Share
DriveShares []*drive.Share
Persist *persist.Persist
}{})

View File

@@ -92,8 +92,8 @@ func (v PrefsView) AutoUpdate() AutoUpdatePrefs { return v.ж.AutoUpda
func (v PrefsView) AppConnector() AppConnectorPrefs { return v.ж.AppConnector }
func (v PrefsView) PostureChecking() bool { return v.ж.PostureChecking }
func (v PrefsView) NetfilterKind() string { return v.ж.NetfilterKind }
func (v PrefsView) TailFSShares() views.SliceView[*drive.Share, drive.ShareView] {
return views.SliceOfViews[*drive.Share, drive.ShareView](v.ж.TailFSShares)
func (v PrefsView) DriveShares() views.SliceView[*drive.Share, drive.ShareView] {
return views.SliceOfViews[*drive.Share, drive.ShareView](v.ж.DriveShares)
}
func (v PrefsView) Persist() persist.PersistView { return v.ж.Persist.View() }
@@ -125,7 +125,7 @@ var _PrefsViewNeedsRegeneration = Prefs(struct {
AppConnector AppConnectorPrefs
PostureChecking bool
NetfilterKind string
TailFSShares []*drive.Share
DriveShares []*drive.Share
Persist *persist.Persist
}{})

View File

@@ -19,61 +19,61 @@ import (
)
const (
// TailFSLocalPort is the port on which the TailFS listens for location
// DriveLocalPort is the port on which the Taildrive listens for location
// connections on quad 100.
TailFSLocalPort = 8080
DriveLocalPort = 8080
)
var (
shareNameRegex = regexp.MustCompile(`^[a-z0-9_\(\) ]+$`)
ErrTailFSNotEnabled = errors.New("TailFS not enabled")
ErrDriveNotEnabled = errors.New("TailFS not enabled")
ErrInvalidShareName = errors.New("Share names may only contain the letters a-z, underscore _, parentheses (), or spaces")
)
// TailFSSharingEnabled reports whether sharing to remote nodes via tailfs is
// DriveSharingEnabled reports whether sharing to remote nodes via Taildrive is
// enabled. This is currently based on checking for the tailfs:share node
// attribute.
func (b *LocalBackend) TailFSSharingEnabled() bool {
func (b *LocalBackend) DriveSharingEnabled() bool {
b.mu.Lock()
defer b.mu.Unlock()
return b.tailFSSharingEnabledLocked()
return b.driveSharingEnabledLocked()
}
func (b *LocalBackend) tailFSSharingEnabledLocked() bool {
func (b *LocalBackend) driveSharingEnabledLocked() bool {
return b.netMap != nil && b.netMap.SelfNode.HasCap(tailcfg.NodeAttrsTailFSShare)
}
// TailFSAccessEnabled reports whether accessing TailFS shares on remote nodes
// DriveAccessEnabled reports whether accessing Taildrive shares on remote nodes
// is enabled. This is currently based on checking for the tailfs:access node
// attribute.
func (b *LocalBackend) TailFSAccessEnabled() bool {
func (b *LocalBackend) DriveAccessEnabled() bool {
b.mu.Lock()
defer b.mu.Unlock()
return b.tailFSAccessEnabledLocked()
return b.driveAccessEnabledLocked()
}
func (b *LocalBackend) tailFSAccessEnabledLocked() bool {
func (b *LocalBackend) driveAccessEnabledLocked() bool {
return b.netMap != nil && b.netMap.SelfNode.HasCap(tailcfg.NodeAttrsTailFSAccess)
}
// TailFSSetFileServerAddr tells tailfs to use the given address for connecting
// to the tailfs.FileServer that's exposing local files as an unprivileged
// DriveSetServerAddr tells Taildrive to use the given address for connecting
// to the drive.FileServer that's exposing local files as an unprivileged
// user.
func (b *LocalBackend) TailFSSetFileServerAddr(addr string) error {
fs, ok := b.sys.TailFSForRemote.GetOK()
func (b *LocalBackend) DriveSetServerAddr(addr string) error {
fs, ok := b.sys.DriveForRemote.GetOK()
if !ok {
return ErrTailFSNotEnabled
return ErrDriveNotEnabled
}
fs.SetFileServerAddr(addr)
return nil
}
// TailFSSetShare adds the given share if no share with that name exists, or
// DriveSetShare adds the given share if no share with that name exists, or
// replaces the existing share if one with the same name already exists. To
// avoid potential incompatibilities across file systems, share names are
// limited to alphanumeric characters and the underscore _.
func (b *LocalBackend) TailFSSetShare(share *drive.Share) error {
func (b *LocalBackend) DriveSetShare(share *drive.Share) error {
var err error
share.Name, err = normalizeShareName(share.Name)
if err != nil {
@@ -81,13 +81,13 @@ func (b *LocalBackend) TailFSSetShare(share *drive.Share) error {
}
b.mu.Lock()
shares, err := b.tailFSSetShareLocked(share)
shares, err := b.driveSetShareLocked(share)
b.mu.Unlock()
if err != nil {
return err
}
b.tailFSNotifyShares(shares)
b.driveNotifyShares(shares)
return nil
}
@@ -108,12 +108,12 @@ func normalizeShareName(name string) (string, error) {
return name, nil
}
func (b *LocalBackend) tailFSSetShareLocked(share *drive.Share) (views.SliceView[*drive.Share, drive.ShareView], error) {
existingShares := b.pm.prefs.TailFSShares()
func (b *LocalBackend) driveSetShareLocked(share *drive.Share) (views.SliceView[*drive.Share, drive.ShareView], error) {
existingShares := b.pm.prefs.DriveShares()
fs, ok := b.sys.TailFSForRemote.GetOK()
fs, ok := b.sys.DriveForRemote.GetOK()
if !ok {
return existingShares, ErrTailFSNotEnabled
return existingShares, ErrDriveNotEnabled
}
addedShare := false
@@ -133,23 +133,23 @@ func (b *LocalBackend) tailFSSetShareLocked(share *drive.Share) (views.SliceView
shares = append(shares, share)
}
err := b.tailFSSetSharesLocked(shares)
err := b.driveSetSharesLocked(shares)
if err != nil {
return existingShares, err
}
fs.SetShares(shares)
return b.pm.prefs.TailFSShares(), nil
return b.pm.prefs.DriveShares(), nil
}
// TailFSRenameShare renames the share at old name to new name. To avoid
// DriveRenameShare renames the share at old name to new name. To avoid
// potential incompatibilities across file systems, the new share name is
// limited to alphanumeric characters and the underscore _.
// Any of the following will result in an error.
// - no share found under old name
// - new share name contains disallowed characters
// - share already exists under new name
func (b *LocalBackend) TailFSRenameShare(oldName, newName string) error {
func (b *LocalBackend) DriveRenameShare(oldName, newName string) error {
var err error
newName, err = normalizeShareName(newName)
if err != nil {
@@ -157,22 +157,22 @@ func (b *LocalBackend) TailFSRenameShare(oldName, newName string) error {
}
b.mu.Lock()
shares, err := b.tailFSRenameShareLocked(oldName, newName)
shares, err := b.driveRenameShareLocked(oldName, newName)
b.mu.Unlock()
if err != nil {
return err
}
b.tailFSNotifyShares(shares)
b.driveNotifyShares(shares)
return nil
}
func (b *LocalBackend) tailFSRenameShareLocked(oldName, newName string) (views.SliceView[*drive.Share, drive.ShareView], error) {
existingShares := b.pm.prefs.TailFSShares()
func (b *LocalBackend) driveRenameShareLocked(oldName, newName string) (views.SliceView[*drive.Share, drive.ShareView], error) {
existingShares := b.pm.prefs.DriveShares()
fs, ok := b.sys.TailFSForRemote.GetOK()
fs, ok := b.sys.DriveForRemote.GetOK()
if !ok {
return existingShares, ErrTailFSNotEnabled
return existingShares, ErrDriveNotEnabled
}
found := false
@@ -197,18 +197,18 @@ func (b *LocalBackend) tailFSRenameShareLocked(oldName, newName string) (views.S
}
slices.SortFunc(shares, drive.CompareShares)
err := b.tailFSSetSharesLocked(shares)
err := b.driveSetSharesLocked(shares)
if err != nil {
return existingShares, err
}
fs.SetShares(shares)
return b.pm.prefs.TailFSShares(), nil
return b.pm.prefs.DriveShares(), nil
}
// TailFSRemoveShare removes the named share. Share names are forced to
// DriveRemoveShare removes the named share. Share names are forced to
// lowercase.
func (b *LocalBackend) TailFSRemoveShare(name string) error {
func (b *LocalBackend) DriveRemoveShare(name string) error {
// Force all share names to lowercase to avoid potential incompatibilities
// with clients that don't support case-sensitive filenames.
var err error
@@ -218,22 +218,22 @@ func (b *LocalBackend) TailFSRemoveShare(name string) error {
}
b.mu.Lock()
shares, err := b.tailFSRemoveShareLocked(name)
shares, err := b.driveRemoveShareLocked(name)
b.mu.Unlock()
if err != nil {
return err
}
b.tailFSNotifyShares(shares)
b.driveNotifyShares(shares)
return nil
}
func (b *LocalBackend) tailFSRemoveShareLocked(name string) (views.SliceView[*drive.Share, drive.ShareView], error) {
existingShares := b.pm.prefs.TailFSShares()
func (b *LocalBackend) driveRemoveShareLocked(name string) (views.SliceView[*drive.Share, drive.ShareView], error) {
existingShares := b.pm.prefs.DriveShares()
fs, ok := b.sys.TailFSForRemote.GetOK()
fs, ok := b.sys.DriveForRemote.GetOK()
if !ok {
return existingShares, ErrTailFSNotEnabled
return existingShares, ErrDriveNotEnabled
}
found := false
@@ -251,53 +251,53 @@ func (b *LocalBackend) tailFSRemoveShareLocked(name string) (views.SliceView[*dr
return existingShares, os.ErrNotExist
}
err := b.tailFSSetSharesLocked(shares)
err := b.driveSetSharesLocked(shares)
if err != nil {
return existingShares, err
}
fs.SetShares(shares)
return b.pm.prefs.TailFSShares(), nil
return b.pm.prefs.DriveShares(), nil
}
func (b *LocalBackend) tailFSSetSharesLocked(shares []*drive.Share) error {
func (b *LocalBackend) driveSetSharesLocked(shares []*drive.Share) error {
prefs := b.pm.prefs.AsStruct()
prefs.ApplyEdits(&ipn.MaskedPrefs{
Prefs: ipn.Prefs{
TailFSShares: shares,
DriveShares: shares,
},
TailFSSharesSet: true,
DriveSharesSet: true,
})
return b.pm.setPrefsLocked(prefs.View())
}
// tailFSNotifyShares notifies IPN bus listeners (e.g. Mac Application process)
// driveNotifyShares notifies IPN bus listeners (e.g. Mac Application process)
// about the latest list of shares.
func (b *LocalBackend) tailFSNotifyShares(shares views.SliceView[*drive.Share, drive.ShareView]) {
func (b *LocalBackend) driveNotifyShares(shares views.SliceView[*drive.Share, drive.ShareView]) {
// Ensures shares is not nil to distinguish "no shares" from "not notifying shares"
if shares.IsNil() {
shares = views.SliceOfViews(make([]*drive.Share, 0))
}
b.send(ipn.Notify{TailFSShares: shares})
b.send(ipn.Notify{DriveShares: shares})
}
// tailFSNotifyCurrentSharesLocked sends an ipn.Notify if the current set of
// driveNotifyCurrentSharesLocked sends an ipn.Notify if the current set of
// shares has changed since the last notification.
func (b *LocalBackend) tailFSNotifyCurrentSharesLocked() {
func (b *LocalBackend) driveNotifyCurrentSharesLocked() {
var shares views.SliceView[*drive.Share, drive.ShareView]
if b.tailFSSharingEnabledLocked() {
if b.driveSharingEnabledLocked() {
// Only populate shares if sharing is enabled.
shares = b.pm.prefs.TailFSShares()
shares = b.pm.prefs.DriveShares()
}
lastNotified := b.lastNotifiedTailFSShares.Load()
if lastNotified == nil || !tailFSShareViewsEqual(lastNotified, shares) {
lastNotified := b.lastNotifiedDriveShares.Load()
if lastNotified == nil || !driveShareViewsEqual(lastNotified, shares) {
// Do the below on a goroutine to avoid deadlocking on b.mu in b.send().
go b.tailFSNotifyShares(shares)
go b.driveNotifyShares(shares)
}
}
func tailFSShareViewsEqual(a *views.SliceView[*drive.Share, drive.ShareView], b views.SliceView[*drive.Share, drive.ShareView]) bool {
func driveShareViewsEqual(a *views.SliceView[*drive.Share, drive.ShareView], b views.SliceView[*drive.Share, drive.ShareView]) bool {
if a == nil {
return false
}
@@ -315,35 +315,35 @@ func tailFSShareViewsEqual(a *views.SliceView[*drive.Share, drive.ShareView], b
return true
}
// TailFSGetShares() gets the current list of TailFS shares, sorted by name.
func (b *LocalBackend) TailFSGetShares() views.SliceView[*drive.Share, drive.ShareView] {
// DriveGetShares gets the current list of Taildrive shares, sorted by name.
func (b *LocalBackend) DriveGetShares() views.SliceView[*drive.Share, drive.ShareView] {
b.mu.Lock()
defer b.mu.Unlock()
return b.pm.prefs.TailFSShares()
return b.pm.prefs.DriveShares()
}
// updateTailFSPeersLocked sets all applicable peers from the netmap as tailfs
// updateDrivePeersLocked sets all applicable peers from the netmap as Taildrive
// remotes.
func (b *LocalBackend) updateTailFSPeersLocked(nm *netmap.NetworkMap) {
fs, ok := b.sys.TailFSForLocal.GetOK()
func (b *LocalBackend) updateDrivePeersLocked(nm *netmap.NetworkMap) {
fs, ok := b.sys.DriveForLocal.GetOK()
if !ok {
return
}
var tailFSRemotes []*drive.Remote
if b.tailFSAccessEnabledLocked() {
var driveRemotes []*drive.Remote
if b.driveAccessEnabledLocked() {
// Only populate peers if access is enabled, otherwise leave blank.
tailFSRemotes = b.tailFSRemotesFromPeers(nm)
driveRemotes = b.driveRemotesFromPeers(nm)
}
fs.SetRemotes(b.netMap.Domain, tailFSRemotes, &tailFSTransport{b: b})
fs.SetRemotes(b.netMap.Domain, driveRemotes, &driveTransport{b: b})
}
func (b *LocalBackend) tailFSRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Remote {
tailFSRemotes := make([]*drive.Remote, 0, len(nm.Peers))
func (b *LocalBackend) driveRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Remote {
driveRemotes := make([]*drive.Remote, 0, len(nm.Peers))
for _, p := range nm.Peers {
// Exclude mullvad exit nodes from list of TailFS peers
// Exclude mullvad exit nodes from list of Taildrive peers
// TODO(oxtoacart) - once we have a better mechanism for finding only accessible sharers
// (see below) we can remove this logic.
if strings.HasSuffix(p.Name(), ".mullvad.ts.net.") {
@@ -352,7 +352,7 @@ func (b *LocalBackend) tailFSRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Re
peerID := p.ID()
url := fmt.Sprintf("%s/%s", peerAPIBase(nm, p), tailFSPrefix[1:])
tailFSRemotes = append(tailFSRemotes, &drive.Remote{
driveRemotes = append(driveRemotes, &drive.Remote{
Name: p.DisplayName(false),
URL: url,
Available: func() bool {
@@ -381,5 +381,5 @@ func (b *LocalBackend) tailFSRemotesFromPeers(nm *netmap.NetworkMap) []*drive.Re
},
})
}
return tailFSRemotes
return driveRemotes
}

View File

@@ -316,9 +316,9 @@ type LocalBackend struct {
// Last ClientVersion received in MapResponse, guarded by mu.
lastClientVersion *tailcfg.ClientVersion
// lastNotifiedTailFSShares keeps track of the last set of shares that we
// lastNotifiedDriveShares keeps track of the last set of shares that we
// notified about.
lastNotifiedTailFSShares atomic.Pointer[views.SliceView[*drive.Share, drive.ShareView]]
lastNotifiedDriveShares atomic.Pointer[views.SliceView[*drive.Share, drive.ShareView]]
// outgoingFiles keeps track of Taildrop outgoing files keyed to their OutgoingFile.ID
outgoingFiles map[string]*ipn.OutgoingFile
@@ -442,10 +442,10 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
}
}
// initialize TailFS shares from saved state
fs, ok := b.sys.TailFSForRemote.GetOK()
// initialize Taildrive shares from saved state
fs, ok := b.sys.DriveForRemote.GetOK()
if ok {
currentShares := b.pm.prefs.TailFSShares()
currentShares := b.pm.prefs.DriveShares()
if currentShares.Len() > 0 {
var shares []*drive.Share
for i := 0; i < currentShares.Len(); i++ {
@@ -2292,7 +2292,7 @@ func (b *LocalBackend) WatchNotifications(ctx context.Context, mask ipn.NotifyWa
b.mu.Lock()
const initialBits = ipn.NotifyInitialState | ipn.NotifyInitialPrefs | ipn.NotifyInitialNetMap | ipn.NotifyInitialTailFSShares
const initialBits = ipn.NotifyInitialState | ipn.NotifyInitialPrefs | ipn.NotifyInitialNetMap | ipn.NotifyInitialDriveShares
if mask&initialBits != 0 {
ini = &ipn.Notify{Version: version.Long()}
if mask&ipn.NotifyInitialState != 0 {
@@ -2308,8 +2308,8 @@ func (b *LocalBackend) WatchNotifications(ctx context.Context, mask ipn.NotifyWa
if mask&ipn.NotifyInitialNetMap != 0 {
ini.NetMap = b.netMap
}
if mask&ipn.NotifyInitialTailFSShares != 0 && b.tailFSSharingEnabledLocked() {
ini.TailFSShares = b.pm.prefs.TailFSShares()
if mask&ipn.NotifyInitialDriveShares != 0 && b.driveSharingEnabledLocked() {
ini.DriveShares = b.pm.prefs.DriveShares()
}
}
@@ -3382,8 +3382,8 @@ func (b *LocalBackend) TCPHandlerForDst(src, dst netip.AddrPort) (handler func(c
return b.handleWebClientConn, opts
}
return b.HandleQuad100Port80Conn, opts
case TailFSLocalPort:
return b.handleTailFSConn, opts
case DriveLocalPort:
return b.handleDriveConn, opts
}
}
@@ -3417,9 +3417,9 @@ func (b *LocalBackend) TCPHandlerForDst(src, dst netip.AddrPort) (handler func(c
return nil, nil
}
func (b *LocalBackend) handleTailFSConn(conn net.Conn) error {
fs, ok := b.sys.TailFSForLocal.GetOK()
if !ok || !b.TailFSAccessEnabled() {
func (b *LocalBackend) handleDriveConn(conn net.Conn) error {
fs, ok := b.sys.DriveForLocal.GetOK()
if !ok || !b.DriveAccessEnabled() {
conn.Close()
return nil
}
@@ -4729,8 +4729,8 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
}
}
b.updateTailFSPeersLocked(nm)
b.tailFSNotifyCurrentSharesLocked()
b.updateDrivePeersLocked(nm)
b.driveNotifyCurrentSharesLocked()
}
func (b *LocalBackend) updatePeersFromNetmapLocked(nm *netmap.NetworkMap) {
@@ -4757,10 +4757,10 @@ func (b *LocalBackend) updatePeersFromNetmapLocked(nm *netmap.NetworkMap) {
}
}
// tailFSTransport is an http.RoundTripper that uses the latest value of
// driveTransport is an http.RoundTripper that uses the latest value of
// b.Dialer().PeerAPITransport() for each round trip and imposes a short
// dial timeout to avoid hanging on connecting to offline/unreachable hosts.
type tailFSTransport struct {
type driveTransport struct {
b *LocalBackend
}
@@ -4817,7 +4817,7 @@ func (rbw *responseBodyWrapper) Close() error {
return err
}
func (t *tailFSTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
func (dt *driveTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
bw := &requestBodyWrapper{}
if req.Body != nil {
bw.ReadCloser = req.Body
@@ -4839,24 +4839,24 @@ func (t *tailFSTransport) RoundTrip(req *http.Request) (resp *http.Response, err
return
}
t.b.mu.Lock()
selfNodeKey := t.b.netMap.SelfNode.Key().ShortString()
t.b.mu.Unlock()
n, _, ok := t.b.WhoIs(netip.MustParseAddrPort(req.URL.Host))
dt.b.mu.Lock()
selfNodeKey := dt.b.netMap.SelfNode.Key().ShortString()
dt.b.mu.Unlock()
n, _, ok := dt.b.WhoIs(netip.MustParseAddrPort(req.URL.Host))
shareNodeKey := "unknown"
if ok {
shareNodeKey = string(n.Key().ShortString())
}
rbw := responseBodyWrapper{
log: t.b.logf,
log: dt.b.logf,
method: req.Method,
bytesTx: int64(bw.bytesRead),
selfNodeKey: selfNodeKey,
shareNodeKey: shareNodeKey,
contentType: contentType,
contentLength: resp.ContentLength,
fileExtension: parseTailFSFileExtensionForLog(req.URL.Path),
fileExtension: parseDriveFileExtensionForLog(req.URL.Path),
statusCode: resp.StatusCode,
ReadCloser: resp.Body,
}
@@ -4873,7 +4873,7 @@ func (t *tailFSTransport) RoundTrip(req *http.Request) (resp *http.Response, err
// unreachable hosts.
dialTimeout := 1 * time.Second // TODO(oxtoacart): tune this
tr := t.b.Dialer().PeerAPITransport().Clone()
tr := dt.b.Dialer().PeerAPITransport().Clone()
dialContext := tr.DialContext
tr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
ctxWithTimeout, cancel := context.WithTimeout(ctx, dialTimeout)

View File

@@ -2295,12 +2295,12 @@ func TestTCPHandlerForDst(t *testing.T) {
intercept: false,
},
{
desc: "intercept port 8080 (TailFS) on quad100 IPv4",
desc: "intercept port 8080 (Taildrive) on quad100 IPv4",
dst: "100.100.100.100:8080",
intercept: true,
},
{
desc: "intercept port 8080 (TailFS) on quad100 IPv6",
desc: "intercept port 8080 (Taildrive) on quad100 IPv6",
dst: "[fd7a:115c:a1e0::53]:8080",
intercept: true,
},
@@ -2340,7 +2340,7 @@ func TestTCPHandlerForDst(t *testing.T) {
}
}
func TestTailFSManageShares(t *testing.T) {
func TestDriveManageShares(t *testing.T) {
tests := []struct {
name string
disabled bool
@@ -2410,7 +2410,7 @@ func TestTailFSManageShares(t *testing.T) {
name: "add_disabled",
disabled: true,
add: &drive.Share{Name: "a"},
expect: ErrTailFSNotEnabled,
expect: ErrDriveNotEnabled,
},
{
name: "remove",
@@ -2439,7 +2439,7 @@ func TestTailFSManageShares(t *testing.T) {
name: "remove_disabled",
disabled: true,
remove: "b",
expect: ErrTailFSNotEnabled,
expect: ErrDriveNotEnabled,
},
{
name: "rename",
@@ -2480,7 +2480,7 @@ func TestTailFSManageShares(t *testing.T) {
name: "rename_disabled",
disabled: true,
rename: [2]string{"a", "c"},
expect: ErrTailFSNotEnabled,
expect: ErrDriveNotEnabled,
},
}
@@ -2494,7 +2494,7 @@ func TestTailFSManageShares(t *testing.T) {
b := newTestBackend(t)
b.mu.Lock()
if tt.existing != nil {
b.tailFSSetSharesLocked(tt.existing)
b.driveSetSharesLocked(tt.existing)
}
if !tt.disabled {
self := b.netMap.SelfNode.AsStruct()
@@ -2517,7 +2517,7 @@ func TestTailFSManageShares(t *testing.T) {
func() { wg.Done() },
func(n *ipn.Notify) bool {
select {
case result <- n.TailFSShares:
case result <- n.DriveShares:
default:
//
}
@@ -2529,11 +2529,11 @@ func TestTailFSManageShares(t *testing.T) {
var err error
switch {
case tt.add != nil:
err = b.TailFSSetShare(tt.add)
err = b.DriveSetShare(tt.add)
case tt.remove != "":
err = b.TailFSRemoveShare(tt.remove)
err = b.DriveRemoveShare(tt.remove)
default:
err = b.TailFSRenameShare(tt.rename[0], tt.rename[1])
err = b.DriveRenameShare(tt.rename[0], tt.rename[1])
}
switch e := tt.expect.(type) {

View File

@@ -325,7 +325,7 @@ func (h *peerAPIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
if strings.HasPrefix(r.URL.Path, tailFSPrefix) {
h.handleServeTailFS(w, r)
h.handleServeDrive(w, r)
return
}
switch r.URL.Path {
@@ -1141,23 +1141,23 @@ func (rbw *requestBodyWrapper) Read(b []byte) (int, error) {
return n, err
}
func (h *peerAPIHandler) handleServeTailFS(w http.ResponseWriter, r *http.Request) {
if !h.ps.b.TailFSSharingEnabled() {
func (h *peerAPIHandler) handleServeDrive(w http.ResponseWriter, r *http.Request) {
if !h.ps.b.DriveSharingEnabled() {
h.logf("tailfs: not enabled")
http.Error(w, "tailfs not enabled", http.StatusNotFound)
return
}
capsMap := h.peerCaps()
tailfsCaps, ok := capsMap[tailcfg.PeerCapabilityTailFS]
driveCaps, ok := capsMap[tailcfg.PeerCapabilityTailFS]
if !ok {
h.logf("tailfs: not permitted")
http.Error(w, "tailfs not permitted", http.StatusForbidden)
return
}
rawPerms := make([][]byte, 0, len(tailfsCaps))
for _, cap := range tailfsCaps {
rawPerms := make([][]byte, 0, len(driveCaps))
for _, cap := range driveCaps {
rawPerms = append(rawPerms, []byte(cap))
}
@@ -1168,7 +1168,7 @@ func (h *peerAPIHandler) handleServeTailFS(w http.ResponseWriter, r *http.Reques
return
}
fs, ok := h.ps.b.sys.TailFSForRemote.GetOK()
fs, ok := h.ps.b.sys.DriveForRemote.GetOK()
if !ok {
h.logf("tailfs: not supported on platform")
http.Error(w, "tailfs not supported on platform", http.StatusNotFound)
@@ -1193,7 +1193,7 @@ func (h *peerAPIHandler) handleServeTailFS(w http.ResponseWriter, r *http.Reques
contentType = ct
}
h.logf("tailfs: share: %s from %s to %s: status-code=%d ext=%q content-type=%q tx=%.f rx=%.f", r.Method, h.peerNode.Key().ShortString(), h.selfNode.Key().ShortString(), wr.statusCode, parseTailFSFileExtensionForLog(r.URL.Path), contentType, roundTraffic(wr.contentLength), roundTraffic(bw.bytesRead))
h.logf("tailfs: share: %s from %s to %s: status-code=%d ext=%q content-type=%q tx=%.f rx=%.f", r.Method, h.peerNode.Key().ShortString(), h.selfNode.Key().ShortString(), wr.statusCode, parseDriveFileExtensionForLog(r.URL.Path), contentType, roundTraffic(wr.contentLength), roundTraffic(bw.bytesRead))
}
}()
}
@@ -1202,13 +1202,13 @@ func (h *peerAPIHandler) handleServeTailFS(w http.ResponseWriter, r *http.Reques
fs.ServeHTTPWithPerms(p, wr, r)
}
// parseTailFSFileExtensionForLog parses the file extension, if available.
// parseDriveFileExtensionForLog parses the file extension, if available.
// If a file extension is not present or parsable, the file extension is
// set to "unknown". If the file extension contains a double quote, it is
// replaced with "removed".
// All whitespace is removed from a parsed file extension.
// File extensions including the leading ., e.g. ".gif".
func parseTailFSFileExtensionForLog(path string) string {
func parseDriveFileExtensionForLog(path string) string {
fileExt := "unknown"
if fe := filepath.Ext(path); fe != "" {
if strings.Contains(fe, "\"") {

View File

@@ -64,7 +64,7 @@ type serveHTTPContext struct {
//
// This is not used in userspace-networking mode.
//
// localListener is used by tailscale serve (TCP only), the built-in web client and tailfs.
// localListener is used by tailscale serve (TCP only), the built-in web client and Taildrive.
// Most serve traffic and peer traffic for the web client are intercepted by netstack.
// This listener exists purely for connections from the machine itself, as that goes via the kernel,
// so we need to be in the kernel's listening/routing tables.

View File

@@ -116,7 +116,7 @@ var handler = map[string]localAPIHandler{
"set-dns": (*Handler).serveSetDNS,
"set-expiry-sooner": (*Handler).serveSetExpirySooner,
"set-gui-visible": (*Handler).serveSetGUIVisible,
"tailfs/fileserver-address": (*Handler).serveTailFSFileServerAddr,
"tailfs/fileserver-address": (*Handler).serveDriveServerAddr,
"tailfs/shares": (*Handler).serveShares,
"start": (*Handler).serveStart,
"status": (*Handler).serveStatus,
@@ -2735,8 +2735,8 @@ func (h *Handler) serveUpdateProgress(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(ups)
}
// serveTailFSFileServerAddr handles updates of the tailfs file server address.
func (h *Handler) serveTailFSFileServerAddr(w http.ResponseWriter, r *http.Request) {
// serveDriveServerAddr handles updates of the Taildrive file server address.
func (h *Handler) serveDriveServerAddr(w http.ResponseWriter, r *http.Request) {
if r.Method != "PUT" {
http.Error(w, "only PUT allowed", http.StatusMethodNotAllowed)
return
@@ -2748,18 +2748,18 @@ func (h *Handler) serveTailFSFileServerAddr(w http.ResponseWriter, r *http.Reque
return
}
h.b.TailFSSetFileServerAddr(string(b))
h.b.DriveSetServerAddr(string(b))
w.WriteHeader(http.StatusCreated)
}
// serveShares handles the management of tailfs shares.
// serveShares handles the management of Taildrive shares.
//
// PUT - adds or updates an existing share
// DELETE - removes a share
// GET - gets a list of all shares, sorted by name
// POST - renames an existing share
func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) {
if !h.b.TailFSSharingEnabled() {
if !h.b.DriveSharingEnabled() {
http.Error(w, `tailfs sharing not enabled, please add the attribute "tailfs:share" to this node in your ACLs' "nodeAttrs" section`, http.StatusForbidden)
return
}
@@ -2790,7 +2790,7 @@ func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) {
}
share.As = username
}
err = h.b.TailFSSetShare(&share)
err = h.b.DriveSetShare(&share)
if err != nil {
if errors.Is(err, ipnlocal.ErrInvalidShareName) {
http.Error(w, "invalid share name", http.StatusBadRequest)
@@ -2806,7 +2806,7 @@ func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err = h.b.TailFSRemoveShare(string(b))
err = h.b.DriveRemoveShare(string(b))
if err != nil {
if os.IsNotExist(err) {
http.Error(w, "share not found", http.StatusNotFound)
@@ -2823,7 +2823,7 @@ func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err = h.b.TailFSRenameShare(names[0], names[1])
err = h.b.DriveRenameShare(names[0], names[1])
if err != nil {
if os.IsNotExist(err) {
http.Error(w, "share not found", http.StatusNotFound)
@@ -2842,7 +2842,7 @@ func (h *Handler) serveShares(w http.ResponseWriter, r *http.Request) {
}
w.WriteHeader(http.StatusNoContent)
case "GET":
shares := h.b.TailFSGetShares()
shares := h.b.DriveGetShares()
err := json.NewEncoder(w).Encode(shares)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)

View File

@@ -225,9 +225,9 @@ type Prefs struct {
// Linux-only.
NetfilterKind string
// TailFSShares are the configured TailFSShares, stored in increasing order
// DriveShares are the configured DriveShares, stored in increasing order
// by name.
TailFSShares []*drive.Share
DriveShares []*drive.Share
// The Persist field is named 'Config' in the file for backward
// compatibility with earlier versions.
@@ -300,7 +300,7 @@ type MaskedPrefs struct {
AppConnectorSet bool `json:",omitempty"`
PostureCheckingSet bool `json:",omitempty"`
NetfilterKindSet bool `json:",omitempty"`
TailFSSharesSet bool `json:",omitempty"`
DriveSharesSet bool `json:",omitempty"`
}
type AutoUpdatePrefsMask struct {
@@ -564,7 +564,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool {
p.AutoUpdate.Equals(p2.AutoUpdate) &&
p.AppConnector == p2.AppConnector &&
p.PostureChecking == p2.PostureChecking &&
slices.EqualFunc(p.TailFSShares, p2.TailFSShares, drive.SharesEqual) &&
slices.EqualFunc(p.DriveShares, p2.DriveShares, drive.SharesEqual) &&
p.NetfilterKind == p2.NetfilterKind
}

View File

@@ -62,7 +62,7 @@ func TestPrefsEqual(t *testing.T) {
"AppConnector",
"PostureChecking",
"NetfilterKind",
"TailFSShares",
"DriveShares",
"Persist",
}
if have := fieldsOf(reflect.TypeFor[Prefs]()); !reflect.DeepEqual(have, prefsHandles) {