ooni-probe-cli/internal/engine/legacy/errorsx/dialer.go
Simone Basso 6d3a4f1db8
refactor: merge dnsx and errorsx into netxlite (#517)
When preparing a tutorial for netxlite, I figured it is easier
to tell people "hey, this is the package you should use for all
low-level networking stuff" rather than introducing people to
a set of packages working together where some piece of functionality
is here and some other piece is there.

Part of https://github.com/ooni/probe/issues/1591
2021-09-28 12:42:01 +02:00

80 lines
2.0 KiB
Go

package errorsx
import (
"context"
"net"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// Dialer establishes network connections.
type Dialer interface {
// DialContext behaves like net.Dialer.DialContext.
DialContext(ctx context.Context, network, address string) (net.Conn, error)
}
// ErrorWrapperDialer is a dialer that performs error wrapping. The connection
// returned by the DialContext function will also perform error wrapping.
type ErrorWrapperDialer struct {
// Dialer is the underlying dialer.
Dialer
}
// DialContext implements Dialer.DialContext.
func (d *ErrorWrapperDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
conn, err := d.Dialer.DialContext(ctx, network, address)
if err != nil {
return nil, SafeErrWrapperBuilder{
Classifier: netxlite.ClassifyGenericError,
Operation: netxlite.ConnectOperation,
Error: err,
}.MaybeBuild()
}
return &errorWrapperConn{Conn: conn}, nil
}
// errorWrapperConn is a net.Conn that performs error wrapping.
type errorWrapperConn struct {
// Conn is the underlying connection.
net.Conn
}
// Read implements net.Conn.Read.
func (c *errorWrapperConn) Read(b []byte) (int, error) {
count, err := c.Conn.Read(b)
if err != nil {
return 0, SafeErrWrapperBuilder{
Classifier: netxlite.ClassifyGenericError,
Operation: netxlite.ReadOperation,
Error: err,
}.MaybeBuild()
}
return count, nil
}
// Write implements net.Conn.Write.
func (c *errorWrapperConn) Write(b []byte) (int, error) {
count, err := c.Conn.Write(b)
if err != nil {
return 0, SafeErrWrapperBuilder{
Classifier: netxlite.ClassifyGenericError,
Operation: netxlite.WriteOperation,
Error: err,
}.MaybeBuild()
}
return count, nil
}
// Close implements net.Conn.Close.
func (c *errorWrapperConn) Close() error {
err := c.Conn.Close()
if err != nil {
return SafeErrWrapperBuilder{
Classifier: netxlite.ClassifyGenericError,
Operation: netxlite.CloseOperation,
Error: err,
}.MaybeBuild()
}
return nil
}