Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion aperture.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,12 @@ func createHashMailServer(cfg *Config) ([]proxy.LocalService, func(), error) {
}

// Wrap the default grpc-gateway handler with the WebSocket handler.
// We enable WebSocket-level pings to keep the underlying connection
// alive through intermediary proxies and load balancers that may
// silently drop idle WebSocket connections.
restHandler := lnrpc.NewWebSocketProxy(
mux, log, 0, 0, clientStreamingURIs,
mux, log, cfg.WsPingInterval, cfg.WsPongWait,
clientStreamingURIs,
)

// Create our proxy chain now. A request will pass
Expand Down
37 changes: 37 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ const (
defaultIdleTimeout = time.Minute * 2
defaultReadTimeout = time.Second * 15
defaultWriteTimeout = time.Second * 30

// defaultWsPingInterval is the default interval at which we send
// WebSocket-level pings to connected clients. This keeps the
// connection alive through intermediary proxies and load balancers
// that may drop idle connections.
defaultWsPingInterval = 30 * time.Second

// defaultWsPongWait is the default duration we wait for a pong
// response after sending a WebSocket ping before considering the
// connection dead.
defaultWsPongWait = 15 * time.Second
)

type EtcdConfig struct {
Expand Down Expand Up @@ -233,6 +244,18 @@ type Config struct {
// Logging controls various aspects of aperture logging.
Logging *build.LogConfig `group:"logging" namespace:"logging"`

// WsPingInterval is the interval at which WebSocket-level pings are
// sent to connected clients. This keeps the underlying WebSocket
// connection alive through intermediary proxies and load balancers.
// Set to 0 to disable.
WsPingInterval time.Duration `long:"wspinginterval" description:"Interval for WebSocket-level ping messages to keep connections alive through proxies."`

// WsPongWait is the duration to wait for a pong response after
// sending a WebSocket-level ping. If no pong is received within this
// duration, the WebSocket connection is considered dead. Must be
// strictly less than WsPingInterval when pings are enabled.
WsPongWait time.Duration `long:"wspongwait" description:"Duration to wait for a WebSocket pong response before closing the connection."`

// Blocklist is a list of IPs to deny access to.
Blocklist []string `long:"blocklist" description:"List of IP addresses to block from accessing the proxy."`
}
Expand All @@ -252,6 +275,18 @@ func (c *Config) validate() error {
return fmt.Errorf("invoice batch size must be greater than 0")
}

if c.WsPingInterval < 0 {
return fmt.Errorf("wspinginterval must not be negative")
}
if c.WsPongWait < 0 {
return fmt.Errorf("wspongwait must not be negative")
}
if c.WsPingInterval > 0 && c.WsPongWait >= c.WsPingInterval {
return fmt.Errorf("wspongwait (%v) must be less than "+
"wspinginterval (%v)", c.WsPongWait,
c.WsPingInterval)
}

return nil
}

Expand All @@ -277,6 +312,8 @@ func NewConfig() *Config {
IdleTimeout: defaultIdleTimeout,
ReadTimeout: defaultReadTimeout,
WriteTimeout: defaultWriteTimeout,
WsPingInterval: defaultWsPingInterval,
WsPongWait: defaultWsPongWait,
InvoiceBatchSize: defaultInvoiceBatchSize,
Logging: build.DefaultLogConfig(),
Blocklist: []string{},
Expand Down
11 changes: 11 additions & 0 deletions sample-conf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ readtimeout: 15s
# The maximum amount of time to wait for a response to be fully written.
writetimeout: 30s

# Interval at which WebSocket-level pings are sent to connected clients. This
# keeps LNC connections alive through intermediary proxies and load balancers
# that may drop idle WebSocket connections. Set to 0 to disable.
# Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
wspinginterval: 30s

# Duration to wait for a WebSocket pong response after sending a ping. If no
# pong is received within this duration, the connection is considered dead.
# Must be strictly less than wspinginterval.
wspongwait: 15s

# Settings for the lnd node used to generate payment requests. All of these
# options are required.
authenticator:
Expand Down
Loading