Skip to content

Commit 2f17df1

Browse files
authored
Merge pull request #427 from Jigsaw-Code/psiphon-bug
bug(x) fix psiphon wrapper context
2 parents 0604279 + 581c17a commit 2f17df1

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

x/psiphon/psiphon.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func getClientPlatform() string {
101101
// Allows for overriding in tests.
102102
var startTunnel func(ctx context.Context, config *DialerConfig) (psiphonTunnel, error) = psiphonStartTunnel
103103

104-
func psiphonStartTunnel(ctx context.Context, config *DialerConfig) (psiphonTunnel, error) {
104+
func psiphonStartTunnel(tunnelCtx context.Context, config *DialerConfig) (psiphonTunnel, error) {
105105
if config == nil {
106106
return nil, errors.New("config must not be nil")
107107
}
@@ -117,11 +117,11 @@ func psiphonStartTunnel(ctx context.Context, config *DialerConfig) (psiphonTunne
117117
DisableLocalHTTPProxy: &trueValue,
118118
}
119119

120-
return clientlib.StartTunnel(ctx, config.ProviderConfig, "", params, nil, nil)
120+
return clientlib.StartTunnel(tunnelCtx, config.ProviderConfig, "", params, nil, nil)
121121
}
122122

123123
// Start configures and runs the Dialer. It must be called before you can use the Dialer. It returns when the tunnel is ready.
124-
func (d *Dialer) Start(ctx context.Context, config *DialerConfig) error {
124+
func (d *Dialer) Start(startCtx context.Context, config *DialerConfig) error {
125125
resultCh := make(chan error)
126126
go func() {
127127
d.mu.Lock()
@@ -132,13 +132,23 @@ func (d *Dialer) Start(ctx context.Context, config *DialerConfig) error {
132132
return
133133
}
134134

135-
ctx, cancel := context.WithCancel(ctx)
136-
defer cancel()
135+
// startCtx is intended for the lifetime of the startup.
136+
// dialerCtx is intended for the lifetime of the tunnel.
137+
dialerCtx, dialerCancel := context.WithCancel(context.Background())
138+
defer dialerCancel()
139+
140+
// This ties startCtx and dialerCtx together
141+
// so dialerCtx will be cancelled if startCtx is cancelled.
142+
// We run detatchContexts after startTunnel to disconnect them.
143+
detatchContexts := context.AfterFunc(startCtx, func() {
144+
dialerCancel()
145+
})
146+
137147
tunnelDone := make(chan struct{})
138148
defer close(tunnelDone)
139149
d.stop = func() {
140150
// Tell start to stop.
141-
cancel()
151+
dialerCancel()
142152
// Wait for tunnel to be done.
143153
<-tunnelDone
144154
}
@@ -148,13 +158,13 @@ func (d *Dialer) Start(ctx context.Context, config *DialerConfig) error {
148158
}()
149159

150160
d.mu.Unlock()
151-
152-
tunnel, err := startTunnel(ctx, config)
161+
tunnel, err := startTunnel(dialerCtx, config)
153162

154163
d.mu.Lock()
164+
detatchContexts()
155165

156-
if ctx.Err() != nil {
157-
err = context.Cause(ctx)
166+
if dialerCtx.Err() != nil {
167+
err = context.Cause(dialerCtx)
158168
}
159169
if err != nil {
160170
resultCh <- err
@@ -169,7 +179,7 @@ func (d *Dialer) Start(ctx context.Context, config *DialerConfig) error {
169179

170180
d.mu.Unlock()
171181
// wait for Stop
172-
<-ctx.Done()
182+
<-dialerCtx.Done()
173183
d.mu.Lock()
174184
}()
175185
return <-resultCh

x/psiphon/psiphon_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func TestDialer_Start_Timeout(t *testing.T) {
139139
errCh <- GetSingletonDialer().Start(ctx, cfg)
140140
}()
141141
err := <-errCh
142-
require.ErrorIs(t, err, context.DeadlineExceeded)
142+
require.ErrorIs(t, err, context.Canceled)
143143
}
144144

145145
type errorTunnel struct {

0 commit comments

Comments
 (0)