feat: enhance listener lease management and improve MITM probe handling
Kim committed
Apr 15, 2026 at 12:16 UTC
8423099eb96b001d2b87b1aeb474ba9d12b8111f
4 files changed
+175
-154
sdk/expose.go
+7
-2
@@ -154,11 +154,16 @@ func (e *Exposure) ActiveRelayURLs() []string {
154
155
func (e *Exposure) Addr() net.Addr {
156
if e.identity.Address == "" {
157
- return listenerAddr("portal:exposure")
157
+ return exposureAddr("portal:exposure")
158
}
159
- return listenerAddr("portal:" + e.identity.Address)
159
+ return exposureAddr("portal:" + e.identity.Address)
160
}
161
162
+type exposureAddr string
163
+
164
+func (a exposureAddr) Network() string { return "portal" }
165
+func (a exposureAddr) String() string { return string(a) }
166
+
167
func (e *Exposure) Identity() types.Identity {
168
return e.identity
169
}
sdk/listener.go
+138
-109
@@ -54,6 +54,7 @@ type listener struct {
54
identity types.Identity
55
metadata types.LeaseMetadata
56
relaySet *discovery.RelaySet
57
+ udpEnabled bool
58
tcpEnabled bool
59
dialTimeout time.Duration
60
requestTimeout time.Duration
@@ -70,13 +71,8 @@ type listener struct {
71
httpClient *http.Client
72
tlsConfig *tls.Config
73
73
- hostname string
74
- udpAddr string
75
- accessToken string
76
- expiresAt time.Time
77
- sniPort int
78
- tenantTLSConfig *tls.Config
79
- tenantTLSCloser io.Closer
74
+ leaseMu sync.RWMutex
75
+ lease *listenerLease
76
}
77
78
// newListener creates one relay listener and its dedicated relay transport for one relay URL.
@@ -109,6 +105,7 @@ func newListener(ctx context.Context, relayURL string, cfg listenerConfig) (*lis
105
identity: cfg.Identity,
106
metadata: cfg.Metadata,
107
relaySet: cfg.relaySet,
108
+ udpEnabled: cfg.UDPEnabled,
109
tcpEnabled: cfg.TCPEnabled,
110
dialTimeout: dialTimeout,
111
requestTimeout: requestTimeout,
@@ -120,7 +117,7 @@ func newListener(ctx context.Context, relayURL string, cfg listenerConfig) (*lis
117
}
118
l.mitmManager = newMITMManager(listenerCtx, l, cfg.BanMITM)
119
l.stream = transport.NewClientStream(readyTarget, handshakeTimeout)
123
- if cfg.UDPEnabled {
120
+ if l.udpEnabled {
121
l.datagram = transport.NewClientDatagram(func(err error) {
122
log.Info().
123
Err(err).
@@ -185,9 +182,9 @@ func (l *listener) run(ctx context.Context) {
182
}
183
184
if errors.Is(err, errLeaseRefreshRequired) {
188
- _, _, tenantTLSCloser := l.clearLease("lease refresh required")
189
- if tenantTLSCloser != nil {
190
- _ = tenantTLSCloser.Close()
185
+ lease := l.clearLease("lease refresh required")
186
+ if lease != nil && lease.tlsCloser != nil {
187
+ _ = lease.tlsCloser.Close()
188
}
189
l.resetTransport()
190
continue
@@ -211,7 +208,7 @@ func (l *listener) Close() error {
208
l.cancel()
209
}
210
214
- registered, accessToken, tenantTLSCloser := l.clearLease("")
211
+ lease := l.clearLease("")
212
213
if l.stream != nil {
214
l.stream.Drain()
@@ -220,37 +217,52 @@ func (l *listener) Close() error {
217
l.datagram.Close()
218
}
219
223
- if registered && l.identity.Key() != "" && accessToken != "" {
220
+ if lease != nil && lease.hostname != "" && l.identity.Key() != "" && lease.accessToken != "" {
221
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
225
- closeErr = errors.Join(closeErr, l.unregisterLease(ctx, accessToken))
222
+ closeErr = errors.Join(closeErr, l.unregisterLease(ctx, lease.accessToken))
223
cancel()
224
}
228
- if tenantTLSCloser != nil {
229
- closeErr = errors.Join(closeErr, tenantTLSCloser.Close())
225
+ if lease != nil && lease.tlsCloser != nil {
226
+ closeErr = errors.Join(closeErr, lease.tlsCloser.Close())
227
}
228
l.resetTransport()
229
})
230
return closeErr
231
}
232
236
-func (l *listener) clearLease(reason string) (bool, string, io.Closer) {
237
- registered := l.hostname != ""
238
- accessToken := l.accessToken
239
- tenantTLSCloser := l.tenantTLSCloser
240
- l.hostname = ""
241
- l.udpAddr = ""
242
- l.accessToken = ""
243
- l.expiresAt = time.Time{}
244
- l.sniPort = 0
245
- l.tenantTLSConfig = nil
246
- l.tenantTLSCloser = nil
233
+type listenerLease struct {
234
+ hostname string
235
+ udpAddr string
236
+ accessToken string
237
+ expiresAt time.Time
238
+ sniPort int
239
+ tlsConfig *tls.Config
240
+ tlsCloser io.Closer
241
+}
242
+
243
+func (l *listener) clearLease(reason string) *listenerLease {
244
+ l.leaseMu.Lock()
245
+ lease := l.lease
246
+ l.lease = nil
247
+ l.leaseMu.Unlock()
248
+
249
if l.mitmManager != nil {
250
l.mitmManager.reset()
251
}
252
if l.datagram != nil && reason != "" {
253
l.datagram.Clear(reason)
254
}
253
- return registered, accessToken, tenantTLSCloser
255
+ return lease
256
+}
257
+
258
+func (l *listener) leaseSnapshot() (listenerLease, bool) {
259
+ l.leaseMu.RLock()
260
+ defer l.leaseMu.RUnlock()
261
+
262
+ if l.lease == nil {
263
+ return listenerLease{}, false
264
+ }
265
+ return *l.lease, true
266
}
267
268
func (l *listener) Accept() (net.Conn, error) {
@@ -274,7 +286,7 @@ func (l *listener) Accept() (net.Conn, error) {
286
if handled {
287
continue
288
}
277
- return wrapMITMProbeConn(l.mitmManager, nextConn), nil
289
+ return &mitmProbeConn{Conn: nextConn, manager: l.mitmManager}, nil
290
}
291
}
292
@@ -289,7 +301,9 @@ func (l *listener) acceptDatagram() (types.DatagramFrame, error) {
301
}
302
303
frame.Payload = append([]byte(nil), frame.Payload...)
292
- frame.UDPAddr = l.udpAddr
304
+ if lease, ok := l.leaseSnapshot(); ok {
305
+ frame.UDPAddr = lease.udpAddr
306
+ }
307
frame.Address = l.identity.Address
308
if l.relayURL != nil {
309
frame.RelayURL = l.relayURL.String()
@@ -316,8 +330,12 @@ func (l *listener) datagramReady() (string, bool, bool) {
330
return "", false, false
331
}
332
319
- hostname := l.hostname
320
- udpAddr := l.udpAddr
333
+ hostname := ""
334
+ udpAddr := ""
335
+ if lease, ok := l.leaseSnapshot(); ok {
336
+ hostname = lease.hostname
337
+ udpAddr = lease.udpAddr
338
+ }
339
ready := l.datagram.Connected() && udpAddr != ""
340
closed := false
341
select {
@@ -330,11 +348,17 @@ func (l *listener) datagramReady() (string, bool, bool) {
348
}
349
350
func (l *listener) publicURL() string {
333
- if l.relayURL == nil {
351
+ lease, ok := l.leaseSnapshot()
352
+ if !ok {
353
return ""
354
}
355
+ return l.publicURLForHostname(lease.hostname)
356
+}
357
337
- hostname := l.hostname
358
+func (l *listener) publicURLForHostname(hostname string) string {
359
+ if l.relayURL == nil {
360
+ return ""
361
+ }
362
if hostname == "" {
363
return ""
364
}
@@ -355,24 +379,21 @@ func (l *listener) publicURL() string {
379
}
380
381
func (l *listener) runLease(ctx context.Context) error {
358
- registered := l.hostname != ""
359
- tlsConfig := l.tenantTLSConfig
360
- if !registered {
382
+ lease, ok := l.leaseSnapshot()
383
+ if !ok || lease.hostname == "" {
384
if ctx.Err() != nil {
385
return ctx.Err()
386
}
387
return errLeaseRefreshRequired
388
}
366
- readyTarget := l.readyTarget
367
-
389
leaseCtx, cancel := context.WithCancel(ctx)
390
defer cancel()
391
371
- errCh := make(chan error, max(readyTarget, 1)+1)
372
- if l.stream != nil && readyTarget > 0 {
373
- for range readyTarget {
392
+ errCh := make(chan error, max(l.readyTarget, 1)+1)
393
+ if l.stream != nil && l.readyTarget > 0 {
394
+ for range l.readyTarget {
395
go func() {
375
- if err := l.runReverseSessionLoop(leaseCtx, tlsConfig); err != nil {
396
+ if err := l.runReverseSessionLoop(leaseCtx, lease.tlsConfig); err != nil {
397
select {
398
case errCh <- err:
399
case <-leaseCtx.Done():
@@ -381,7 +402,7 @@ func (l *listener) runLease(ctx context.Context) error {
402
}()
403
}
404
}
384
- if l.datagram != nil {
405
+ if l.udpEnabled {
406
go l.runDatagramLoop(leaseCtx)
407
}
408
go func() {
@@ -442,7 +463,6 @@ func (l *listener) runDatagramLoop(ctx context.Context) {
463
if l.datagram == nil {
464
return
465
}
445
- address := l.identity.Address
466
467
for {
468
select {
@@ -457,7 +477,7 @@ func (l *listener) runDatagramLoop(ctx context.Context) {
477
log.Info().
478
Err(err).
479
Str("component", "sdk-datagram-plane").
460
- Str("address", address).
480
+ Str("address", l.identity.Address).
481
Msg("quic datagram plane unavailable; retrying")
482
if !utils.SleepOrDone(ctx, 2*time.Second) {
483
l.datagram.Clear("lease stopped")
@@ -468,7 +488,7 @@ func (l *listener) runDatagramLoop(ctx context.Context) {
488
489
log.Info().
490
Str("component", "sdk-datagram-plane").
471
- Str("address", address).
491
+ Str("address", l.identity.Address).
492
Str("remote_addr", conn.RemoteAddr().String()).
493
Msg("quic tunnel connected")
494
@@ -480,7 +500,7 @@ func (l *listener) runDatagramLoop(ctx context.Context) {
500
log.Info().
501
Err(err).
502
Str("component", "sdk-datagram-plane").
483
- Str("address", address).
503
+ Str("address", l.identity.Address).
504
Msg("quic datagram plane did not bind cleanly; retrying")
505
if !utils.SleepOrDone(ctx, time.Second) {
506
return
@@ -502,9 +522,13 @@ func (l *listener) runDatagramLoop(ctx context.Context) {
522
}
523
524
func (l *listener) openReverseSession(ctx context.Context) (net.Conn, error) {
505
- if l.accessToken == "" {
525
+ lease, ok := l.leaseSnapshot()
526
+ if !ok || lease.accessToken == "" {
527
return nil, errors.New("access token is not available")
528
}
529
+ if l.tlsConfig == nil {
530
+ return nil, errors.New("relay tls config is unavailable")
531
+ }
532
533
dialer := &tls.Dialer{
534
NetDialer: &net.Dialer{Timeout: l.dialTimeout},
@@ -522,7 +546,7 @@ func (l *listener) openReverseSession(ctx context.Context) (net.Conn, error) {
546
Host: l.relayURL.Host,
547
Header: make(http.Header),
548
}
525
- req.Header.Set(types.HeaderAccessToken, l.accessToken)
549
+ req.Header.Set(types.HeaderAccessToken, lease.accessToken)
550
req.Header.Set("Connection", "keep-alive")
551
552
if writeErr := req.Write(conn); writeErr != nil {
@@ -547,37 +571,17 @@ func (l *listener) openReverseSession(ctx context.Context) (net.Conn, error) {
571
return wrapBufferedConn(conn, reader), nil
572
}
573
550
-type bufferedConn struct {
551
- net.Conn
552
- reader *bytes.Reader
553
-}
554
-
555
-func wrapBufferedConn(conn net.Conn, reader *bufio.Reader) net.Conn {
556
- if reader == nil || reader.Buffered() == 0 {
557
- return conn
558
- }
559
- buf := make([]byte, reader.Buffered())
560
- if _, err := io.ReadFull(reader, buf); err != nil {
561
- return conn
562
- }
563
- return &bufferedConn{Conn: conn, reader: bytes.NewReader(buf)}
564
-}
565
-
566
-func (c *bufferedConn) Read(p []byte) (int, error) {
567
- if c.reader != nil && c.reader.Len() > 0 {
568
- return c.reader.Read(p)
569
- }
570
- return c.Conn.Read(p)
571
-}
572
-
574
func (l *listener) openQUICSession(ctx context.Context) (*quic.Conn, error) {
574
- if l.accessToken == "" {
575
+ lease, ok := l.leaseSnapshot()
576
+ if !ok || lease.accessToken == "" {
577
return nil, errors.New("access token is not available")
578
}
577
- if l.sniPort <= 0 {
579
+ if lease.sniPort <= 0 {
580
return nil, errors.New("sni port is not available")
581
}
580
-
582
+ if l.tlsConfig == nil {
583
+ return nil, errors.New("relay tls config is unavailable")
584
+ }
585
tlsConf := l.tlsConfig.Clone()
586
tlsConf.NextProtos = []string{"portal-tunnel"}
587
@@ -591,7 +595,7 @@ func (l *listener) openQUICSession(ctx context.Context) (*quic.Conn, error) {
595
if host == "" {
596
host = strings.TrimSpace(l.relayURL.Host)
597
}
594
- dialAddr := net.JoinHostPort(host, fmt.Sprintf("%d", l.sniPort))
598
+ dialAddr := net.JoinHostPort(host, fmt.Sprintf("%d", lease.sniPort))
599
conn, err := quic.DialAddr(ctx, dialAddr, tlsConf, quicConf)
600
if err != nil {
601
return nil, fmt.Errorf("quic dial: %w", err)
@@ -604,7 +608,7 @@ func (l *listener) openQUICSession(ctx context.Context) (*quic.Conn, error) {
608
}
609
610
controlMsg := types.QUICControlMessage{
607
- AccessToken: l.accessToken,
611
+ AccessToken: lease.accessToken,
612
}
613
if err := json.NewEncoder(stream).Encode(controlMsg); err != nil {
614
_ = conn.CloseWithError(1, "control write failed")
@@ -683,14 +687,13 @@ func (l *listener) runRenewLoop(ctx context.Context) error {
687
}
688
689
func (l *listener) renewLease(ctx context.Context) error {
686
- expiresAt := l.expiresAt
687
- accessToken := l.accessToken
688
- if accessToken == "" || !time.Now().Before(expiresAt) {
690
+ lease, ok := l.leaseSnapshot()
691
+ if !ok || lease.accessToken == "" || !time.Now().Before(lease.expiresAt) {
692
return errLeaseRefreshRequired
693
}
694
695
requestCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
693
- resp, err := l.renewRegisteredLease(requestCtx, l.leaseTTL, accessToken)
696
+ resp, err := l.renewRegisteredLease(requestCtx, l.leaseTTL, lease.accessToken)
697
cancel()
698
if err != nil {
699
if errors.Is(err, &types.APIRequestError{Code: types.APIErrorCodeLeaseNotFound}) {
@@ -703,10 +706,16 @@ func (l *listener) renewLease(ctx context.Context) error {
706
if resp.AccessToken == "" {
707
return errors.New("relay did not return renewed access token")
708
}
706
- if l.accessToken == accessToken {
707
- l.accessToken = resp.AccessToken
708
- l.expiresAt = resp.ExpiresAt
709
+ l.leaseMu.Lock()
710
+ if l.lease == nil || l.lease.accessToken != lease.accessToken {
711
+ l.leaseMu.Unlock()
712
+ return errLeaseRefreshRequired
713
}
714
+ next := *l.lease
715
+ next.accessToken = resp.AccessToken
716
+ next.expiresAt = resp.ExpiresAt
717
+ l.lease = &next
718
+ l.leaseMu.Unlock()
719
return nil
720
}
721
@@ -715,7 +724,7 @@ func (l *listener) registerAndConfigure(ctx context.Context) error {
724
return err
725
}
726
718
- resp, err := l.registerLease(ctx, l.leaseTTL, l.datagram != nil, l.tcpEnabled)
727
+ resp, err := l.registerLease(ctx, l.leaseTTL, l.udpEnabled, l.tcpEnabled)
728
if err != nil {
729
return err
730
}
@@ -732,14 +741,14 @@ func (l *listener) registerAndConfigure(ctx context.Context) error {
741
_ = l.unregisterLease(context.Background(), resp.AccessToken)
742
return errors.New("relay returned mismatched lease identity")
743
}
735
- if l.datagram != nil && !resp.UDPEnabled {
744
+ if l.udpEnabled && !resp.UDPEnabled {
745
_ = l.unregisterLease(context.Background(), resp.AccessToken)
746
return &types.APIRequestError{
747
Code: types.APIErrorCodeFeatureUnavailable,
748
Message: "relay did not enable required udp support",
749
}
750
}
742
- if l.datagram != nil && resp.SNIPort <= 0 {
751
+ if l.udpEnabled && resp.SNIPort <= 0 {
752
_ = l.unregisterLease(context.Background(), resp.AccessToken)
753
return errors.New("relay did not return sni port for udp transport")
754
}
@@ -756,24 +765,26 @@ func (l *listener) registerAndConfigure(ctx context.Context) error {
765
}
766
return ctx.Err()
767
}
759
- datagram := l.datagram
760
- oldCloser := l.tenantTLSCloser
761
- l.hostname = resp.Hostname
762
- l.udpAddr = resp.UDPAddr
763
- l.accessToken = resp.AccessToken
764
- l.expiresAt = resp.ExpiresAt
765
- if datagram != nil {
766
- l.sniPort = resp.SNIPort
767
- } else {
768
- l.sniPort = 0
769
- }
770
- l.tenantTLSConfig = tlsConf
771
- l.tenantTLSCloser = tenantTLSCloser
772
- if oldCloser != nil {
773
- _ = oldCloser.Close()
774
- }
775
- if datagram != nil {
776
- datagram.Clear("lease updated")
768
+ next := &listenerLease{
769
+ hostname: resp.Hostname,
770
+ udpAddr: resp.UDPAddr,
771
+ accessToken: resp.AccessToken,
772
+ expiresAt: resp.ExpiresAt,
773
+ tlsConfig: tlsConf,
774
+ tlsCloser: tenantTLSCloser,
775
+ }
776
+ if l.udpEnabled {
777
+ next.sniPort = resp.SNIPort
778
+ }
779
+ l.leaseMu.Lock()
780
+ oldLease := l.lease
781
+ l.lease = next
782
+ l.leaseMu.Unlock()
783
+ if oldLease != nil && oldLease.tlsCloser != nil {
784
+ _ = oldLease.tlsCloser.Close()
785
+ }
786
+ if l.udpEnabled && l.datagram != nil {
787
+ l.datagram.Clear("lease updated")
788
}
789
relayURL := l.relayURL.String()
790
if l.relaySet != nil && relayURL != "" {
@@ -823,7 +834,25 @@ func (l *listener) waitRetry(ctx context.Context, operation string, err error, r
834
return utils.SleepOrDone(ctx, l.retryWait)
835
}
836
826
-type listenerAddr string
837
+type bufferedConn struct {
838
+ net.Conn
839
+ reader *bytes.Reader
840
+}
841
828
-func (a listenerAddr) Network() string { return "portal" }
829
-func (a listenerAddr) String() string { return string(a) }
842
+func wrapBufferedConn(conn net.Conn, reader *bufio.Reader) net.Conn {
843
+ if reader == nil || reader.Buffered() == 0 {
844
+ return conn
845
+ }
846
+ buf := make([]byte, reader.Buffered())
847
+ if _, err := io.ReadFull(reader, buf); err != nil {
848
+ return conn
849
+ }
850
+ return &bufferedConn{Conn: conn, reader: bytes.NewReader(buf)}
851
+}
852
+
853
+func (c *bufferedConn) Read(p []byte) (int, error) {
854
+ if c.reader != nil && c.reader.Len() > 0 {
855
+ return c.reader.Read(p)
856
+ }
857
+ return c.Conn.Read(p)
858
+}
sdk/mitm.go
+24
-34
@@ -41,12 +41,7 @@ type MITMProbeReport struct {
41
42
type mitmProbePending struct {
43
expected []byte
44
- resultCh chan mitmProbeResult
45
-}
46
-
47
-type mitmProbeResult struct {
48
- matched bool
49
- reason string
44
+ resultCh chan string
45
}
46
47
type mitmManager struct {
@@ -83,15 +78,19 @@ func (m *mitmManager) probeTLSPassthrough(ctx context.Context) (MITMProbeReport,
78
return MITMProbeReport{}, errors.New("listener is not ready")
79
}
80
86
- publicURL := l.publicURL()
87
- if publicURL == "" {
81
+ lease, ok := l.leaseSnapshot()
82
+ if !ok {
83
return MITMProbeReport{}, errors.New("listener is not registered")
84
}
90
-
91
- if l.hostname == "" {
85
+ if lease.hostname == "" {
86
return MITMProbeReport{}, errors.New("listener hostname is unavailable")
87
}
88
89
+ publicURL := l.publicURLForHostname(lease.hostname)
90
+ if publicURL == "" {
91
+ return MITMProbeReport{}, errors.New("listener is not registered")
92
+ }
93
+
94
report := MITMProbeReport{
95
RelayURL: l.relayURL.String(),
96
PublicURL: publicURL,
@@ -113,14 +112,14 @@ func (m *mitmManager) probeTLSPassthrough(ctx context.Context) (MITMProbeReport,
112
}
113
114
probeTLSConf := &tls.Config{
116
- ServerName: l.hostname,
115
+ ServerName: lease.hostname,
116
InsecureSkipVerify: true,
117
}
119
- if l.tenantTLSConfig != nil {
120
- probeTLSConf.MinVersion = l.tenantTLSConfig.MinVersion
121
- probeTLSConf.MaxVersion = l.tenantTLSConfig.MaxVersion
122
- if len(l.tenantTLSConfig.NextProtos) > 0 {
123
- probeTLSConf.NextProtos = append([]string(nil), l.tenantTLSConfig.NextProtos...)
118
+ if lease.tlsConfig != nil {
119
+ probeTLSConf.MinVersion = lease.tlsConfig.MinVersion
120
+ probeTLSConf.MaxVersion = lease.tlsConfig.MaxVersion
121
+ if len(lease.tlsConfig.NextProtos) > 0 {
122
+ probeTLSConf.NextProtos = append([]string(nil), lease.tlsConfig.NextProtos...)
123
}
124
}
125
@@ -166,9 +165,9 @@ func (m *mitmManager) probeTLSPassthrough(ctx context.Context) (MITMProbeReport,
165
}
166
167
select {
169
- case result := <-resultCh:
170
- report.Detected = !result.matched
171
- report.Reason = result.reason
168
+ case reason := <-resultCh:
169
+ report.Detected = reason != ""
170
+ report.Reason = reason
171
case <-probeCtx.Done():
172
report.Reason = types.MITMProbeReasonProbeTimeout
173
if !errors.Is(probeCtx.Err(), context.DeadlineExceeded) {
@@ -334,11 +333,11 @@ func (m *mitmManager) maybeHandleConn(conn net.Conn) (net.Conn, bool, error) {
333
return nil, true, nil
334
}
335
337
-func (m *mitmManager) startProbe(nonce string, expected []byte) (<-chan mitmProbeResult, func()) {
336
+func (m *mitmManager) startProbe(nonce string, expected []byte) (<-chan string, func()) {
337
m.mu.Lock()
338
state := &mitmProbePending{
339
expected: append([]byte(nil), expected...),
341
- resultCh: make(chan mitmProbeResult, 1),
340
+ resultCh: make(chan string, 1),
341
}
342
m.pending[nonce] = state
343
m.mu.Unlock()
@@ -358,26 +357,17 @@ func (m *mitmManager) completeProbe(nonce string, actual []byte) {
357
return
358
}
359
361
- result := mitmProbeResult{
362
- matched: bytes.Equal(state.expected, actual),
363
- }
364
- if !result.matched {
365
- result.reason = types.MITMProbeReasonExporterMismatch
360
+ reason := ""
361
+ if !bytes.Equal(state.expected, actual) {
362
+ reason = types.MITMProbeReasonExporterMismatch
363
}
364
365
select {
369
- case state.resultCh <- result:
366
+ case state.resultCh <- reason:
367
default:
368
}
369
}
370
374
-func wrapMITMProbeConn(manager *mitmManager, conn net.Conn) net.Conn {
375
- if conn == nil {
376
- return conn
377
- }
378
- return &mitmProbeConn{Conn: conn, manager: manager}
379
-}
380
-
371
type mitmProbeConn struct {
372
net.Conn
373
manager *mitmManager
sdk/mitm_test.go
+6
-9
@@ -66,9 +66,9 @@ func TestMITMProbeConnMatchesExporter(t *testing.T) {
66
_ = clientConn.Close()
67
68
select {
69
- case result := <-resultCh:
70
- if !result.matched {
71
- t.Fatalf("probe matched = false, reason = %q", result.reason)
69
+ case reason := <-resultCh:
70
+ if reason != "" {
71
+ t.Fatalf("probe reason = %q, want empty", reason)
72
}
73
case <-time.After(2 * time.Second):
74
t.Fatal("timed out waiting for probe result")
@@ -121,12 +121,9 @@ func TestMITMProbeConnDetectsExporterMismatch(t *testing.T) {
121
_ = clientConn.Close()
122
123
select {
124
- case result := <-resultCh:
125
- if result.matched {
126
- t.Fatal("probe matched = true, want false")
127
- }
128
- if result.reason != types.MITMProbeReasonExporterMismatch {
129
- t.Fatalf("probe reason = %q, want %q", result.reason, types.MITMProbeReasonExporterMismatch)
124
+ case reason := <-resultCh:
125
+ if reason != types.MITMProbeReasonExporterMismatch {
126
+ t.Fatalf("probe reason = %q, want %q", reason, types.MITMProbeReasonExporterMismatch)
127
}
128
case <-time.After(2 * time.Second):
129
t.Fatal("timed out waiting for probe result")