Skip to content

Commit

Permalink
Merge pull request #87 from openziti/dtls-updated
Browse files Browse the repository at this point in the history
Update to latest dtls library. Fixes #85
  • Loading branch information
plorenz authored Aug 19, 2024
2 parents cab193f + d94cf00 commit 206684d
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 83 deletions.
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

0 comments on commit 206684d

Please sign in to comment.