~ubuntu-branches/ubuntu/maverick/dbus/maverick-proposed

« back to all changes in this revision

Viewing changes to dbus/dbus-transport-socket.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-27 13:06:32 UTC
  • mfrom: (1.1.23 upstream)
  • Revision ID: james.westby@ubuntu.com-20100927130632-bqs145trvchd2lmf
Tags: 1.4.0-0ubuntu1
* New upstream release
 - Fixes https://bugs.freedesktop.org/show_bug.cgi?id=17754 Race condition in protected_change_timeout
 - Requested by various upstream KDE developers http://lists.kde.org/?t=128514970000004&r=1&w=2

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 *
22
22
 */
23
23
 
 
24
#include <config.h>
24
25
#include "dbus-internals.h"
25
26
#include "dbus-connection-internal.h"
 
27
#include "dbus-nonce.h"
26
28
#include "dbus-transport-socket.h"
27
29
#include "dbus-transport-protected.h"
28
30
#include "dbus-watch.h"
29
31
#include "dbus-credentials.h"
30
32
 
31
 
 
32
33
/**
33
34
 * @defgroup DBusTransportSocket DBusTransport implementations for sockets
34
35
 * @ingroup  DBusInternals
72
73
{
73
74
  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
74
75
 
75
 
  _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
 
76
  _dbus_verbose ("start\n");
76
77
  
77
78
  if (socket_transport->read_watch)
78
79
    {
94
95
      socket_transport->write_watch = NULL;
95
96
    }
96
97
 
97
 
  _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
 
98
  _dbus_verbose ("end\n");
98
99
}
99
100
 
100
101
static void
102
103
{
103
104
  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
104
105
 
105
 
  _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
 
106
  _dbus_verbose ("\n");
106
107
  
107
108
  free_watches (transport);
108
109
 
176
177
  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
177
178
  dbus_bool_t need_read_watch;
178
179
 
179
 
  _dbus_verbose ("%s: fd = %d\n",
180
 
                 _DBUS_FUNCTION_NAME, socket_transport->fd);
 
180
  _dbus_verbose ("fd = %d\n",socket_transport->fd);
181
181
  
182
182
  if (transport->connection == NULL)
183
183
    return;
192
192
 
193
193
  if (_dbus_transport_get_is_authenticated (transport))
194
194
    need_read_watch =
195
 
      _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
 
195
      (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
 
196
      (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
196
197
  else
197
198
    {
198
199
      if (transport->receive_credentials_pending)
551
552
 
552
553
      if (_dbus_auth_needs_encoding (transport->auth))
553
554
        {
 
555
          /* Does fd passing even make sense with encoded data? */
 
556
          _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
 
557
 
554
558
          if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
