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