Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu" -*- */
      2 /* dbus-transport-socket.c  Socket subclasses of DBusTransport
      3  *
      4  * Copyright (C) 2002, 2003, 2004, 2006  Red Hat Inc.
      5  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21  *
     22  */
     23 
     24 #include "dbus-internals.h"
     25 #include "dbus-connection-internal.h"
     26 #include "dbus-transport-socket.h"
     27 #include "dbus-transport-protected.h"
     28 #include "dbus-watch.h"
     29 
     30 
     31 /**
     32  * @defgroup DBusTransportSocket DBusTransport implementations for sockets
     33  * @ingroup  DBusInternals
     34  * @brief Implementation details of DBusTransport on sockets
     35  *
     36  * @{
     37  */
     38 
     39 /**
     40  * Opaque object representing a socket file descriptor transport.
     41  */
     42 typedef struct DBusTransportSocket DBusTransportSocket;
     43 
     44 /**
     45  * Implementation details of DBusTransportSocket. All members are private.
     46  */
     47 struct DBusTransportSocket
     48 {
     49   DBusTransport base;                   /**< Parent instance */
     50   int fd;                               /**< File descriptor. */
     51   DBusWatch *read_watch;                /**< Watch for readability. */
     52   DBusWatch *write_watch;               /**< Watch for writability. */
     53 
     54   int max_bytes_read_per_iteration;     /**< To avoid blocking too long. */
     55   int max_bytes_written_per_iteration;  /**< To avoid blocking too long. */
     56 
     57   int message_bytes_written;            /**< Number of bytes of current
     58                                          *   outgoing message that have
     59                                          *   been written.
     60                                          */
     61   DBusString encoded_outgoing;          /**< Encoded version of current
     62                                          *   outgoing message.
     63                                          */
     64   DBusString encoded_incoming;          /**< Encoded version of current
     65                                          *   incoming data.
     66                                          */
     67 };
     68 
     69 static void
     70 free_watches (DBusTransport *transport)
     71 {
     72   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
     73 
     74   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
     75 
     76   if (socket_transport->read_watch)
     77     {
     78       if (transport->connection)
     79         _dbus_connection_remove_watch_unlocked (transport->connection,
     80                                                 socket_transport->read_watch);
     81       _dbus_watch_invalidate (socket_transport->read_watch);
     82       _dbus_watch_unref (socket_transport->read_watch);
     83       socket_transport->read_watch = NULL;
     84     }
     85 
     86   if (socket_transport->write_watch)
     87     {
     88       if (transport->connection)
     89         _dbus_connection_remove_watch_unlocked (transport->connection,
     90                                                 socket_transport->write_watch);
     91       _dbus_watch_invalidate (socket_transport->write_watch);
     92       _dbus_watch_unref (socket_transport->write_watch);
     93       socket_transport->write_watch = NULL;
     94     }
     95 
     96   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
     97 }
     98 
     99 static void
    100 socket_finalize (DBusTransport *transport)
    101 {
    102   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    103 
    104   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
    105 
    106   free_watches (transport);
    107 
    108   _dbus_string_free (&socket_transport->encoded_outgoing);
    109   _dbus_string_free (&socket_transport->encoded_incoming);
    110 
    111   _dbus_transport_finalize_base (transport);
    112 
    113   _dbus_assert (socket_transport->read_watch == NULL);
    114   _dbus_assert (socket_transport->write_watch == NULL);
    115 
    116   dbus_free (transport);
    117 }
    118 
    119 static void
    120 check_write_watch (DBusTransport *transport)
    121 {
    122   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    123   dbus_bool_t needed;
    124 
    125   if (transport->connection == NULL)
    126     return;
    127 
    128   if (transport->disconnected)
    129     {
    130       _dbus_assert (socket_transport->write_watch == NULL);
    131       return;
    132     }
    133 
    134   _dbus_transport_ref (transport);
    135 
    136   if (_dbus_transport_get_is_authenticated (transport))
    137     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
    138   else
    139     {
    140       if (transport->send_credentials_pending)
    141         needed = TRUE;
    142       else
    143         {
    144           DBusAuthState auth_state;
    145 
    146           auth_state = _dbus_auth_do_work (transport->auth);
    147 
    148           /* If we need memory we install the write watch just in case,
    149            * if there's no need for it, it will get de-installed
    150            * next time we try reading.
    151            */
    152           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
    153               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
    154             needed = TRUE;
    155           else
    156             needed = FALSE;
    157         }
    158     }
    159 
    160   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
    161                  needed, transport->connection, socket_transport->write_watch,
    162                  socket_transport->fd,
    163                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
    164 
    165   _dbus_connection_toggle_watch_unlocked (transport->connection,
    166                                           socket_transport->write_watch,
    167                                           needed);
    168 
    169   _dbus_transport_unref (transport);
    170 }
    171 
    172 static void
    173 check_read_watch (DBusTransport *transport)
    174 {
    175   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    176   dbus_bool_t need_read_watch;
    177 
    178   _dbus_verbose ("%s: fd = %d\n",
    179                  _DBUS_FUNCTION_NAME, socket_transport->fd);
    180 
    181   if (transport->connection == NULL)
    182     return;
    183 
    184   if (transport->disconnected)
    185     {
    186       _dbus_assert (socket_transport->read_watch == NULL);
    187       return;
    188     }
    189 
    190   _dbus_transport_ref (transport);
    191 
    192   if (_dbus_transport_get_is_authenticated (transport))
    193     need_read_watch =
    194       _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
    195   else
    196     {
    197       if (transport->receive_credentials_pending)
    198         need_read_watch = TRUE;
    199       else
    200         {
    201           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
    202            * is to avoid spinning on the file descriptor when we're waiting
    203            * to write or for some other part of the auth process
    204            */
    205           DBusAuthState auth_state;
    206 
    207           auth_state = _dbus_auth_do_work (transport->auth);
    208 
    209           /* If we need memory we install the read watch just in case,
    210            * if there's no need for it, it will get de-installed
    211            * next time we try reading. If we're authenticated we
    212            * install it since we normally have it installed while
    213            * authenticated.
    214            */
    215           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
    216               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
    217               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
    218             need_read_watch = TRUE;
    219           else
    220             need_read_watch = FALSE;
    221         }
    222     }
    223 
    224   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
    225   _dbus_connection_toggle_watch_unlocked (transport->connection,
    226                                           socket_transport->read_watch,
    227                                           need_read_watch);
    228 
    229   _dbus_transport_unref (transport);
    230 }
    231 
    232 static void
    233 do_io_error (DBusTransport *transport)
    234 {
    235   _dbus_transport_ref (transport);
    236   _dbus_transport_disconnect (transport);
    237   _dbus_transport_unref (transport);
    238 }
    239 
    240 /* return value is whether we successfully read any new data. */
    241 static dbus_bool_t
    242 read_data_into_auth (DBusTransport *transport,
    243                      dbus_bool_t   *oom)
    244 {
    245   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    246   DBusString *buffer;
    247   int bytes_read;
    248 
    249   *oom = FALSE;
    250 
    251   _dbus_auth_get_buffer (transport->auth, &buffer);
    252 
    253   bytes_read = _dbus_read_socket (socket_transport->fd,
    254                                   buffer, socket_transport->max_bytes_read_per_iteration);
    255 
    256   _dbus_auth_return_buffer (transport->auth, buffer,
    257                             bytes_read > 0 ? bytes_read : 0);
    258 
    259   if (bytes_read > 0)
    260     {
    261       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
    262 
    263       return TRUE;
    264     }
    265   else if (bytes_read < 0)
    266     {
    267       /* EINTR already handled for us */
    268 
    269       if (errno == ENOMEM)
    270         {
    271           *oom = TRUE;
    272         }
    273       else if (errno == EAGAIN ||
    274                errno == EWOULDBLOCK)
    275         ; /* do nothing, just return FALSE below */
    276       else
    277         {
    278           _dbus_verbose ("Error reading from remote app: %s\n",
    279                          _dbus_strerror (errno));
    280           do_io_error (transport);
    281         }
    282 
    283       return FALSE;
    284     }
    285   else
    286     {
    287       _dbus_assert (bytes_read == 0);
    288 
    289       _dbus_verbose ("Disconnected from remote app\n");
    290       do_io_error (transport);
    291 
    292       return FALSE;
    293     }
    294 }
    295 
    296 /* Return value is whether we successfully wrote any bytes */
    297 static dbus_bool_t
    298 write_data_from_auth (DBusTransport *transport)
    299 {
    300   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    301   int bytes_written;
    302   const DBusString *buffer;
    303 
    304   if (!_dbus_auth_get_bytes_to_send (transport->auth,
    305                                      &buffer))
    306     return FALSE;
    307 
    308   bytes_written = _dbus_write_socket (socket_transport->fd,
    309                                       buffer,
    310                                       0, _dbus_string_get_length (buffer));
    311 
    312   if (bytes_written > 0)
    313     {
    314       _dbus_auth_bytes_sent (transport->auth, bytes_written);
    315       return TRUE;
    316     }
    317   else if (bytes_written < 0)
    318     {
    319       /* EINTR already handled for us */
    320 
    321       if (errno == EAGAIN ||
    322           errno == EWOULDBLOCK)
    323         ;
    324       else
    325         {
    326           _dbus_verbose ("Error writing to remote app: %s\n",
    327                          _dbus_strerror (errno));
    328           do_io_error (transport);
    329         }
    330     }
    331 
    332   return FALSE;
    333 }
    334 
    335 static void
    336 exchange_credentials (DBusTransport *transport,
    337                       dbus_bool_t    do_reading,
    338                       dbus_bool_t    do_writing)
    339 {
    340   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    341   DBusError error;
    342 
    343   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
    344                   do_reading, do_writing);
    345 
    346   dbus_error_init (&error);
    347   if (do_writing && transport->send_credentials_pending)
    348     {
    349       if (_dbus_send_credentials_unix_socket (socket_transport->fd,
    350                                               &error))
    351         {
    352           transport->send_credentials_pending = FALSE;
    353         }
    354       else
    355         {
    356           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
    357           dbus_error_free (&error);
    358           do_io_error (transport);
    359         }
    360     }
    361 
    362   if (do_reading && transport->receive_credentials_pending)
    363     {
    364       if (_dbus_read_credentials_unix_socket (socket_transport->fd,
    365                                               &transport->credentials,
    366                                               &error))
    367         {
    368           transport->receive_credentials_pending = FALSE;
    369         }
    370       else
    371         {
    372           _dbus_verbose ("Failed to read credentials %s\n", error.message);
    373           dbus_error_free (&error);
    374           do_io_error (transport);
    375         }
    376     }
    377 
    378   if (!(transport->send_credentials_pending ||
    379         transport->receive_credentials_pending))
    380     {
    381       _dbus_auth_set_credentials (transport->auth,
    382                                   &transport->credentials);
    383     }
    384 }
    385 
    386 static dbus_bool_t
    387 do_authentication (DBusTransport *transport,
    388                    dbus_bool_t    do_reading,
    389                    dbus_bool_t    do_writing,
    390 		   dbus_bool_t   *auth_completed)
    391 {
    392   dbus_bool_t oom;
    393   dbus_bool_t orig_auth_state;
    394 
    395   oom = FALSE;
    396 
    397   orig_auth_state = _dbus_transport_get_is_authenticated (transport);
    398 
    399   /* This is essential to avoid the check_write_watch() at the end,
    400    * we don't want to add a write watch in do_iteration before
    401    * we try writing and get EAGAIN
    402    */
    403   if (orig_auth_state)
    404     {
    405       if (auth_completed)
    406         *auth_completed = FALSE;
    407       return TRUE;
    408     }
    409 
    410   _dbus_transport_ref (transport);
    411 
    412   while (!_dbus_transport_get_is_authenticated (transport) &&
    413          _dbus_transport_get_is_connected (transport))
    414     {
    415       exchange_credentials (transport, do_reading, do_writing);
    416 
    417       if (transport->send_credentials_pending ||
    418           transport->receive_credentials_pending)
    419         {
    420           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
    421                          transport->send_credentials_pending,
    422                          transport->receive_credentials_pending);
    423           goto out;
    424         }
    425 
    426 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
    427       switch (_dbus_auth_do_work (transport->auth))
    428         {
    429         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
    430           _dbus_verbose (" %s auth state: waiting for input\n",
    431                          TRANSPORT_SIDE (transport));
    432           if (!do_reading || !read_data_into_auth (transport, &oom))
    433             goto out;
    434           break;
    435 
    436         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
    437           _dbus_verbose (" %s auth state: waiting for memory\n",
    438                          TRANSPORT_SIDE (transport));
    439           oom = TRUE;
    440           goto out;
    441           break;
    442 
    443         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
    444           _dbus_verbose (" %s auth state: bytes to send\n",
    445                          TRANSPORT_SIDE (transport));
    446           if (!do_writing || !write_data_from_auth (transport))
    447             goto out;
    448           break;
    449 
    450         case DBUS_AUTH_STATE_NEED_DISCONNECT:
    451           _dbus_verbose (" %s auth state: need to disconnect\n",
    452                          TRANSPORT_SIDE (transport));
    453           do_io_error (transport);
    454           break;
    455 
    456         case DBUS_AUTH_STATE_AUTHENTICATED:
    457           _dbus_verbose (" %s auth state: authenticated\n",
    458                          TRANSPORT_SIDE (transport));
    459           break;
    460         }
    461     }
    462 
    463  out:
    464   if (auth_completed)
    465     *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
    466 
    467   check_read_watch (transport);
    468   check_write_watch (transport);
    469   _dbus_transport_unref (transport);
    470 
    471   if (oom)
    472     return FALSE;
    473   else
    474     return TRUE;
    475 }
    476 
    477 /* returns false on oom */
    478 static dbus_bool_t
    479 do_writing (DBusTransport *transport)
    480 {
    481   int total;
    482   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    483   dbus_bool_t oom;
    484 
    485   /* No messages without authentication! */
    486   if (!_dbus_transport_get_is_authenticated (transport))
    487     {
    488       _dbus_verbose ("Not authenticated, not writing anything\n");
    489       return TRUE;
    490     }
    491 
    492   if (transport->disconnected)
    493     {
    494       _dbus_verbose ("Not connected, not writing anything\n");
    495       return TRUE;
    496     }
    497 
    498 #if 1
    499   _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
    500                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
    501                  socket_transport->fd);
    502 #endif
    503 
    504   oom = FALSE;
    505   total = 0;
    506 
    507   while (!transport->disconnected &&
    508          _dbus_connection_has_messages_to_send_unlocked (transport->connection))
    509     {
    510       int bytes_written;
    511       DBusMessage *message;
    512       const DBusString *header;
    513       const DBusString *body;
    514       int header_len, body_len;
    515       int total_bytes_to_write;
    516 
    517       if (total > socket_transport->max_bytes_written_per_iteration)
    518         {
    519           _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
    520                          total, socket_transport->max_bytes_written_per_iteration);
    521           goto out;
    522         }
    523 
    524       message = _dbus_connection_get_message_to_send (transport->connection);
    525       _dbus_assert (message != NULL);
    526       _dbus_message_lock (message);
    527 
    528 #if 0
    529       _dbus_verbose ("writing message %p\n", message);
    530 #endif
    531 
    532       _dbus_message_get_network_data (message,
    533                                       &header, &body);
    534 
    535       header_len = _dbus_string_get_length (header);
    536       body_len = _dbus_string_get_length (body);
    537 
    538       if (_dbus_auth_needs_encoding (transport->auth))
    539         {
    540           if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
    541             {
    542               if (!_dbus_auth_encode_data (transport->auth,
    543                                            header, &socket_transport->encoded_outgoing))
    544                 {
    545                   oom = TRUE;
    546                   goto out;
    547                 }
    548 
    549               if (!_dbus_auth_encode_data (transport->auth,
    550                                            body, &socket_transport->encoded_outgoing))
    551                 {
    552                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
    553                   oom = TRUE;
    554                   goto out;
    555                 }
    556             }
    557 
    558           total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
    559 
    560 #if 0
    561           _dbus_verbose ("encoded message is %d bytes\n",
    562                          total_bytes_to_write);
    563 #endif
    564 
    565           bytes_written =
    566             _dbus_write_socket (socket_transport->fd,
    567                                 &socket_transport->encoded_outgoing,
    568                                 socket_transport->message_bytes_written,
    569                                 total_bytes_to_write - socket_transport->message_bytes_written);
    570         }
    571       else
    572         {
    573           total_bytes_to_write = header_len + body_len;
    574 
    575 #if 0
    576           _dbus_verbose ("message is %d bytes\n",
    577                          total_bytes_to_write);
    578 #endif
    579 
    580           if (socket_transport->message_bytes_written < header_len)
    581             {
    582               bytes_written =
    583                 _dbus_write_socket_two (socket_transport->fd,
    584                                         header,
    585                                         socket_transport->message_bytes_written,
    586                                         header_len - socket_transport->message_bytes_written,
    587                                         body,
    588                                         0, body_len);
    589             }
    590           else
    591             {
    592               bytes_written =
    593                 _dbus_write_socket (socket_transport->fd,
    594                                     body,
    595                                     (socket_transport->message_bytes_written - header_len),
    596                                     body_len -
    597                                     (socket_transport->message_bytes_written - header_len));
    598             }
    599         }
    600 
    601       if (bytes_written < 0)
    602         {
    603           /* EINTR already handled for us */
    604 
    605           if (errno == EAGAIN ||
    606               errno == EWOULDBLOCK)
    607             goto out;
    608           else
    609             {
    610               _dbus_verbose ("Error writing to remote app: %s\n",
    611                              _dbus_strerror (errno));
    612               do_io_error (transport);
    613               goto out;
    614             }
    615         }
    616       else
    617         {
    618           _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
    619                          total_bytes_to_write);
    620 
    621           total += bytes_written;
    622           socket_transport->message_bytes_written += bytes_written;
    623 
    624           _dbus_assert (socket_transport->message_bytes_written <=
    625                         total_bytes_to_write);
    626 
    627           if (socket_transport->message_bytes_written == total_bytes_to_write)
    628             {
    629               socket_transport->message_bytes_written = 0;
    630               _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
    631 
    632               _dbus_connection_message_sent (transport->connection,
    633                                              message);
    634             }
    635         }
    636     }
    637 
    638  out:
    639   if (oom)
    640     return FALSE;
    641   else
    642     return TRUE;
    643 }
    644 
    645 /* returns false on out-of-memory */
    646 static dbus_bool_t
    647 do_reading (DBusTransport *transport)
    648 {
    649   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    650   DBusString *buffer;
    651   int bytes_read;
    652   int total;
    653   dbus_bool_t oom;
    654 
    655   _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
    656                  socket_transport->fd);
    657 
    658   /* No messages without authentication! */
    659   if (!_dbus_transport_get_is_authenticated (transport))
    660     return TRUE;
    661 
    662   oom = FALSE;
    663 
    664   total = 0;
    665 
    666  again:
    667 
    668   /* See if we've exceeded max messages and need to disable reading */
    669   check_read_watch (transport);
    670 
    671   if (total > socket_transport->max_bytes_read_per_iteration)
    672     {
    673       _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
    674                      total, socket_transport->max_bytes_read_per_iteration);
    675       goto out;
    676     }
    677 
    678   _dbus_assert (socket_transport->read_watch != NULL ||
    679                 transport->disconnected);
    680 
    681   if (transport->disconnected)
    682     goto out;
    683 
    684   if (!dbus_watch_get_enabled (socket_transport->read_watch))
    685     return TRUE;
    686 
    687   if (_dbus_auth_needs_decoding (transport->auth))
    688     {
    689       if (_dbus_string_get_length (&socket_transport->encoded_incoming) > 0)
    690         bytes_read = _dbus_string_get_length (&socket_transport->encoded_incoming);
    691       else
    692         bytes_read = _dbus_read_socket (socket_transport->fd,
    693                                         &socket_transport->encoded_incoming,
    694                                         socket_transport->max_bytes_read_per_iteration);
    695 
    696       _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) ==
    697                     bytes_read);
    698 
    699       if (bytes_read > 0)
    700         {
    701           int orig_len;
    702 
    703           _dbus_message_loader_get_buffer (transport->loader,
    704                                            &buffer);
    705 
    706           orig_len = _dbus_string_get_length (buffer);
    707 
    708           if (!_dbus_auth_decode_data (transport->auth,
    709                                        &socket_transport->encoded_incoming,
    710                                        buffer))
    711             {
    712               _dbus_verbose ("Out of memory decoding incoming data\n");
    713               oom = TRUE;
    714               goto out;
    715             }
    716 
    717           _dbus_message_loader_return_buffer (transport->loader,
    718                                               buffer,
    719                                               _dbus_string_get_length (buffer) - orig_len);
    720 
    721           _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
    722         }
    723     }
    724   else
    725     {
    726       _dbus_message_loader_get_buffer (transport->loader,
    727                                        &buffer);
    728 
    729       bytes_read = _dbus_read_socket (socket_transport->fd,
    730                                       buffer, socket_transport->max_bytes_read_per_iteration);
    731 
    732       _dbus_message_loader_return_buffer (transport->loader,
    733                                           buffer,
    734                                           bytes_read < 0 ? 0 : bytes_read);
    735     }
    736 
    737   if (bytes_read < 0)
    738     {
    739       /* EINTR already handled for us */
    740 
    741       if (errno == ENOMEM)
    742         {
    743           _dbus_verbose ("Out of memory in read()/do_reading()\n");
    744           oom = TRUE;
    745           goto out;
    746         }
    747       else if (errno == EAGAIN ||
    748                errno == EWOULDBLOCK)
    749         goto out;
    750       else
    751         {
    752           _dbus_verbose ("Error reading from remote app: %s\n",
    753                          _dbus_strerror (errno));
    754           do_io_error (transport);
    755           goto out;
    756         }
    757     }
    758   else if (bytes_read == 0)
    759     {
    760       _dbus_verbose ("Disconnected from remote app\n");
    761       do_io_error (transport);
    762       goto out;
    763     }
    764   else
    765     {
    766       _dbus_verbose (" read %d bytes\n", bytes_read);
    767 
    768       total += bytes_read;
    769 
    770       if (!_dbus_transport_queue_messages (transport))
    771         {
    772           oom = TRUE;
    773           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
    774           goto out;
    775         }
    776 
    777       /* Try reading more data until we get EAGAIN and return, or
    778        * exceed max bytes per iteration.  If in blocking mode of
    779        * course we'll block instead of returning.
    780        */
    781       goto again;
    782     }
    783 
    784  out:
    785   if (oom)
    786     return FALSE;
    787   else
    788     return TRUE;
    789 }
    790 
    791 static dbus_bool_t
    792 socket_handle_watch (DBusTransport *transport,
    793                    DBusWatch     *watch,
    794                    unsigned int   flags)
    795 {
    796   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    797 
    798   _dbus_assert (watch == socket_transport->read_watch ||
    799                 watch == socket_transport->write_watch);
    800   _dbus_assert (watch != NULL);
    801 
    802   /* Disconnect in case of an error.  In case of hangup do not
    803    * disconnect the transport because data can still be in the buffer
    804    * and do_reading may need several iteration to read it all (because
    805    * of its max_bytes_read_per_iteration limit).  The condition where
    806    * flags == HANGUP (without READABLE) probably never happen in fact.
    807    */
    808   if ((flags & DBUS_WATCH_ERROR) ||
    809       ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
    810     {
    811       _dbus_verbose ("Hang up or error on watch\n");
    812       _dbus_transport_disconnect (transport);
    813       return TRUE;
    814     }
    815 
    816   if (watch == socket_transport->read_watch &&
    817       (flags & DBUS_WATCH_READABLE))
    818     {
    819       dbus_bool_t auth_finished;
    820 #if 1
    821       _dbus_verbose ("handling read watch %p flags = %x\n",
    822                      watch, flags);
    823 #endif
    824       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
    825         return FALSE;
    826 
    827       /* We don't want to do a read immediately following
    828        * a successful authentication.  This is so we
    829        * have a chance to propagate the authentication
    830        * state further up.  Specifically, we need to
    831        * process any pending data from the auth object.
    832        */
    833       if (!auth_finished)
    834 	{
    835 	  if (!do_reading (transport))
    836 	    {
    837 	      _dbus_verbose ("no memory to read\n");
    838 	      return FALSE;
    839 	    }
    840 	}
    841       else
    842         {
    843           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
    844         }
    845     }
    846   else if (watch == socket_transport->write_watch &&
    847            (flags & DBUS_WATCH_WRITABLE))
    848     {
    849 #if 1
    850       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
    851                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
    852 #endif
    853       if (!do_authentication (transport, FALSE, TRUE, NULL))
    854         return FALSE;
    855 
    856       if (!do_writing (transport))
    857         {
    858           _dbus_verbose ("no memory to write\n");
    859           return FALSE;
    860         }
    861 
    862       /* See if we still need the write watch */
    863       check_write_watch (transport);
    864     }
    865 #ifdef DBUS_ENABLE_VERBOSE_MODE
    866   else
    867     {
    868       if (watch == socket_transport->read_watch)
    869         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
    870                        flags);
    871       else if (watch == socket_transport->write_watch)
    872         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
    873                        flags);
    874       else
    875         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
    876                        watch, dbus_watch_get_fd (watch));
    877     }
    878 #endif /* DBUS_ENABLE_VERBOSE_MODE */
    879 
    880   return TRUE;
    881 }
    882 
    883 static void
    884 socket_disconnect (DBusTransport *transport)
    885 {
    886   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    887 
    888   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
    889 
    890   free_watches (transport);
    891 
    892   _dbus_close_socket (socket_transport->fd, NULL);
    893   socket_transport->fd = -1;
    894 }
    895 
    896 static dbus_bool_t
    897 socket_connection_set (DBusTransport *transport)
    898 {
    899   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    900 
    901   _dbus_watch_set_handler (socket_transport->write_watch,
    902                            _dbus_connection_handle_watch,
    903                            transport->connection, NULL);
    904 
    905   _dbus_watch_set_handler (socket_transport->read_watch,
    906                            _dbus_connection_handle_watch,
    907                            transport->connection, NULL);
    908 
    909   if (!_dbus_connection_add_watch_unlocked (transport->connection,
    910                                             socket_transport->write_watch))
    911     return FALSE;
    912 
    913   if (!_dbus_connection_add_watch_unlocked (transport->connection,
    914                                             socket_transport->read_watch))
    915     {
    916       _dbus_connection_remove_watch_unlocked (transport->connection,
    917                                               socket_transport->write_watch);
    918       return FALSE;
    919     }
    920 
    921   check_read_watch (transport);
    922   check_write_watch (transport);
    923 
    924   return TRUE;
    925 }
    926 
    927 /**
    928  * @todo We need to have a way to wake up the select sleep if
    929  * a new iteration request comes in with a flag (read/write) that
    930  * we're not currently serving. Otherwise a call that just reads
    931  * could block a write call forever (if there are no incoming
    932  * messages).
    933  */
    934 static  void
    935 socket_do_iteration (DBusTransport *transport,
    936                    unsigned int   flags,
    937                    int            timeout_milliseconds)
    938 {
    939   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
    940   DBusPollFD poll_fd;
    941   int poll_res;
    942   int poll_timeout;
    943 
    944   _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
    945                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
    946                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
    947                  timeout_milliseconds,
    948                  socket_transport->read_watch,
    949                  socket_transport->write_watch,
    950                  socket_transport->fd);
    951 
    952   /* the passed in DO_READING/DO_WRITING flags indicate whether to
    953    * read/write messages, but regardless of those we may need to block
    954    * for reading/writing to do auth.  But if we do reading for auth,
    955    * we don't want to read any messages yet if not given DO_READING.
    956    */
    957 
    958   poll_fd.fd = socket_transport->fd;
    959   poll_fd.events = 0;
    960 
    961   if (_dbus_transport_get_is_authenticated (transport))
    962     {
    963       /* This is kind of a hack; if we have stuff to write, then try
    964        * to avoid the poll. This is probably about a 5% speedup on an
    965        * echo client/server.
    966        *
    967        * If both reading and writing were requested, we want to avoid this
    968        * since it could have funky effects:
    969        *   - both ends spinning waiting for the other one to read
    970        *     data so they can finish writing
    971        *   - prioritizing all writing ahead of reading
    972        */
    973       if ((flags & DBUS_ITERATION_DO_WRITING) &&
    974           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
    975           !transport->disconnected &&
    976           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
    977         {
    978           do_writing (transport);
    979 
    980           if (transport->disconnected ||
    981               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
    982             goto out;
    983         }
    984 
    985       /* If we get here, we decided to do the poll() after all */
    986       _dbus_assert (socket_transport->read_watch);
    987       if (flags & DBUS_ITERATION_DO_READING)
    988 	poll_fd.events |= _DBUS_POLLIN;
    989 
    990       _dbus_assert (socket_transport->write_watch);
    991       if (flags & DBUS_ITERATION_DO_WRITING)
    992         poll_fd.events |= _DBUS_POLLOUT;
    993     }
    994   else
    995     {
    996       DBusAuthState auth_state;
    997 
    998       auth_state = _dbus_auth_do_work (transport->auth);
    999 
   1000       if (transport->receive_credentials_pending ||
   1001           auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
   1002 	poll_fd.events |= _DBUS_POLLIN;
   1003 
   1004       if (transport->send_credentials_pending ||
   1005           auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
   1006 	poll_fd.events |= _DBUS_POLLOUT;
   1007     }
   1008 
   1009   if (poll_fd.events)
   1010     {
   1011       if (flags & DBUS_ITERATION_BLOCK)
   1012 	poll_timeout = timeout_milliseconds;
   1013       else
   1014 	poll_timeout = 0;
   1015 
   1016       /* For blocking selects we drop the connection lock here
   1017        * to avoid blocking out connection access during a potentially
   1018        * indefinite blocking call. The io path is still protected
   1019        * by the io_path_cond condvar, so we won't reenter this.
   1020        */
   1021       if (flags & DBUS_ITERATION_BLOCK)
   1022         {
   1023           _dbus_verbose ("unlock %s pre poll\n", _DBUS_FUNCTION_NAME);
   1024           _dbus_connection_unlock (transport->connection);
   1025         }
   1026 
   1027     again:
   1028       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
   1029 
   1030       if (poll_res < 0 && errno == EINTR)
   1031 	goto again;
   1032 
   1033       if (flags & DBUS_ITERATION_BLOCK)
   1034         {
   1035           _dbus_verbose ("lock %s post poll\n", _DBUS_FUNCTION_NAME);
   1036           _dbus_connection_lock (transport->connection);
   1037         }
   1038 
   1039       if (poll_res >= 0)
   1040         {
   1041           if (poll_res == 0)
   1042             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
   1043                                   * valgrind flags it as an error. though it probably
   1044                                   * is guaranteed on linux at least.
   1045                                   */
   1046 
   1047           if (poll_fd.revents & _DBUS_POLLERR)
   1048             do_io_error (transport);
   1049           else
   1050             {
   1051               dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
   1052               dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
   1053 	      dbus_bool_t authentication_completed;
   1054 
   1055               _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
   1056                              need_read, need_write);
   1057               do_authentication (transport, need_read, need_write,
   1058 				 &authentication_completed);
   1059 
   1060 	      /* See comment in socket_handle_watch. */
   1061 	      if (authentication_completed)
   1062                 goto out;
   1063 
   1064               if (need_read && (flags & DBUS_ITERATION_DO_READING))
   1065                 do_reading (transport);
   1066               if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
   1067                 do_writing (transport);
   1068             }
   1069         }
   1070       else
   1071         {
   1072           _dbus_verbose ("Error from _dbus_poll(): %s\n",
   1073                          _dbus_strerror (errno));
   1074         }
   1075     }
   1076 
   1077 
   1078  out:
   1079   /* We need to install the write watch only if we did not
   1080    * successfully write everything. Note we need to be careful that we
   1081    * don't call check_write_watch *before* do_writing, since it's
   1082    * inefficient to add the write watch, and we can avoid it most of
   1083    * the time since we can write immediately.
   1084    *
   1085    * However, we MUST always call check_write_watch(); DBusConnection code
   1086    * relies on the fact that running an iteration will notice that
   1087    * messages are pending.
   1088    */
   1089   check_write_watch (transport);
   1090 
   1091   _dbus_verbose (" ... leaving do_iteration()\n");
   1092 }
   1093 
   1094 static void
   1095 socket_live_messages_changed (DBusTransport *transport)
   1096 {
   1097   /* See if we should look for incoming messages again */
   1098   check_read_watch (transport);
   1099 }
   1100 
   1101 
   1102 static dbus_bool_t
   1103 socket_get_socket_fd (DBusTransport *transport,
   1104                       int           *fd_p)
   1105 {
   1106   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
   1107 
   1108   *fd_p = socket_transport->fd;
   1109 
   1110   return TRUE;
   1111 }
   1112 
   1113 static const DBusTransportVTable socket_vtable = {
   1114   socket_finalize,
   1115   socket_handle_watch,
   1116   socket_disconnect,
   1117   socket_connection_set,
   1118   socket_do_iteration,
   1119   socket_live_messages_changed,
   1120   socket_get_socket_fd
   1121 };
   1122 
   1123 /**
   1124  * Creates a new transport for the given socket file descriptor.  The file
   1125  * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
   1126  * make it so). This function is shared by various transports that
   1127  * boil down to a full duplex file descriptor.
   1128  *
   1129  * @param fd the file descriptor.
   1130  * @param server_guid non-#NULL if this transport is on the server side of a connection
   1131  * @param address the transport's address
   1132  * @returns the new transport, or #NULL if no memory.
   1133  */
   1134 DBusTransport*
   1135 _dbus_transport_new_for_socket (int               fd,
   1136                                 const DBusString *server_guid,
   1137                                 const DBusString *address)
   1138 {
   1139   DBusTransportSocket *socket_transport;
   1140 
   1141   socket_transport = dbus_new0 (DBusTransportSocket, 1);
   1142   if (socket_transport == NULL)
   1143     return NULL;
   1144 
   1145   if (!_dbus_string_init (&socket_transport->encoded_outgoing))
   1146     goto failed_0;
   1147 
   1148   if (!_dbus_string_init (&socket_transport->encoded_incoming))
   1149     goto failed_1;
   1150 
   1151   socket_transport->write_watch = _dbus_watch_new (fd,
   1152                                                  DBUS_WATCH_WRITABLE,
   1153                                                  FALSE,
   1154                                                  NULL, NULL, NULL);
   1155   if (socket_transport->write_watch == NULL)
   1156     goto failed_2;
   1157 
   1158   socket_transport->read_watch = _dbus_watch_new (fd,
   1159                                                 DBUS_WATCH_READABLE,
   1160                                                 FALSE,
   1161                                                 NULL, NULL, NULL);
   1162   if (socket_transport->read_watch == NULL)
   1163     goto failed_3;
   1164 
   1165   if (!_dbus_transport_init_base (&socket_transport->base,
   1166                                   &socket_vtable,
   1167                                   server_guid, address))
   1168     goto failed_4;
   1169 
   1170   socket_transport->fd = fd;
   1171   socket_transport->message_bytes_written = 0;
   1172 
   1173   /* These values should probably be tunable or something. */
   1174   socket_transport->max_bytes_read_per_iteration = 2048;
   1175   socket_transport->max_bytes_written_per_iteration = 2048;
   1176 
   1177   return (DBusTransport*) socket_transport;
   1178 
   1179  failed_4:
   1180   _dbus_watch_unref (socket_transport->read_watch);
   1181  failed_3:
   1182   _dbus_watch_unref (socket_transport->write_watch);
   1183  failed_2:
   1184   _dbus_string_free (&socket_transport->encoded_incoming);
   1185  failed_1:
   1186   _dbus_string_free (&socket_transport->encoded_outgoing);
   1187  failed_0:
   1188   dbus_free (socket_transport);
   1189   return NULL;
   1190 }
   1191 
   1192 /**
   1193  * Creates a new transport for the given hostname and port.
   1194  *
   1195  * @param host the host to connect to
   1196  * @param port the port to connect to
   1197  * @param error location to store reason for failure.
   1198  * @returns a new transport, or #NULL on failure.
   1199  */
   1200 DBusTransport*
   1201 _dbus_transport_new_for_tcp_socket (const char     *host,
   1202                                     dbus_int32_t    port,
   1203                                     DBusError      *error)
   1204 {
   1205   int fd;
   1206   DBusTransport *transport;
   1207   DBusString address;
   1208 
   1209   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1210 
   1211   if (!_dbus_string_init (&address))
   1212     {
   1213       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
   1214       return NULL;
   1215     }
   1216 
   1217   if (!_dbus_string_append (&address, "tcp:"))
   1218     goto error;
   1219 
   1220   if (host != NULL &&
   1221        (!_dbus_string_append (&address, "host=") ||
   1222         !_dbus_string_append (&address, host)))
   1223     goto error;
   1224 
   1225   if (!_dbus_string_append (&address, ",port=") ||
   1226       !_dbus_string_append_int (&address, port))
   1227     goto error;
   1228 
   1229   fd = _dbus_connect_tcp_socket (host, port, error);
   1230   if (fd < 0)
   1231     {
   1232       _DBUS_ASSERT_ERROR_IS_SET (error);
   1233       _dbus_string_free (&address);
   1234       return NULL;
   1235     }
   1236 
   1237   _dbus_fd_set_close_on_exec (fd);
   1238 
   1239   _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
   1240                  host, port);
   1241 
   1242   transport = _dbus_transport_new_for_socket (fd, NULL, &address);
   1243   if (transport == NULL)
   1244     {
   1245       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
   1246       _dbus_close_socket (fd, NULL);
   1247       _dbus_string_free (&address);
   1248       fd = -1;
   1249     }
   1250 
   1251   _dbus_string_free (&address);
   1252 
   1253   return transport;
   1254 
   1255 error:
   1256   _dbus_string_free (&address);
   1257   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
   1258   return NULL;
   1259 }
   1260 
   1261 /**
   1262  * Opens a TCP socket transport.
   1263  *
   1264  * @param entry the address entry to try opening as a tcp transport.
   1265  * @param transport_p return location for the opened transport
   1266  * @param error error to be set
   1267  * @returns result of the attempt
   1268  */
   1269 DBusTransportOpenResult
   1270 _dbus_transport_open_socket(DBusAddressEntry  *entry,
   1271                             DBusTransport    **transport_p,
   1272                             DBusError         *error)
   1273 {
   1274   const char *method;
   1275 
   1276   method = dbus_address_entry_get_method (entry);
   1277   _dbus_assert (method != NULL);
   1278 
   1279   if (strcmp (method, "tcp") == 0)
   1280     {
   1281       const char *host = dbus_address_entry_get_value (entry, "host");
   1282       const char *port = dbus_address_entry_get_value (entry, "port");
   1283       DBusString  str;
   1284       long lport;
   1285       dbus_bool_t sresult;
   1286 
   1287       if (port == NULL)
   1288         {
   1289           _dbus_set_bad_address (error, "tcp", "port", NULL);
   1290           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
   1291         }
   1292 
   1293       _dbus_string_init_const (&str, port);
   1294       sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
   1295       _dbus_string_free (&str);
   1296 
   1297       if (sresult == FALSE || lport <= 0 || lport > 65535)
   1298         {
   1299           _dbus_set_bad_address (error, NULL, NULL,
   1300                                  "Port is not an integer between 0 and 65535");
   1301           return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
   1302         }
   1303 
   1304       *transport_p = _dbus_transport_new_for_tcp_socket (host, lport, error);
   1305       if (*transport_p == NULL)
   1306         {
   1307           _DBUS_ASSERT_ERROR_IS_SET (error);
   1308           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
   1309         }
   1310       else
   1311         {
   1312           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1313           return DBUS_TRANSPORT_OPEN_OK;
   1314         }
   1315     }
   1316   else
   1317     {
   1318       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   1319       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
   1320     }
   1321 }
   1322 
   1323 /** @} */
   1324 
   1325