Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to latest dtls library. Fixes #85 #87

Merged
merged 2 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,27 @@ updates:
schedule:
interval: daily
open-pull-requests-limit: 10
groups:
non-major:
applies-to: version-updates
update-types:
- "minor"
- "patch"
ignore:
- dependency-name: github.com/lucas-clemente/quic-go
versions:
- "> 0.18.1"

- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
groups:
all:
applies-to: version-updates
update-types:
- "major"
- "minor"
- "patch"

13 changes: 8 additions & 5 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@ jobs:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version: 1.19
- uses: actions/checkout@v3
go-version-file: ./go.mod


- name: golangci-lint
uses: golangci/golangci-lint-action@v3
uses: golangci/golangci-lint-action@v6
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.49
version: v1.57.2

# Optional: working directory, useful for monorepos
# working-directory: somedir
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/update-dependency.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jobs:
fetch-depth: 0

- name: Install Go
uses: actions/setup-go@v3
uses: actions/setup-go@v5
with:
go-version: '~1.19.0'
go-version-file: ./go.mod

- name: Install Ziti CI
uses: openziti/ziti-ci@v1
Expand Down
25 changes: 25 additions & 0 deletions address.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ const (
KeyProxy = "proxy"
KeyProtocol = "protocol"
KeyCachedProxyConfiguration = "cachedProxyConfiguration"

KeyHandshakeTimeout = "handshakeTimeout"
KeyCachedHandshakeTimeout = "cachedHandshakeTimeout"
)

type Configuration map[interface{}]interface{}
Expand Down Expand Up @@ -84,6 +87,28 @@ func (self Configuration) GetProxyConfiguration() (*ProxyConfiguration, error) {
return result, nil
}

func (self Configuration) GetHandshakeTimeout() (time.Duration, error) {
if val, ok := self[KeyCachedHandshakeTimeout]; ok {
if timeout, ok := val.(time.Duration); ok {
return timeout, nil
}
}

if val, ok := self[KeyHandshakeTimeout]; ok {
if strVal, ok := val.(string); ok {
timeout, err := time.ParseDuration(strVal)
if err == nil {
self[KeyCachedHandshakeTimeout] = timeout
}
return timeout, errors.Wrapf(err, "unable to parse handshake timeout '%s' to duration", strVal)
} else {
return 0, errors.New("invalid handshake timeout, must be string value")
}
}

return 0, nil
}

type ProxyType string