555
559
            {
556
560
              if (!_dbus_auth_encode_data (transport->auth,
588
592
 
589
593
#if 0
590
594
          _dbus_verbose ("message is %d bytes\n",
591
 
                         total_bytes_to_write);          
 
595
                         total_bytes_to_write);
592
596
#endif
593
 
          
594
 
          if (socket_transport->message_bytes_written < header_len)
 
597
 
 
598
#ifdef HAVE_UNIX_FD_PASSING
 
599
          if (socket_transport->message_bytes_written <= 0 && DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
595
600
            {
 
601
              /* Send the fds along with the first byte of the message */
 
602
              const int *unix_fds;
 
603
              unsigned n;
 
604
 
 
605
              _dbus_message_get_unix_fds(message, &unix_fds, &n);
 
606
 
596
607
              bytes_written =
597
 
                _dbus_write_socket_two (socket_transport->fd,
598
 
                                        header,
599
 
                                        socket_transport->message_bytes_written,
600
 
                                        header_len - socket_transport->message_bytes_written,
 
608
                _dbus_write_socket_with_unix_fds_two (socket_transport->fd,
 
609
                                                      header,
 
610
                                                      socket_transport->message_bytes_written,
 
611
                                                      header_len - socket_transport->message_bytes_written,
 
612
                                                      body,
 
613
                                                      0, body_len,
 
614
                                                      unix_fds,
 
615
                                                      n);
 
616
 
 
617
              if (bytes_written > 0 && n > 0)
 
618
                _dbus_verbose("Wrote %i unix fds\n", n);
 
619
            }
 
620
          else
 
621
#endif
 
622
            {
 
623
              if (socket_transport->message_bytes_written < header_len)
 
624
                {
 
625
                  bytes_written =
 
626
                    _dbus_write_socket_two (socket_transport->fd,
 
627
                                            header,
 
628
                                            socket_transport->message_bytes_written,
 
629
                                            header_len - socket_transport->message_bytes_written,
 
630
                                            body,
 
631
                                            0, body_len);
 
632
                }
 
633
              else
 
634
                {
 
635
                  bytes_written =
 
636
                    _dbus_write_socket (socket_transport->fd,
601
637
                                        body,
602
 
                                        0, body_len);
603
 
            }
604
 
          else
605
 
            {
606
 
              bytes_written =
607
 
                _dbus_write_socket (socket_transport->fd,
608
 
                                    body,
609
 
                                    (socket_transport->message_bytes_written - header_len),
610
 
                                    body_len -
611
 
                                    (socket_transport->message_bytes_written - header_len));
 
638
                                        (socket_transport->message_bytes_written - header_len),
 
639
                                        body_len -
 
640
                                        (socket_transport->message_bytes_written - header_len));
 
641
                }
612
642
            }
613
643
        }
614
644
 
670
700
  int total;
671
701
  dbus_bool_t oom;
672
702
 
673
 
  _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
674
 
                 socket_transport->fd);
 
703
  _dbus_verbose ("fd = %d\n",socket_transport->fd);
675
704
  
676
705
  /* No messages without authentication! */
677
706
  if (!_dbus_transport_get_is_authenticated (transport))
704
733
  
705
734
  if (_dbus_auth_needs_decoding (transport->auth))
706
735
    {
 
736
      /* Does fd passing even make sense with encoded data? */
 
737
      _dbus_assert(!DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport));
 
738
 
707
739
      if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
708
740
        bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
709
741
      else
748
780
    {
749
781
      _dbus_message_loader_get_buffer (transport->loader,
750
782
                                       &buffer);
751
 
      
752
 
      bytes_read = _dbus_read_socket (socket_transport->fd,
753
 
                                      buffer, socket_transport->max_bytes_read_per_iteration);
754
 
      
 
783
 
 
784
#ifdef HAVE_UNIX_FD_PASSING
 
785
      if (DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport))
 
786
        {
 
787
          int *fds, n_fds;
 
788
 
 
789
          if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
 
790
            {
 
791
              _dbus_verbose ("Out of memory reading file descriptors\n");
 
792
              _dbus_message_loader_return_buffer (transport->loader, buffer, 0);
 
793
              oom = TRUE;
 
794
              goto out;
 
795
            }
 
796
 
 
797
          bytes_read = _dbus_read_socket_with_unix_fds(socket_transport->fd,
 
798
                                                       buffer,
 
799
                                                       socket_transport->max_bytes_read_per_iteration,
 
800
                                                       fds, &n_fds);
 
801
 
 
802
          if (bytes_read >= 0 && n_fds > 0)
 
803
            _dbus_verbose("Read %i unix fds\n", n_fds);
 
804
 
 
805
          _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
 
806
        }
 
807
      else
 
808
#endif
 
809
        {
 
810
          bytes_read = _dbus_read_socket (socket_transport->fd,
 
811
                                          buffer, socket_transport->max_bytes_read_per_iteration);
 
812
        }
 
813
 
755
814
      _dbus_message_loader_return_buffer (transport->loader,
756
815
                                          buffer,
757
816
                                          bytes_read < 0 ? 0 : bytes_read);
923
982
{
924
983
  DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
925
984
 
926
 
  _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
 
985
  _dbus_verbose ("\n");
927
986
  
928
987
  free_watches (transport);
929
988
  
1058
1117
       */
1059
1118
      if (flags & DBUS_ITERATION_BLOCK)
1060
1119
        {
1061
 
          _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
 
1120
          _dbus_verbose ("unlock pre poll\n");
1062
1121
          _dbus_connection_unlock (transport->connection);
1063
1122
        }
1064
1123
      
1070
1129
 
1071
1130
      if (flags & DBUS_ITERATION_BLOCK)
1072
1131
        {
1073
 
          _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
 
1132
          _dbus_verbose ("lock post poll\n");
1074
1133
          _dbus_connection_lock (transport->connection);
1075
1134
        }
1076
1135
      
1204
1263
                                  &socket_vtable,
1205
1264
                                  server_guid, address))
