mirror of
https://github.com/bjdgyc/anylink.git
synced 2025-08-08 11:44:11 +08:00
添加 github.com/pion/dtls 代码
This commit is contained in:
11
dtls-2.0.9/e2e/Dockerfile
Normal file
11
dtls-2.0.9/e2e/Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM golang:1.14-alpine3.11
|
||||
|
||||
RUN apk add --no-cache \
|
||||
openssl
|
||||
|
||||
ENV CGO_ENABLED=0
|
||||
|
||||
COPY . /go/src/github.com/pion/dtls
|
||||
WORKDIR /go/src/github.com/pion/dtls/e2e
|
||||
|
||||
CMD ["go", "test", "-tags=openssl", "-v", "."]
|
2
dtls-2.0.9/e2e/e2e.go
Normal file
2
dtls-2.0.9/e2e/e2e.go
Normal file
@@ -0,0 +1,2 @@
|
||||
// Package e2e contains end to end tests for pion/dtls
|
||||
package e2e
|
207
dtls-2.0.9/e2e/e2e_lossy_test.go
Normal file
207
dtls-2.0.9/e2e/e2e_lossy_test.go
Normal file
@@ -0,0 +1,207 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
|
||||
transportTest "github.com/pion/transport/test"
|
||||
)
|
||||
|
||||
const (
|
||||
flightInterval = time.Millisecond * 100
|
||||
lossyTestTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
/*
|
||||
DTLS Client/Server over a lossy transport, just asserts it can handle at increasing increments
|
||||
*/
|
||||
func TestPionE2ELossy(t *testing.T) {
|
||||
// Check for leaking routines
|
||||
report := transportTest.CheckRoutines(t)
|
||||
defer report()
|
||||
|
||||
type runResult struct {
|
||||
dtlsConn *dtls.Conn
|
||||
err error
|
||||
}
|
||||
|
||||
serverCert, err := selfsign.GenerateSelfSigned()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
clientCert, err := selfsign.GenerateSelfSigned()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, test := range []struct {
|
||||
LossChanceRange int
|
||||
DoClientAuth bool
|
||||
CipherSuites []dtls.CipherSuiteID
|
||||
MTU int
|
||||
}{
|
||||
{
|
||||
LossChanceRange: 0,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 10,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 20,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 50,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 0,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 10,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 20,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 50,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 0,
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
},
|
||||
{
|
||||
LossChanceRange: 10,
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
},
|
||||
{
|
||||
LossChanceRange: 20,
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
},
|
||||
{
|
||||
LossChanceRange: 50,
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
|
||||
},
|
||||
{
|
||||
LossChanceRange: 10,
|
||||
MTU: 100,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 20,
|
||||
MTU: 100,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
{
|
||||
LossChanceRange: 50,
|
||||
MTU: 100,
|
||||
DoClientAuth: true,
|
||||
},
|
||||
} {
|
||||
name := fmt.Sprintf("Loss%d_MTU%d", test.LossChanceRange, test.MTU)
|
||||
if test.DoClientAuth {
|
||||
name += "_WithCliAuth"
|
||||
}
|
||||
for _, ciph := range test.CipherSuites {
|
||||
name += "_With" + ciph.String()
|
||||
}
|
||||
test := test
|
||||
t.Run(name, func(t *testing.T) {
|
||||
// Limit runtime in case of deadlocks
|
||||
lim := transportTest.TimeOut(lossyTestTimeout + time.Second)
|
||||
defer lim.Stop()
|
||||
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
chosenLoss := rand.Intn(9) + test.LossChanceRange //nolint:gosec
|
||||
serverDone := make(chan runResult)
|
||||
clientDone := make(chan runResult)
|
||||
br := transportTest.NewBridge()
|
||||
|
||||
if err = br.SetLossChance(chosenLoss); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
cfg := &dtls.Config{
|
||||
FlightInterval: flightInterval,
|
||||
CipherSuites: test.CipherSuites,
|
||||
InsecureSkipVerify: true,
|
||||
MTU: test.MTU,
|
||||
}
|
||||
|
||||
if test.DoClientAuth {
|
||||
cfg.Certificates = []tls.Certificate{clientCert}
|
||||
}
|
||||
|
||||
client, startupErr := dtls.Client(br.GetConn0(), cfg)
|
||||
clientDone <- runResult{client, startupErr}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
cfg := &dtls.Config{
|
||||
Certificates: []tls.Certificate{serverCert},
|
||||
FlightInterval: flightInterval,
|
||||
MTU: test.MTU,
|
||||
}
|
||||
|
||||
if test.DoClientAuth {
|
||||
cfg.ClientAuth = dtls.RequireAnyClientCert
|
||||
}
|
||||
|
||||
server, startupErr := dtls.Server(br.GetConn1(), cfg)
|
||||
serverDone <- runResult{server, startupErr}
|
||||
}()
|
||||
|
||||
testTimer := time.NewTimer(lossyTestTimeout)
|
||||
var serverConn, clientConn *dtls.Conn
|
||||
defer func() {
|
||||
if serverConn != nil {
|
||||
if err = serverConn.Close(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
if clientConn != nil {
|
||||
if err = clientConn.Close(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
if serverConn != nil && clientConn != nil {
|
||||
break
|
||||
}
|
||||
|
||||
br.Tick()
|
||||
select {
|
||||
case serverResult := <-serverDone:
|
||||
if serverResult.err != nil {
|
||||
t.Errorf("Fail, serverError: clientComplete(%t) serverComplete(%t) LossChance(%d) error(%v)", clientConn != nil, serverConn != nil, chosenLoss, serverResult.err)
|
||||
return
|
||||
}
|
||||
|
||||
serverConn = serverResult.dtlsConn
|
||||
case clientResult := <-clientDone:
|
||||
if clientResult.err != nil {
|
||||
t.Errorf("Fail, clientError: clientComplete(%t) serverComplete(%t) LossChance(%d) error(%v)", clientConn != nil, serverConn != nil, chosenLoss, clientResult.err)
|
||||
return
|
||||
}
|
||||
|
||||
clientConn = clientResult.dtlsConn
|
||||
case <-testTimer.C:
|
||||
t.Errorf("Test expired: clientComplete(%t) serverComplete(%t) LossChance(%d)", clientConn != nil, serverConn != nil, chosenLoss)
|
||||
return
|
||||
case <-time.After(10 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
250
dtls-2.0.9/e2e/e2e_openssl_test.go
Normal file
250
dtls-2.0.9/e2e/e2e_openssl_test.go
Normal file
@@ -0,0 +1,250 @@
|
||||
// +build openssl,!js
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
)
|
||||
|
||||
func serverOpenSSL(c *comm) {
|
||||
go func() {
|
||||
c.serverMutex.Lock()
|
||||
defer c.serverMutex.Unlock()
|
||||
|
||||
cfg := c.serverConfig
|
||||
|
||||
// create openssl arguments
|
||||
args := []string{
|
||||
"s_server",
|
||||
"-dtls1_2",
|
||||
"-quiet",
|
||||
"-verify_quiet",
|
||||
"-verify_return_error",
|
||||
fmt.Sprintf("-accept=%d", c.serverPort),
|
||||
}
|
||||
ciphers := ciphersOpenSSL(cfg)
|
||||
if ciphers != "" {
|
||||
args = append(args, fmt.Sprintf("-cipher=%s", ciphers))
|
||||
}
|
||||
|
||||
// psk arguments
|
||||
if cfg.PSK != nil {
|
||||
psk, err := cfg.PSK(nil)
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
args = append(args, fmt.Sprintf("-psk=%X", psk))
|
||||
if len(cfg.PSKIdentityHint) > 0 {
|
||||
args = append(args, fmt.Sprintf("-psk_hint=%s", cfg.PSKIdentityHint))
|
||||
}
|
||||
}
|
||||
|
||||
// certs arguments
|
||||
if len(cfg.Certificates) > 0 {
|
||||
// create temporary cert files
|
||||
certPEM, keyPEM, err := writeTempPEM(cfg)
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
args = append(args,
|
||||
fmt.Sprintf("-cert=%s", certPEM),
|
||||
fmt.Sprintf("-key=%s", keyPEM))
|
||||
defer func() {
|
||||
_ = os.Remove(certPEM)
|
||||
_ = os.Remove(keyPEM)
|
||||
}()
|
||||
} else {
|
||||
args = append(args, "-nocert")
|
||||
}
|
||||
|
||||
// launch command
|
||||
// #nosec G204
|
||||
cmd := exec.CommandContext(c.ctx, "openssl", args...)
|
||||
var inner net.Conn
|
||||
inner, c.serverConn = net.Pipe()
|
||||
cmd.Stdin = inner
|
||||
cmd.Stdout = inner
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Start(); err != nil {
|
||||
c.errChan <- err
|
||||
_ = inner.Close()
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure that server has started
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
c.serverReady <- struct{}{}
|
||||
simpleReadWrite(c.errChan, c.serverChan, c.serverConn, c.messageRecvCount)
|
||||
}()
|
||||
}
|
||||
|
||||
func clientOpenSSL(c *comm) {
|
||||
select {
|
||||
case <-c.serverReady:
|
||||
// OK
|
||||
case <-time.After(time.Second):
|
||||
c.errChan <- errors.New("waiting on serverReady err: timeout")
|
||||
}
|
||||
|
||||
c.clientMutex.Lock()
|
||||
defer c.clientMutex.Unlock()
|
||||
|
||||
cfg := c.clientConfig
|
||||
|
||||
// create openssl arguments
|
||||
args := []string{
|
||||
"s_client",
|
||||
"-dtls1_2",
|
||||
"-quiet",
|
||||
"-verify_quiet",
|
||||
"-verify_return_error",
|
||||
"-servername=localhost",
|
||||
fmt.Sprintf("-connect=127.0.0.1:%d", c.serverPort),
|
||||
}
|
||||
ciphers := ciphersOpenSSL(cfg)
|
||||
if ciphers != "" {
|
||||
args = append(args, fmt.Sprintf("-cipher=%s", ciphers))
|
||||
}
|
||||
|
||||
// psk arguments
|
||||
if cfg.PSK != nil {
|
||||
psk, err := cfg.PSK(nil)
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
args = append(args, fmt.Sprintf("-psk=%X", psk))
|
||||
}
|
||||
|
||||
// certificate arguments
|
||||
if len(cfg.Certificates) > 0 {
|
||||
// create temporary cert files
|
||||
certPEM, keyPEM, err := writeTempPEM(cfg)
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
args = append(args, fmt.Sprintf("-CAfile=%s", certPEM))
|
||||
defer func() {
|
||||
_ = os.Remove(certPEM)
|
||||
_ = os.Remove(keyPEM)
|
||||
}()
|
||||
}
|
||||
|
||||
// launch command
|
||||
// #nosec G204
|
||||
cmd := exec.CommandContext(c.ctx, "openssl", args...)
|
||||
var inner net.Conn
|
||||
inner, c.clientConn = net.Pipe()
|
||||
cmd.Stdin = inner
|
||||
cmd.Stdout = inner
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Start(); err != nil {
|
||||
c.errChan <- err
|
||||
_ = inner.Close()
|
||||
return
|
||||
}
|
||||
|
||||
simpleReadWrite(c.errChan, c.clientChan, c.clientConn, c.messageRecvCount)
|
||||
}
|
||||
|
||||
func ciphersOpenSSL(cfg *dtls.Config) string {
|
||||
// See https://tls.mbed.org/supported-ssl-ciphersuites
|
||||
translate := map[dtls.CipherSuiteID]string{
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: "ECDHE-ECDSA-AES128-CCM",
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: "ECDHE-ECDSA-AES128-CCM8",
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "ECDHE-ECDSA-AES128-GCM-SHA256",
|
||||
dtls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "ECDHE-RSA-AES128-GCM-SHA256",
|
||||
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "ECDHE-ECDSA-AES256-SHA",
|
||||
dtls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "ECDHE-RSA-AES128-SHA",
|
||||
|
||||
dtls.TLS_PSK_WITH_AES_128_CCM: "PSK-AES128-CCM",
|
||||
dtls.TLS_PSK_WITH_AES_128_CCM_8: "PSK-AES128-CCM8",
|
||||
dtls.TLS_PSK_WITH_AES_128_GCM_SHA256: "PSK-AES128-GCM-SHA256",
|
||||
}
|
||||
|
||||
var ciphers []string
|
||||
for _, c := range cfg.CipherSuites {
|
||||
if text, ok := translate[c]; ok {
|
||||
ciphers = append(ciphers, text)
|
||||
}
|
||||
}
|
||||
return strings.Join(ciphers, ";")
|
||||
}
|
||||
|
||||
func writeTempPEM(cfg *dtls.Config) (string, string, error) {
|
||||
certOut, err := ioutil.TempFile("", "cert.pem")
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to create temporary file: %w", err)
|
||||
}
|
||||
keyOut, err := ioutil.TempFile("", "key.pem")
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to create temporary file: %w", err)
|
||||
}
|
||||
|
||||
cert := cfg.Certificates[0]
|
||||
derBytes := cert.Certificate[0]
|
||||
if err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
|
||||
return "", "", fmt.Errorf("failed to write data to cert.pem: %w", err)
|
||||
}
|
||||
if err = certOut.Close(); err != nil {
|
||||
return "", "", fmt.Errorf("error closing cert.pem: %w", err)
|
||||
}
|
||||
|
||||
priv := cert.PrivateKey
|
||||
var privBytes []byte
|
||||
privBytes, err = x509.MarshalPKCS8PrivateKey(priv)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("unable to marshal private key: %w", err)
|
||||
}
|
||||
if err = pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
|
||||
return "", "", fmt.Errorf("failed to write data to key.pem: %w", err)
|
||||
}
|
||||
if err = keyOut.Close(); err != nil {
|
||||
return "", "", fmt.Errorf("error closing key.pem: %w", err)
|
||||
}
|
||||
return certOut.Name(), keyOut.Name(), nil
|
||||
}
|
||||
|
||||
func TestPionOpenSSLE2ESimple(t *testing.T) {
|
||||
t.Run("OpenSSLServer", func(t *testing.T) {
|
||||
testPionE2ESimple(t, serverOpenSSL, clientPion)
|
||||
})
|
||||
t.Run("OpenSSLClient", func(t *testing.T) {
|
||||
testPionE2ESimple(t, serverPion, clientOpenSSL)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPionOpenSSLE2ESimplePSK(t *testing.T) {
|
||||
t.Run("OpenSSLServer", func(t *testing.T) {
|
||||
testPionE2ESimplePSK(t, serverOpenSSL, clientPion)
|
||||
})
|
||||
t.Run("OpenSSLClient", func(t *testing.T) {
|
||||
testPionE2ESimplePSK(t, serverPion, clientOpenSSL)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPionOpenSSLE2EMTUs(t *testing.T) {
|
||||
t.Run("OpenSSLServer", func(t *testing.T) {
|
||||
testPionE2EMTUs(t, serverOpenSSL, clientPion)
|
||||
})
|
||||
t.Run("OpenSSLClient", func(t *testing.T) {
|
||||
testPionE2EMTUs(t, serverPion, clientOpenSSL)
|
||||
})
|
||||
}
|
17
dtls-2.0.9/e2e/e2e_openssl_v113_test.go
Normal file
17
dtls-2.0.9/e2e/e2e_openssl_v113_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
// +build openssl,go1.13,!js
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPionOpenSSLE2ESimpleED25519(t *testing.T) {
|
||||
t.Skip("TODO: waiting OpenSSL's DTLS Ed25519 support")
|
||||
t.Run("OpenSSLServer", func(t *testing.T) {
|
||||
testPionE2ESimpleED25519(t, serverOpenSSL, clientPion)
|
||||
})
|
||||
t.Run("OpenSSLClient", func(t *testing.T) {
|
||||
testPionE2ESimpleED25519(t, serverPion, clientOpenSSL)
|
||||
})
|
||||
}
|
329
dtls-2.0.9/e2e/e2e_test.go
Normal file
329
dtls-2.0.9/e2e/e2e_test.go
Normal file
@@ -0,0 +1,329 @@
|
||||
// +build !js
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
|
||||
"github.com/pion/transport/test"
|
||||
)
|
||||
|
||||
const (
|
||||
testMessage = "Hello World"
|
||||
testTimeLimit = 5 * time.Second
|
||||
messageRetry = 200 * time.Millisecond
|
||||
)
|
||||
|
||||
var errServerTimeout = errors.New("waiting on serverReady err: timeout")
|
||||
|
||||
func randomPort(t testing.TB) int {
|
||||
t.Helper()
|
||||
conn, err := net.ListenPacket("udp4", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to pickPort: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
}()
|
||||
switch addr := conn.LocalAddr().(type) {
|
||||
case *net.UDPAddr:
|
||||
return addr.Port
|
||||
default:
|
||||
t.Fatalf("unknown addr type %T", addr)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func simpleReadWrite(errChan chan error, outChan chan string, conn io.ReadWriter, messageRecvCount *uint64) {
|
||||
go func() {
|
||||
buffer := make([]byte, 8192)
|
||||
n, err := conn.Read(buffer)
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
outChan <- string(buffer[:n])
|
||||
atomic.AddUint64(messageRecvCount, 1)
|
||||
}()
|
||||
|
||||
for {
|
||||
if atomic.LoadUint64(messageRecvCount) == 2 {
|
||||
break
|
||||
} else if _, err := conn.Write([]byte(testMessage)); err != nil {
|
||||
errChan <- err
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(messageRetry)
|
||||
}
|
||||
}
|
||||
|
||||
type comm struct {
|
||||
ctx context.Context
|
||||
clientConfig, serverConfig *dtls.Config
|
||||
serverPort int
|
||||
messageRecvCount *uint64 // Counter to make sure both sides got a message
|
||||
clientMutex *sync.Mutex
|
||||
clientConn net.Conn
|
||||
serverMutex *sync.Mutex
|
||||
serverConn net.Conn
|
||||
serverListener net.Listener
|
||||
serverReady chan struct{}
|
||||
errChan chan error
|
||||
clientChan chan string
|
||||
serverChan chan string
|
||||
client func(*comm)
|
||||
server func(*comm)
|
||||
}
|
||||
|
||||
func newComm(ctx context.Context, clientConfig, serverConfig *dtls.Config, serverPort int, server, client func(*comm)) *comm {
|
||||
messageRecvCount := uint64(0)
|
||||
c := &comm{
|
||||
ctx: ctx,
|
||||
clientConfig: clientConfig,
|
||||
serverConfig: serverConfig,
|
||||
serverPort: serverPort,
|
||||
messageRecvCount: &messageRecvCount,
|
||||
clientMutex: &sync.Mutex{},
|
||||
serverMutex: &sync.Mutex{},
|
||||
serverReady: make(chan struct{}),
|
||||
errChan: make(chan error),
|
||||
clientChan: make(chan string),
|
||||
serverChan: make(chan string),
|
||||
server: server,
|
||||
client: client,
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *comm) assert(t *testing.T) {
|
||||
// DTLS Client
|
||||
go c.client(c)
|
||||
|
||||
// DTLS Server
|
||||
go c.server(c)
|
||||
|
||||
defer func() {
|
||||
if c.clientConn != nil {
|
||||
if err := c.clientConn.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if c.serverConn != nil {
|
||||
if err := c.serverConn.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if c.serverListener != nil {
|
||||
if err := c.serverListener.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
func() {
|
||||
seenClient, seenServer := false, false
|
||||
for {
|
||||
select {
|
||||
case err := <-c.errChan:
|
||||
t.Fatal(err)
|
||||
case <-time.After(testTimeLimit):
|
||||
t.Fatalf("Test timeout, seenClient %t seenServer %t", seenClient, seenServer)
|
||||
case clientMsg := <-c.clientChan:
|
||||
if clientMsg != testMessage {
|
||||
t.Fatalf("clientMsg does not equal test message: %s %s", clientMsg, testMessage)
|
||||
}
|
||||
|
||||
seenClient = true
|
||||
if seenClient && seenServer {
|
||||
return
|
||||
}
|
||||
case serverMsg := <-c.serverChan:
|
||||
if serverMsg != testMessage {
|
||||
t.Fatalf("serverMsg does not equal test message: %s %s", serverMsg, testMessage)
|
||||
}
|
||||
|
||||
seenServer = true
|
||||
if seenClient && seenServer {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func clientPion(c *comm) {
|
||||
select {
|
||||
case <-c.serverReady:
|
||||
// OK
|
||||
case <-time.After(time.Second):
|
||||
c.errChan <- errServerTimeout
|
||||
}
|
||||
|
||||
c.clientMutex.Lock()
|
||||
defer c.clientMutex.Unlock()
|
||||
|
||||
var err error
|
||||
c.clientConn, err = dtls.DialWithContext(c.ctx, "udp",
|
||||
&net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: c.serverPort},
|
||||
c.clientConfig,
|
||||
)
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
simpleReadWrite(c.errChan, c.clientChan, c.clientConn, c.messageRecvCount)
|
||||
}
|
||||
|
||||
func serverPion(c *comm) {
|
||||
c.serverMutex.Lock()
|
||||
defer c.serverMutex.Unlock()
|
||||
|
||||
var err error
|
||||
c.serverListener, err = dtls.Listen("udp",
|
||||
&net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: c.serverPort},
|
||||
c.serverConfig,
|
||||
)
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
c.serverReady <- struct{}{}
|
||||
c.serverConn, err = c.serverListener.Accept()
|
||||
if err != nil {
|
||||
c.errChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
simpleReadWrite(c.errChan, c.serverChan, c.serverConn, c.messageRecvCount)
|
||||
}
|
||||
|
||||
/*
|
||||
Simple DTLS Client/Server can communicate
|
||||
- Assert that you can send messages both ways
|
||||
- Assert that Close() on both ends work
|
||||
- Assert that no Goroutines are leaked
|
||||
*/
|
||||
func testPionE2ESimple(t *testing.T, server, client func(*comm)) {
|
||||
lim := test.TimeOut(time.Second * 30)
|
||||
defer lim.Stop()
|
||||
|
||||
report := test.CheckRoutines(t)
|
||||
defer report()
|
||||
|
||||
for _, cipherSuite := range []dtls.CipherSuiteID{
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
} {
|
||||
cipherSuite := cipherSuite
|
||||
t.Run(cipherSuite.String(), func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cert, err := selfsign.GenerateSelfSignedWithDNS("localhost")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg := &dtls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
CipherSuites: []dtls.CipherSuiteID{cipherSuite},
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
serverPort := randomPort(t)
|
||||
comm := newComm(ctx, cfg, cfg, serverPort, server, client)
|
||||
comm.assert(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testPionE2ESimplePSK(t *testing.T, server, client func(*comm)) {
|
||||
lim := test.TimeOut(time.Second * 30)
|
||||
defer lim.Stop()
|
||||
|
||||
report := test.CheckRoutines(t)
|
||||
defer report()
|
||||
|
||||
for _, cipherSuite := range []dtls.CipherSuiteID{
|
||||
dtls.TLS_PSK_WITH_AES_128_CCM,
|
||||
dtls.TLS_PSK_WITH_AES_128_CCM_8,
|
||||
dtls.TLS_PSK_WITH_AES_128_GCM_SHA256,
|
||||
} {
|
||||
cipherSuite := cipherSuite
|
||||
t.Run(cipherSuite.String(), func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cfg := &dtls.Config{
|
||||
PSK: func(hint []byte) ([]byte, error) {
|
||||
return []byte{0xAB, 0xC1, 0x23}, nil
|
||||
},
|
||||
PSKIdentityHint: []byte{0x01, 0x02, 0x03, 0x04, 0x05},
|
||||
CipherSuites: []dtls.CipherSuiteID{cipherSuite},
|
||||
}
|
||||
serverPort := randomPort(t)
|
||||
comm := newComm(ctx, cfg, cfg, serverPort, server, client)
|
||||
comm.assert(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testPionE2EMTUs(t *testing.T, server, client func(*comm)) {
|
||||
lim := test.TimeOut(time.Second * 30)
|
||||
defer lim.Stop()
|
||||
|
||||
report := test.CheckRoutines(t)
|
||||
defer report()
|
||||
|
||||
for _, mtu := range []int{
|
||||
10000,
|
||||
1000,
|
||||
100,
|
||||
} {
|
||||
mtu := mtu
|
||||
t.Run(fmt.Sprintf("MTU%d", mtu), func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cert, err := selfsign.GenerateSelfSignedWithDNS("localhost")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg := &dtls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||
InsecureSkipVerify: true,
|
||||
MTU: mtu,
|
||||
}
|
||||
serverPort := randomPort(t)
|
||||
comm := newComm(ctx, cfg, cfg, serverPort, server, client)
|
||||
comm.assert(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPionE2ESimple(t *testing.T) {
|
||||
testPionE2ESimple(t, serverPion, clientPion)
|
||||
}
|
||||
|
||||
func TestPionE2ESimplePSK(t *testing.T) {
|
||||
testPionE2ESimplePSK(t, serverPion, clientPion)
|
||||
}
|
||||
|
||||
func TestPionE2EMTUs(t *testing.T) {
|
||||
testPionE2EMTUs(t, serverPion, clientPion)
|
||||
}
|
62
dtls-2.0.9/e2e/e2e_v113_test.go
Normal file
62
dtls-2.0.9/e2e/e2e_v113_test.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// +build go1.13,!js
|
||||
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
|
||||
"github.com/pion/transport/test"
|
||||
)
|
||||
|
||||
// ED25519 is not supported in Go 1.12 crypto/x509.
|
||||
// Once Go 1.12 is deprecated, move this test to e2e_test.go.
|
||||
|
||||
func testPionE2ESimpleED25519(t *testing.T, server, client func(*comm)) {
|
||||
lim := test.TimeOut(time.Second * 30)
|
||||
defer lim.Stop()
|
||||
|
||||
report := test.CheckRoutines(t)
|
||||
defer report()
|
||||
|
||||
for _, cipherSuite := range []dtls.CipherSuiteID{
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
||||
} {
|
||||
cipherSuite := cipherSuite
|
||||
t.Run(cipherSuite.String(), func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, key, err := ed25519.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cert, err := selfsign.SelfSign(key)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg := &dtls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
CipherSuites: []dtls.CipherSuiteID{cipherSuite},
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
serverPort := randomPort(t)
|
||||
comm := newComm(ctx, cfg, cfg, serverPort, server, client)
|
||||
comm.assert(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPionE2ESimpleED25519(t *testing.T) {
|
||||
testPionE2ESimpleED25519(t, serverPion, clientPion)
|
||||
}
|
Reference in New Issue
Block a user