Skip to main content

gio/auto/
dtls_connection.rs

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