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