Skip to content
Open
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
29 changes: 17 additions & 12 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,18 +254,23 @@ func (a *agent) createListener(ctx context.Context, endpointOpts *endpointOpts)
// Create endpoint listener
endpoint := &endpointListener{
baseEndpoint: baseEndpoint{
agent: a,
id: tunnel.ID(),
name: tunnel.Name(),
poolingEnabled: endpointOpts.poolingEnabled,
bindings: endpointOpts.bindings,
description: endpointOpts.description,
metadata: endpointOpts.metadata,
agentTLSConfig: endpointOpts.agentTLSConfig,
trafficPolicy: endpointOpts.trafficPolicy,
endpointURL: *tunnelURL,
doneChannel: make(chan struct{}),
doneOnce: &sync.Once{},
agent: a,
id: tunnel.ID(),
name: tunnel.Name(),
poolingEnabled: endpointOpts.poolingEnabled,
bindings: endpointOpts.bindings,
description: endpointOpts.description,
metadata: endpointOpts.metadata,
agentTLSConfig: endpointOpts.agentTLSConfig,
trafficPolicy: endpointOpts.trafficPolicy,
endpointURL: *tunnelURL,
doneChannel: make(chan struct{}),
doneOnce: &sync.Once{},
region: tunnel.Region(),
createdAt: tunnel.CreatedAt(),
updatedAt: tunnel.UpdatedAt(),
tunnelSessionID: tunnel.TunnelSessionID(),
tunnelID: tunnel.TunnelID(),
},
tunnel: tunnel,
}
Expand Down
65 changes: 53 additions & 12 deletions endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"net/url"
"sync"
"time"
)

// Endpoint is the interface implemented by both EndpointListener and
Expand Down Expand Up @@ -54,23 +55,43 @@ type Endpoint interface {

// URL returns the Endpoint's URL
URL() *url.URL

// Region returns the region where this endpoint was created.
Region() string

// CreatedAt returns the time when the endpoint was created.
CreatedAt() time.Time

// UpdatedAt returns the time when the endpoint was last updated.
UpdatedAt() time.Time

// TunnelSessionID returns the ID of the session that created this endpoint.
TunnelSessionID() string

// TunnelID returns the tunnel resource ID.
TunnelID() string
}

// baseEndpoint implements the common functionality for both EndpointListener and
// EndpointForwarder.
type baseEndpoint struct {
agent Agent
name string
poolingEnabled bool
bindings []string
description string
id string
metadata string
agentTLSConfig *tls.Config // TLS config for termination
trafficPolicy string
endpointURL url.URL
doneChannel chan struct{}
doneOnce *sync.Once
agent Agent
name string
poolingEnabled bool
bindings []string
description string
id string
metadata string
agentTLSConfig *tls.Config // TLS config for termination
trafficPolicy string
endpointURL url.URL
doneChannel chan struct{}
doneOnce *sync.Once
region string
createdAt time.Time
updatedAt time.Time
tunnelSessionID string
tunnelID string
}

