gio/auto/
dtls_connection.rs

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