ipn: add/move some constants, update a comment
And make the StateStore implementations be Stringers, for error messages.pull/797/head
parent
1fecf87363
commit
90b7293b3b
|
@ -28,15 +28,6 @@ import (
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
// globalStateKey is the ipn.StateKey that tailscaled loads on
|
|
||||||
// startup.
|
|
||||||
//
|
|
||||||
// We have to support multiple state keys for other OSes (Windows in
|
|
||||||
// particular), but right now Unix daemons run with a single
|
|
||||||
// node-global state. To keep open the option of having per-user state
|
|
||||||
// later, the global state key doesn't look like a username.
|
|
||||||
const globalStateKey = "_daemon"
|
|
||||||
|
|
||||||
var upCmd = &ffcli.Command{
|
var upCmd = &ffcli.Command{
|
||||||
Name: "up",
|
Name: "up",
|
||||||
ShortUsage: "up [flags]",
|
ShortUsage: "up [flags]",
|
||||||
|
@ -239,7 +230,7 @@ func runUp(ctx context.Context, args []string) error {
|
||||||
|
|
||||||
bc.SetPrefs(prefs)
|
bc.SetPrefs(prefs)
|
||||||
opts := ipn.Options{
|
opts := ipn.Options{
|
||||||
StateKey: globalStateKey,
|
StateKey: ipn.GlobalDaemonStateKey,
|
||||||
AuthKey: upArgs.authKey,
|
AuthKey: upArgs.authKey,
|
||||||
Notify: func(n ipn.Notify) {
|
Notify: func(n ipn.Notify) {
|
||||||
if n.ErrMessage != nil {
|
if n.ErrMessage != nil {
|
||||||
|
|
|
@ -81,14 +81,12 @@ type Notify struct {
|
||||||
// shared by several consecutive users. Ideally we would just use the
|
// shared by several consecutive users. Ideally we would just use the
|
||||||
// username of the connected frontend as the StateKey.
|
// username of the connected frontend as the StateKey.
|
||||||
//
|
//
|
||||||
// However, on Windows, there seems to be no safe way to figure out
|
// Various platforms currently set StateKey in different ways:
|
||||||
// the owning user of a process connected over IPC mechanisms
|
//
|
||||||
// (sockets, named pipes). So instead, on Windows, we use a
|
// * the macOS/iOS GUI apps set it to "ipn-go-bridge"
|
||||||
// capability-oriented system where the frontend generates a random
|
// * the Android app sets it to "ipn-android"
|
||||||
// identifier for itself, and uses that as the StateKey when talking
|
// * on Windows, it's always the the empty string
|
||||||
// to the backend. That way, while we can't identify an OS user by
|
// * on Linux/etc, it's always "_daemon" (ipn.GlobalDaemonStateKey)
|
||||||
// name, we can tell two different users apart, because they'll have
|
|
||||||
// different opaque state keys (and no access to each others's keys).
|
|
||||||
type StateKey string
|
type StateKey string
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
|
16
ipn/store.go
16
ipn/store.go
|
@ -7,6 +7,7 @@ package ipn
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -19,6 +20,17 @@ import (
|
||||||
// requested state ID doesn't exist.
|
// requested state ID doesn't exist.
|
||||||
var ErrStateNotExist = errors.New("no state with given ID")
|
var ErrStateNotExist = errors.New("no state with given ID")
|
||||||
|
|
||||||
|
const (
|
||||||
|
// GlobalDaemonStateKey is the ipn.StateKey that tailscaled
|
||||||
|
// loads on startup.
|
||||||
|
//
|
||||||
|
// We have to support multiple state keys for other OSes (Windows in
|
||||||
|
// particular), but right now Unix daemons run with a single
|
||||||
|
// node-global state. To keep open the option of having per-user state
|
||||||
|
// later, the global state key doesn't look like a username.
|
||||||
|
GlobalDaemonStateKey = StateKey("_daemon")
|
||||||
|
)
|
||||||
|
|
||||||
// StateStore persists state, and produces it back on request.
|
// StateStore persists state, and produces it back on request.
|
||||||
type StateStore interface {
|
type StateStore interface {
|
||||||
// ReadState returns the bytes associated with ID. Returns (nil,
|
// ReadState returns the bytes associated with ID. Returns (nil,
|
||||||
|
@ -34,6 +46,8 @@ type MemoryStore struct {
|
||||||
cache map[StateKey][]byte
|
cache map[StateKey][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *MemoryStore) String() string { return "MemoryStore" }
|
||||||
|
|
||||||
// ReadState implements the StateStore interface.
|
// ReadState implements the StateStore interface.
|
||||||
func (s *MemoryStore) ReadState(id StateKey) ([]byte, error) {
|
func (s *MemoryStore) ReadState(id StateKey) ([]byte, error) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
@ -67,6 +81,8 @@ type FileStore struct {
|
||||||
cache map[StateKey][]byte
|
cache map[StateKey][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FileStore) String() string { return fmt.Sprintf("FileStore(%q)", s.path) }
|
||||||
|
|
||||||
// NewFileStore returns a new file store that persists to path.
|
// NewFileStore returns a new file store that persists to path.
|
||||||
func NewFileStore(path string) (*FileStore, error) {
|
func NewFileStore(path string) (*FileStore, error) {
|
||||||
bs, err := ioutil.ReadFile(path)
|
bs, err := ioutil.ReadFile(path)
|
||||||
|
|
Loading…
Reference in New Issue