func (e *baseEndpoint) Agent() Agent {
Expand Down Expand Up @@ -125,6 +146,26 @@ func (e *baseEndpoint) URL() *url.URL {
return &e.endpointURL
}

func (e *baseEndpoint) Region() string {
return e.region
}

func (e *baseEndpoint) CreatedAt() time.Time {
return e.createdAt
}

func (e *baseEndpoint) UpdatedAt() time.Time {
return e.updatedAt
}

func (e *baseEndpoint) TunnelSessionID() string {
return e.tunnelSessionID
}

func (e *baseEndpoint) TunnelID() string {
return e.tunnelID
}

// signalDone safely closes the done channel using sync.Once
func (e *baseEndpoint) signalDone() {
e.doneOnce.Do(func() {
Expand Down
30 changes: 30 additions & 0 deletions internal/legacy/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ type TunnelInfo interface {
// URL returns the tunnel endpoint's URL.
// Labeled tunnels will return the empty string.
URL() string
// Region returns the region where this tunnel was created.
Region() string
// CreatedAt returns the time when the tunnel was created.
CreatedAt() time.Time
// UpdatedAt returns the time when the tunnel was last updated.
UpdatedAt() time.Time
// TunnelSessionID returns the ID of the session that created this tunnel.
TunnelSessionID() string
// TunnelID returns the tunnel resource ID.
TunnelID() string
}

type tunnelImpl struct {
Expand Down Expand Up @@ -135,6 +145,26 @@ func (t *tunnelImpl) Labels() map[string]string {
return t.Tunnel.RemoteBindConfig().Labels
}

func (t *tunnelImpl) Region() string {
return t.Tunnel.Region()
}

func (t *tunnelImpl) CreatedAt() time.Time {
return t.Tunnel.CreatedAt()
}

func (t *tunnelImpl) UpdatedAt() time.Time {
return t.Tunnel.UpdatedAt()
}

func (t *tunnelImpl) TunnelSessionID() string {
return t.Tunnel.TunnelSessionID()
}

func (t *tunnelImpl) TunnelID() string {
return t.Tunnel.TunnelID()
}

func (t *tunnelImpl) Session() Session {
return t.Sess
}
Expand Down
85 changes: 65 additions & 20 deletions internal/tunnel/client/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"
"net/url"
"sync/atomic"
"time"

"golang.ngrok.com/ngrok/v2/internal/tunnel/proto"
)
Expand All @@ -18,6 +19,11 @@ type Tunnel interface {
Name() string
ForwardsTo() string
ForwardsProto() string
Region() string
CreatedAt() time.Time
UpdatedAt() time.Time
TunnelSessionID() string
TunnelID() string
}

type ProxyConn struct {
Expand All @@ -28,15 +34,20 @@ type ProxyConn struct {
// A Tunnel is a net.Listener that Accept()'s connections from a
// remote machine.
type tunnel struct {
id atomic.Value
configProto string
url string
opts any
token string
bindExtra proto.BindExtra
labels map[string]string
forwardsTo string
forwardsProto string
id atomic.Value
configProto string
url string
opts any
token string
bindExtra proto.BindExtra
labels map[string]string
forwardsTo string
forwardsProto string
region string
createdAt time.Time
updatedAt time.Time
tunnelSessionID string
tunnelID string

accept chan *ProxyConn // new connections come on this channel
unlisten func() error // call this function to close the tunnel
Expand All @@ -48,18 +59,32 @@ type tunnel struct {
func newTunnel(resp proto.BindResp, extra proto.BindExtra, s *session, forwardsTo string, forwardsProto string) *tunnel {
id := atomic.Value{}
id.Store(resp.ClientID)

var createdAt, updatedAt time.Time
if resp.Extra.CreatedAt != 0 {
createdAt = time.Unix(resp.Extra.CreatedAt, 0)
}
if resp.Extra.UpdatedAt != 0 {
updatedAt = time.Unix(resp.Extra.UpdatedAt, 0)
}

return &tunnel{
id: id,
configProto: resp.Proto,
url: resp.URL,
opts: resp.Opts,
token: resp.Extra.Token,
bindExtra: extra, // this makes the reconnecting session a little easier
accept: make(chan *ProxyConn),
unlisten: func() error { return s.unlisten(resp.ClientID) },
forwardsTo: forwardsTo,
forwardsProto: forwardsProto,
closeError: errors.New("Listener closed"),
id: id,
configProto: resp.Proto,
url: resp.URL,
opts: resp.Opts,
token: resp.Extra.Token,
bindExtra: extra, // this makes the reconnecting session a little easier
accept: make(chan *ProxyConn),
unlisten: func() error { return s.unlisten(resp.ClientID) },
forwardsTo: forwardsTo,
forwardsProto: forwardsProto,
closeError: errors.New("Listener closed"),
region: resp.Extra.Region,
createdAt: createdAt,
updatedAt: updatedAt,
tunnelSessionID: resp.Extra.TunnelSessionID,
tunnelID: resp.Extra.TunnelID,
}
}

Expand Down Expand Up @@ -140,6 +165,26 @@ func (t *tunnel) Name() string {
return t.bindExtra.Name
}

func (t *tunnel) Region() string {
return t.region
}

func (t *tunnel) CreatedAt() time.Time {
return t.createdAt
}

func (t *tunnel) UpdatedAt() time.Time {
return t.updatedAt
}

func (t *tunnel) TunnelSessionID() string {
return t.tunnelSessionID
}

func (t *tunnel) TunnelID() string {
return t.tunnelID
}

// RemoteBindConfig returns more detailed information about the public endpoint of the
// tunnel listener on the remote machine.
func (t *tunnel) RemoteBindConfig() *RemoteBindConfig {
Expand Down
7 changes: 6 additions & 1 deletion internal/tunnel/proto/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,12 @@ type BindResp struct {
}

type BindRespExtra struct {
Token string
Token string
Region string
CreatedAt int64 // unix timestamp in seconds when the tunnel was created
UpdatedAt int64 // unix timestamp in seconds when the tunnel was last updated
TunnelSessionID string // ID of the session that created this tunnel
TunnelID string // ID of the tunnel resource
}

// A client sends this message to the server over a new stream
Expand Down
Loading