1206
1265
    goto failed_4;
1207
 
  
 
1266
 
 
1267
#ifdef HAVE_UNIX_FD_PASSING
 
1268
  _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
 
1269
#endif
 
1270
 
1208
1271
  socket_transport->fd = fd;
1209
1272
  socket_transport->message_bytes_written = 0;
1210
1273
  
1234
1297
 * @param host the host to connect to
1235
1298
 * @param port the port to connect to
1236
1299
 * @param family the address family to connect to
 
1300
 * @param path to nonce file
1237
1301
 * @param error location to store reason for failure.
1238
1302
 * @returns a new transport, or #NULL on failure.
1239
1303
 */
1241
1305
_dbus_transport_new_for_tcp_socket (const char     *host,
1242
1306
                                    const char     *port,
1243
1307
                                    const char     *family,
 
1308
                                    const char     *noncefile,
1244
1309
                                    DBusError      *error)
1245
1310
{
1246
1311
  int fd;
1258
1323
  if (host == NULL)
1259
1324
    host = "localhost";
1260
1325
 
1261
 
  if (!_dbus_string_append (&address, "tcp:"))
 
1326
  if (!_dbus_string_append (&address, noncefile ? "nonce-tcp:" : "tcp:"))
1262
1327
    goto error;
1263
1328
 
1264
1329
  if (!_dbus_string_append (&address, "host=") ||
1274
1339
       !_dbus_string_append (&address, family)))
1275
1340
    goto error;
1276
1341
 
1277
 
  fd = _dbus_connect_tcp_socket (host, port, family, error);
 
1342
  if (noncefile != NULL &&
 
1343
      (!_dbus_string_append (&address, "noncefile=") ||
 
1344
       !_dbus_string_append (&address, noncefile)))
 
1345
    goto error;
 
1346
 
 
1347
  fd = _dbus_connect_tcp_socket_with_nonce (host, port, family, noncefile, error);
1278
1348
  if (fd < 0)
1279
1349
    {
1280
1350
      _DBUS_ASSERT_ERROR_IS_SET (error);
1282
1352
      return NULL;
1283
1353
    }
1284
1354
 
1285
 
  _dbus_fd_set_close_on_exec (fd);
1286
 
  
1287
1355
  _dbus_verbose ("Successfully connected to tcp socket %s:%s\n",
1288
1356
                 host, port);
1289
1357
  
1318
1386
                            DBusError         *error)
1319
1387
{
1320
1388
  const char *method;
 
1389
  dbus_bool_t isTcp;
 
1390
  dbus_bool_t isNonceTcp;
1321
1391
  
1322
1392
  method = dbus_address_entry_get_method (entry);
1323
1393
  _dbus_assert (method != NULL);
1324
1394
 
1325
 
  if (strcmp (method, "tcp") == 0)
 
1395
  isTcp = strcmp (method, "tcp") == 0;
 
1396
  isNonceTcp = strcmp (method, "nonce-tcp") == 0;
 
1397
 
 
1398
  if (isTcp || isNonceTcp)
1326
1399
    {
1327
1400
      const char *host = dbus_address_entry_get_value (entry, "host");
1328
1401
      const char *port = dbus_address_entry_get_value (entry, "port");
1329
1402
      const char *family = dbus_address_entry_get_value (entry, "family");
 
1403
      const char *noncefile = dbus_address_entry_get_value (entry, "noncefile");
 
1404
 
 
1405
      if ((isNonceTcp == TRUE) != (noncefile != NULL)) {
 
1406
          _dbus_set_bad_address (error, method, "noncefile", NULL);
 
1407
          return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
 
1408
      }
1330
1409
 
1331
1410
      if (port == NULL)
1332
1411
        {
1333
 
          _dbus_set_bad_address (error, "tcp", "port", NULL);
 
1412
          _dbus_set_bad_address (error, method, "port", NULL);
1334
1413
          return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
1335
1414
        }
1336
1415
 
1337
 
      *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, error);
 
1416
      *transport_p = _dbus_transport_new_for_tcp_socket (host, port, family, noncefile, error);
1338
1417
      if (*transport_p == NULL)
1339
1418
        {
1340
1419
          _DBUS_ASSERT_ERROR_IS_SET (error);