const (
Expand Down
8 changes: 4 additions & 4 deletions dtls/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ func (a *address) DialWithLocalBinding(name string, localBinding string, i *iden
return DialWithLocalBinding(a, name, localBinding, i, timeout)
}

func (a *address) Listen(name string, i *identity.TokenId, acceptF func(transport.Conn), _ transport.Configuration) (io.Closer, error) {
return Listen(a, name, i, acceptF)
func (a *address) Listen(name string, i *identity.TokenId, acceptF func(transport.Conn), tcfg transport.Configuration) (io.Closer, error) {
return Listen(a, name, i, tcfg, acceptF)
}

func (a *address) MustListen(name string, i *identity.TokenId, acceptF func(transport.Conn), tcfg transport.Configuration) io.Closer {
Expand All @@ -62,7 +62,7 @@ func (a *address) String() string {
return a.original
}

func (a address) Type() string {
func (a *address) Type() string {
return Type
}

Expand All @@ -75,7 +75,7 @@ func (a *address) Hostname() string {
return a.UDPAddr.IP.String()
}

func (a address) Port() uint16 {
func (a *address) Port() uint16 {
return uint16(a.UDPAddr.Port)
}

Expand Down
8 changes: 6 additions & 2 deletions dtls/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ package dtls
import (
"crypto/x509"
"github.com/openziti/transport/v2"
"github.com/pion/dtls/v2"
"github.com/pion/dtls/v3"
"github.com/pkg/errors"
)

func getPeerCerts(conn *dtls.Conn) ([]*x509.Certificate, error) {
var certs []*x509.Certificate
for _, certBytes := range conn.ConnectionState().PeerCertificates {
connState, ok := conn.ConnectionState()
if !ok {
return nil, errors.New("unable to get dtls connection state, couldn't get peer certificates")
}
for _, certBytes := range connState.PeerCertificates {
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
return nil, errors.Wrap(err, "couldn't parse peer cert")
Expand Down
47 changes: 30 additions & 17 deletions dtls/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/identity"
"github.com/openziti/transport/v2"
"github.com/pion/dtls/v2"
"github.com/pion/dtls/v3"
"github.com/pkg/errors"
"net"
"time"
)
Expand All @@ -32,16 +33,17 @@ func Dial(addr *address, name string, i *identity.TokenId, timeout time.Duration
}

func DialWithLocalBinding(addr *address, name, localBinding string, i *identity.TokenId, timeout time.Duration) (transport.Conn, error) {
log := pfxlog.Logger()
log.WithField("address", addr.String()).Debug("dialing")

if addr.err != nil {
return nil, addr.err
}
ip, err := transport.ResolveLocalBinding(localBinding)
if err != nil {
return nil, err
ip, closeErr := transport.ResolveLocalBinding(localBinding)
if closeErr != nil {
return nil, closeErr
}

log := pfxlog.Logger()

cfg := &dtls.Config{
Certificates: []tls.Certificate{*i.Cert()},
//ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
Expand All @@ -53,29 +55,40 @@ func DialWithLocalBinding(addr *address, name, localBinding string, i *identity.
localAddr = &net.UDPAddr{IP: ip}
}

udpConn, err := net.DialUDP("udp", localAddr, &addr.UDPAddr)
if err != nil {
return nil, err
udpConn, closeErr := net.ListenUDP("udp", localAddr)
if closeErr != nil {
return nil, closeErr
}

conn, closeErr := dtls.Client(udpConn, &addr.UDPAddr, cfg)
if closeErr != nil {
return nil, closeErr
}

ctx := context.Background()
cancelF := func() {}
if timeout > 0 {
ctx, cancelF = context.WithTimeout(ctx, timeout)
}
conn, err := dtls.ClientWithContext(ctx, udpConn, cfg)
closeErr = conn.HandshakeContext(ctx)
cancelF()
if err != nil {
return nil, err
if closeErr != nil {
if closeErr := conn.Close(); closeErr != nil {
log.WithError(closeErr).Error("error closing connection")
}
return nil, errors.Wrap(closeErr, "dtls handshake error")
}

log.Debugf("server provided [%d] certificates", len(conn.ConnectionState().PeerCertificates))

certs, err := getPeerCerts(conn)
if err != nil {
return nil, err
certs, closeErr := getPeerCerts(conn)
if closeErr != nil {
if closeErr = conn.Close(); closeErr != nil {
log.WithError(closeErr).Error("error closing connection")
}
return nil, errors.Wrap(closeErr, "error getting peer certificates")
}

log.Debugf("server provided [%d] certificates", len(certs))

return &Connection{
detail: &transport.ConnectionDetail{
Address: addr.String(),
Expand Down
39 changes: 33 additions & 6 deletions dtls/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,30 @@ import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/identity"
"github.com/openziti/transport/v2"
"github.com/pion/dtls/v2"
"github.com/pion/dtls/v3"
"github.com/sirupsen/logrus"
"io"
"net"
"sync/atomic"
"time"
)

func Listen(addr *address, name string, i *identity.TokenId, acceptF func(transport.Conn)) (io.Closer, error) {
const DefaultHandshakeTimeout = 30 * time.Second

func Listen(addr *address, name string, i *identity.TokenId, tcfg transport.Configuration, acceptF func(transport.Conn)) (io.Closer, error) {
if addr.err != nil {
return nil, addr.err
}

timeout, err := tcfg.GetHandshakeTimeout()
if err != nil {
return nil, err
}

if timeout == 0 {
timeout = DefaultHandshakeTimeout
}

log := pfxlog.ContextLogger(name + "/" + addr.String()).Entry

var certs []tls.Certificate
Expand All @@ -49,9 +61,6 @@ func Listen(addr *address, name string, i *identity.TokenId, acceptF func(transp
RootCAs: i.CA(),
//CipherSuites: tlz.GetCipherSuites(),
// Create timeout context for accepted connection.
ConnectContextMaker: func() (context.Context, func()) {
return context.WithTimeout(context.Background(), 30*time.Second)
},
}

listener, err := dtls.Listen("udp", &addr.UDPAddr, cfg)
Expand All @@ -63,6 +72,7 @@ func Listen(addr *address, name string, i *identity.TokenId, acceptF func(transp
name: name,
listener: listener,
acceptF: acceptF,
timeout: timeout,
}

go result.acceptLoop(log)
Expand All @@ -75,6 +85,7 @@ type acceptor struct {
listener net.Listener
acceptF func(transport.Conn)
closed atomic.Bool
timeout time.Duration
}

func (self *acceptor) Close() error {
Expand All @@ -99,6 +110,22 @@ func (self *acceptor) acceptLoop(log *logrus.Entry) {
}

conn := socket.(*dtls.Conn)
ctx := context.Background()
cancelF := func() {}
if self.timeout > 0 {
ctx, cancelF = context.WithTimeout(ctx, self.timeout)
}
err = conn.HandshakeContext(ctx)
cancelF()

if err != nil {
log.WithError(err).Error("dtls handshake error")
if err = conn.Close(); err != nil {
log.WithError(err).Error("error closing connection")
}
continue
}

certs, err := getPeerCerts(conn)
if err != nil {
log.WithError(err).Error("unable to parse peer certificates")
Expand All @@ -115,7 +142,7 @@ func (self *acceptor) acceptLoop(log *logrus.Entry) {
Name: self.name,
},
certs: certs,
Conn: socket.(*dtls.Conn),
Conn: conn,
}
self.acceptF(connection)
}
Expand Down
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/openziti/transport/v2

go 1.19
go 1.21

require (
github.com/gorilla/mux v1.8.1
Expand All @@ -9,11 +9,11 @@ require (
github.com/openziti/dilithium v0.3.3
github.com/openziti/foundation/v2 v2.0.48
github.com/openziti/identity v1.0.84
github.com/pion/dtls/v2 v2.2.10
github.com/pion/dtls/v3 v3.0.1
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
golang.org/x/net v0.24.0
golang.org/x/net v0.27.0
nhooyr.io/websocket v1.8.11
)

Expand All @@ -25,18 +25,18 @@ require (
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/pion/logging v0.2.2 // indirect
github.com/pion/transport/v2 v2.2.4 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/parallaxsecond/parsec-client-go v0.0.0-20221025095442-f0a77d263cf9 // indirect
github.com/pion/transport/v3 v3.0.7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading