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