github.com/pion/dtls/v2@v2.2.12/flight2handler.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package dtls
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  
    10  	"github.com/pion/dtls/v2/pkg/protocol"
    11  	"github.com/pion/dtls/v2/pkg/protocol/alert"
    12  	"github.com/pion/dtls/v2/pkg/protocol/handshake"
    13  	"github.com/pion/dtls/v2/pkg/protocol/recordlayer"
    14  )
    15  
    16  func flight2Parse(ctx context.Context, c flightConn, state *State, cache *handshakeCache, cfg *handshakeConfig) (flightVal, *alert.Alert, error) {
    17  	seq, msgs, ok := cache.fullPullMap(state.handshakeRecvSequence, state.cipherSuite,
    18  		handshakeCachePullRule{handshake.TypeClientHello, cfg.initialEpoch, true, false},
    19  	)
    20  	if !ok {
    21  		// Client may retransmit the first ClientHello when HelloVerifyRequest is dropped.
    22  		// Parse as flight 0 in this case.
    23  		return flight0Parse(ctx, c, state, cache, cfg)
    24  	}
    25  	state.handshakeRecvSequence = seq
    26  
    27  	var clientHello *handshake.MessageClientHello
    28  
    29  	// Validate type
    30  	if clientHello, ok = msgs[handshake.TypeClientHello].(*handshake.MessageClientHello); !ok {
    31  		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.InternalError}, nil
    32  	}
    33  
    34  	if !clientHello.Version.Equal(protocol.Version1_2) {
    35  		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.ProtocolVersion}, errUnsupportedProtocolVersion
    36  	}
    37  
    38  	if len(clientHello.Cookie) == 0 {
    39  		return 0, nil, nil
    40  	}
    41  	if !bytes.Equal(state.cookie, clientHello.Cookie) {
    42  		return 0, &alert.Alert{Level: alert.Fatal, Description: alert.AccessDenied}, errCookieMismatch
    43  	}
    44  	return flight4, nil, nil
    45  }
    46  
    47  func flight2Generate(_ flightConn, state *State, _ *handshakeCache, _ *handshakeConfig) ([]*packet, *alert.Alert, error) {
    48  	state.handshakeSendSequence = 0
    49  	return []*packet{
    50  		{
    51  			record: &recordlayer.RecordLayer{
    52  				Header: recordlayer.Header{
    53  					Version: protocol.Version1_2,
    54  				},
    55  				Content: &handshake.Handshake{
    56  					Message: &handshake.MessageHelloVerifyRequest{
    57  						Version: protocol.Version1_2,
    58  						Cookie:  state.cookie,
    59  					},
    60  				},
    61  			},
    62  		},
    63  	}, nil, nil
    64  }