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 let _ = 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 let _ =
660 ffi::g_dtls_connection_handshake_finish(_source_object as *mut _, res, &mut error);
661 let result = if error.is_null() {
662 Ok(())
663 } else {
664 Err(from_glib_full(error))
665 };
666 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
667 Box_::from_raw(user_data as *mut _);
668 let callback: P = callback.into_inner();
669 callback(result);
670 }
671 let callback = handshake_async_trampoline::<P>;
672 unsafe {
673 ffi::g_dtls_connection_handshake_async(
674 self.as_ref().to_glib_none().0,
675 io_priority.into_glib(),
676 cancellable.map(|p| p.as_ref()).to_glib_none().0,
677 Some(callback),
678 Box_::into_raw(user_data) as *mut _,
679 );
680 }
681 }
682
683 fn handshake_future(
684 &self,
685 io_priority: glib::Priority,
686 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
687 Box_::pin(crate::GioFuture::new(
688 self,
689 move |obj, cancellable, send| {
690 obj.handshake_async(io_priority, Some(cancellable), move |res| {
691 send.resolve(res);
692 });
693 },
694 ))
695 }
696
697 /// Sets the list of application-layer protocols to advertise that the
698 /// caller is willing to speak on this connection. The
699 /// Application-Layer Protocol Negotiation (ALPN) extension will be
700 /// used to negotiate a compatible protocol with the peer; use
701 /// g_dtls_connection_get_negotiated_protocol() to find the negotiated
702 /// protocol after the handshake. Specifying [`None`] for the the value
703 /// of @protocols will disable ALPN negotiation.
704 ///
705 /// See [IANA TLS ALPN Protocol IDs](https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids)
706 /// for a list of registered protocol IDs.
707 /// ## `protocols`
708 /// a [`None`]-terminated
709 /// array of ALPN protocol names (eg, "http/1.1", "h2"), or [`None`]
710 #[cfg(feature = "v2_60")]
711 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
712 #[doc(alias = "g_dtls_connection_set_advertised_protocols")]
713 #[doc(alias = "advertised-protocols")]
714 fn set_advertised_protocols(&self, protocols: &[&str]) {
715 unsafe {
716 ffi::g_dtls_connection_set_advertised_protocols(
717 self.as_ref().to_glib_none().0,
718 protocols.to_glib_none().0,
719 );
720 }
721 }
722
723 /// This sets the certificate that @self will present to its peer
724 /// during the TLS handshake. For a #GDtlsServerConnection, it is
725 /// mandatory to set this, and that will normally be done at construct
726 /// time.
727 ///
728 /// For a #GDtlsClientConnection, this is optional. If a handshake fails
729 /// with [`TlsError::CertificateRequired`][crate::TlsError::CertificateRequired], that means that the server
730 /// requires a certificate, and if you try connecting again, you should
731 /// call this method first. You can call
732 /// g_dtls_client_connection_get_accepted_cas() on the failed connection
733 /// to get a list of Certificate Authorities that the server will
734 /// accept certificates from.
735 ///
736 /// (It is also possible that a server will allow the connection with
737 /// or without a certificate; in that case, if you don't provide a
738 /// certificate, you can tell that the server requested one by the fact
739 /// that g_dtls_client_connection_get_accepted_cas() will return
740 /// non-[`None`].)
741 /// ## `certificate`
742 /// the certificate to use for @self
743 #[doc(alias = "g_dtls_connection_set_certificate")]
744 #[doc(alias = "certificate")]
745 fn set_certificate(&self, certificate: &impl IsA<TlsCertificate>) {
746 unsafe {
747 ffi::g_dtls_connection_set_certificate(
748 self.as_ref().to_glib_none().0,
749 certificate.as_ref().to_glib_none().0,
750 );
751 }
752 }
753
754 /// Sets the certificate database that is used to verify peer certificates.
755 /// This is set to the default database by default. See
756 /// g_tls_backend_get_default_database(). If set to [`None`], then
757 /// peer certificate validation will always set the
758 /// [`TlsCertificateFlags::UNKNOWN_CA`][crate::TlsCertificateFlags::UNKNOWN_CA] error (meaning
759 /// #GDtlsConnection::accept-certificate will always be emitted on
760 /// client-side connections, unless that bit is not set in
761 /// #GDtlsClientConnection:validation-flags).
762 ///
763 /// There are nonintuitive security implications when using a non-default
764 /// database. See #GDtlsConnection:database for details.
765 /// ## `database`
766 /// a #GTlsDatabase
767 #[doc(alias = "g_dtls_connection_set_database")]
768 #[doc(alias = "database")]
769 fn set_database(&self, database: Option<&impl IsA<TlsDatabase>>) {
770 unsafe {
771 ffi::g_dtls_connection_set_database(
772 self.as_ref().to_glib_none().0,
773 database.map(|p| p.as_ref()).to_glib_none().0,
774 );
775 }
776 }
777
778 /// Set the object that will be used to interact with the user. It will be used
779 /// for things like prompting the user for passwords.
780 ///
781 /// The @interaction argument will normally be a derived subclass of
782 /// #GTlsInteraction. [`None`] can also be provided if no user interaction
783 /// should occur for this connection.
784 /// ## `interaction`
785 /// an interaction object, or [`None`]
786 #[doc(alias = "g_dtls_connection_set_interaction")]
787 #[doc(alias = "interaction")]
788 fn set_interaction(&self, interaction: Option<&impl IsA<TlsInteraction>>) {
789 unsafe {
790 ffi::g_dtls_connection_set_interaction(
791 self.as_ref().to_glib_none().0,
792 interaction.map(|p| p.as_ref()).to_glib_none().0,
793 );
794 }
795 }
796
797 /// Since GLib 2.64, changing the rehandshake mode is no longer supported
798 /// and will have no effect. With TLS 1.3, rehandshaking has been removed from
799 /// the TLS protocol, replaced by separate post-handshake authentication and
800 /// rekey operations.
801 ///
802 /// # Deprecated since 2.60
803 ///
804 /// Changing the rehandshake mode is no longer
805 /// required for compatibility. Also, rehandshaking has been removed
806 /// from the TLS protocol in TLS 1.3.
807 /// ## `mode`
808 /// the rehandshaking mode
809 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
810 #[allow(deprecated)]
811 #[doc(alias = "g_dtls_connection_set_rehandshake_mode")]
812 #[doc(alias = "rehandshake-mode")]
813 fn set_rehandshake_mode(&self, mode: TlsRehandshakeMode) {
814 unsafe {
815 ffi::g_dtls_connection_set_rehandshake_mode(
816 self.as_ref().to_glib_none().0,
817 mode.into_glib(),
818 );
819 }
820 }
821
822 /// Sets whether or not @self expects a proper TLS close notification
823 /// before the connection is closed. If this is [`true`] (the default),
824 /// then @self will expect to receive a TLS close notification from its
825 /// peer before the connection is closed, and will return a
826 /// [`TlsError::Eof`][crate::TlsError::Eof] error if the connection is closed without proper
827 /// notification (since this may indicate a network error, or
828 /// man-in-the-middle attack).
829 ///
830 /// In some protocols, the application will know whether or not the
831 /// connection was closed cleanly based on application-level data
832 /// (because the application-level data includes a length field, or is
833 /// somehow self-delimiting); in this case, the close notify is
834 /// redundant and may be omitted. You
835 /// can use g_dtls_connection_set_require_close_notify() to tell @self
836 /// to allow an "unannounced" connection close, in which case the close
837 /// will show up as a 0-length read, as in a non-TLS
838 /// #GDatagramBased, and it is up to the application to check that
839 /// the data has been fully received.
840 ///
841 /// Note that this only affects the behavior when the peer closes the
842 /// connection; when the application calls g_dtls_connection_close_async() on
843 /// @self itself, this will send a close notification regardless of the
844 /// setting of this property. If you explicitly want to do an unclean
845 /// close, you can close @self's #GDtlsConnection:base-socket rather
846 /// than closing @self itself.
847 /// ## `require_close_notify`
848 /// whether or not to require close notification
849 #[doc(alias = "g_dtls_connection_set_require_close_notify")]
850 #[doc(alias = "require-close-notify")]
851 fn set_require_close_notify(&self, require_close_notify: bool) {
852 unsafe {
853 ffi::g_dtls_connection_set_require_close_notify(
854 self.as_ref().to_glib_none().0,
855 require_close_notify.into_glib(),
856 );
857 }
858 }
859
860 /// Shut down part or all of a DTLS connection.
861 ///
862 /// If @shutdown_read is [`true`] then the receiving side of the connection is shut
863 /// down, and further reading is disallowed. Subsequent calls to
864 /// g_datagram_based_receive_messages() will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
865 ///
866 /// If @shutdown_write is [`true`] then the sending side of the connection is shut
867 /// down, and further writing is disallowed. Subsequent calls to
868 /// g_datagram_based_send_messages() will return [`IOErrorEnum::Closed`][crate::IOErrorEnum::Closed].
869 ///
870 /// It is allowed for both @shutdown_read and @shutdown_write to be TRUE — this
871 /// is equivalent to calling g_dtls_connection_close().
872 ///
873 /// If @cancellable is cancelled, the #GDtlsConnection may be left
874 /// partially-closed and any pending untransmitted data may be lost. Call
875 /// g_dtls_connection_shutdown() again to complete closing the #GDtlsConnection.
876 /// ## `shutdown_read`
877 /// [`true`] to stop reception of incoming datagrams
878 /// ## `shutdown_write`
879 /// [`true`] to stop sending outgoing datagrams
880 /// ## `cancellable`
881 /// a #GCancellable, or [`None`]
882 ///
883 /// # Returns
884 ///
885 /// [`true`] on success, [`false`] otherwise
886 #[doc(alias = "g_dtls_connection_shutdown")]
887 fn shutdown(
888 &self,
889 shutdown_read: bool,
890 shutdown_write: bool,
891 cancellable: Option<&impl IsA<Cancellable>>,
892 ) -> Result<(), glib::Error> {
893 unsafe {
894 let mut error = std::ptr::null_mut();
895 let is_ok = ffi::g_dtls_connection_shutdown(
896 self.as_ref().to_glib_none().0,
897 shutdown_read.into_glib(),
898 shutdown_write.into_glib(),
899 cancellable.map(|p| p.as_ref()).to_glib_none().0,
900 &mut error,
901 );
902 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
903 if error.is_null() {
904 Ok(())
905 } else {
906 Err(from_glib_full(error))
907 }
908 }
909 }
910
911 /// Asynchronously shut down part or all of the DTLS connection. See
912 /// g_dtls_connection_shutdown() for more information.
913 /// ## `shutdown_read`
914 /// [`true`] to stop reception of incoming datagrams
915 /// ## `shutdown_write`
916 /// [`true`] to stop sending outgoing datagrams
917 /// ## `io_priority`
918 /// the [I/O priority](iface.AsyncResult.html#io-priority) of the request
919 /// ## `cancellable`
920 /// a #GCancellable, or [`None`]
921 /// ## `callback`
922 /// callback to call when the shutdown operation is complete
923 #[doc(alias = "g_dtls_connection_shutdown_async")]
924 fn shutdown_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
925 &self,
926 shutdown_read: bool,
927 shutdown_write: bool,
928 io_priority: glib::Priority,
929 cancellable: Option<&impl IsA<Cancellable>>,
930 callback: P,
931 ) {
932 let main_context = glib::MainContext::ref_thread_default();
933 let is_main_context_owner = main_context.is_owner();
934 let has_acquired_main_context = (!is_main_context_owner)
935 .then(|| main_context.acquire().ok())
936 .flatten();
937 assert!(
938 is_main_context_owner || has_acquired_main_context.is_some(),
939 "Async operations only allowed if the thread is owning the MainContext"
940 );
941
942 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
943 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
944 unsafe extern "C" fn shutdown_async_trampoline<
945 P: FnOnce(Result<(), glib::Error>) + 'static,
946 >(
947 _source_object: *mut glib::gobject_ffi::GObject,
948 res: *mut crate::ffi::GAsyncResult,
949 user_data: glib::ffi::gpointer,
950 ) {
951 let mut error = std::ptr::null_mut();
952 let _ =
953 ffi::g_dtls_connection_shutdown_finish(_source_object as *mut _, res, &mut error);
954 let result = if error.is_null() {
955 Ok(())
956 } else {
957 Err(from_glib_full(error))
958 };
959 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
960 Box_::from_raw(user_data as *mut _);
961 let callback: P = callback.into_inner();
962 callback(result);
963 }
964 let callback = shutdown_async_trampoline::<P>;
965 unsafe {
966 ffi::g_dtls_connection_shutdown_async(
967 self.as_ref().to_glib_none().0,
968 shutdown_read.into_glib(),
969 shutdown_write.into_glib(),
970 io_priority.into_glib(),
971 cancellable.map(|p| p.as_ref()).to_glib_none().0,
972 Some(callback),
973 Box_::into_raw(user_data) as *mut _,
974 );
975 }
976 }
977
978 fn shutdown_future(
979 &self,
980 shutdown_read: bool,
981 shutdown_write: bool,
982 io_priority: glib::Priority,
983 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
984 Box_::pin(crate::GioFuture::new(
985 self,
986 move |obj, cancellable, send| {
987 obj.shutdown_async(
988 shutdown_read,
989 shutdown_write,
990 io_priority,
991 Some(cancellable),
992 move |res| {
993 send.resolve(res);
994 },
995 );
996 },
997 ))
998 }
999
1000 /// The list of application-layer protocols that the connection
1001 /// advertises that it is willing to speak. See
1002 /// g_dtls_connection_set_advertised_protocols().
1003 #[cfg(feature = "v2_60")]
1004 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1005 #[doc(alias = "advertised-protocols")]
1006 fn advertised_protocols(&self) -> Vec<glib::GString> {
1007 ObjectExt::property(self.as_ref(), "advertised-protocols")
1008 }
1009
1010 /// The #GDatagramBased that the connection wraps. Note that this may be any
1011 /// implementation of #GDatagramBased, not just a #GSocket.
1012 #[doc(alias = "base-socket")]
1013 fn base_socket(&self) -> Option<DatagramBased> {
1014 ObjectExt::property(self.as_ref(), "base-socket")
1015 }
1016
1017 /// Emitted during the TLS handshake after the peer certificate has
1018 /// been received. You can examine @peer_cert's certification path by
1019 /// calling g_tls_certificate_get_issuer() on it.
1020 ///
1021 /// For a client-side connection, @peer_cert is the server's
1022 /// certificate, and the signal will only be emitted if the
1023 /// certificate was not acceptable according to @conn's
1024 /// #GDtlsClientConnection:validation_flags. If you would like the
1025 /// certificate to be accepted despite @errors, return [`true`] from the
1026 /// signal handler. Otherwise, if no handler accepts the certificate,
1027 /// the handshake will fail with [`TlsError::BadCertificate`][crate::TlsError::BadCertificate].
1028 ///
1029 /// GLib guarantees that if certificate verification fails, this signal
1030 /// will be emitted with at least one error will be set in @errors, but
1031 /// it does not guarantee that all possible errors will be set.
1032 /// Accordingly, you may not safely decide to ignore any particular
1033 /// type of error. For example, it would be incorrect to ignore
1034 /// [`TlsCertificateFlags::EXPIRED`][crate::TlsCertificateFlags::EXPIRED] if you want to allow expired
1035 /// certificates, because this could potentially be the only error flag
1036 /// set even if other problems exist with the certificate.
1037 ///
1038 /// For a server-side connection, @peer_cert is the certificate
1039 /// presented by the client, if this was requested via the server's
1040 /// #GDtlsServerConnection:authentication_mode. On the server side,
1041 /// the signal is always emitted when the client presents a
1042 /// certificate, and the certificate will only be accepted if a
1043 /// handler returns [`true`].
1044 ///
1045 /// Note that if this signal is emitted as part of asynchronous I/O
1046 /// in the main thread, then you should not attempt to interact with
1047 /// the user before returning from the signal handler. If you want to
1048 /// let the user decide whether or not to accept the certificate, you
1049 /// would have to return [`false`] from the signal handler on the first
1050 /// attempt, and then after the connection attempt returns a
1051 /// [`TlsError::BadCertificate`][crate::TlsError::BadCertificate], you can interact with the user, and
1052 /// if the user decides to accept the certificate, remember that fact,
1053 /// create a new connection, and return [`true`] from the signal handler
1054 /// the next time.
1055 ///
1056 /// If you are doing I/O in another thread, you do not
1057 /// need to worry about this, and can simply block in the signal
1058 /// handler until the UI thread returns an answer.
1059 /// ## `peer_cert`
1060 /// the peer's #GTlsCertificate
1061 /// ## `errors`
1062 /// the problems with @peer_cert.
1063 ///
1064 /// # Returns
1065 ///
1066 /// [`true`] to accept @peer_cert (which will also
1067 /// immediately end the signal emission). [`false`] to allow the signal
1068 /// emission to continue, which will cause the handshake to fail if
1069 /// no one else overrides it.
1070 #[doc(alias = "accept-certificate")]
1071 fn connect_accept_certificate<
1072 F: Fn(&Self, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
1073 >(
1074 &self,
1075 f: F,
1076 ) -> SignalHandlerId {
1077 unsafe extern "C" fn accept_certificate_trampoline<
1078 P: IsA<DtlsConnection>,
1079 F: Fn(&P, &TlsCertificate, TlsCertificateFlags) -> bool + 'static,
1080 >(
1081 this: *mut ffi::GDtlsConnection,
1082 peer_cert: *mut ffi::GTlsCertificate,
1083 errors: ffi::GTlsCertificateFlags,
1084 f: glib::ffi::gpointer,
1085 ) -> glib::ffi::gboolean {
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 unsafe {
1095 let f: Box_<F> = Box_::new(f);
1096 connect_raw(
1097 self.as_ptr() as *mut _,
1098 b"accept-certificate\0".as_ptr() as *const _,
1099 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1100 accept_certificate_trampoline::<Self, F> as *const (),
1101 )),
1102 Box_::into_raw(f),
1103 )
1104 }
1105 }
1106
1107 #[cfg(feature = "v2_60")]
1108 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1109 #[doc(alias = "advertised-protocols")]
1110 fn connect_advertised_protocols_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1111 unsafe extern "C" fn notify_advertised_protocols_trampoline<
1112 P: IsA<DtlsConnection>,
1113 F: Fn(&P) + 'static,
1114 >(
1115 this: *mut ffi::GDtlsConnection,
1116 _param_spec: glib::ffi::gpointer,
1117 f: glib::ffi::gpointer,
1118 ) {
1119 let f: &F = &*(f as *const F);
1120 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1121 }
1122 unsafe {
1123 let f: Box_<F> = Box_::new(f);
1124 connect_raw(
1125 self.as_ptr() as *mut _,
1126 b"notify::advertised-protocols\0".as_ptr() as *const _,
1127 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1128 notify_advertised_protocols_trampoline::<Self, F> as *const (),
1129 )),
1130 Box_::into_raw(f),
1131 )
1132 }
1133 }
1134
1135 #[doc(alias = "certificate")]
1136 fn connect_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1137 unsafe extern "C" fn notify_certificate_trampoline<
1138 P: IsA<DtlsConnection>,
1139 F: Fn(&P) + 'static,
1140 >(
1141 this: *mut ffi::GDtlsConnection,
1142 _param_spec: glib::ffi::gpointer,
1143 f: glib::ffi::gpointer,
1144 ) {
1145 let f: &F = &*(f as *const F);
1146 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1147 }
1148 unsafe {
1149 let f: Box_<F> = Box_::new(f);
1150 connect_raw(
1151 self.as_ptr() as *mut _,
1152 b"notify::certificate\0".as_ptr() as *const _,
1153 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1154 notify_certificate_trampoline::<Self, F> as *const (),
1155 )),
1156 Box_::into_raw(f),
1157 )
1158 }
1159 }
1160
1161 #[cfg(feature = "v2_70")]
1162 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
1163 #[doc(alias = "ciphersuite-name")]
1164 fn connect_ciphersuite_name_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1165 unsafe extern "C" fn notify_ciphersuite_name_trampoline<
1166 P: IsA<DtlsConnection>,
1167 F: Fn(&P) + 'static,
1168 >(
1169 this: *mut ffi::GDtlsConnection,
1170 _param_spec: glib::ffi::gpointer,
1171 f: glib::ffi::gpointer,
1172 ) {
1173 let f: &F = &*(f as *const F);
1174 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1175 }
1176 unsafe {
1177 let f: Box_<F> = Box_::new(f);
1178 connect_raw(
1179 self.as_ptr() as *mut _,
1180 b"notify::ciphersuite-name\0".as_ptr() as *const _,
1181 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1182 notify_ciphersuite_name_trampoline::<Self, F> as *const (),
1183 )),
1184 Box_::into_raw(f),
1185 )
1186 }
1187 }
1188
1189 #[doc(alias = "database")]
1190 fn connect_database_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1191 unsafe extern "C" fn notify_database_trampoline<
1192 P: IsA<DtlsConnection>,
1193 F: Fn(&P) + 'static,
1194 >(
1195 this: *mut ffi::GDtlsConnection,
1196 _param_spec: glib::ffi::gpointer,
1197 f: glib::ffi::gpointer,
1198 ) {
1199 let f: &F = &*(f as *const F);
1200 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1201 }
1202 unsafe {
1203 let f: Box_<F> = Box_::new(f);
1204 connect_raw(
1205 self.as_ptr() as *mut _,
1206 b"notify::database\0".as_ptr() as *const _,
1207 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1208 notify_database_trampoline::<Self, F> as *const (),
1209 )),
1210 Box_::into_raw(f),
1211 )
1212 }
1213 }
1214
1215 #[doc(alias = "interaction")]
1216 fn connect_interaction_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1217 unsafe extern "C" fn notify_interaction_trampoline<
1218 P: IsA<DtlsConnection>,
1219 F: Fn(&P) + 'static,
1220 >(
1221 this: *mut ffi::GDtlsConnection,
1222 _param_spec: glib::ffi::gpointer,
1223 f: glib::ffi::gpointer,
1224 ) {
1225 let f: &F = &*(f as *const F);
1226 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1227 }
1228 unsafe {
1229 let f: Box_<F> = Box_::new(f);
1230 connect_raw(
1231 self.as_ptr() as *mut _,
1232 b"notify::interaction\0".as_ptr() as *const _,
1233 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1234 notify_interaction_trampoline::<Self, F> as *const (),
1235 )),
1236 Box_::into_raw(f),
1237 )
1238 }
1239 }
1240
1241 #[cfg(feature = "v2_60")]
1242 #[cfg_attr(docsrs, doc(cfg(feature = "v2_60")))]
1243 #[doc(alias = "negotiated-protocol")]
1244 fn connect_negotiated_protocol_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1245 unsafe extern "C" fn notify_negotiated_protocol_trampoline<
1246 P: IsA<DtlsConnection>,
1247 F: Fn(&P) + 'static,
1248 >(
1249 this: *mut ffi::GDtlsConnection,
1250 _param_spec: glib::ffi::gpointer,
1251 f: glib::ffi::gpointer,
1252 ) {
1253 let f: &F = &*(f as *const F);
1254 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1255 }
1256 unsafe {
1257 let f: Box_<F> = Box_::new(f);
1258 connect_raw(
1259 self.as_ptr() as *mut _,
1260 b"notify::negotiated-protocol\0".as_ptr() as *const _,
1261 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1262 notify_negotiated_protocol_trampoline::<Self, F> as *const (),
1263 )),
1264 Box_::into_raw(f),
1265 )
1266 }
1267 }
1268
1269 #[doc(alias = "peer-certificate")]
1270 fn connect_peer_certificate_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1271 unsafe extern "C" fn notify_peer_certificate_trampoline<
1272 P: IsA<DtlsConnection>,
1273 F: Fn(&P) + 'static,
1274 >(
1275 this: *mut ffi::GDtlsConnection,
1276 _param_spec: glib::ffi::gpointer,
1277 f: glib::ffi::gpointer,
1278 ) {
1279 let f: &F = &*(f as *const F);
1280 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1281 }
1282 unsafe {
1283 let f: Box_<F> = Box_::new(f);
1284 connect_raw(
1285 self.as_ptr() as *mut _,
1286 b"notify::peer-certificate\0".as_ptr() as *const _,
1287 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1288 notify_peer_certificate_trampoline::<Self, F> as *const (),
1289 )),
1290 Box_::into_raw(f),
1291 )
1292 }
1293 }
1294
1295 #[doc(alias = "peer-certificate-errors")]
1296 fn connect_peer_certificate_errors_notify<F: Fn(&Self) + 'static>(
1297 &self,
1298 f: F,
1299 ) -> SignalHandlerId {
1300 unsafe extern "C" fn notify_peer_certificate_errors_trampoline<
1301 P: IsA<DtlsConnection>,
1302 F: Fn(&P) + 'static,
1303 >(
1304 this: *mut ffi::GDtlsConnection,
1305 _param_spec: glib::ffi::gpointer,
1306 f: glib::ffi::gpointer,
1307 ) {
1308 let f: &F = &*(f as *const F);
1309 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1310 }
1311 unsafe {
1312 let f: Box_<F> = Box_::new(f);
1313 connect_raw(
1314 self.as_ptr() as *mut _,
1315 b"notify::peer-certificate-errors\0".as_ptr() as *const _,
1316 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1317 notify_peer_certificate_errors_trampoline::<Self, F> as *const (),
1318 )),
1319 Box_::into_raw(f),
1320 )
1321 }
1322 }
1323
1324 #[cfg(feature = "v2_70")]
1325 #[cfg_attr(docsrs, doc(cfg(feature = "v2_70")))]
1326 #[doc(alias = "protocol-version")]
1327 fn connect_protocol_version_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1328 unsafe extern "C" fn notify_protocol_version_trampoline<
1329 P: IsA<DtlsConnection>,
1330 F: Fn(&P) + 'static,
1331 >(
1332 this: *mut ffi::GDtlsConnection,
1333 _param_spec: glib::ffi::gpointer,
1334 f: glib::ffi::gpointer,
1335 ) {
1336 let f: &F = &*(f as *const F);
1337 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1338 }
1339 unsafe {
1340 let f: Box_<F> = Box_::new(f);
1341 connect_raw(
1342 self.as_ptr() as *mut _,
1343 b"notify::protocol-version\0".as_ptr() as *const _,
1344 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1345 notify_protocol_version_trampoline::<Self, F> as *const (),
1346 )),
1347 Box_::into_raw(f),
1348 )
1349 }
1350 }
1351
1352 #[cfg_attr(feature = "v2_60", deprecated = "Since 2.60")]
1353 #[doc(alias = "rehandshake-mode")]
1354 fn connect_rehandshake_mode_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1355 unsafe extern "C" fn notify_rehandshake_mode_trampoline<
1356 P: IsA<DtlsConnection>,
1357 F: Fn(&P) + 'static,
1358 >(
1359 this: *mut ffi::GDtlsConnection,
1360 _param_spec: glib::ffi::gpointer,
1361 f: glib::ffi::gpointer,
1362 ) {
1363 let f: &F = &*(f as *const F);
1364 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1365 }
1366 unsafe {
1367 let f: Box_<F> = Box_::new(f);
1368 connect_raw(
1369 self.as_ptr() as *mut _,
1370 b"notify::rehandshake-mode\0".as_ptr() as *const _,
1371 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1372 notify_rehandshake_mode_trampoline::<Self, F> as *const (),
1373 )),
1374 Box_::into_raw(f),
1375 )
1376 }
1377 }
1378
1379 #[doc(alias = "require-close-notify")]
1380 fn connect_require_close_notify_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
1381 unsafe extern "C" fn notify_require_close_notify_trampoline<
1382 P: IsA<DtlsConnection>,
1383 F: Fn(&P) + 'static,
1384 >(
1385 this: *mut ffi::GDtlsConnection,
1386 _param_spec: glib::ffi::gpointer,
1387 f: glib::ffi::gpointer,
1388 ) {
1389 let f: &F = &*(f as *const F);
1390 f(DtlsConnection::from_glib_borrow(this).unsafe_cast_ref())
1391 }
1392 unsafe {
1393 let f: Box_<F> = Box_::new(f);
1394 connect_raw(
1395 self.as_ptr() as *mut _,
1396 b"notify::require-close-notify\0".as_ptr() as *const _,
1397 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
1398 notify_require_close_notify_trampoline::<Self, F> as *const (),
1399 )),
1400 Box_::into_raw(f),
1401 )
1402 }
1403 }
1404}
1405
1406impl<O: IsA<DtlsConnection>> DtlsConnectionExt for O {}