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