github.com/pion/dtls/v2@v2.2.12/examples/listen/verify/main.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  // Package main implements an example DTLS server which verifies client certificates.
     5  package main
     6  
     7  import (
     8  	"context"
     9  	"crypto/tls"
    10  	"crypto/x509"
    11  	"fmt"
    12  	"net"
    13  	"time"
    14  
    15  	"github.com/pion/dtls/v2"
    16  	"github.com/pion/dtls/v2/examples/util"
    17  )
    18  
    19  func main() {
    20  	// Prepare the IP to connect to
    21  	addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
    22  
    23  	// Create parent context to cleanup handshaking connections on exit.
    24  	ctx, cancel := context.WithCancel(context.Background())
    25  	defer cancel()
    26  
    27  	//
    28  	// Everything below is the pion-DTLS API! Thanks for using it ❤️.
    29  	//
    30  
    31  	certificate, err := util.LoadKeyAndCertificate("examples/certificates/server.pem",
    32  		"examples/certificates/server.pub.pem")
    33  	util.Check(err)
    34  
    35  	rootCertificate, err := util.LoadCertificate("examples/certificates/server.pub.pem")
    36  	util.Check(err)
    37  	certPool := x509.NewCertPool()
    38  	cert, err := x509.ParseCertificate(rootCertificate.Certificate[0])
    39  	util.Check(err)
    40  	certPool.AddCert(cert)
    41  
    42  	// Prepare the configuration of the DTLS connection
    43  	config := &dtls.Config{
    44  		Certificates:         []tls.Certificate{certificate},
    45  		ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
    46  		ClientAuth:           dtls.RequireAndVerifyClientCert,
    47  		ClientCAs:            certPool,
    48  		// Create timeout context for accepted connection.
    49  		ConnectContextMaker: func() (context.Context, func()) {
    50  			return context.WithTimeout(ctx, 30*time.Second)
    51  		},
    52  	}
    53  
    54  	// Connect to a DTLS server
    55  	listener, err := dtls.Listen("udp", addr, config)
    56  	util.Check(err)
    57  	defer func() {
    58  		util.Check(listener.Close())
    59  	}()
    60  
    61  	fmt.Println("Listening")
    62  
    63  	// Simulate a chat session
    64  	hub := util.NewHub()
    65  
    66  	go func() {
    67  		for {
    68  			// Wait for a connection.
    69  			conn, err := listener.Accept()
    70  			util.Check(err)
    71  			// defer conn.Close() // TODO: graceful shutdown
    72  
    73  			// `conn` is of type `net.Conn` but may be casted to `dtls.Conn`
    74  			// using `dtlsConn := conn.(*dtls.Conn)` in order to to expose
    75  			// functions like `ConnectionState` etc.
    76  
    77  			// Register the connection with the chat hub
    78  			hub.Register(conn)
    79  		}
    80  	}()
    81  
    82  	// Start chatting
    83  	hub.Chat()
    84  }