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