Skip to content

Instantly share code, notes, and snippets.

@jspc

jspc/client.go Secret

Last active June 25, 2024 08:11
Show Gist options
  • Save jspc/716d826faef4bfdb8c9b95fef26233b6 to your computer and use it in GitHub Desktop.
Save jspc/716d826faef4bfdb8c9b95fef26233b6 to your computer and use it in GitHub Desktop.
Large(r) DTLS Packets
package main
import (
"bytes"
"context"
"crypto/tls"
"io"
"log"
"net"
"github.com/pion/dtls/v2"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
)
func main() {
conn := dtlsConn()
buf := new(bytes.Buffer)
conn.Write([]byte("some ignored message"))
packets := 0
for {
log.Print("reading")
packets++
// Work in buffers of 64k
data := make([]byte, 64_000)
read, err := conn.Read(data)
if err == io.EOF {
err = nil
}
log.Printf("%d -> %#v", read, err)
if err != nil {
panic(err)
}
buf.Write(data[:read])
if read < len(data) {
break
}
}
log.Printf("Received %d packets, for a total of %d bytes",
packets,
buf.Len(),
)
}
func dtlsConn() io.ReadWriteCloser {
// Prepare the IP to connect to
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
// Generate a certificate and private key to secure the connection
certificate, err := selfsign.GenerateSelfSigned()
if err != nil {
panic(err)
}
//
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
//
// Prepare the configuration of the DTLS connection
config := &dtls.Config{
Certificates: []tls.Certificate{certificate},
InsecureSkipVerify: true,
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
}
// Connect to a DTLS server
ctx := context.Background()
dtlsConn, err := dtls.DialWithContext(ctx, "udp", addr, config)
if err != nil {
panic(err)
}
return dtlsConn
}
package main
import (
"bytes"
"context"
"crypto/tls"
"fmt"
"io"
"log"
"net"
"os"
"strconv"
"strings"
"time"
"github.com/pion/dtls/v2"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
)
const (
MaxMessageSize = 64_000
DefaultBufferS = 1_000_000
)
var (
BufferSize = bufferSize()
)
func main() {
listener := dtlsConn()
defer listener.Close()
fmt.Println("Listening")
for {
// Wait for a connection.
conn, err := listener.Accept()
if err != nil {
panic(err)
}
// Discard anything read; it's irrelevant
_, err = conn.Read(make([]byte, MaxMessageSize))
if err != nil {
panic(err)
}
msgBuffer := bytes.NewBufferString(strings.Repeat("a", BufferSize))
err = fragmenter(conn, msgBuffer)
if err != nil {
panic(err)
}
}
}
func fragmenter(conn net.Conn, buf io.Reader) error {
for {
log.Print("fragmenter")
payload := make([]byte, MaxMessageSize)
count, err := buf.Read(payload)
if err != nil {
if err == io.EOF {
err = nil
}
return err
}
_, err = conn.Write(payload[:count])
if err != nil {
return err
}
if count < MaxMessageSize {
return err
}
log.Print("next")
}
}
func dtlsConn() net.Listener {
// Prepare the IP to connect to
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
// Generate a certificate and private key to secure the connection
certificate, err := selfsign.GenerateSelfSigned()
if err != nil {
panic(err)
}
// Create parent context to cleanup handshaking connections on exit.
ctx := context.Background()
//
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
//
// Prepare the configuration of the DTLS connection
config := &dtls.Config{
Certificates: []tls.Certificate{certificate},
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
// Create timeout context for accepted connection.
ConnectContextMaker: func() (context.Context, func()) {
return context.WithTimeout(ctx, time.Second)
},
}
// Connect to a DTLS server
listener, err := dtls.Listen("udp", addr, config)
if err != nil {
panic(err)
}
return listener
}
func bufferSize() int {
s, ok := os.LookupEnv("BUF_SIZE")
if !ok {
return 1_000_000
}
i, err := strconv.Atoi(s)
if err != nil {
panic(err)
}
return i
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment