refactor(netxlite): adapt single-use-quic-dialer from websteps (#472)
This is the last bit of functionality we need before rewriting a chunk of websteps to use netxlite. To rewrite most of it, we still need to move over: 1. dnstransport code 2. errorsx code With both done, netxlite is a good library for websteps as well as for most other operations we perform outside of the experiments. Part of https://github.com/ooni/probe/issues/1591
This commit is contained in:
parent
b9c4ad0b2b
commit
fe3c90479d
|
@ -164,7 +164,7 @@ func NewSingleUseDialer(conn net.Conn) Dialer {
|
|||
return &dialerSingleUse{conn: conn}
|
||||
}
|
||||
|
||||
// dialerSingleUse is the type of Dialer returned by NewSingleDialer.
|
||||
// dialerSingleUse is the Dialer returned by NewSingleDialer.
|
||||
type dialerSingleUse struct {
|
||||
sync.Mutex
|
||||
conn net.Conn
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"errors"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/lucas-clemente/quic-go"
|
||||
"github.com/ooni/probe-cli/v3/internal/netxlite/quicx"
|
||||
|
@ -288,3 +289,36 @@ func (d *quicDialerLogger) DialContext(
|
|||
func (d *quicDialerLogger) CloseIdleConnections() {
|
||||
d.Dialer.CloseIdleConnections()
|
||||
}
|
||||
|
||||
// NewSingleUseQUICDialer returns a dialer that returns the given connection
|
||||
// once and after that always fails with the ErrNoConnReuse error.
|
||||
func NewSingleUseQUICDialer(sess quic.EarlySession) QUICDialer {
|
||||
return &quicDialerSingleUse{sess: sess}
|
||||
}
|
||||
|
||||
// quicDialerSingleUse is the QUICDialer returned by NewSingleQUICDialer.
|
||||
type quicDialerSingleUse struct {
|
||||
sync.Mutex
|
||||
sess quic.EarlySession
|
||||
}
|
||||
|
||||
var _ QUICDialer = &quicDialerSingleUse{}
|
||||
|
||||
// DialContext implements QUICDialer.DialContext.
|
||||
func (s *quicDialerSingleUse) DialContext(
|
||||
ctx context.Context, network, addr string, tlsCfg *tls.Config,
|
||||
cfg *quic.Config) (quic.EarlySession, error) {
|
||||
var sess quic.EarlySession
|
||||
defer s.Unlock()
|
||||
s.Lock()
|
||||
if s.sess == nil {
|
||||
return nil, ErrNoConnReuse
|
||||
}
|
||||
sess, s.sess = s.sess, nil
|
||||
return sess, nil
|
||||
}
|
||||
|
||||
// CloseIdleConnections closes idle connections.
|
||||
func (s *quicDialerSingleUse) CloseIdleConnections() {
|
||||
// nothing to do
|
||||
}
|
||||
|
|
|
@ -460,3 +460,26 @@ func TestNewQUICDialerWithoutResolverChain(t *testing.T) {
|
|||
t.Fatal("invalid quic listener")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewSingleUseQUICDialerWorksAsIntended(t *testing.T) {
|
||||
sess := &mocks.QUICEarlySession{}
|
||||
qd := NewSingleUseQUICDialer(sess)
|
||||
outsess, err := qd.DialContext(
|
||||
context.Background(), "", "", &tls.Config{}, &quic.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if sess != outsess {
|
||||
t.Fatal("invalid outsess")
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
outsess, err = qd.DialContext(
|
||||
context.Background(), "", "", &tls.Config{}, &quic.Config{})
|
||||
if !errors.Is(err, ErrNoConnReuse) {
|
||||
t.Fatal("not the error we expected", err)
|
||||
}
|
||||
if outsess != nil {
|
||||
t.Fatal("expected nil outconn here")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user