Documentation ¶
Index ¶
- Variables
- func LogId(sid string, r *http.Request, hostport string, c *oauth.CredentialsCookie) string
- func NewBList() *blist
- func ToAbsolute(reference uint64, trunc uint32) uint64
- type AllowErrors
- type BlockingReceiveWindow
- func (b *BlockingReceiveWindow) Empty(size int)
- func (b *BlockingReceiveWindow) Fail(err error)
- func (b *BlockingReceiveWindow) Fill(size int) uint64
- func (b *BlockingReceiveWindow) Reset(wu uint32) error
- func (b *BlockingReceiveWindow) ToEmpty() []byte
- func (b *BlockingReceiveWindow) ToFill() []byte
- func (b *BlockingReceiveWindow) WaitToEmpty() error
- func (b *BlockingReceiveWindow) WaitToFill() error
- type BlockingSendWindow
- func (b *BlockingSendWindow) AcknowledgeUntil(wu uint32) (uint64, error)
- func (b *BlockingSendWindow) Empty(size int)
- func (b *BlockingSendWindow) Fail(err error)
- func (b *BlockingSendWindow) Fill(size int) uint64
- func (b *BlockingSendWindow) Reset(wu uint32) error
- func (b *BlockingSendWindow) ToEmpty() []byte
- func (b *BlockingSendWindow) ToFill() []byte
- func (b *BlockingSendWindow) WaitToEmpty(d time.Duration) error
- func (b *BlockingSendWindow) WaitToFill() error
- type BrowserWindowCounters
- type BufferPool
- type ExpirationPolicy
- type ExpireCounters
- type FailEmptyHost
- type FailEmptyPort
- type Filter
- type Flags
- type Modifier
- func FromFlags(fl *Flags) Modifier
- func WithBufferSize(size int) Modifier
- func WithExpirationPolicy(ep *ExpirationPolicy) Modifier
- func WithFilter(filter Filter) Modifier
- func WithLogging(log logger.Logger) Modifier
- func WithOriginChecker(checker func(r *http.Request) bool) Modifier
- func WithRelayHost(relayHost string) Modifier
- func WithResolver(r Resolver) Modifier
- func WithSymmetricOptions(mods ...token.SymmetricSetter) Modifier
- func WithTimeouts(timeouts *Timeouts) Modifier
- type Modifiers
- type MultiResolver
- type MuxHandle
- type NasshProxy
- func (np *NasshProxy) ExportMetrics(register prometheus.Registerer) error
- func (np *NasshProxy) ProxySsh(logid string, r *http.Request, w http.ResponseWriter, sid string, ...) error
- func (np *NasshProxy) Register(add MuxHandle)
- func (np *NasshProxy) RelayHost() string
- func (np *NasshProxy) Run(ctx context.Context)
- func (np *NasshProxy) ServeConnect(w http.ResponseWriter, r *http.Request)
- func (np *NasshProxy) ServeCookie(w http.ResponseWriter, r *http.Request)
- func (np *NasshProxy) ServeProxy(w http.ResponseWriter, r *http.Request)
- type ProxyCounters
- type ProxyErrors
- type ReadWriterCounters
- type ReceiveWindow
- type ReplaceableBrowser
- func (gb *ReplaceableBrowser) Close(err error)
- func (gb *ReplaceableBrowser) Error(wc *websocket.Conn, err error)
- func (gb *ReplaceableBrowser) Get() (*websocket.Conn, error)
- func (gb *ReplaceableBrowser) GetForReceive() (*websocket.Conn, uint32, error)
- func (gb *ReplaceableBrowser) GetForSend() (*websocket.Conn, uint32, uint32, error)
- func (gb *ReplaceableBrowser) GetRack() (*websocket.Conn, uint32, uint32, error)
- func (gb *ReplaceableBrowser) GetWack() (*websocket.Conn, uint32, uint32, error)
- func (gb *ReplaceableBrowser) GetWriteReadUntil() (uint32, uint32)
- func (gb *ReplaceableBrowser) Init(log logger.Logger, counters *BrowserWindowCounters)
- func (gb *ReplaceableBrowser) PushReadUntil(ru uint32)
- func (gb *ReplaceableBrowser) PushWrittenUntil(wu uint32)
- func (gb *ReplaceableBrowser) Set(wc *websocket.Conn, rack, wack uint32) waiter
- type Resolver
- type SRVResolver
- type SendWindow
- func (w *SendWindow) Acknowledge(size int)
- func (w *SendWindow) AcknowledgeUntil(trunc uint32) (uint64, error)
- func (sw *SendWindow) Drop()
- func (w *SendWindow) Empty(size int)
- func (w *SendWindow) Fill(size int) uint64
- func (w *SendWindow) Reset(trunc uint32) error
- func (w *SendWindow) ToEmpty() []byte
- func (w *SendWindow) ToFill() []byte
- type SessionCounters
- type TerminatingError
- type Timeouts
- type Waiter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrorExpired = errors.New("timer expired")
ErrorExpired is returned by WaitFor when the timer expires without events.
var OriginMatcher = regexp.MustCompile(`^chrome(-extension)?://`)
Functions ¶
func ToAbsolute ¶
Types ¶
type AllowErrors ¶
type BlockingReceiveWindow ¶
type BlockingReceiveWindow struct {
// contains filtered or unexported fields
}
BlockingReceiveWindow allows to split the filling and emptying of a ReceiveWindow across different goroutines.
Specifically, it assumes that there is one goroutine calling ToFill and Fill, and another goroutine calling ToEmpty, Empty, and Reset.
Having more than one filling or more than one empting goroutine is unsupported.
func NewBlockingReceiveWindow ¶
func NewBlockingReceiveWindow(pool *BufferPool, max uint64) *BlockingReceiveWindow
func (*BlockingReceiveWindow) Empty ¶
func (b *BlockingReceiveWindow) Empty(size int)
func (*BlockingReceiveWindow) Fail ¶
func (b *BlockingReceiveWindow) Fail(err error)
func (*BlockingReceiveWindow) Fill ¶
func (b *BlockingReceiveWindow) Fill(size int) uint64
func (*BlockingReceiveWindow) Reset ¶
func (b *BlockingReceiveWindow) Reset(wu uint32) error
func (*BlockingReceiveWindow) ToEmpty ¶
func (b *BlockingReceiveWindow) ToEmpty() []byte
func (*BlockingReceiveWindow) ToFill ¶
func (b *BlockingReceiveWindow) ToFill() []byte
func (*BlockingReceiveWindow) WaitToEmpty ¶
func (b *BlockingReceiveWindow) WaitToEmpty() error
func (*BlockingReceiveWindow) WaitToFill ¶
func (b *BlockingReceiveWindow) WaitToFill() error
type BlockingSendWindow ¶
type BlockingSendWindow struct {
// contains filtered or unexported fields
}
BlockingSendWindow allows to split the filling and emptying of a SendWindow across different goroutines.
Specifically, it assumes that there is one goroutine calling ToFill and Fill, and another goroutine calling ToEmpty, Empty, and possibly Reset and Acknowledge.
Note that the BlockingSendWindow still supports at most one sender and at most one receiver, not more.
func NewBlockingSendWindow ¶
func NewBlockingSendWindow(pool *BufferPool, max uint64) *BlockingSendWindow
func (*BlockingSendWindow) AcknowledgeUntil ¶
func (b *BlockingSendWindow) AcknowledgeUntil(wu uint32) (uint64, error)
func (*BlockingSendWindow) Empty ¶
func (b *BlockingSendWindow) Empty(size int)
func (*BlockingSendWindow) Fail ¶
func (b *BlockingSendWindow) Fail(err error)
func (*BlockingSendWindow) Fill ¶
func (b *BlockingSendWindow) Fill(size int) uint64
func (*BlockingSendWindow) Reset ¶
func (b *BlockingSendWindow) Reset(wu uint32) error
func (*BlockingSendWindow) ToEmpty ¶
func (b *BlockingSendWindow) ToEmpty() []byte
func (*BlockingSendWindow) ToFill ¶
func (b *BlockingSendWindow) ToFill() []byte
func (*BlockingSendWindow) WaitToEmpty ¶
func (b *BlockingSendWindow) WaitToEmpty(d time.Duration) error
func (*BlockingSendWindow) WaitToFill ¶
func (b *BlockingSendWindow) WaitToFill() error
type BrowserWindowCounters ¶
type BufferPool ¶
type BufferPool struct {
// contains filtered or unexported fields
}
BufferPool is a sync.Pool of buffers, used to allocate (and free) nodes used by the window implementation below.
func NewBufferPool ¶
func NewBufferPool(size int) *BufferPool
func (*BufferPool) Get ¶
func (bp *BufferPool) Get() *buffer
func (*BufferPool) Put ¶
func (bp *BufferPool) Put(b *buffer)
func (*BufferPool) Stats ¶
func (bp *BufferPool) Stats() (uint64, uint64, uint64)
Stats returns statistics about the pool.
Specifically, it returns the number of times Get() was called, the number of times Put() was called, and the number of times a new object had to be greated.
The delta between Get()s and Put()s indicates how many buffers have been allocated but not returned to the pool. This does not necessarily mean a memory leak: the garbage collector is still able to free those objects if unreferenced - they just won't be reused through the pool.
Together with the number of new called, though, it can provide a good signal toward the efficacy of the pool.
type ExpirationPolicy ¶
type ExpirationPolicy struct { // How often to run session garbage collection. Every time.Duration // If number of orphaned sessions exceed this threshold, the oldest // orphaned sessions will be terminated until fewer than this limit are // left, no matter what. This is meant to be a last resort option. RuthlessThreshold int // If number of orphaned sessions exceed this threshold, the oldest // sessions that have been orphaned for longer than OrphanLimit are // expired until either the number of sessions goes below // OrphanThreshold, or there are no orphaned sessions that have been // around longer than OrphanLimit. // // Tl;Dr: this only expires the oldest sessions that have been orphaned // for longer than OrphanLimit. OrphanThreshold int OrphanLimit time.Duration }
func DefaultExpirationPolicy ¶
func DefaultExpirationPolicy() *ExpirationPolicy
func (*ExpirationPolicy) Expire ¶
func (ep *ExpirationPolicy) Expire(ctx context.Context, clock utils.Clock, sessions *sessions, counters *ExpireCounters)
type ExpireCounters ¶
type ExpireCounters struct { ExpireRuns utils.Counter ExpireDuration utils.Counter ExpireAboveOrphanThresholdRuns utils.Counter ExpireAboveOrphanThresholdTotal utils.Counter ExpireAboveOrphanThresholdFound utils.Counter ExpireRaced utils.Counter ExpireOrphanClosed utils.Counter ExpireRuthlessClosed utils.Counter ExpireLifetimeTotal utils.Counter ExpireYoungest utils.Counter }
type FailEmptyHost ¶
type FailEmptyHost struct{}
FailEmptyHost is a Resolver that errors if host is empty, but otherwise returns the host and port unmodified.
type FailEmptyPort ¶
type FailEmptyPort struct{}
FailEmptyPort is a Resolver that errors if port is empty, but otherwise returns the host and port unmodified.
type Flags ¶
type Flags struct { *Timeouts *ExpirationPolicy SymmetricKey []byte BufferSize int RelayHost string }
func DefaultFlags ¶
func DefaultFlags() *Flags
type Modifier ¶
type Modifier func(*NasshProxy, *options) error
func WithBufferSize ¶
func WithExpirationPolicy ¶
func WithExpirationPolicy(ep *ExpirationPolicy) Modifier
func WithFilter ¶
func WithLogging ¶
func WithRelayHost ¶
func WithResolver ¶
func WithSymmetricOptions ¶
func WithSymmetricOptions(mods ...token.SymmetricSetter) Modifier
func WithTimeouts ¶
type Modifiers ¶
type Modifiers []Modifier
func (Modifiers) Apply ¶
func (mods Modifiers) Apply(np *NasshProxy, o *options) error
type MultiResolver ¶
type MultiResolver []Resolver
MultiResolver is a list of Resolvers that are applied in order until the list is exhausted or an error is encountered.
type MuxHandle ¶
MuxHandle is a function capable of instructing an http Mux to invoke an handler for a path.
pattern is a string representing a path without host (example: "/", or "/test"). No wildcards or field extraction is used by nasshp, only constants need to be supported by MuxHandle.
handler is the http.Handler to invoke for the specified path.
type NasshProxy ¶
type NasshProxy struct {
// contains filtered or unexported fields
}
func New ¶
func New(rng *rand.Rand, authenticator oauth.Authenticate, mods ...Modifier) (*NasshProxy, error)
New creates a new instance of a nasshp tunnel protocol.
rng MUST be a secure random number generator, use github.com/enfabrica/lib/srand in case of doubt to create one. authenticator is optional, can be left to nil to disable authentication.
mods MUST either contain FromFlags, to initialize all the nassh parameters from command line flags, or it MUST provide a symmetric key with nasshp.WithSymmetricOptions.
func (*NasshProxy) ExportMetrics ¶
func (np *NasshProxy) ExportMetrics(register prometheus.Registerer) error
func (*NasshProxy) ProxySsh ¶
func (np *NasshProxy) ProxySsh(logid string, r *http.Request, w http.ResponseWriter, sid string, rack, wack uint32, hostport string) error
func (*NasshProxy) Register ¶
func (np *NasshProxy) Register(add MuxHandle)
Register is a convenience function to configure all the handlers in your favourite Mux.
It configures the http paths and corresponding handlers that are necessary for a nassh implementation to support.
Registering the paths can also be done manually. Rather than document the required paths in comments here,look at the source code of the function.
func (*NasshProxy) RelayHost ¶
func (np *NasshProxy) RelayHost() string
func (*NasshProxy) Run ¶
func (np *NasshProxy) Run(ctx context.Context)
Run starts nasshp background workers.
It should typically be started in a goroutine of its own.
It completes eiter when there are no workers to be run, or when the supplied ctx is canceled.
func (*NasshProxy) ServeConnect ¶
func (np *NasshProxy) ServeConnect(w http.ResponseWriter, r *http.Request)
func (*NasshProxy) ServeCookie ¶
func (np *NasshProxy) ServeCookie(w http.ResponseWriter, r *http.Request)
func (*NasshProxy) ServeProxy ¶
func (np *NasshProxy) ServeProxy(w http.ResponseWriter, r *http.Request)
type ProxyCounters ¶
type ProxyCounters struct { ReadWriterCounters SshProxyStarted utils.Counter SshProxyStopped utils.Counter }
type ProxyErrors ¶
type ProxyErrors struct { CookieInvalidParameters utils.Counter CookieInvalidAuth utils.Counter ProxyInvalidAuth utils.Counter ProxyInvalidHostPort utils.Counter ProxyCouldNotEncrypt utils.Counter ProxyAllow AllowErrors ConnectInvalidSID utils.Counter ConnectInvalidAck utils.Counter ConnectInvalidPos utils.Counter ConnectAllow AllowErrors SshFailedUpgrade utils.Counter SshResumeNoSID utils.Counter SshCreateExists utils.Counter SshDialFailed utils.Counter }
type ReadWriterCounters ¶
type ReadWriterCounters struct { BrowserWindowCounters BrowserWriterStarted utils.Counter BrowserWriterStopped utils.Counter BrowserWriterError utils.Counter BrowserReaderStarted utils.Counter BrowserReaderStopped utils.Counter BrowserReaderError utils.Counter BrowserBytesRead utils.Counter BackendBytesWrite utils.Counter BackendBytesRead utils.Counter BrowserBytesWrite utils.Counter }
type ReceiveWindow ¶
type ReceiveWindow struct { Filled uint64 // Absolute counter of bytes Filled. Emptied uint64 // Absolute counter of bytes Emptied. // contains filtered or unexported fields }
func NewReceiveWindow ¶
func NewReceiveWindow(pool *BufferPool) *ReceiveWindow
func (*ReceiveWindow) Drop ¶
func (sw *ReceiveWindow) Drop()
func (*ReceiveWindow) Empty ¶
func (w *ReceiveWindow) Empty(size int)
func (*ReceiveWindow) Fill ¶
func (w *ReceiveWindow) Fill(size int) uint64
func (*ReceiveWindow) Reset ¶
func (w *ReceiveWindow) Reset(wack uint32) error
func (*ReceiveWindow) ToEmpty ¶
func (w *ReceiveWindow) ToEmpty() []byte
func (*ReceiveWindow) ToFill ¶
func (w *ReceiveWindow) ToFill() []byte
type ReplaceableBrowser ¶
type ReplaceableBrowser struct {
// contains filtered or unexported fields
}
func NewReplaceableBrowser ¶
func NewReplaceableBrowser(log logger.Logger, counters *BrowserWindowCounters) *ReplaceableBrowser
func (*ReplaceableBrowser) Close ¶
func (gb *ReplaceableBrowser) Close(err error)
func (*ReplaceableBrowser) Error ¶
func (gb *ReplaceableBrowser) Error(wc *websocket.Conn, err error)
func (*ReplaceableBrowser) GetForReceive ¶
func (gb *ReplaceableBrowser) GetForReceive() (*websocket.Conn, uint32, error)
func (*ReplaceableBrowser) GetForSend ¶
func (*ReplaceableBrowser) GetWriteReadUntil ¶
func (gb *ReplaceableBrowser) GetWriteReadUntil() (uint32, uint32)
func (*ReplaceableBrowser) Init ¶
func (gb *ReplaceableBrowser) Init(log logger.Logger, counters *BrowserWindowCounters)
func (*ReplaceableBrowser) PushReadUntil ¶
func (gb *ReplaceableBrowser) PushReadUntil(ru uint32)
func (*ReplaceableBrowser) PushWrittenUntil ¶
func (gb *ReplaceableBrowser) PushWrittenUntil(wu uint32)
type SRVResolver ¶
type SRVResolver struct{}
SRVResolver is a Resolver that attempts to resolve the port via an SRV record if the port is empty.
type SendWindow ¶
type SendWindow struct { Filled uint64 // Absolute counter of bytes Filled. Emptied uint64 // Absolute counter of bytes consumed from this window. // contains filtered or unexported fields }
func NewSendWindow ¶
func NewSendWindow(pool *BufferPool) *SendWindow
func (*SendWindow) Acknowledge ¶
func (w *SendWindow) Acknowledge(size int)
func (*SendWindow) AcknowledgeUntil ¶
func (w *SendWindow) AcknowledgeUntil(trunc uint32) (uint64, error)
func (*SendWindow) Drop ¶
func (sw *SendWindow) Drop()
func (*SendWindow) Empty ¶
func (w *SendWindow) Empty(size int)
func (*SendWindow) Fill ¶
func (w *SendWindow) Fill(size int) uint64
func (*SendWindow) Reset ¶
func (w *SendWindow) Reset(trunc uint32) error
func (*SendWindow) ToEmpty ¶
func (w *SendWindow) ToEmpty() []byte
func (*SendWindow) ToFill ¶
func (w *SendWindow) ToFill() []byte
type SessionCounters ¶
type TerminatingError ¶
type TerminatingError struct {
// contains filtered or unexported fields
}
func (*TerminatingError) Unwrap ¶
func (te *TerminatingError) Unwrap() error
type Timeouts ¶
type Timeouts struct { Now utils.TimeSource ResolutionTimeout time.Duration BrowserWriteTimeout time.Duration BrowserAckTimeout time.Duration ConnWriteTimeout time.Duration }
func DefaultTimeouts ¶
func DefaultTimeouts() *Timeouts
type Waiter ¶
type Waiter struct {
// contains filtered or unexported fields
}
Waiter is similar to sync.CondWait as it can be used exactly the same way, except:
- it only supports a single waiter. Having more than one waiter will lead to undefined behavior.
- it allows to configure wait timeouts.
- it allows to propagate error failures.
Example ¶
lock := &sync.Mutex{} waiter := NewWaiter(lock) wg := &sync.WaitGroup{} wg.Add(2) counter := 0 // Produces events: increments counter. go func() { for i := 0; i < 10; i++ { time.Sleep(10 * time.Millisecond) lock.Lock() counter += 1 waiter.Signal() lock.Unlock() } wg.Done() }() go func() { lock.Lock() defer lock.Unlock() for counter < 10 { waiter.Wait() } fmt.Println("counter is now >= 10") wg.Done() }() wg.Wait()
Output: counter is now >= 10
func (*Waiter) Fail ¶
Fail will cause anyone waiting on Wait*() to receive the specified error. Do NOT hold the lock when invoking Fail().
func (*Waiter) Signal ¶
func (w *Waiter) Signal()
Signal will notify anyone waiting on Wait*() to check the condition again. It can be invoked with or without the lock held.