LCOV - code coverage report
Current view: top level - src/plugins/lan - valent-lan-channel.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 83.9 % 192 161
Test Date: 2024-03-22 06:22:29 Functions: 93.8 % 16 15
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 44.5 % 128 57

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: GPL-3.0-or-later
       2                 :             : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
       3                 :             : 
       4                 :             : #define G_LOG_DOMAIN "valent-lan-channel"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <gio/gio.h>
       9                 :             : #include <gio/gnetworking.h>
      10                 :             : #include <json-glib/json-glib.h>
      11                 :             : #include <valent.h>
      12                 :             : 
      13                 :             : #include "valent-lan-channel.h"
      14                 :             : #include "valent-lan-utils.h"
      15                 :             : 
      16                 :             : 
      17                 :             : struct _ValentLanChannel
      18                 :             : {
      19                 :             :   ValentChannel    parent_instance;
      20                 :             : 
      21                 :             :   char            *verification_key;
      22                 :             :   char            *host;
      23                 :             :   uint16_t         port;
      24                 :             : };
      25                 :             : 
      26   [ +  +  +  - ]:          30 : G_DEFINE_FINAL_TYPE (ValentLanChannel, valent_lan_channel, VALENT_TYPE_CHANNEL)
      27                 :             : 
      28                 :             : enum {
      29                 :             :   PROP_0,
      30                 :             :   PROP_CERTIFICATE,
      31                 :             :   PROP_HOST,
      32                 :             :   PROP_PEER_CERTIFICATE,
      33                 :             :   PROP_PORT,
      34                 :             :   N_PROPERTIES
      35                 :             : };
      36                 :             : 
      37                 :             : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
      38                 :             : 
      39                 :             : 
      40                 :             : /*
      41                 :             :  * ValentChannel
      42                 :             :  */
      43                 :             : static const char *
      44                 :           2 : valent_lan_channel_get_verification_key (ValentChannel *channel)
      45                 :             : {
      46                 :           2 :   ValentLanChannel *self = VALENT_LAN_CHANNEL (channel);
      47                 :           4 :   g_autoptr (GChecksum) checksum = NULL;
      48         [ +  - ]:           2 :   g_autoptr (GTlsCertificate) cert = NULL;
      49         [ +  - ]:           2 :   g_autoptr (GTlsCertificate) peer_cert = NULL;
      50                 :           2 :   GByteArray *pubkey;
      51                 :           2 :   GByteArray *peer_pubkey;
      52                 :           2 :   size_t cmplen;
      53                 :             : 
      54         [ +  - ]:           2 :   if (self->verification_key == NULL)
      55                 :             :     {
      56         [ +  - ]:           2 :       if ((cert = valent_lan_channel_ref_certificate (self)) == NULL ||
      57         [ -  + ]:           2 :           (peer_cert = valent_lan_channel_ref_peer_certificate (self)) == NULL)
      58                 :           0 :         g_return_val_if_reached (NULL);
      59                 :             : 
      60         [ +  - ]:           2 :       if ((pubkey = valent_certificate_get_public_key (cert)) == NULL ||
      61         [ -  + ]:           2 :           (peer_pubkey = valent_certificate_get_public_key (peer_cert)) == NULL)
      62                 :           0 :         g_return_val_if_reached (NULL);
      63                 :             : 
      64                 :           2 :       checksum = g_checksum_new (G_CHECKSUM_SHA256);
      65                 :           2 :       cmplen = MIN (pubkey->len, peer_pubkey->len);
      66                 :             : 
      67         [ +  + ]:           2 :       if (memcmp (pubkey->data, peer_pubkey->data, cmplen) > 0)
      68                 :             :         {
      69                 :           1 :           g_checksum_update (checksum, pubkey->data, pubkey->len);
      70                 :           1 :           g_checksum_update (checksum, peer_pubkey->data, peer_pubkey->len);
      71                 :             :         }
      72                 :             :       else
      73                 :             :         {
      74                 :           1 :           g_checksum_update (checksum, peer_pubkey->data, peer_pubkey->len);
      75                 :           1 :           g_checksum_update (checksum, pubkey->data, pubkey->len);
      76                 :             :         }
      77                 :             : 
      78         [ -  + ]:           2 :       self->verification_key = g_strdup (g_checksum_get_string (checksum));
      79                 :             :     }
      80                 :             : 
      81                 :           2 :   return self->verification_key;
      82                 :             : }
      83                 :             : 
      84                 :             : static GIOStream *
      85                 :           1 : valent_lan_channel_download (ValentChannel  *channel,
      86                 :             :                              JsonNode       *packet,
      87                 :             :                              GCancellable   *cancellable,
      88                 :             :                              GError        **error)
      89                 :             : {
      90                 :           1 :   ValentLanChannel *self = VALENT_LAN_CHANNEL (channel);
      91                 :           1 :   JsonObject *info;
      92                 :           1 :   int64_t port;
      93                 :           1 :   goffset size;
      94                 :           2 :   g_autoptr (GSocketClient) client = NULL;
      95         [ +  - ]:           1 :   g_autoptr (GSocketConnection) connection = NULL;
      96         [ +  - ]:           1 :   g_autoptr (GTlsCertificate) certificate = NULL;
      97         [ +  - ]:           1 :   g_autoptr (GTlsCertificate) peer_certificate = NULL;
      98         [ +  - ]:           1 :   g_autofree char *host = NULL;
      99                 :           1 :   g_autoptr (GIOStream) tls_stream = NULL;
     100                 :             : 
     101         [ +  - ]:           1 :   g_assert (VALENT_IS_CHANNEL (channel));
     102         [ -  + ]:           1 :   g_assert (VALENT_IS_PACKET (packet));
     103   [ -  +  -  -  :           1 :   g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
             -  -  -  - ]
     104   [ +  -  -  + ]:           1 :   g_assert (error == NULL || *error == NULL);
     105                 :             : 
     106                 :             :   /* Get the payload information */
     107         [ +  - ]:           1 :   if ((info = valent_packet_get_payload_full (packet, &size, error)) == NULL)
     108                 :             :     return NULL;
     109                 :             : 
     110         [ +  - ]:           1 :   if ((port = json_object_get_int_member (info, "port")) == 0 ||
     111         [ -  + ]:           1 :       (port < VALENT_LAN_TRANSFER_PORT_MIN || port > VALENT_LAN_TRANSFER_PORT_MAX))
     112                 :             :     {
     113                 :           0 :       g_set_error (error,
     114                 :             :                    VALENT_PACKET_ERROR,
     115                 :             :                    VALENT_PACKET_ERROR_INVALID_FIELD,
     116                 :             :                    "expected \"port\" field holding a uint16 between %u-%u",
     117                 :             :                    VALENT_LAN_TRANSFER_PORT_MIN,
     118                 :             :                    VALENT_LAN_TRANSFER_PORT_MAX);
     119                 :           0 :       return NULL;
     120                 :             :     }
     121                 :             : 
     122                 :             :   /* Open the outgoing connection */
     123                 :           1 :   host = valent_lan_channel_dup_host (self);
     124                 :           1 :   client = g_object_new (G_TYPE_SOCKET_CLIENT,
     125                 :             :                          "enable-proxy", FALSE,
     126                 :             :                          NULL);
     127                 :           1 :   connection = g_socket_client_connect_to_host (client,
     128                 :             :                                                 host,
     129                 :             :                                                 (uint16_t)port,
     130                 :             :                                                 cancellable,
     131                 :             :                                                 error);
     132                 :             : 
     133         [ +  - ]:           1 :   if (connection == NULL)
     134                 :             :     return NULL;
     135                 :             : 
     136                 :             :   /* We're the TLS client when downloading */
     137                 :           1 :   certificate = valent_lan_channel_ref_certificate (self);
     138                 :           1 :   peer_certificate = valent_lan_channel_ref_peer_certificate (self);
     139                 :           1 :   tls_stream = valent_lan_encrypt_client (connection,
     140                 :             :                                           certificate,
     141                 :             :                                           peer_certificate,
     142                 :             :                                           cancellable,
     143                 :             :                                           error);
     144                 :             : 
     145         [ -  + ]:           1 :   if (tls_stream == NULL)
     146                 :             :     {
     147                 :           0 :       g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
     148                 :           0 :       return NULL;
     149                 :             :     }
     150                 :             : 
     151                 :             :   return g_steal_pointer (&tls_stream);
     152                 :             : }
     153                 :             : 
     154                 :             : static GIOStream *
     155                 :           1 : valent_lan_channel_upload (ValentChannel  *channel,
     156                 :             :                            JsonNode       *packet,
     157                 :             :                            GCancellable   *cancellable,
     158                 :             :                            GError        **error)
     159                 :             : {
     160                 :           1 :   ValentLanChannel *self = VALENT_LAN_CHANNEL (channel);
     161                 :           1 :   JsonObject *info;
     162                 :           2 :   g_autoptr (GSocketListener) listener = NULL;
     163         [ +  - ]:           1 :   g_autoptr (GSocketConnection) connection = NULL;
     164                 :           1 :   uint16_t port = VALENT_LAN_TRANSFER_PORT_MIN;
     165         [ +  - ]:           1 :   g_autoptr (GTlsCertificate) certificate = NULL;
     166         [ +  - ]:           1 :   g_autoptr (GTlsCertificate) peer_certificate = NULL;
     167         [ +  - ]:           1 :   g_autoptr (GIOStream) tls_stream = NULL;
     168                 :             : 
     169         [ +  - ]:           1 :   g_assert (VALENT_IS_CHANNEL (channel));
     170         [ -  + ]:           1 :   g_assert (VALENT_IS_PACKET (packet));
     171   [ -  +  -  -  :           1 :   g_assert (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
             -  -  -  - ]
     172   [ +  -  -  + ]:           1 :   g_assert (error == NULL || *error == NULL);
     173                 :             : 
     174                 :             :   /* Find an open port */
     175                 :           1 :   listener = g_socket_listener_new ();
     176                 :             : 
     177         [ -  + ]:           1 :   while (!g_socket_listener_add_inet_port (listener, port, NULL, error))
     178                 :             :     {
     179         [ #  # ]:           0 :       if (port >= VALENT_LAN_TRANSFER_PORT_MAX)
     180                 :             :         return NULL;
     181                 :             : 
     182                 :           0 :       port++;
     183                 :           0 :       g_clear_error (error);
     184                 :             :     }
     185                 :             : 
     186                 :             :   /* Set the payload information */
     187                 :           1 :   info = json_object_new();
     188                 :           1 :   json_object_set_int_member (info, "port", (int64_t)port);
     189                 :           1 :   valent_packet_set_payload_info (packet, info);
     190                 :             : 
     191                 :             :   /* Notify the device and accept the incoming connection */
     192                 :           1 :   valent_channel_write_packet (channel, packet, cancellable, NULL, NULL);
     193                 :             : 
     194                 :           1 :   connection = g_socket_listener_accept (listener, NULL, cancellable, error);
     195                 :           1 :   g_socket_listener_close (listener);
     196                 :             : 
     197         [ -  + ]:           1 :   if (connection == NULL)
     198                 :             :     return NULL;
     199                 :             : 
     200                 :             :   /* We're the TLS server when uploading */
     201                 :           1 :   certificate = valent_lan_channel_ref_certificate (self);
     202                 :           1 :   peer_certificate = valent_lan_channel_ref_peer_certificate (self);
     203                 :           1 :   tls_stream = valent_lan_encrypt_server (connection,
     204                 :             :                                           certificate,
     205                 :             :                                           peer_certificate,
     206                 :             :                                           cancellable,
     207                 :             :                                           error);
     208                 :             : 
     209         [ -  + ]:           1 :   if (tls_stream == NULL)
     210                 :             :     {
     211                 :           0 :       g_io_stream_close (G_IO_STREAM (connection), NULL, NULL);
     212                 :           0 :       return NULL;
     213                 :             :     }
     214                 :             : 
     215                 :             :   return g_steal_pointer (&tls_stream);
     216                 :             : }
     217                 :             : 
     218                 :             : static void
     219                 :           0 : valent_lan_channel_store_data (ValentChannel *channel,
     220                 :             :                                ValentContext *context)
     221                 :             : {
     222                 :           0 :   g_autoptr (GTlsCertificate) certificate = NULL;
     223         [ #  # ]:           0 :   g_autofree char *certificate_pem = NULL;
     224                 :           0 :   g_autoptr (GFile) certificate_file = NULL;
     225         [ #  # ]:           0 :   g_autoptr (GError) error = NULL;
     226                 :             : 
     227         [ #  # ]:           0 :   g_assert (VALENT_IS_LAN_CHANNEL (channel));
     228         [ #  # ]:           0 :   g_assert (VALENT_IS_CONTEXT (context));
     229                 :             : 
     230                 :             :   /* Chain-up first */
     231                 :           0 :   VALENT_CHANNEL_CLASS (valent_lan_channel_parent_class)->store_data (channel,
     232                 :             :                                                                       context);
     233                 :             : 
     234                 :             :   /* Save the peer certificate */
     235                 :           0 :   g_object_get (channel, "peer-certificate", &certificate, NULL);
     236                 :           0 :   g_object_get (certificate, "certificate-pem", &certificate_pem, NULL);
     237                 :             : 
     238                 :           0 :   certificate_file = valent_context_get_config_file (context, "certificate.pem");
     239                 :           0 :   g_file_set_contents_full (g_file_peek_path (certificate_file),
     240                 :             :                             certificate_pem,
     241                 :           0 :                             strlen (certificate_pem),
     242                 :             :                             G_FILE_SET_CONTENTS_DURABLE,
     243                 :             :                             0600,
     244                 :             :                             &error);
     245                 :             : 
     246         [ #  # ]:           0 :   if (error != NULL)
     247                 :             :     {
     248                 :           0 :       g_warning ("%s(): failed to write \"%s\": %s",
     249                 :             :                  G_STRFUNC,
     250                 :             :                  g_file_peek_path (certificate_file),
     251                 :             :                  error->message);
     252                 :             :     }
     253                 :           0 : }
     254                 :             : 
     255                 :             : /*
     256                 :             :  * GObject
     257                 :             :  */
     258                 :             : static void
     259                 :           6 : valent_lan_channel_finalize (GObject *object)
     260                 :             : {
     261                 :           6 :   ValentLanChannel *self = VALENT_LAN_CHANNEL (object);
     262                 :             : 
     263         [ +  - ]:           6 :   g_clear_pointer (&self->host, g_free);
     264         [ +  + ]:           6 :   g_clear_pointer (&self->verification_key, g_free);
     265                 :             : 
     266                 :           6 :   G_OBJECT_CLASS (valent_lan_channel_parent_class)->finalize (object);
     267                 :           6 : }
     268                 :             : 
     269                 :             : static void
     270                 :           4 : valent_lan_channel_get_property (GObject    *object,
     271                 :             :                                  guint       prop_id,
     272                 :             :                                  GValue     *value,
     273                 :             :                                  GParamSpec *pspec)
     274                 :             : {
     275                 :           4 :   ValentLanChannel *self = VALENT_LAN_CHANNEL (object);
     276                 :             : 
     277   [ +  +  +  +  :           4 :   switch (prop_id)
                      - ]
     278                 :             :     {
     279                 :           1 :     case PROP_CERTIFICATE:
     280                 :           1 :       g_value_take_object (value, valent_lan_channel_ref_certificate (self));
     281                 :           1 :       break;
     282                 :             : 
     283                 :           1 :     case PROP_HOST:
     284                 :           1 :       g_value_take_string (value, valent_lan_channel_dup_host (self));
     285                 :           1 :       break;
     286                 :             : 
     287                 :           1 :     case PROP_PEER_CERTIFICATE:
     288                 :           1 :       g_value_take_object (value, valent_lan_channel_ref_peer_certificate (self));
     289                 :           1 :       break;
     290                 :             : 
     291                 :           1 :     case PROP_PORT:
     292                 :           1 :       g_value_set_uint (value, valent_lan_channel_get_port (self));
     293                 :           1 :       break;
     294                 :             : 
     295                 :           0 :     default:
     296                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     297                 :             :     }
     298                 :           4 : }
     299                 :             : 
     300                 :             : static void
     301                 :          12 : valent_lan_channel_set_property (GObject      *object,
     302                 :             :                                  guint         prop_id,
     303                 :             :                                  const GValue *value,
     304                 :             :                                  GParamSpec   *pspec)
     305                 :             : {
     306                 :          12 :   ValentLanChannel *self = VALENT_LAN_CHANNEL (object);
     307                 :             : 
     308      [ +  +  - ]:          12 :   switch (prop_id)
     309                 :             :     {
     310                 :             :     case PROP_HOST:
     311                 :           6 :       valent_object_lock (VALENT_OBJECT (self));
     312                 :           6 :       self->host = g_value_dup_string (value);
     313                 :           6 :       valent_object_unlock (VALENT_OBJECT (self));
     314                 :           6 :       break;
     315                 :             : 
     316                 :             :     case PROP_PORT:
     317                 :           6 :       valent_object_lock (VALENT_OBJECT (self));
     318                 :           6 :       self->port = g_value_get_uint (value);
     319                 :           6 :       valent_object_unlock (VALENT_OBJECT (self));
     320                 :           6 :       break;
     321                 :             : 
     322                 :           0 :     default:
     323                 :           0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     324                 :             :     }
     325                 :          12 : }
     326                 :             : 
     327                 :             : static void
     328                 :           1 : valent_lan_channel_class_init (ValentLanChannelClass *klass)
     329                 :             : {
     330                 :           1 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     331                 :           1 :   ValentChannelClass *channel_class = VALENT_CHANNEL_CLASS (klass);
     332                 :             : 
     333                 :           1 :   object_class->finalize = valent_lan_channel_finalize;
     334                 :           1 :   object_class->get_property = valent_lan_channel_get_property;
     335                 :           1 :   object_class->set_property = valent_lan_channel_set_property;
     336                 :             : 
     337                 :           1 :   channel_class->get_verification_key = valent_lan_channel_get_verification_key;
     338                 :           1 :   channel_class->download = valent_lan_channel_download;
     339                 :           1 :   channel_class->upload = valent_lan_channel_upload;
     340                 :           1 :   channel_class->store_data = valent_lan_channel_store_data;
     341                 :             : 
     342                 :             :   /**
     343                 :             :    * ValentLanChannel:certificate:
     344                 :             :    *
     345                 :             :    * The TLS certificate.
     346                 :             :    */
     347                 :           2 :   properties [PROP_CERTIFICATE] =
     348                 :           1 :     g_param_spec_object ("certificate", NULL, NULL,
     349                 :             :                          G_TYPE_TLS_CERTIFICATE,
     350                 :             :                          (G_PARAM_READABLE |
     351                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     352                 :             :                           G_PARAM_STATIC_STRINGS));
     353                 :             : 
     354                 :             :   /**
     355                 :             :    * ValentLanChannel:host:
     356                 :             :    *
     357                 :             :    * The remote TCP/IP address for the channel.
     358                 :             :    */
     359                 :           2 :   properties [PROP_HOST] =
     360                 :           1 :     g_param_spec_string ("host", NULL, NULL,
     361                 :             :                          NULL,
     362                 :             :                          (G_PARAM_READWRITE |
     363                 :             :                           G_PARAM_CONSTRUCT_ONLY |
     364                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     365                 :             :                           G_PARAM_STATIC_STRINGS));
     366                 :             : 
     367                 :             :   /**
     368                 :             :    * ValentLanChannel:peer-certificate:
     369                 :             :    *
     370                 :             :    * The peer TLS certificate.
     371                 :             :    */
     372                 :           2 :   properties [PROP_PEER_CERTIFICATE] =
     373                 :           1 :     g_param_spec_object ("peer-certificate", NULL, NULL,
     374                 :             :                          G_TYPE_TLS_CERTIFICATE,
     375                 :             :                          (G_PARAM_READABLE |
     376                 :             :                           G_PARAM_EXPLICIT_NOTIFY |
     377                 :             :                           G_PARAM_STATIC_STRINGS));
     378                 :             : 
     379                 :             :   /**
     380                 :             :    * ValentLanChannel:port:
     381                 :             :    *
     382                 :             :    * The remote TCP/IP port for the channel.
     383                 :             :    */
     384                 :           2 :   properties [PROP_PORT] =
     385                 :           1 :     g_param_spec_uint ("port", NULL, NULL,
     386                 :             :                        0, G_MAXUINT16,
     387                 :             :                        VALENT_LAN_PROTOCOL_PORT,
     388                 :             :                        (G_PARAM_READWRITE |
     389                 :             :                         G_PARAM_CONSTRUCT_ONLY |
     390                 :             :                         G_PARAM_EXPLICIT_NOTIFY |
     391                 :             :                         G_PARAM_STATIC_STRINGS));
     392                 :             : 
     393                 :           1 :   g_object_class_install_properties (object_class, N_PROPERTIES, properties);
     394                 :           1 : }
     395                 :             : 
     396                 :             : static void
     397                 :           6 : valent_lan_channel_init (ValentLanChannel *self)
     398                 :             : {
     399                 :           6 : }
     400                 :             : 
     401                 :             : /**
     402                 :             :  * valent_lan_channel_ref_certificate:
     403                 :             :  * @self: a `ValentLanChannel`
     404                 :             :  *
     405                 :             :  * Get the TLS certificate.
     406                 :             :  *
     407                 :             :  * Returns: (transfer full) (nullable): a `GTlsCertificate`
     408                 :             :  */
     409                 :             : GTlsCertificate *
     410                 :           7 : valent_lan_channel_ref_certificate (ValentLanChannel *self)
     411                 :             : {
     412                 :          14 :   g_autoptr (GIOStream) base_stream = NULL;
     413                 :           7 :   GTlsCertificate *ret = NULL;
     414                 :             : 
     415         [ +  - ]:           7 :   g_return_val_if_fail (VALENT_IS_LAN_CHANNEL (self), NULL);
     416                 :             : 
     417                 :           7 :   base_stream = valent_channel_ref_base_stream (VALENT_CHANNEL (self));
     418                 :             : 
     419         [ +  - ]:           7 :   if (base_stream != NULL)
     420                 :           7 :     g_object_get (base_stream, "certificate", &ret, NULL);
     421                 :             : 
     422         [ -  + ]:           7 :   return g_steal_pointer (&ret);
     423                 :             : }
     424                 :             : 
     425                 :             : /**
     426                 :             :  * valent_lan_channel_ref_peer_certificate:
     427                 :             :  * @self: a `ValentLanChannel`
     428                 :             :  *
     429                 :             :  * Get the peer TLS certificate.
     430                 :             :  *
     431                 :             :  * Returns: (transfer full) (nullable): a `GTlsCertificate`
     432                 :             :  */
     433                 :             : GTlsCertificate *
     434                 :          10 : valent_lan_channel_ref_peer_certificate (ValentLanChannel *self)
     435                 :             : {
     436                 :          20 :   g_autoptr (GIOStream) base_stream = NULL;
     437                 :          10 :   GTlsCertificate *ret = NULL;
     438                 :             : 
     439         [ +  - ]:          10 :   g_return_val_if_fail (VALENT_IS_LAN_CHANNEL (self), NULL);
     440                 :             : 
     441                 :          10 :   base_stream = valent_channel_ref_base_stream (VALENT_CHANNEL (self));
     442                 :             : 
     443         [ +  - ]:          10 :   if (base_stream != NULL)
     444                 :          10 :     g_object_get (base_stream, "peer-certificate", &ret, NULL);
     445                 :             : 
     446         [ -  + ]:          10 :   return g_steal_pointer (&ret);
     447                 :             : }
     448                 :             : 
     449                 :             : /**
     450                 :             :  * valent_lan_channel_dup_host:
     451                 :             :  * @self: a `ValentLanChannel`
     452                 :             :  *
     453                 :             :  * Get the host address.
     454                 :             :  *
     455                 :             :  * Returns: (transfer full) (nullable): the remote host address
     456                 :             :  */
     457                 :             : char *
     458                 :           2 : valent_lan_channel_dup_host (ValentLanChannel *self)
     459                 :             : {
     460                 :           2 :   char *ret = NULL;
     461                 :             : 
     462         [ +  - ]:           2 :   g_return_val_if_fail (VALENT_LAN_CHANNEL (self), NULL);
     463                 :             : 
     464                 :           2 :   valent_object_lock (VALENT_OBJECT (self));
     465         [ -  + ]:           2 :   ret = g_strdup (self->host);
     466                 :           2 :   valent_object_unlock (VALENT_OBJECT (self));
     467                 :             : 
     468                 :           2 :   return g_steal_pointer (&ret);
     469                 :             : }
     470                 :             : 
     471                 :             : /**
     472                 :             :  * valent_lan_channel_get_port:
     473                 :             :  * @self: a `ValentLanChannel`
     474                 :             :  *
     475                 :             :  * Get the host port.
     476                 :             :  *
     477                 :             :  * Returns: the remote host port
     478                 :             :  */
     479                 :             : uint16_t
     480                 :           1 : valent_lan_channel_get_port (ValentLanChannel *self)
     481                 :             : {
     482                 :           1 :   uint16_t ret;
     483                 :             : 
     484         [ +  - ]:           1 :   g_return_val_if_fail (VALENT_IS_LAN_CHANNEL (self), 0);
     485                 :             : 
     486                 :           1 :   valent_object_lock (VALENT_OBJECT (self));
     487                 :           1 :   ret = self->port;
     488                 :           1 :   valent_object_unlock (VALENT_OBJECT (self));
     489                 :             : 
     490                 :           1 :   return ret;
     491                 :             : }
     492                 :             : 
        

Generated by: LCOV version 2.0-1