xref: /aosp_15_r20/external/webrtc/p2p/base/dtls_transport.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2011 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef P2P_BASE_DTLS_TRANSPORT_H_
12*d9f75844SAndroid Build Coastguard Worker #define P2P_BASE_DTLS_TRANSPORT_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <string>
16*d9f75844SAndroid Build Coastguard Worker #include <vector>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/crypto_options.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/dtls_transport_interface.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h"
22*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/dtls_transport_internal.h"
23*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/ice_transport_internal.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/buffer.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/buffer_queue.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_stream_adapter.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/stream.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h"
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker namespace rtc {
32*d9f75844SAndroid Build Coastguard Worker class PacketTransportInternal;
33*d9f75844SAndroid Build Coastguard Worker }
34*d9f75844SAndroid Build Coastguard Worker 
35*d9f75844SAndroid Build Coastguard Worker namespace cricket {
36*d9f75844SAndroid Build Coastguard Worker 
37*d9f75844SAndroid Build Coastguard Worker // A bridge between a packet-oriented/transport-type interface on
38*d9f75844SAndroid Build Coastguard Worker // the bottom and a StreamInterface on the top.
39*d9f75844SAndroid Build Coastguard Worker class StreamInterfaceChannel : public rtc::StreamInterface {
40*d9f75844SAndroid Build Coastguard Worker  public:
41*d9f75844SAndroid Build Coastguard Worker   explicit StreamInterfaceChannel(IceTransportInternal* ice_transport);
42*d9f75844SAndroid Build Coastguard Worker 
43*d9f75844SAndroid Build Coastguard Worker   StreamInterfaceChannel(const StreamInterfaceChannel&) = delete;
44*d9f75844SAndroid Build Coastguard Worker   StreamInterfaceChannel& operator=(const StreamInterfaceChannel&) = delete;
45*d9f75844SAndroid Build Coastguard Worker 
46*d9f75844SAndroid Build Coastguard Worker   // Push in a packet; this gets pulled out from Read().
47*d9f75844SAndroid Build Coastguard Worker   bool OnPacketReceived(const char* data, size_t size);
48*d9f75844SAndroid Build Coastguard Worker 
49*d9f75844SAndroid Build Coastguard Worker   // Implementations of StreamInterface
50*d9f75844SAndroid Build Coastguard Worker   rtc::StreamState GetState() const override;
51*d9f75844SAndroid Build Coastguard Worker   void Close() override;
52*d9f75844SAndroid Build Coastguard Worker   rtc::StreamResult Read(rtc::ArrayView<uint8_t> buffer,
53*d9f75844SAndroid Build Coastguard Worker                          size_t& read,
54*d9f75844SAndroid Build Coastguard Worker                          int& error) override;
55*d9f75844SAndroid Build Coastguard Worker   rtc::StreamResult Write(rtc::ArrayView<const uint8_t> data,
56*d9f75844SAndroid Build Coastguard Worker                           size_t& written,
57*d9f75844SAndroid Build Coastguard Worker                           int& error) override;
58*d9f75844SAndroid Build Coastguard Worker 
59*d9f75844SAndroid Build Coastguard Worker  private:
60*d9f75844SAndroid Build Coastguard Worker   RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker sequence_checker_;
61*d9f75844SAndroid Build Coastguard Worker   IceTransportInternal* const ice_transport_;  // owned by DtlsTransport
62*d9f75844SAndroid Build Coastguard Worker   rtc::StreamState state_ RTC_GUARDED_BY(sequence_checker_);
63*d9f75844SAndroid Build Coastguard Worker   rtc::BufferQueue packets_ RTC_GUARDED_BY(sequence_checker_);
64*d9f75844SAndroid Build Coastguard Worker };
65*d9f75844SAndroid Build Coastguard Worker 
66*d9f75844SAndroid Build Coastguard Worker // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style
67*d9f75844SAndroid Build Coastguard Worker // packet-based interface, wrapping an existing TransportChannel instance
68*d9f75844SAndroid Build Coastguard Worker // (e.g a P2PTransportChannel)
69*d9f75844SAndroid Build Coastguard Worker // Here's the way this works:
70*d9f75844SAndroid Build Coastguard Worker //
71*d9f75844SAndroid Build Coastguard Worker //   DtlsTransport {
72*d9f75844SAndroid Build Coastguard Worker //       SSLStreamAdapter* dtls_ {
73*d9f75844SAndroid Build Coastguard Worker //           StreamInterfaceChannel downward_ {
74*d9f75844SAndroid Build Coastguard Worker //               IceTransportInternal* ice_transport_;
75*d9f75844SAndroid Build Coastguard Worker //           }
76*d9f75844SAndroid Build Coastguard Worker //       }
77*d9f75844SAndroid Build Coastguard Worker //   }
78*d9f75844SAndroid Build Coastguard Worker //
79*d9f75844SAndroid Build Coastguard Worker //   - Data which comes into DtlsTransport from the underlying
80*d9f75844SAndroid Build Coastguard Worker //     ice_transport_ via OnReadPacket() is checked for whether it is DTLS
81*d9f75844SAndroid Build Coastguard Worker //     or not, and if it is, is passed to DtlsTransport::HandleDtlsPacket,
82*d9f75844SAndroid Build Coastguard Worker //     which pushes it into to downward_. dtls_ is listening for events on
83*d9f75844SAndroid Build Coastguard Worker //     downward_, so it immediately calls downward_->Read().
84*d9f75844SAndroid Build Coastguard Worker //
85*d9f75844SAndroid Build Coastguard Worker //   - Data written to DtlsTransport is passed either to downward_ or directly
86*d9f75844SAndroid Build Coastguard Worker //     to ice_transport_, depending on whether DTLS is negotiated and whether
87*d9f75844SAndroid Build Coastguard Worker //     the flags include PF_SRTP_BYPASS
88*d9f75844SAndroid Build Coastguard Worker //
89*d9f75844SAndroid Build Coastguard Worker //   - The SSLStreamAdapter writes to downward_->Write() which translates it
90*d9f75844SAndroid Build Coastguard Worker //     into packet writes on ice_transport_.
91*d9f75844SAndroid Build Coastguard Worker //
92*d9f75844SAndroid Build Coastguard Worker // This class is not thread safe; all methods must be called on the same thread
93*d9f75844SAndroid Build Coastguard Worker // as the constructor.
94*d9f75844SAndroid Build Coastguard Worker class DtlsTransport : public DtlsTransportInternal {
95*d9f75844SAndroid Build Coastguard Worker  public:
96*d9f75844SAndroid Build Coastguard Worker   // `ice_transport` is the ICE transport this DTLS transport is wrapping.  It
97*d9f75844SAndroid Build Coastguard Worker   // must outlive this DTLS transport.
98*d9f75844SAndroid Build Coastguard Worker   //
99*d9f75844SAndroid Build Coastguard Worker   // `crypto_options` are the options used for the DTLS handshake. This affects
100*d9f75844SAndroid Build Coastguard Worker   // whether GCM crypto suites are negotiated.
101*d9f75844SAndroid Build Coastguard Worker   //
102*d9f75844SAndroid Build Coastguard Worker   // `event_log` is an optional RtcEventLog for logging state changes. It should
103*d9f75844SAndroid Build Coastguard Worker   // outlive the DtlsTransport.
104*d9f75844SAndroid Build Coastguard Worker   DtlsTransport(
105*d9f75844SAndroid Build Coastguard Worker       IceTransportInternal* ice_transport,
106*d9f75844SAndroid Build Coastguard Worker       const webrtc::CryptoOptions& crypto_options,
107*d9f75844SAndroid Build Coastguard Worker       webrtc::RtcEventLog* event_log,
108*d9f75844SAndroid Build Coastguard Worker       rtc::SSLProtocolVersion max_version = rtc::SSL_PROTOCOL_DTLS_12);
109*d9f75844SAndroid Build Coastguard Worker 
110*d9f75844SAndroid Build Coastguard Worker   ~DtlsTransport() override;
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   DtlsTransport(const DtlsTransport&) = delete;
113*d9f75844SAndroid Build Coastguard Worker   DtlsTransport& operator=(const DtlsTransport&) = delete;
114*d9f75844SAndroid Build Coastguard Worker 
115*d9f75844SAndroid Build Coastguard Worker   webrtc::DtlsTransportState dtls_state() const override;
116*d9f75844SAndroid Build Coastguard Worker   const std::string& transport_name() const override;
117*d9f75844SAndroid Build Coastguard Worker   int component() const override;
118*d9f75844SAndroid Build Coastguard Worker 
119*d9f75844SAndroid Build Coastguard Worker   // DTLS is active if a local certificate was set. Otherwise this acts in a
120*d9f75844SAndroid Build Coastguard Worker   // "passthrough" mode, sending packets directly through the underlying ICE
121*d9f75844SAndroid Build Coastguard Worker   // transport.
122*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Remove this weirdness, and handle it in the upper layers.
123*d9f75844SAndroid Build Coastguard Worker   bool IsDtlsActive() const override;
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker   // SetLocalCertificate is what makes DTLS active. It must be called before
126*d9f75844SAndroid Build Coastguard Worker   // SetRemoteFinterprint.
127*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Once DtlsTransport no longer has the concept of being
128*d9f75844SAndroid Build Coastguard Worker   // "active" or not (acting as a passthrough if not active), just require this
129*d9f75844SAndroid Build Coastguard Worker   // certificate on construction or "Start".
130*d9f75844SAndroid Build Coastguard Worker   bool SetLocalCertificate(
131*d9f75844SAndroid Build Coastguard Worker       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override;
132*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override;
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker   // SetRemoteFingerprint must be called after SetLocalCertificate, and any
135*d9f75844SAndroid Build Coastguard Worker   // other methods like SetDtlsRole. It's what triggers the actual DTLS setup.
136*d9f75844SAndroid Build Coastguard Worker   // TODO(deadbeef): Rename to "Start" like in ORTC?
137*d9f75844SAndroid Build Coastguard Worker   bool SetRemoteFingerprint(absl::string_view digest_alg,
138*d9f75844SAndroid Build Coastguard Worker                             const uint8_t* digest,
139*d9f75844SAndroid Build Coastguard Worker                             size_t digest_len) override;
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   // SetRemoteParameters must be called after SetLocalCertificate.
142*d9f75844SAndroid Build Coastguard Worker   webrtc::RTCError SetRemoteParameters(
143*d9f75844SAndroid Build Coastguard Worker       absl::string_view digest_alg,
144*d9f75844SAndroid Build Coastguard Worker       const uint8_t* digest,
145*d9f75844SAndroid Build Coastguard Worker       size_t digest_len,
146*d9f75844SAndroid Build Coastguard Worker       absl::optional<rtc::SSLRole> role) override;
147*d9f75844SAndroid Build Coastguard Worker 
148*d9f75844SAndroid Build Coastguard Worker   // Called to send a packet (via DTLS, if turned on).
149*d9f75844SAndroid Build Coastguard Worker   int SendPacket(const char* data,
150*d9f75844SAndroid Build Coastguard Worker                  size_t size,
151*d9f75844SAndroid Build Coastguard Worker                  const rtc::PacketOptions& options,
152*d9f75844SAndroid Build Coastguard Worker                  int flags) override;
153*d9f75844SAndroid Build Coastguard Worker 
154*d9f75844SAndroid Build Coastguard Worker   bool GetOption(rtc::Socket::Option opt, int* value) override;
155*d9f75844SAndroid Build Coastguard Worker 
156*d9f75844SAndroid Build Coastguard Worker   // Find out which TLS version was negotiated
157*d9f75844SAndroid Build Coastguard Worker   bool GetSslVersionBytes(int* version) const override;
158*d9f75844SAndroid Build Coastguard Worker   // Find out which DTLS-SRTP cipher was negotiated
159*d9f75844SAndroid Build Coastguard Worker   bool GetSrtpCryptoSuite(int* cipher) override;
160*d9f75844SAndroid Build Coastguard Worker 
161*d9f75844SAndroid Build Coastguard Worker   bool GetDtlsRole(rtc::SSLRole* role) const override;
162*d9f75844SAndroid Build Coastguard Worker   bool SetDtlsRole(rtc::SSLRole role) override;
163*d9f75844SAndroid Build Coastguard Worker 
164*d9f75844SAndroid Build Coastguard Worker   // Find out which DTLS cipher was negotiated
165*d9f75844SAndroid Build Coastguard Worker   bool GetSslCipherSuite(int* cipher) override;
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker   // Once DTLS has been established, this method retrieves the certificate
168*d9f75844SAndroid Build Coastguard Worker   // chain in use by the remote peer, for use in external identity
169*d9f75844SAndroid Build Coastguard Worker   // verification.
170*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::SSLCertChain> GetRemoteSSLCertChain() const override;
171*d9f75844SAndroid Build Coastguard Worker 
172*d9f75844SAndroid Build Coastguard Worker   // Once DTLS has established (i.e., this ice_transport is writable), this
173*d9f75844SAndroid Build Coastguard Worker   // method extracts the keys negotiated during the DTLS handshake, for use in
174*d9f75844SAndroid Build Coastguard Worker   // external encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
175*d9f75844SAndroid Build Coastguard Worker   // See the SSLStreamAdapter documentation for info on the specific parameters.
176*d9f75844SAndroid Build Coastguard Worker   bool ExportKeyingMaterial(absl::string_view label,
177*d9f75844SAndroid Build Coastguard Worker                             const uint8_t* context,
178*d9f75844SAndroid Build Coastguard Worker                             size_t context_len,
179*d9f75844SAndroid Build Coastguard Worker                             bool use_context,
180*d9f75844SAndroid Build Coastguard Worker                             uint8_t* result,
181*d9f75844SAndroid Build Coastguard Worker                             size_t result_len) override;
182*d9f75844SAndroid Build Coastguard Worker 
183*d9f75844SAndroid Build Coastguard Worker   IceTransportInternal* ice_transport() override;
184*d9f75844SAndroid Build Coastguard Worker 
185*d9f75844SAndroid Build Coastguard Worker   // For informational purposes. Tells if the DTLS handshake has finished.
186*d9f75844SAndroid Build Coastguard Worker   // This may be true even if writable() is false, if the remote fingerprint
187*d9f75844SAndroid Build Coastguard Worker   // has not yet been verified.
188*d9f75844SAndroid Build Coastguard Worker   bool IsDtlsConnected();
189*d9f75844SAndroid Build Coastguard Worker 
190*d9f75844SAndroid Build Coastguard Worker   bool receiving() const override;
191*d9f75844SAndroid Build Coastguard Worker   bool writable() const override;
192*d9f75844SAndroid Build Coastguard Worker 
193*d9f75844SAndroid Build Coastguard Worker   int GetError() override;
194*d9f75844SAndroid Build Coastguard Worker 
195*d9f75844SAndroid Build Coastguard Worker   absl::optional<rtc::NetworkRoute> network_route() const override;
196*d9f75844SAndroid Build Coastguard Worker 
197*d9f75844SAndroid Build Coastguard Worker   int SetOption(rtc::Socket::Option opt, int value) override;
198*d9f75844SAndroid Build Coastguard Worker 
ToString()199*d9f75844SAndroid Build Coastguard Worker   std::string ToString() const {
200*d9f75844SAndroid Build Coastguard Worker     const absl::string_view RECEIVING_ABBREV[2] = {"_", "R"};
201*d9f75844SAndroid Build Coastguard Worker     const absl::string_view WRITABLE_ABBREV[2] = {"_", "W"};
202*d9f75844SAndroid Build Coastguard Worker     rtc::StringBuilder sb;
203*d9f75844SAndroid Build Coastguard Worker     sb << "DtlsTransport[" << transport_name() << "|" << component_ << "|"
204*d9f75844SAndroid Build Coastguard Worker        << RECEIVING_ABBREV[receiving()] << WRITABLE_ABBREV[writable()] << "]";
205*d9f75844SAndroid Build Coastguard Worker     return sb.Release();
206*d9f75844SAndroid Build Coastguard Worker   }
207*d9f75844SAndroid Build Coastguard Worker 
208*d9f75844SAndroid Build Coastguard Worker  private:
209*d9f75844SAndroid Build Coastguard Worker   void ConnectToIceTransport();
210*d9f75844SAndroid Build Coastguard Worker 
211*d9f75844SAndroid Build Coastguard Worker   void OnWritableState(rtc::PacketTransportInternal* transport);
212*d9f75844SAndroid Build Coastguard Worker   void OnReadPacket(rtc::PacketTransportInternal* transport,
213*d9f75844SAndroid Build Coastguard Worker                     const char* data,
214*d9f75844SAndroid Build Coastguard Worker                     size_t size,
215*d9f75844SAndroid Build Coastguard Worker                     const int64_t& packet_time_us,
216*d9f75844SAndroid Build Coastguard Worker                     int flags);
217*d9f75844SAndroid Build Coastguard Worker   void OnSentPacket(rtc::PacketTransportInternal* transport,
218*d9f75844SAndroid Build Coastguard Worker                     const rtc::SentPacket& sent_packet);
219*d9f75844SAndroid Build Coastguard Worker   void OnReadyToSend(rtc::PacketTransportInternal* transport);
220*d9f75844SAndroid Build Coastguard Worker   void OnReceivingState(rtc::PacketTransportInternal* transport);
221*d9f75844SAndroid Build Coastguard Worker   void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err);
222*d9f75844SAndroid Build Coastguard Worker   void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route);
223*d9f75844SAndroid Build Coastguard Worker   bool SetupDtls();
224*d9f75844SAndroid Build Coastguard Worker   void MaybeStartDtls();
225*d9f75844SAndroid Build Coastguard Worker   bool HandleDtlsPacket(const char* data, size_t size);
226*d9f75844SAndroid Build Coastguard Worker   void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
227*d9f75844SAndroid Build Coastguard Worker   void ConfigureHandshakeTimeout();
228*d9f75844SAndroid Build Coastguard Worker 
229*d9f75844SAndroid Build Coastguard Worker   void set_receiving(bool receiving);
230*d9f75844SAndroid Build Coastguard Worker   void set_writable(bool writable);
231*d9f75844SAndroid Build Coastguard Worker   // Sets the DTLS state, signaling if necessary.
232*d9f75844SAndroid Build Coastguard Worker   void set_dtls_state(webrtc::DtlsTransportState state);
233*d9f75844SAndroid Build Coastguard Worker 
234*d9f75844SAndroid Build Coastguard Worker   webrtc::SequenceChecker thread_checker_;
235*d9f75844SAndroid Build Coastguard Worker 
236*d9f75844SAndroid Build Coastguard Worker   const int component_;
237*d9f75844SAndroid Build Coastguard Worker   webrtc::DtlsTransportState dtls_state_ = webrtc::DtlsTransportState::kNew;
238*d9f75844SAndroid Build Coastguard Worker   // Underlying ice_transport, not owned by this class.
239*d9f75844SAndroid Build Coastguard Worker   IceTransportInternal* const ice_transport_;
240*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::SSLStreamAdapter> dtls_;  // The DTLS stream
241*d9f75844SAndroid Build Coastguard Worker   StreamInterfaceChannel*
242*d9f75844SAndroid Build Coastguard Worker       downward_;  // Wrapper for ice_transport_, owned by dtls_.
243*d9f75844SAndroid Build Coastguard Worker   const std::vector<int> srtp_ciphers_;  // SRTP ciphers to use with DTLS.
244*d9f75844SAndroid Build Coastguard Worker   bool dtls_active_ = false;
245*d9f75844SAndroid Build Coastguard Worker   rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_;
246*d9f75844SAndroid Build Coastguard Worker   absl::optional<rtc::SSLRole> dtls_role_;
247*d9f75844SAndroid Build Coastguard Worker   const rtc::SSLProtocolVersion ssl_max_version_;
248*d9f75844SAndroid Build Coastguard Worker   rtc::Buffer remote_fingerprint_value_;
249*d9f75844SAndroid Build Coastguard Worker   std::string remote_fingerprint_algorithm_;
250*d9f75844SAndroid Build Coastguard Worker 
251*d9f75844SAndroid Build Coastguard Worker   // Cached DTLS ClientHello packet that was received before we started the
252*d9f75844SAndroid Build Coastguard Worker   // DTLS handshake. This could happen if the hello was received before the
253*d9f75844SAndroid Build Coastguard Worker   // ice transport became writable, or before a remote fingerprint was received.
254*d9f75844SAndroid Build Coastguard Worker   rtc::Buffer cached_client_hello_;
255*d9f75844SAndroid Build Coastguard Worker 
256*d9f75844SAndroid Build Coastguard Worker   bool receiving_ = false;
257*d9f75844SAndroid Build Coastguard Worker   bool writable_ = false;
258*d9f75844SAndroid Build Coastguard Worker 
259*d9f75844SAndroid Build Coastguard Worker   webrtc::RtcEventLog* const event_log_;
260*d9f75844SAndroid Build Coastguard Worker };
261*d9f75844SAndroid Build Coastguard Worker 
262*d9f75844SAndroid Build Coastguard Worker }  // namespace cricket
263*d9f75844SAndroid Build Coastguard Worker 
264*d9f75844SAndroid Build Coastguard Worker #endif  // P2P_BASE_DTLS_TRANSPORT_H_
265