fix(netxlite): gracefully handle utls panics (#462)
* fix(netxlite): gracefully handle utls panics See https://github.com/ooni/probe/issues/1770 * fix(netxlite): remove wrong timeout from newly written test
This commit is contained in:
parent
b834af83ac
commit
3caf5800a2
|
@ -3,6 +3,7 @@ package netxlite
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
utls "gitlab.com/yawning/utls.git"
|
utls "gitlab.com/yawning/utls.git"
|
||||||
|
@ -43,17 +44,29 @@ func newConnUTLS(clientHello *utls.ClientHelloID) func(conn net.Conn, config *tl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *utlsConn) HandshakeContext(ctx context.Context) error {
|
// ErrUTLSHandshakePanic indicates that there was panic handshaking
|
||||||
|
// when we were using the yawning/utls library for parroting.
|
||||||
|
//
|
||||||
|
// See https://github.com/ooni/probe/issues/1770
|
||||||
|
var ErrUTLSHandshakePanic = errors.New("utls: handshake panic")
|
||||||
|
|
||||||
|
func (c *utlsConn) HandshakeContext(ctx context.Context) (err error) {
|
||||||
errch := make(chan error, 1)
|
errch := make(chan error, 1)
|
||||||
go func() {
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
// See https://github.com/ooni/probe/issues/1770
|
||||||
|
if recover() != nil {
|
||||||
|
errch <- ErrUTLSHandshakePanic
|
||||||
|
}
|
||||||
|
}()
|
||||||
errch <- c.handshakefn()()
|
errch <- c.handshakefn()()
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case err := <-errch:
|
case err = <-errch:
|
||||||
return err
|
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
err = ctx.Err()
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *utlsConn) handshakefn() func() error {
|
func (c *utlsConn) handshakefn() func() error {
|
||||||
|
|
|
@ -49,7 +49,7 @@ func TestNewTLSHandshakerUTLSTypes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUTLSConnHandshakeNotInterrupted(t *testing.T) {
|
func TestUTLSConnHandshakeNotInterruptedSuccess(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
conn := &utlsConn{
|
conn := &utlsConn{
|
||||||
testableHandshake: func() error {
|
testableHandshake: func() error {
|
||||||
|
@ -62,6 +62,20 @@ func TestUTLSConnHandshakeNotInterrupted(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUTLSConnHandshakeNotInterruptedFailure(t *testing.T) {
|
||||||
|
expected := errors.New("mocked error")
|
||||||
|
ctx := context.Background()
|
||||||
|
conn := &utlsConn{
|
||||||
|
testableHandshake: func() error {
|
||||||
|
return expected
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := conn.HandshakeContext(ctx)
|
||||||
|
if !errors.Is(err, expected) {
|
||||||
|
t.Fatal("not the error we expected", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestUTLSConnHandshakeInterrupted(t *testing.T) {
|
func TestUTLSConnHandshakeInterrupted(t *testing.T) {
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
@ -82,3 +96,20 @@ func TestUTLSConnHandshakeInterrupted(t *testing.T) {
|
||||||
close(sigch)
|
close(sigch)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUTLSConnHandshakePanic(t *testing.T) {
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
wg.Add(1)
|
||||||
|
ctx := context.Background()
|
||||||
|
conn := &utlsConn{
|
||||||
|
testableHandshake: func() error {
|
||||||
|
defer wg.Done()
|
||||||
|
panic("mascetti")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := conn.HandshakeContext(ctx)
|
||||||
|
if !errors.Is(err, ErrUTLSHandshakePanic) {
|
||||||
|
t.Fatal("not the error we expected", err)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user