gio/auto/
dtls_connection.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4#![allow(deprecated)]
5
6#[cfg(feature = "v2_70")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
8use crate::TlsProtocolVersion;
9use crate::{
10    AsyncResult, Cancellable, DatagramBased, TlsCertificate, TlsCertificateFlags, TlsDatabase,
11    TlsInteraction, TlsRehandshakeMode, ffi,
12};
13use glib::{
14    object::ObjectType as _,
15    prelude::*,
16    signal::{SignalHandlerId, connect_raw},
17    translate::*,
18};
19use std::{boxed::Box as Box_, pin::Pin};
20
21glib::wrapper! {
22    /// `GDtlsConnection` is the base DTLS connection class type, which wraps
23    /// a [`DatagramBased`][crate::DatagramBased] and provides DTLS encryption on top of it. Its
24    /// subclasses, [`DtlsClientConnection`][crate::DtlsClientConnection] and
25    /// [`DtlsServerConnection`][crate::DtlsServerConnection], implement client-side and server-side DTLS,
26    /// respectively.
27    ///
28    /// For TLS support, see [`TlsConnection`][crate::TlsConnection].
29    ///
30    /// As DTLS is datagram based, `GDtlsConnection` implements
31    /// [`DatagramBased`][crate::DatagramBased], presenting a datagram-socket-like API for the
32    /// encrypted connection. This operates over a base datagram connection, which is
33    /// also a `GDatagramBased` ([`base-socket`][struct@crate::DtlsConnection#base-socket]).
34    ///
35    /// To close a DTLS connection, use [`DtlsConnectionExt::close()`][crate::prelude::DtlsConnectionExt::close()].
36    ///
37    /// Neither [`DtlsServerConnection`][crate::DtlsServerConnection] or [`DtlsClientConnection`][crate::DtlsClientConnection]
38    /// set the peer address on their base [`DatagramBased`][crate::DatagramBased] if it is a
39    /// [`Socket`][crate::Socket] — it is up to the caller to do that if they wish. If they
40    /// do not, and [`SocketExt::close()`][crate::prelude::SocketExt::close()] is called on the base socket, the
41    /// `GDtlsConnection` will not raise a `G_IO_ERROR_NOT_CONNECTED` error on
42    /// further I/O.
43    ///
44    /// ## Properties
45    ///
46    ///
47    /// #### `advertised-protocols`
48    ///  The list of application-layer protocols that the connection
49    /// advertises that it is willing to speak. See
50    /// g_dtls_connection_set_advertised_protocols().
51    ///
52    /// Readable | Writeable
53    ///
54    ///
55    /// #### `base-socket`
56    ///  The #GDatagramBased that the connection wraps. Note that this may be any
57    /// implementation of #GDatagramBased, not just a #GSocket.
58    ///
59    /// Readable | Writeable | Construct Only
60    ///
61    ///
62    /// #### `certificate`
63    ///  The connection's certificate; see
64    /// g_dtls_connection_set_certificate().
65    ///
66    /// Readable | Writeable
67    ///
68    ///
69    /// #### `ciphersuite-name`
70    ///  The name of the DTLS ciphersuite in use. See g_dtls_connection_get_ciphersuite_name().
71    ///
72    /// Readable
73    ///
74    ///
75    /// #### `database`
76    ///  The certificate database to use when verifying this TLS connection.
77    /// If no certificate database is set, then the default database will be
78    /// used. See g_tls_backend_get_default_database().
79    ///
80    /// When using a non-default database, #GDtlsConnection must fall back to using
81    /// the #GTlsDatabase to perform certificate verification using
82    /// g_tls_database_verify_chain(), which means certificate verification will
83    /// not be able to make use of TLS session context. This may be less secure.
84    /// For example, if you create your own #GTlsDatabase that just wraps the
85    /// default #GTlsDatabase, you might expect that you have not changed anything,
86    /// but this is not true because you may have altered the behavior of
87    /// #GDtlsConnection by causing it to use g_tls_database_verify_chain(). See the
88    /// documentation of g_tls_database_verify_chain() for more details on specific
89    /// security checks that may not be performed. Accordingly, setting a
90    /// non-default database is discouraged except for specialty applications with
91    /// unusual security requirements.
92    ///
93    /// Readable | Writeable
94    ///
95    ///
96    /// #### `interaction`
97    ///  A #GTlsInteraction object to be used when the connection or certificate
98    /// database need to interact with the user. This will be used to prompt the
99    /// user for passwords where necessary.
100    ///
101    /// Readable | Writeable
102    ///
103    ///
104    /// #### `negotiated-protocol`
105    ///  The application-layer protocol negotiated during the TLS
106    /// handshake. See g_dtls_connection_get_negotiated_protocol().
107    ///
108    /// Readable
109    ///
110    ///
111    /// #### `peer-certificate`
112    ///  The connection's peer's certificate, after the TLS handshake has
113    /// completed or failed. Note in particular that this is not yet set
114    /// during the emission of #GDtlsConnection::accept-certificate.
115    ///
116    /// (You can watch for a #GObject::notify signal on this property to
117    /// detect when a handshake has occurred.)
118    ///
119    /// Readable
120    ///
121    ///
122    /// #### `peer-certificate-errors`
123    ///  The errors noticed while verifying
124    /// #GDtlsConnection:peer-certificate. Normally this should be 0, but
125    /// it may not be if #GDtlsClientConnection:validation-flags is not
126    /// [`TlsCertificateFlags::VALIDATE_ALL`][crate::TlsCertificateFlags::VALIDATE_ALL], or if
127    /// #GDtlsConnection::accept-certificate overrode the default
128    /// behavior.
129    ///
130    /// GLib guarantees that if certificate verification fails, at least
131    /// one error will be set, but it does not guarantee that all possible
132    /// errors will be set. Accordingly, you may not safely decide to
133    /// ignore any particular type of error. For example, it would be
134    /// incorrect to mask [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow
135    /// expired certificates, because this could potentially be the only
136    /// error flag set even if other problems exist with the certificate.
137    ///
138    /// Readable
139    ///
140    ///
141    /// #### `protocol-version`
142    ///  The DTLS protocol version in use. See g_dtls_connection_get_protocol_version().
143    ///
144    /// Readable
145    ///
146    ///
147    /// #### `rehandshake-mode`
148    ///  The rehandshaking mode. See
149    /// g_dtls_connection_set_rehandshake_mode().
150    ///
151    /// Readable | Writeable | Construct
152    ///
153    ///
154    /// #### `require-close-notify`
155    ///  Whether or not proper TLS close notification is required.
156    /// See g_dtls_connection_set_require_close_notify().
157    ///
158    /// Readable | Writeable | Construct
159    ///
160    /// ## Signals
161    ///
162    ///
163    /// #### `accept-certificate`
164    ///  Emitted during the TLS handshake after the peer certificate has
165    /// been received. You can examine @peer_cert's certification path by
166    /// calling g_tls_certificate_get_issuer() on it.
167    ///
168    /// For a client-side connection, @peer_cert is the server's
169    /// certificate, and the signal will only be emitted if the
170    /// certificate was not acceptable according to @conn's
171    /// #GDtlsClientConnection:validation_flags. If you would like the
172    /// certificate to be accepted despite @errors, return [`true`] from the
173    /// signal handler. Otherwise, if no handler accepts the certificate,
174    /// the handshake will fail with [`TlsError::BadCertificate`][crate::TlsError::BadCertificate].
175    ///
176    /// GLib guarantees that if certificate verification fails, this signal
177    /// will be emitted with at least one error will be set in @errors, but
178    /// it does not guarantee that all possible errors will be set.
179    /// Accordingly, you may not safely decide to ignore any particular
180    /// type of error. For example, it would be incorrect to ignore
181    /// [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow expired
182    /// certificates, because this could potentially be the only error flag
183    /// set even if other problems exist with the certificate.
184    ///
185    /// For a server-side connection, @peer_cert is the certificate
186    /// presented by the client, if this was requested via the server's
187    /// #GDtlsServerConnection:authentication_mode. On the server side,
188    /// the signal is always emitted when the client presents a
189    /// certificate, and the certificate will only be accepted if a
190    /// handler returns [`true`].
191    ///
192    /// Note that if this signal is emitted as part of asynchronous I/O
193    /// in the main thread, then you should not attempt to interact with
194    /// the user before returning from the signal handler. If you want to
195    /// let the user decide whether or not to accept the certificate, you
196    /// would have to return [`false`] from the signal handler on the first
197    /// attempt, and then after the connection attempt returns a
198    /// [`TlsError::BadCertificate`][crate::TlsError::BadCertificate], you can interact with the user, and
199    /// if the user decides to accept the certificate, remember that fact,
200    /// create a new connection, and return [`true`] from the signal handler
201    /// the next time.
202    ///
203    /// If you are doing I/O in another thread, you do not
204    /// need to worry about this, and can simply block in the signal
205    /// handler until the UI thread returns an answer.
206    ///
207    ///
208    ///
209    /// # Implements
210    ///
211    /// [`DtlsConnectionExt`][trait@crate::prelude::DtlsConnectionExt], [`DatagramBasedExt`][trait@crate::prelude::DatagramBasedExt], [`DatagramBasedExtManual`][trait@crate::prelude::DatagramBasedExtManual]
212    #[doc(alias = "GDtlsConnection")]
213    pub struct DtlsConnection(Interface<ffi::GDtlsConnection, ffi::GDtlsConnectionInterface>) @requires DatagramBased;
214
215    match fn {
216        type_ => || ffi::g_dtls_connection_get_type(),
217    }
218}
219
220impl DtlsConnection {
221    pub const NONE: Option<&'static DtlsConnection> = None;
222}
223
224/// Trait containing all [`struct@DtlsConnection`] methods.
225///
226/// # Implementors
227///
228/// [`DtlsClientConnection`][struct@crate::DtlsClientConnection], [`DtlsConnection`][struct@crate::DtlsConnection], [`DtlsServerConnection`][struct@crate::DtlsServerConnection]
229pub trait DtlsConnectionExt: IsA<DtlsConnection> + 'static {
230    /// Close the DTLS connection. This is equivalent to calling
231    /// g_dtls_connection_shutdown() to shut down both sides of the connection.
232    ///
233    /// Closing a #GDtlsConnection waits for all buffered but untransmitted data to
234    /// be sent before it completes. It then sends a `close_notify` DTLS alert to the
235    /// peer and may wait for a `close_notify` to be received from the peer. It does
236    /// not close the underlying #GDtlsConnection:base-socket; that must be closed
237    /// separately.
238    ///
239    /// Once @self is closed, all other operations will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
240    /// Closing a #GDtlsConnection multiple times will not return an error.
241    ///
242    /// #GDtlsConnections will be automatically closed when the last reference is
243    /// dropped, but you might want to call this function to make sure resources are
244    /// released as early as possible.
245    ///
246    /// If @cancellable is cancelled, the #GDtlsConnection may be left
247    /// partially-closed and any pending untransmitted data may be lost. Call
248    /// g_dtls_connection_close() again to complete closing the #GDtlsConnection.
249    /// ## `cancellable`
250    /// a #GCancellable, or [`None`]
251    ///
252    /// # Returns
253    ///
254    /// [`true`] on success, [`false`] otherwise
255    #[doc(alias = "g_dtls_connection_close")]
256    fn close(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
257        unsafe {
258            let mut error = std::ptr::null_mut();
259            let is_ok = ffi::g_dtls_connection_close(
260                self.as_ref().to_glib_none().0,
261                cancellable.map(|p| p.as_ref()).to_glib_none().0,
262                &mut error,
263            );
264            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
265            if error.is_null() {
266                Ok(())
267            } else {
268                Err(from_glib_full(error))
269            }
270        }
271    }
272
273    /// Asynchronously close the DTLS connection. See g_dtls_connection_close() for
274    /// more information.
275    /// ## `io_priority`
276    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
277    /// ## `cancellable`
278    /// a #GCancellable, or [`None`]
279    /// ## `callback`
280    /// callback to call when the close operation is complete
281    #[doc(alias = "g_dtls_connection_close_async")]
282    fn close_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
283        &self,
284        io_priority: glib::Priority,
285        cancellable: Option<&impl IsA<Cancellable>>,
286        callback: P,
287    ) {
288        let main_context = glib::MainContext::ref_thread_default();
289        let is_main_context_owner = main_context.is_owner();
290        let has_acquired_main_context = (!is_main_context_owner)
291            .then(|| main_context.acquire().ok())
292            .flatten();
293        assert!(
294            is_main_context_owner || has_acquired_main_context.is_some(),
295            "Async operations only allowed if the thread is owning the MainContext"
296        );
297
298        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
299            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
300        unsafe extern "C" fn close_async_trampoline<
301            P: FnOnce(Result<(), glib::Error>) + 'static,
302        >(
303            _source_object: *mut glib::gobject_ffi::GObject,
304            res: *mut crate::ffi::GAsyncResult,
305            user_data: glib::ffi::gpointer,
306        ) {
307            unsafe {
308                let mut error = std::ptr::null_mut();
309                ffi::g_dtls_connection_close_finish(_source_object as *mut _, res, &mut error);
310                let result = if error.is_null() {
311                    Ok(())
312                } else {
313                    Err(from_glib_full(error))
314                };
315                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
316                    Box_::from_raw(user_data as *mut _);
317                let callback: P = callback.into_inner();
318                callback(result);
319            }
320        }
321        let callback = close_async_trampoline::<P>;
322        unsafe {
323            ffi::g_dtls_connection_close_async(
324                self.as_ref().to_glib_none().0,
325                io_priority.into_glib(),
326                cancellable.map(|p| p.as_ref()).to_glib_none().0,
327                Some(callback),
328                Box_::into_raw(user_data) as *mut _,
329            );
330        }
331    }
332
333    fn close_future(
334        &self,
335        io_priority: glib::Priority,
336    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
337        Box_::pin(crate::GioFuture::new(
338            self,
339            move |obj, cancellable, send| {
340                obj.close_async(io_priority, Some(cancellable), move |res| {
341                    send.resolve(res);
342                });
343            },
344        ))
345    }
346
347    /// Used by #GDtlsConnection implementations to emit the
348    /// #GDtlsConnection::accept-certificate signal.
349    /// ## `peer_cert`
350    /// the peer's #GTlsCertificate
351    /// ## `errors`
352    /// the problems with @peer_cert
353    ///
354    /// # Returns
355    ///
356    /// [`true`] if one of the signal handlers has returned
357    ///     [`true`] to accept @peer_cert
358    #[doc(alias = "g_dtls_connection_emit_accept_certificate")]
359    fn emit_accept_certificate(
360        &self,
361        peer_cert: &impl IsA<TlsCertificate>,
362        errors: TlsCertificateFlags,
363    ) -> bool {
364        unsafe {
365            from_glib(ffi::g_dtls_connection_emit_accept_certificate(
366                self.as_ref().to_glib_none().0,
367                peer_cert.as_ref().to_glib_none().0,
368                errors.into_glib(),
369            ))
370        }
371    }
372
373    /// Gets @self's certificate, as set by
374    /// g_dtls_connection_set_certificate().
375    ///
376    /// # Returns
377    ///
378    /// @self's certificate, or [`None`]
379    #[doc(alias = "g_dtls_connection_get_certificate")]
380    #[doc(alias = "get_certificate")]
381    fn certificate(&self) -> Option<TlsCertificate> {
382        unsafe {
383            from_glib_none(ffi::g_dtls_connection_get_certificate(
384                self.as_ref().to_glib_none().0,
385            ))
386        }
387    }
388
389    /// Returns the name of the current DTLS ciphersuite, or [`None`] if the
390    /// connection has not handshaked or has been closed. Beware that the TLS
391    /// backend may use any of multiple different naming conventions, because
392    /// OpenSSL and GnuTLS have their own ciphersuite naming conventions that
393    /// are different from each other and different from the standard, IANA-
394    /// registered ciphersuite names. The ciphersuite name is intended to be
395    /// displayed to the user for informative purposes only, and parsing it
396    /// is not recommended.
397    ///
398    /// # Returns
399    ///
400    /// The name of the current DTLS ciphersuite, or [`None`]
401    #[cfg(feature = "v2_70")]
402    #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
403    #[doc(alias = "g_dtls_connection_get_ciphersuite_name")]
404    #[doc(alias = "get_ciphersuite_name")]
405    #[doc(alias = "ciphersuite-name")]
406    fn ciphersuite_name(&self) -> Option<glib::GString> {
407        unsafe {
408            from_glib_full(ffi::g_dtls_connection_get_ciphersuite_name(
409                self.as_ref().to_glib_none().0,
410            ))
411        }
412    }
413
414    /// Gets the certificate database that @self uses to verify
415    /// peer certificates. See g_dtls_connection_set_database().
416    ///
417    /// # Returns
418    ///
419    /// the certificate database that @self uses or [`None`]
420    #[doc(alias = "g_dtls_connection_get_database")]
421    #[doc(alias = "get_database")]
422    fn database(&self) -> Option<TlsDatabase> {
423        unsafe {
424            from_glib_none(ffi::g_dtls_connection_get_database(
425                self.as_ref().to_glib_none().0,
426            ))
427        }
428    }
429
430    /// Get the object that will be used to interact with the user. It will be used
431    /// for things like prompting the user for passwords. If [`None`] is returned, then
432    /// no user interaction will occur for this connection.
433    ///
434    /// # Returns
435    ///
436    /// The interaction object.
437    #[doc(alias = "g_dtls_connection_get_interaction")]
438    #[doc(alias = "get_interaction")]
439    fn interaction(&self) -> Option<TlsInteraction> {
440        unsafe {
441            from_glib_none(ffi::g_dtls_connection_get_interaction(
442                self.as_ref().to_glib_none().0,
443            ))
444        }
445    }
446
447    /// Gets the name of the application-layer protocol negotiated during
448    /// the handshake.
449    ///
450    /// If the peer did not use the ALPN extension, or did not advertise a
451    /// protocol that matched one of @self's protocols, or the TLS backend
452    /// does not support ALPN, then this will be [`None`]. See
453    /// g_dtls_connection_set_advertised_protocols().
454    ///
455    /// # Returns
456    ///
457    /// the negotiated protocol, or [`None`]
458    #[cfg(feature = "v2_60")]
459    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
460    #[doc(alias = "g_dtls_connection_get_negotiated_protocol")]
461    #[doc(alias = "get_negotiated_protocol")]
462    #[doc(alias = "negotiated-protocol")]
463    fn negotiated_protocol(&self) -> Option<glib::GString> {
464        unsafe {
465            from_glib_none(ffi::g_dtls_connection_get_negotiated_protocol(
466                self.as_ref().to_glib_none().0,
467            ))
468        }
469    }
470
471    /// Gets @self's peer's certificate after the handshake has completed
472    /// or failed. (It is not set during the emission of
473    /// #GDtlsConnection::accept-certificate.)
474    ///
475    /// # Returns
476    ///
477    /// @self's peer's certificate, or [`None`]
478    #[doc(alias = "g_dtls_connection_get_peer_certificate")]
479    #[doc(alias = "get_peer_certificate")]
480    #[doc(alias = "peer-certificate")]
481    fn peer_certificate(&self) -> Option<TlsCertificate> {
482        unsafe {
483            from_glib_none(ffi::g_dtls_connection_get_peer_certificate(
484                self.as_ref().to_glib_none().0,
485            ))
486        }
487    }
488
489    /// Gets the errors associated with validating @self's peer's
490    /// certificate, after the handshake has completed or failed. (It is
491    /// not set during the emission of #GDtlsConnection::accept-certificate.)
492    ///
493    /// # Returns
494    ///
495    /// @self's peer's certificate errors
496    #[doc(alias = "g_dtls_connection_get_peer_certificate_errors")]
497    #[doc(alias = "get_peer_certificate_errors")]
498    #[doc(alias = "peer-certificate-errors")]
499    fn peer_certificate_errors(&self) -> TlsCertificateFlags {
500        unsafe {
501            from_glib(ffi::g_dtls_connection_get_peer_certificate_errors(
502                self.as_ref().to_glib_none().0,
503            ))
504        }
505    }
506
507    /// Returns the current DTLS protocol version, which may be
508    /// [`TlsProtocolVersion::Unknown`][crate::TlsProtocolVersion::Unknown] if the connection has not handshaked, or
509    /// has been closed, or if the TLS backend has implemented a protocol version
510    /// that is not a recognized #GTlsProtocolVersion.
511    ///
512    /// # Returns
513    ///
514    /// The current DTLS protocol version
515    #[cfg(feature = "v2_70")]
516    #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
517    #[doc(alias = "g_dtls_connection_get_protocol_version")]
518    #[doc(alias = "get_protocol_version")]
519    #[doc(alias = "protocol-version")]
520    fn protocol_version(&self) -> TlsProtocolVersion {
521        unsafe {
522            from_glib(ffi::g_dtls_connection_get_protocol_version(
523                self.as_ref().to_glib_none().0,
524            ))
525        }
526    }
527
528    /// Gets @self rehandshaking mode. See
529    /// g_dtls_connection_set_rehandshake_mode() for details.
530    ///
531    /// # Deprecated since 2.64
532    ///
533    /// Changing the rehandshake mode is no longer
534    ///   required for compatibility. Also, rehandshaking has been removed
535    ///   from the TLS protocol in TLS 1.3.
536    ///
537    /// # Returns
538    ///
539    /// [`TlsRehandshakeMode::Safely`][crate::TlsRehandshakeMode::Safely]
540    #[cfg_attr(feature = "v2_64", deprecated = "Since 2.64")]
541    #[allow(deprecated)]
542    #[doc(alias = "g_dtls_connection_get_rehandshake_mode")]
543    #[doc(alias = "get_rehandshake_mode")]
544    #[doc(alias = "rehandshake-mode")]
545    fn rehandshake_mode(&self) -> TlsRehandshakeMode {
546        unsafe {
547            from_glib(ffi::g_dtls_connection_get_rehandshake_mode(
548                self.as_ref().to_glib_none().0,
549            ))
550        }
551    }
552
553    /// Tests whether or not @self expects a proper TLS close notification
554    /// when the connection is closed. See
555    /// g_dtls_connection_set_require_close_notify() for details.
556    ///
557    /// # Returns
558    ///
559    /// [`true`] if @self requires a proper TLS close notification.
560    #[doc(alias = "g_dtls_connection_get_require_close_notify")]
561    #[doc(alias = "get_require_close_notify")]
562    #[doc(alias = "require-close-notify")]
563    fn requires_close_notify(&self) -> bool {
564        unsafe {
565            from_glib(ffi::g_dtls_connection_get_require_close_notify(
566                self.as_ref().to_glib_none().0,
567            ))
568        }
569    }
570
571    /// Attempts a TLS handshake on @self.
572    ///
573    /// On the client side, it is never necessary to call this method;
574    /// although the connection needs to perform a handshake after
575    /// connecting, #GDtlsConnection will handle this for you automatically
576    /// when you try to send or receive data on the connection. You can call
577    /// g_dtls_connection_handshake() manually if you want to know whether
578    /// the initial handshake succeeded or failed (as opposed to just
579    /// immediately trying to use @self to read or write, in which case,
580    /// if it fails, it may not be possible to tell if it failed before
581    /// or after completing the handshake), but beware that servers may reject
582    /// client authentication after the handshake has completed, so a
583    /// successful handshake does not indicate the connection will be usable.
584    ///
585    /// Likewise, on the server side, although a handshake is necessary at
586    /// the beginning of the communication, you do not need to call this
587    /// function explicitly unless you want clearer error reporting.
588    ///
589    /// Previously, calling g_dtls_connection_handshake() after the initial
590    /// handshake would trigger a rehandshake; however, this usage was
591    /// deprecated in GLib 2.60 because rehandshaking was removed from the
592    /// TLS protocol in TLS 1.3. Since GLib 2.64, calling this function after
593    /// the initial handshake will no longer do anything.
594    ///
595    /// #GDtlsConnection::accept_certificate may be emitted during the
596    /// handshake.
597    /// ## `cancellable`
598    /// a #GCancellable, or [`None`]
599    ///
600    /// # Returns
601    ///
602    /// success or failure
603    #[doc(alias = "g_dtls_connection_handshake")]
604    fn handshake(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
605        unsafe {
606            let mut error = std::ptr::null_mut();
607            let is_ok = ffi::g_dtls_connection_handshake(
608                self.as_ref().to_glib_none().0,
609                cancellable.map(|p| p.as_ref()).to_glib_none().0,
610                &mut error,
611            );
612            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
613            if error.is_null() {
614                Ok(())
615            } else {
616                Err(from_glib_full(error))
617            }
618        }
619    }
620
621    /// Asynchronously performs a TLS handshake on @self. See
622    /// g_dtls_connection_handshake() for more information.
623    /// ## `io_priority`
624    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
625    /// ## `cancellable`
626    /// a #GCancellable, or [`None`]
627    /// ## `callback`
628    /// callback to call when the handshake is complete
629    #[doc(alias = "g_dtls_connection_handshake_async")]
630    fn handshake_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
631        &self,
632        io_priority: glib::Priority,
633        cancellable: Option<&impl IsA<Cancellable>>,
634        callback: P,
635    ) {
636        let main_context = glib::MainContext::ref_thread_default();
637        let is_main_context_owner = main_context.is_owner();
638        let has_acquired_main_context = (!is_main_context_owner)
639            .then(|| main_context.acquire().ok())
640            .flatten();
641        assert!(
642            is_main_context_owner || has_acquired_main_context.is_some(),
643            "Async operations only allowed if the thread is owning the MainContext"
644        );
645
646        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
647            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
648        unsafe extern "C" fn handshake_async_trampoline<
649            P: FnOnce(Result<(), glib::Error>) + 'static,
650        >(
651            _source_object: *mut glib::gobject_ffi::GObject,
652            res: *mut crate::ffi::GAsyncResult,
653            user_data: glib::ffi::gpointer,
654        ) {
655            unsafe {
656                let mut error = std::ptr::null_mut();
657                ffi::g_dtls_connection_handshake_finish(_source_object as *mut _, res, &mut error);
658                let result = if error.is_null() {
659                    Ok(())
660                } else {
661                    Err(from_glib_full(error))
662                };
663                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
664                    Box_::from_raw(user_data as *mut _);
665                let callback: P = callback.into_inner();
666                callback(result);
667            }
668        }
669        let callback = handshake_async_trampoline::<P>;
670        unsafe {
671            ffi::g_dtls_connection_handshake_async(
672                self.as_ref().to_glib_none().0,
673                io_priority.into_glib(),
674                cancellable.map(|p| p.as_ref()).to_glib_none().0,
675                Some(callback),
676                Box_::into_raw(user_data) as *mut _,
677            );
678        }
679    }
680
681    fn handshake_future(
682        &self,
683        io_priority: glib::Priority,
684    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
685        Box_::pin(crate::GioFuture::new(
686            self,
687            move |obj, cancellable, send| {
688                obj.handshake_async(io_priority, Some(cancellable), move |res| {
689                    send.resolve(res);
690                });
691            },
692        ))
693    }
694
695    /// Sets the list of application-layer protocols to advertise that the
696    /// caller is willing to speak on this connection. The
697    /// Application-Layer Protocol Negotiation (ALPN) extension will be
698    /// used to negotiate a compatible protocol with the peer; use
699    /// g_dtls_connection_get_negotiated_protocol() to find the negotiated
700    /// protocol after the handshake.  Specifying [`None`] for the the value
701    /// of @protocols will disable ALPN negotiation.
702    ///
703    /// See [IANA TLS ALPN Protocol IDs](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
704    /// for a list of registered protocol IDs.
705    /// ## `protocols`
706    /// a [`None`]-terminated
707    ///   array of ALPN protocol names (eg, "http/1.1", "h2"), or [`None`]
708    #[cfg(feature = "v2_60")]
709    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
710    #[doc(alias = "g_dtls_connection_set_advertised_protocols")]
711    #[doc(alias = "advertised-protocols")]
712    fn set_advertised_protocols(&self, protocols: &[&str]) {
713        unsafe {
714            ffi::g_dtls_connection_set_advertised_protocols(
715                self.as_ref().to_glib_none().0,
716                protocols.to_glib_none().0,
717            );
718        }
719    }
720
721    /// This sets the certificate that @self will present to its peer
722    /// during the TLS handshake. For a #GDtlsServerConnection, it is
723    /// mandatory to set this, and that will normally be done at construct
724    /// time.
725    ///
726    /// For a #GDtlsClientConnection, this is optional. If a handshake fails
727    /// with [`TlsError::CertificateRequired`][crate::TlsError::CertificateRequired], that means that the server
728    /// requires a certificate, and if you try connecting again, you should
729    /// call this method first. You can call
730    /// g_dtls_client_connection_get_accepted_cas() on the failed connection
731    /// to get a list of Certificate Authorities that the server will
732    /// accept certificates from.
733    ///
734    /// (It is also possible that a server will allow the connection with
735    /// or without a certificate; in that case, if you don't provide a
736    /// certificate, you can tell that the server requested one by the fact
737    /// that g_dtls_client_connection_get_accepted_cas() will return
738    /// non-[`None`].)
739    /// ## `certificate`
740    /// the certificate to use for @self
741    #[doc(alias = "g_dtls_connection_set_certificate")]
742    #[doc(alias = "certificate")]
743    fn set_certificate(&self, certificate: &impl IsA<TlsCertificate>) {
744        unsafe {
745            ffi::g_dtls_connection_set_certificate(
746                self.as_ref().to_glib_none().0,
747                certificate.as_ref().to_glib_none().0,
748            );
749        }
750    }
751
752    /// Sets the certificate database that is used to verify peer certificates.
753    /// This is set to the default database by default. See
754    /// g_tls_backend_get_default_database(). If set to [`None`], then
755    /// peer certificate validation will always set the
756    /// [`TlsCertificateFlags::UNKNOWN_CA`][crate::TlsCertificateFlags::UNKNOWN_CA] error (meaning
757    /// #GDtlsConnection::accept-certificate will always be emitted on
758    /// client-side connections, unless that bit is not set in
759    /// #GDtlsClientConnection:validation-flags).
760    ///
761    /// There are nonintuitive security implications when using a non-default
762    /// database. See #GDtlsConnection:database for details.
763    /// ## `database`
764    /// a #GTlsDatabase
765    #[doc(alias = "g_dtls_connection_set_database")]
766    #[doc(alias = "database")]
767    fn set_database(&self, database: Option<&impl IsA<TlsDatabase>>) {
768        unsafe {
769            ffi::g_dtls_connection_set_database(
770                self.as_ref().to_glib_none().0,
771                database.map(|p| p.as_ref()).to_glib_none().0,
772            );
773        }
774    }
775
776    /// Set the object that will be used to interact with the user. It will be used
777    /// for things like prompting the user for passwords.
778    ///
779    /// The @interaction argument will normally be a derived subclass of
780    /// #GTlsInteraction. [`None`] can also be provided if no user interaction
781    /// should occur for this connection.
782    /// ## `interaction`
783    /// an interaction object, or [`None`]
784    #[doc(alias = "g_dtls_connection_set_interaction")]
785    #[doc(alias = "interaction")]
786    fn set_interaction(&self, interaction: Option<&impl IsA<TlsInteraction>>) {
787        unsafe {
788            ffi::g_dtls_connection_set_interaction(
789                self.as_ref().to_glib_none().0,
790                interaction.map(|p| p.as_ref()).to_glib_none().0,
791            );
792        }
793    }
794
795    /// Since GLib 2.64, changing the rehandshake mode is no longer supported
796    /// and will have no effect. With TLS 1.3, rehandshaking has been removed from
797    /// the TLS protocol, replaced by separate post-handshake authentication and
798    /// rekey operations.
799    ///
800    /// # Deprecated since 2.60
801    ///
802    /// Changing the rehandshake mode is no longer
803    ///   required for compatibility. Also, rehandshaking has been removed
804    ///   from the TLS protocol in TLS 1.3.
805    /// ## `mode`
806    /// the rehandshaking mode
807    #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
808    #[allow(deprecated)]
809    #[doc(alias = "g_dtls_connection_set_rehandshake_mode")]
810    #[doc(alias = "rehandshake-mode")]
811    fn set_rehandshake_mode(&self, mode: TlsRehandshakeMode) {
812        unsafe {
813            ffi::g_dtls_connection_set_rehandshake_mode(
814                self.as_ref().to_glib_none().0,
815                mode.into_glib(),
816            );
817        }
818    }
819
820    /// Sets whether or not @self expects a proper TLS close notification
821    /// before the connection is closed. If this is [`true`] (the default),
822    /// then @self will expect to receive a TLS close notification from its
823    /// peer before the connection is closed, and will return a
824    /// [`TlsError::Eof`][crate::TlsError::Eof] error if the connection is closed without proper
825    /// notification (since this may indicate a network error, or
826    /// man-in-the-middle attack).
827    ///
828    /// In some protocols, the application will know whether or not the
829    /// connection was closed cleanly based on application-level data
830    /// (because the application-level data includes a length field, or is
831    /// somehow self-delimiting); in this case, the close notify is
832    /// redundant and may be omitted. You
833    /// can use g_dtls_connection_set_require_close_notify() to tell @self
834    /// to allow an "unannounced" connection close, in which case the close
835    /// will show up as a 0-length read, as in a non-TLS
836    /// #GDatagramBased, and it is up to the application to check that
837    /// the data has been fully received.
838    ///
839    /// Note that this only affects the behavior when the peer closes the
840    /// connection; when the application calls g_dtls_connection_close_async() on
841    /// @self itself, this will send a close notification regardless of the
842    /// setting of this property. If you explicitly want to do an unclean
843    /// close, you can close @self's #GDtlsConnection:base-socket rather
844    /// than closing @self itself.
845    /// ## `require_close_notify`
846    /// whether or not to require close notification
847    #[doc(alias = "g_dtls_connection_set_require_close_notify")]
848    #[doc(alias = "require-close-notify")]
849    fn set_require_close_notify(&self, require_close_notify: bool) {
850        unsafe {
851            ffi::g_dtls_connection_set_require_close_notify(
852                self.as_ref().to_glib_none().0,
853                require_close_notify.into_glib(),
854            );
855        }
856    }
857
858    /// Shut down part or all of a DTLS connection.
859    ///
860    /// If @shutdown_read is [`true`] then the receiving side of the connection is shut
861    /// down, and further reading is disallowed. Subsequent calls to
862    /// g_datagram_based_receive_messages() will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
863    ///
864    /// If @shutdown_write is [`true`] then the sending side of the connection is shut
865    /// down, and further writing is disallowed. Subsequent calls to
866    /// g_datagram_based_send_messages() will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
867    ///
868    /// It is allowed for both @shutdown_read and @shutdown_write to be TRUE — this
869    /// is equivalent to calling g_dtls_connection_close().
870    ///
871    /// If @cancellable is cancelled, the #GDtlsConnection may be left
872    /// partially-closed and any pending untransmitted data may be lost. Call
873    /// g_dtls_connection_shutdown() again to complete closing the #GDtlsConnection.
874    /// ## `shutdown_read`
875    /// [`true`] to stop reception of incoming datagrams
876    /// ## `shutdown_write`
877    /// [`true`] to stop sending outgoing datagrams
878    /// ## `cancellable`
879    /// a #GCancellable, or [`None`]
880    ///
881    /// # Returns
882    ///
883    /// [`true`] on success, [`false`] otherwise
884    #[doc(alias = "g_dtls_connection_shutdown")]
885    fn shutdown(
886        &self,
887        shutdown_read: bool,
888        shutdown_write: bool,
889        cancellable: Option<&impl IsA<Cancellable>>,
890    ) -> Result<(), glib::Error> {
891        unsafe {
892            let mut error = std::ptr::null_mut();
893            let is_ok = ffi::g_dtls_connection_shutdown(
894                self.as_ref().to_glib_none().0,
895                shutdown_read.into_glib(),
896                shutdown_write.into_glib(),
897                cancellable.map(|p| p.as_ref()).to_glib_none().0,
898                &mut error,
899            );
900            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
901            if error.is_null() {
902                Ok(())
903            } else {
904                Err(from_glib_full(error))
905            }
906        }
907    }
908
909    /// Asynchronously shut down part or all of the DTLS connection. See
910    /// g_dtls_connection_shutdown() for more information.
911    /// ## `shutdown_read`
912    /// [`true`] to stop reception of incoming datagrams
913    /// ## `shutdown_write`
914    /// [`true`] to stop sending outgoing datagrams
915    /// ## `io_priority`
916    /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
917    /// ## `cancellable`
918    /// a #GCancellable, or [`None`]
919    /// ## `callback`
920    /// callback to call when the shutdown operation is complete
921    #[doc(alias = "g_dtls_connection_shutdown_async")]
922    fn shutdown_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
923        &self,
924        shutdown_read: bool,
925        shutdown_write: bool,
926        io_priority: glib::Priority,
927        cancellable: Option<&impl IsA<Cancellable>>,
928        callback: P,
929    ) {
930        let main_context = glib::MainContext::ref_thread_default();
931        let is_main_context_owner = main_context.is_owner();
932        let has_acquired_main_context = (!is_main_context_owner)
933            .then(|| main_context.acquire().ok())
934            .flatten();
935        assert!(
936            is_main_context_owner || has_acquired_main_context.is_some(),
937            "Async operations only allowed if the thread is owning the MainContext"
938        );
939
940        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
941            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
942        unsafe extern "C" fn shutdown_async_trampoline<
943            P: FnOnce(Result<(), glib::Error>) + 'static,
944        >(
945            _source_object: *mut glib::gobject_ffi::GObject,
946            res: *mut crate::ffi::GAsyncResult,
947            user_data: glib::ffi::gpointer,
948        ) {
949            unsafe {
950                let mut error = std::ptr::null_mut();
951                ffi::g_dtls_connection_shutdown_finish(_source_object as *mut _, res, &mut error);
952                let result = if error.is_null() {
953                    Ok(())
954                } else {
955                    Err(from_glib_full(error))
956                };
957                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
958                    Box_::from_raw(user_data as *mut _);
959                let callback: P = callback.into_inner();
960                callback(result);
961            }
962        }
963        let callback = shutdown_async_trampoline::<P>;
964        unsafe {
965            ffi::g_dtls_connection_shutdown_async(
966                self.as_ref().to_glib_none().0,
967                shutdown_read.into_glib(),
968                shutdown_write.into_glib(),
969                io_priority.into_glib(),
970                cancellable.map(|p| p.as_ref()).to_glib_none().0,
971                Some(callback),
972                Box_::into_raw(user_data) as *mut _,
973            );
974        }
975    }
976
977    fn shutdown_future(
978        &self,
979        shutdown_read: bool,
980        shutdown_write: bool,
981        io_priority: glib::Priority,
982    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
983        Box_::pin(crate::GioFuture::new(
984            self,
985            move |obj, cancellable, send| {
986                obj.shutdown_async(
987                    shutdown_read,
988                    shutdown_write,
989                    io_priority,
990                    Some(cancellable),
991                    move |res| {
992                        send.resolve(res);
993                    },
994                );
995            },
996        ))
997    }
998
999    /// The list of application-layer protocols that the connection
1000    /// advertises that it is willing to speak. See
1001    /// g_dtls_connection_set_advertised_protocols().
1002    #[cfg(feature = "v2_60")]
1003    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1004    #[doc(alias = "advertised-protocols")]
1005    fn advertised_protocols(&self) -> Vec<glib::GString> {
1006        ObjectExt::property(self.as_ref(), "advertised-protocols")
1007    }
1008
1009    /// The #GDatagramBased that the connection wraps. Note that this may be any
1010    /// implementation of #GDatagramBased, not just a #GSocket.
1011    #[doc(alias = "base-socket")]
1012    fn base_socket(&self) -> Option<DatagramBased> {
1013        ObjectExt::property(self.as_ref(), "base-socket")
1014    }
1015
1016    /// Emitted during the TLS handshake after the peer certificate has
1017    /// been received. You can examine @peer_cert's certification path by
1018    /// calling g_tls_certificate_get_issuer() on it.
1019    ///
1020    /// For a client-side connection, @peer_cert is the server's
1021    /// certificate, and the signal will only be emitted if the
1022    /// certificate was not acceptable according to @conn's
1023    /// #GDtlsClientConnection:validation_flags. If you would like the
1024    /// certificate to be accepted despite @errors, return [`true`] from the
1025    /// signal handler. Otherwise, if no handler accepts the certificate,
1026    /// the handshake will fail with [`TlsError::BadCertificate`][crate::TlsError::BadCertificate].
1027    ///
1028    /// GLib guarantees that if certificate verification fails, this signal
1029    /// will be emitted with at least one error will be set in @errors, but
1030    /// it does not guarantee that all possible errors will be set.
1031    /// Accordingly, you may not safely decide to ignore any particular
1032    /// type of error. For example, it would be incorrect to ignore
1033    /// [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow expired
1034    /// certificates, because this could potentially be the only error flag
1035    /// set even if other problems exist with the certificate.
1036    ///
1037    /// For a server-side connection, @peer_cert is the certificate
1038    /// presented by the client, if this was requested via the server's
1039    /// #GDtlsServerConnection:authentication_mode. On the server side,
1040    /// the signal is always emitted when the client presents a
1041    /// certificate, and the certificate will only be accepted if a
1042    /// handler returns [`true`].
1043    ///
1044    /// Note that if this signal is emitted as part of asynchronous I/O
1045    /// in the main thread, then you should not attempt to interact with
1046    /// the user before returning from the signal handler. If you want to
1047    /// let the user decide whether or not to accept the certificate, you
1048    /// would have to return [`false`] from the signal handler on the first
1049    /// attempt, and then after the connection attempt returns a
1050    /// [`TlsError::BadCertificate`][crate::TlsError::BadCertificate], you can interact with the user, and
1051    /// if the user decides to accept the certificate, remember that fact,
1052    /// create a new connection, and return [`true`] from the signal handler
1053    /// the next time.
1054    ///
1055    /// If you are doing I/O in another thread, you do not
1056    /// need to worry about this, and can simply block in the signal
1057    /// handler until the UI thread returns an answer.
1058    /// ## `peer_cert`
1059    /// the peer's #GTlsCertificate
1060    /// ## `errors`
1061    /// the problems with @peer_cert.
1062    ///
1063    /// # Returns
1064    ///
1065    /// [`true`] to accept @peer_cert (which will also
1066    /// immediately end the signal emission). [`false`] to allow the signal
1067    /// emission to continue, which will cause the handshake to fail if
1068    /// no one else overrides it.
1069    #[doc(alias = "accept-certificate")]
1070    fn connect_accept_certificate<
1071        F: Fn(&Self, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
1072    >(
1073        &self,
1074        f: F,
1075    ) -> SignalHandlerId {
1076        unsafe extern "C" fn accept_certificate_trampoline<
1077            P: IsA<DtlsConnection>,
1078            F: Fn(&P, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
1079        >(
1080            this: *mut ffi::GDtlsConnection,
1081            peer_cert: *mut ffi::GTlsCertificate,
1082            errors: ffi::GTlsCertificateFlags,
1083            f: glib::ffi::gpointer,
1084        ) -> glib::ffi::gboolean {
1085            unsafe {
1086                let f: &F = &*(f as *const F);
1087                f(
1088                    DtlsConnection::from_glib_borrow(this).unsafe_cast_ref(),
1089                    &from_glib_borrow(peer_cert),
1090                    from_glib(errors),
1091                )
1092                .into_glib()
1093            }
1094        }
1095        unsafe {
1096            let f: Box_<F> = Box_::new(f);
1097            connect_raw(
1098                self.as_ptr() as *mut _,
1099                c"accept-certificate".as_ptr() as *const _,
1100                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1101                    accept_certificate_trampoline::<Self, F> as *const (),
1102                )),
1103                Box_::into_raw(f),
1104            )
1105        }
1106    }
1107
1108    #[cfg(feature = "v2_60")]
1109    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1110    #[doc(alias = "advertised-protocols")]
1111    fn connect_advertised_protocols_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1112        unsafe extern "C" fn notify_advertised_protocols_trampoline<
1113            P: IsA<DtlsConnection>,
1114            F: Fn(&P) + 'static,
1115        >(
1116            this: *mut ffi::GDtlsConnection,
1117            _param_spec: glib::ffi::gpointer,
1118            f: glib::ffi::gpointer,
1119        ) {
1120            unsafe {
1121                let f: &F = &*(f as *const F);
1122                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1123            }
1124        }
1125        unsafe {
1126            let f: Box_<F> = Box_::new(f);
1127            connect_raw(
1128                self.as_ptr() as *mut _,
1129                c"notify::advertised-protocols".as_ptr() as *const _,
1130                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1131                    notify_advertised_protocols_trampoline::<Self, F> as *const (),
1132                )),
1133                Box_::into_raw(f),
1134            )
1135        }
1136    }
1137
1138    #[doc(alias = "certificate")]
1139    fn connect_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1140        unsafe extern "C" fn notify_certificate_trampoline<
1141            P: IsA<DtlsConnection>,
1142            F: Fn(&P) + 'static,
1143        >(
1144            this: *mut ffi::GDtlsConnection,
1145            _param_spec: glib::ffi::gpointer,
1146            f: glib::ffi::gpointer,
1147        ) {
1148            unsafe {
1149                let f: &F = &*(f as *const F);
1150                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1151            }
1152        }
1153        unsafe {
1154            let f: Box_<F> = Box_::new(f);
1155            connect_raw(
1156                self.as_ptr() as *mut _,
1157                c"notify::certificate".as_ptr() as *const _,
1158                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1159                    notify_certificate_trampoline::<Self, F> as *const (),
1160                )),
1161                Box_::into_raw(f),
1162            )
1163        }
1164    }
1165
1166    #[cfg(feature = "v2_70")]
1167    #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
1168    #[doc(alias = "ciphersuite-name")]
1169    fn connect_ciphersuite_name_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1170        unsafe extern "C" fn notify_ciphersuite_name_trampoline<
1171            P: IsA<DtlsConnection>,
1172            F: Fn(&P) + 'static,
1173        >(
1174            this: *mut ffi::GDtlsConnection,
1175            _param_spec: glib::ffi::gpointer,
1176            f: glib::ffi::gpointer,
1177        ) {
1178            unsafe {
1179                let f: &F = &*(f as *const F);
1180                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1181            }
1182        }
1183        unsafe {
1184            let f: Box_<F> = Box_::new(f);
1185            connect_raw(
1186                self.as_ptr() as *mut _,
1187                c"notify::ciphersuite-name".as_ptr() as *const _,
1188                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1189                    notify_ciphersuite_name_trampoline::<Self, F> as *const (),
1190                )),
1191                Box_::into_raw(f),
1192            )
1193        }
1194    }
1195
1196    #[doc(alias = "database")]
1197    fn connect_database_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1198        unsafe extern "C" fn notify_database_trampoline<
1199            P: IsA<DtlsConnection>,
1200            F: Fn(&P) + 'static,
1201        >(
1202            this: *mut ffi::GDtlsConnection,
1203            _param_spec: glib::ffi::gpointer,
1204            f: glib::ffi::gpointer,
1205        ) {
1206            unsafe {
1207                let f: &F = &*(f as *const F);
1208                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1209            }
1210        }
1211        unsafe {
1212            let f: Box_<F> = Box_::new(f);
1213            connect_raw(
1214                self.as_ptr() as *mut _,
1215                c"notify::database".as_ptr() as *const _,
1216                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1217                    notify_database_trampoline::<Self, F> as *const (),
1218                )),
1219                Box_::into_raw(f),
1220            )
1221        }
1222    }
1223
1224    #[doc(alias = "interaction")]
1225    fn connect_interaction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1226        unsafe extern "C" fn notify_interaction_trampoline<
1227            P: IsA<DtlsConnection>,
1228            F: Fn(&P) + 'static,
1229        >(
1230            this: *mut ffi::GDtlsConnection,
1231            _param_spec: glib::ffi::gpointer,
1232            f: glib::ffi::gpointer,
1233        ) {
1234            unsafe {
1235                let f: &F = &*(f as *const F);
1236                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1237            }
1238        }
1239        unsafe {
1240            let f: Box_<F> = Box_::new(f);
1241            connect_raw(
1242                self.as_ptr() as *mut _,
1243                c"notify::interaction".as_ptr() as *const _,
1244                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1245                    notify_interaction_trampoline::<Self, F> as *const (),
1246                )),
1247                Box_::into_raw(f),
1248            )
1249        }
1250    }
1251
1252    #[cfg(feature = "v2_60")]
1253    #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1254    #[doc(alias = "negotiated-protocol")]
1255    fn connect_negotiated_protocol_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1256        unsafe extern "C" fn notify_negotiated_protocol_trampoline<
1257            P: IsA<DtlsConnection>,
1258            F: Fn(&P) + 'static,
1259        >(
1260            this: *mut ffi::GDtlsConnection,
1261            _param_spec: glib::ffi::gpointer,
1262            f: glib::ffi::gpointer,
1263        ) {
1264            unsafe {
1265                let f: &F = &*(f as *const F);
1266                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1267            }
1268        }
1269        unsafe {
1270            let f: Box_<F> = Box_::new(f);
1271            connect_raw(
1272                self.as_ptr() as *mut _,
1273                c"notify::negotiated-protocol".as_ptr() as *const _,
1274                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1275                    notify_negotiated_protocol_trampoline::<Self, F> as *const (),
1276                )),
1277                Box_::into_raw(f),
1278            )
1279        }
1280    }
1281
1282    #[doc(alias = "peer-certificate")]
1283    fn connect_peer_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1284        unsafe extern "C" fn notify_peer_certificate_trampoline<
1285            P: IsA<DtlsConnection>,
1286            F: Fn(&P) + 'static,
1287        >(
1288            this: *mut ffi::GDtlsConnection,
1289            _param_spec: glib::ffi::gpointer,
1290            f: glib::ffi::gpointer,
1291        ) {
1292            unsafe {
1293                let f: &F = &*(f as *const F);
1294                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1295            }
1296        }
1297        unsafe {
1298            let f: Box_<F> = Box_::new(f);
1299            connect_raw(
1300                self.as_ptr() as *mut _,
1301                c"notify::peer-certificate".as_ptr() as *const _,
1302                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1303                    notify_peer_certificate_trampoline::<Self, F> as *const (),
1304                )),
1305                Box_::into_raw(f),
1306            )
1307        }
1308    }
1309
1310    #[doc(alias = "peer-certificate-errors")]
1311    fn connect_peer_certificate_errors_notify<F: Fn(&Self) + 'static>(
1312        &self,
1313        f: F,
1314    ) -> SignalHandlerId {
1315        unsafe extern "C" fn notify_peer_certificate_errors_trampoline<
1316            P: IsA<DtlsConnection>,
1317            F: Fn(&P) + 'static,
1318        >(
1319            this: *mut ffi::GDtlsConnection,
1320            _param_spec: glib::ffi::gpointer,
1321            f: glib::ffi::gpointer,
1322        ) {
1323            unsafe {
1324                let f: &F = &*(f as *const F);
1325                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1326            }
1327        }
1328        unsafe {
1329            let f: Box_<F> = Box_::new(f);
1330            connect_raw(
1331                self.as_ptr() as *mut _,
1332                c"notify::peer-certificate-errors".as_ptr() as *const _,
1333                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1334                    notify_peer_certificate_errors_trampoline::<Self, F> as *const (),
1335                )),
1336                Box_::into_raw(f),
1337            )
1338        }
1339    }
1340
1341    #[cfg(feature = "v2_70")]
1342    #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
1343    #[doc(alias = "protocol-version")]
1344    fn connect_protocol_version_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1345        unsafe extern "C" fn notify_protocol_version_trampoline<
1346            P: IsA<DtlsConnection>,
1347            F: Fn(&P) + 'static,
1348        >(
1349            this: *mut ffi::GDtlsConnection,
1350            _param_spec: glib::ffi::gpointer,
1351            f: glib::ffi::gpointer,
1352        ) {
1353            unsafe {
1354                let f: &F = &*(f as *const F);
1355                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1356            }
1357        }
1358        unsafe {
1359            let f: Box_<F> = Box_::new(f);
1360            connect_raw(
1361                self.as_ptr() as *mut _,
1362                c"notify::protocol-version".as_ptr() as *const _,
1363                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1364                    notify_protocol_version_trampoline::<Self, F> as *const (),
1365                )),
1366                Box_::into_raw(f),
1367            )
1368        }
1369    }
1370
1371    #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
1372    #[doc(alias = "rehandshake-mode")]
1373    fn connect_rehandshake_mode_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1374        unsafe extern "C" fn notify_rehandshake_mode_trampoline<
1375            P: IsA<DtlsConnection>,
1376            F: Fn(&P) + 'static,
1377        >(
1378            this: *mut ffi::GDtlsConnection,
1379            _param_spec: glib::ffi::gpointer,
1380            f: glib::ffi::gpointer,
1381        ) {
1382            unsafe {
1383                let f: &F = &*(f as *const F);
1384                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1385            }
1386        }
1387        unsafe {
1388            let f: Box_<F> = Box_::new(f);
1389            connect_raw(
1390                self.as_ptr() as *mut _,
1391                c"notify::rehandshake-mode".as_ptr() as *const _,
1392                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1393                    notify_rehandshake_mode_trampoline::<Self, F> as *const (),
1394                )),
1395                Box_::into_raw(f),
1396            )
1397        }
1398    }
1399
1400    #[doc(alias = "require-close-notify")]
1401    fn connect_require_close_notify_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1402        unsafe extern "C" fn notify_require_close_notify_trampoline<
1403            P: IsA<DtlsConnection>,
1404            F: Fn(&P) + 'static,
1405        >(
1406            this: *mut ffi::GDtlsConnection,
1407            _param_spec: glib::ffi::gpointer,
1408            f: glib::ffi::gpointer,
1409        ) {
1410            unsafe {
1411                let f: &F = &*(f as *const F);
1412                f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1413            }
1414        }
1415        unsafe {
1416            let f: Box_<F> = Box_::new(f);
1417            connect_raw(
1418                self.as_ptr() as *mut _,
1419                c"notify::require-close-notify".as_ptr() as *const _,
1420                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1421                    notify_require_close_notify_trampoline::<Self, F> as *const (),
1422                )),
1423                Box_::into_raw(f),
1424            )
1425        }
1426    }
1427}
1428
1429impl<O: IsA<DtlsConnection>> DtlsConnectionExt for O {}