dbus-daemon emulation improved and refactored
[platform/upstream/dbus.git] / dbus / dbus-transport-kdbus.c
1 /*
2  * dbus-transport-kdbus.c
3  *
4  * Transport layer using kdbus
5  *
6  *  Created on: Jun 20, 2013
7  *      Author: r.pajak
8  *
9  *
10  */
11
12 #include "dbus-transport.h"
13 #include "dbus-transport-kdbus.h"
14 #include <dbus/dbus-transport-protected.h>
15 #include "dbus-connection-internal.h"
16 #include "kdbus.h"
17 #include "dbus-watch.h"
18 #include "dbus-errors.h"
19 #include "dbus-bus.h"
20 #include <linux/types.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/mman.h>
30 #include <limits.h>
31 #include <sys/stat.h>
32 #include <openssl/md5.h>
33
34 #define KDBUS_ALIGN8(l) (((l) + 7) & ~7)
35 #define KDBUS_PART_HEADER_SIZE offsetof(struct kdbus_item, data)
36 #define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_PART_HEADER_SIZE)
37
38 #define KDBUS_PART_NEXT(part) \
39         (typeof(part))(((uint8_t *)part) + KDBUS_ALIGN8((part)->size))
40 #define KDBUS_PART_FOREACH(part, head, first)                           \
41         for (part = (head)->first;                                      \
42              (uint8_t *)(part) < (uint8_t *)(head) + (head)->size;      \
43              part = KDBUS_PART_NEXT(part))
44 #define RECEIVE_POOL_SIZE (10 * 1024LU * 1024LU)
45 #define MEMFD_SIZE_THRESHOLD (2 * 1024 * 1024LU) // over this memfd is used
46
47 #define KDBUS_MSG_DECODE_DEBUG 0
48
49 #define ITER_APPEND_STR(string) \
50 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &string))   \
51 { \
52         ret_size = -1;  \
53         goto out;  \
54 }\
55
56 /**
57  * Opaque object representing a socket file descriptor transport.
58  */
59 typedef struct DBusTransportSocket DBusTransportSocket;
60
61 /**
62  * Implementation details of DBusTransportSocket. All members are private.
63  */
64 struct DBusTransportSocket
65 {
66   DBusTransport base;                   /**< Parent instance */
67   int fd;                               /**< File descriptor. */
68   DBusWatch *read_watch;                /**< Watch for readability. */
69   DBusWatch *write_watch;               /**< Watch for writability. */
70
71   int max_bytes_read_per_iteration;     /**< In kdbus only to control overall message size*/
72   int max_bytes_written_per_iteration;  /**< In kdbus only to control overall message size*/
73
74   int message_bytes_written;            /**< Number of bytes of current
75                                          *   outgoing message that have
76                                          *   been written.
77                                          */
78   DBusString encoded_outgoing;          /**< Encoded version of current
79                                          *   outgoing message.
80                                          */
81   DBusString encoded_incoming;          /**< Encoded version of current
82                                          *   incoming data.
83                                          */
84   void* kdbus_mmap_ptr;                 /**< Mapped memory where Kdbus (kernel) writes
85                                          *   messages incoming to us.
86                                          */
87   int memfd;                            /**< File descriptor to special 
88                                          *   memory pool for bulk data
89                                          *   transfer. Retrieved from 
90                                          *   Kdbus kernel module. 
91                                          */
92   __u64 bloom_size;                                             /**<  bloom filter field size */
93 };
94
95 static dbus_bool_t
96 socket_get_socket_fd (DBusTransport *transport,
97                       int           *fd_p)
98 {
99   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
100
101   *fd_p = socket_transport->fd;
102
103   return TRUE;
104 }
105
106 /*
107  * Adds locally generated message to received messages queue
108  *
109  */
110 static dbus_bool_t add_message_to_received(DBusMessage *message, DBusConnection* connection)
111 {
112         DBusList *message_link;
113
114         message_link = _dbus_list_alloc_link (message);
115         if (message_link == NULL)
116         {
117                 dbus_message_unref (message);
118                 return FALSE;
119         }
120
121         _dbus_connection_queue_synthesized_message_link(connection, message_link);
122
123         return TRUE;
124 }
125
126 static dbus_bool_t reply_with_error(char* error_type, const char* template, const char* object, DBusMessage *message, DBusConnection* connection)
127 {
128         DBusMessage *errMessage;
129         char* error_msg = "";
130
131         if(template)
132         {
133                 error_msg = alloca(strlen(template) + strlen(object));
134                 sprintf(error_msg, template, object);
135         }
136         else if(object)
137                 error_msg = (char*)object;
138
139         errMessage = generate_local_error_message(dbus_message_get_serial(message), error_type, error_msg);
140         if(errMessage == NULL)
141                 return FALSE;
142         if (add_message_to_received(errMessage, connection))
143                 return TRUE;
144
145         return FALSE;
146 }
147
148 static dbus_bool_t reply_1_data(DBusMessage *message, int data_type, void* pData, DBusConnection* connection)
149 {
150         DBusMessageIter args;
151         DBusMessage *reply;
152
153         reply = dbus_message_new_method_return(message);
154         if(reply == NULL)
155                 return FALSE;
156         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
157     dbus_message_iter_init_append(reply, &args);
158     if (!dbus_message_iter_append_basic(&args, data_type, pData))
159     {
160         dbus_message_unref(reply);
161         return FALSE;
162     }
163     if(add_message_to_received(reply, connection))
164         return TRUE;
165
166     return FALSE;
167 }
168
169 /**
170  * Retrieves file descriptor to memory pool from kdbus module.
171  * It is then used for bulk data sending.
172  * Triggered when message payload is over MEMFD_SIZE_THRESHOLD
173  * 
174  */
175 static int kdbus_init_memfd(DBusTransportSocket* socket_transport)
176 {
177         int memfd;
178         
179         if(socket_transport->memfd == -1) 
180         {
181                 if (ioctl(socket_transport->fd, KDBUS_CMD_MEMFD_NEW, &memfd) < 0) {
182                         _dbus_verbose("KDBUS_CMD_MEMFD_NEW failed: \n");
183                         return -1;
184                 }
185
186                 socket_transport->memfd = memfd;
187                 _dbus_verbose("kdbus_init_memfd: %d!!\n", socket_transport->memfd);
188         }
189         return 0;
190 }
191
192 /**
193  * Initiates Kdbus message structure. 
194  * Calculates it's size, allocates memory and fills some fields.
195  * @param name Well-known name or NULL
196  * @param dst_id Numeric id of recipient
197  * @param body_size size of message body if present
198  * @param use_memfd flag to build memfd message
199  * @param fds_count number of file descriptors used
200  * @param transport transport
201  * @return initialized kdbus message
202  */
203 static struct kdbus_msg* kdbus_init_msg(const char* name, __u64 dst_id, uint64_t body_size, dbus_bool_t use_memfd, int fds_count, DBusTransportSocket *transport)
204 {
205     struct kdbus_msg* msg;
206     uint64_t msg_size;
207
208     msg_size = sizeof(struct kdbus_msg);
209
210     if(use_memfd == TRUE)  // bulk data - memfd - encoded and plain
211         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_memfd));
212     else {
213         msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
214         if(body_size)
215                 msg_size += KDBUS_ITEM_SIZE(sizeof(struct kdbus_vec));
216     }
217
218     if(fds_count)
219         msg_size += KDBUS_ITEM_SIZE(sizeof(int)*fds_count);
220
221     if (name)
222         msg_size += KDBUS_ITEM_SIZE(strlen(name) + 1);
223     else if (dst_id == KDBUS_DST_ID_BROADCAST)
224         msg_size += KDBUS_PART_HEADER_SIZE + transport->bloom_size;
225
226     msg = malloc(msg_size);
227     if (!msg)
228     {
229         _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
230                 return NULL;
231     }
232
233     memset(msg, 0, msg_size);
234     msg->size = msg_size;
235     msg->payload_type = KDBUS_PAYLOAD_DBUS1;
236     msg->dst_id = name ? 0 : dst_id;
237     msg->src_id = strtoull(dbus_bus_get_unique_name(transport->base.connection), NULL , 10);
238
239     return msg;
240 }
241
242 /**
243  * Builds and sends kdbus message using Dbus message.
244  * Decide whether used payload vector or memfd memory pool.
245  * Handles broadcasts and unicast messages, and passing of Unix fds.
246  * Does error handling.
247  * TODO refactor to be more compact
248  *
249  * @param transport transport
250  * @param message DBus message to be sent
251  * @param encoded flag if the message is encoded
252  * @return size of data sent
253  */
254 static int kdbus_write_msg(DBusTransportSocket *transport, DBusMessage *message, dbus_bool_t encoded)
255 {
256     struct kdbus_msg *msg;
257     struct kdbus_item *item;
258     const char *name;
259     uint64_t dst_id = KDBUS_DST_ID_BROADCAST;
260     const DBusString *header;
261     const DBusString *body;
262     uint64_t ret_size = 0;
263     uint64_t body_size = 0;
264     uint64_t header_size = 0;
265     dbus_bool_t use_memfd;
266     const int *unix_fds;
267     unsigned fds_count;
268
269     // determine name and destination id
270     if((name = dbus_message_get_destination(message)))
271     {
272         dst_id = KDBUS_DST_ID_WELL_KNOWN_NAME;
273                 if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
274         {
275                 dst_id = strtoull(&name[3], NULL, 10);
276                 name = NULL;
277         }    
278     }
279     
280     // get size of data
281     if(encoded)
282         ret_size = _dbus_string_get_length (&transport->encoded_outgoing);
283     else
284     {
285         _dbus_message_get_network_data (message, &header, &body);
286         header_size = _dbus_string_get_length(header);
287         body_size = _dbus_string_get_length(body);
288         ret_size = header_size + body_size;
289     }
290
291     // check if message size is big enough to use memfd kdbus transport
292     use_memfd = ret_size > MEMFD_SIZE_THRESHOLD ? TRUE : FALSE;
293     if(use_memfd) kdbus_init_memfd(transport);
294     
295     _dbus_message_get_unix_fds(message, &unix_fds, &fds_count);
296
297     // init basic message fields
298     msg = kdbus_init_msg(name, dst_id, body_size, use_memfd, fds_count, transport);
299     msg->cookie = dbus_message_get_serial(message);
300     
301     // build message contents
302     item = msg->items;
303
304     // case 1 - bulk data transfer - memfd - encoded and plain
305     if(use_memfd)          
306     {
307         char *buf;
308
309         if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 0) < 0)
310             {
311                         _dbus_verbose("memfd sealing failed: \n");
312                         goto out;
313             }
314
315             buf = mmap(NULL, ret_size, PROT_WRITE, MAP_SHARED, transport->memfd, 0);
316             if (buf == MAP_FAILED) 
317             {
318                         _dbus_verbose("mmap() fd=%i failed:%m", transport->memfd);
319                         goto out;
320             }
321
322                 if(encoded)
323                         memcpy(buf, &transport->encoded_outgoing, ret_size);
324                 else
325                 {
326                         memcpy(buf, _dbus_string_get_const_data(header), header_size);
327                         if(body_size) {
328                                 buf+=header_size;
329                                 memcpy(buf, _dbus_string_get_const_data(body),  body_size);
330                                 buf-=header_size;
331                         }
332                 }
333
334                 munmap(buf, ret_size);
335
336                 // seal data - kdbus module needs it
337                 if(ioctl(transport->memfd, KDBUS_CMD_MEMFD_SEAL_SET, 1) < 0) {
338                         _dbus_verbose("memfd sealing failed: %d (%m)\n", errno);
339                         ret_size = -1;
340                         goto out;
341                 }
342
343             item->type = KDBUS_MSG_PAYLOAD_MEMFD;
344                 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_memfd);
345                 item->memfd.size = ret_size;
346                 item->memfd.fd = transport->memfd;
347     // case 2 - small encoded - don't use memfd
348     } else if(encoded) { 
349         _dbus_verbose("sending encoded data\n");
350
351         item->type = KDBUS_MSG_PAYLOAD_VEC;
352         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
353         item->vec.address = (unsigned long) &transport->encoded_outgoing;
354         item->vec.size = _dbus_string_get_length (&transport->encoded_outgoing);
355
356     // case 3 - small not encoded - don't use memfd
357     } else { 
358         _dbus_verbose("sending normal vector data\n");
359
360         item->type = KDBUS_MSG_PAYLOAD_VEC;
361         item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
362         item->vec.address = (unsigned long) _dbus_string_get_const_data(header);
363         item->vec.size = header_size;
364
365         if(body_size)
366         {
367             _dbus_verbose("body attaching\n");
368                 item = KDBUS_PART_NEXT(item);
369                 item->type = KDBUS_MSG_PAYLOAD_VEC;
370                 item->size = KDBUS_PART_HEADER_SIZE + sizeof(struct kdbus_vec);
371                 item->vec.address = (unsigned long) _dbus_string_get_const_data(body);
372                 item->vec.size = body_size;
373         }
374     }
375
376     if(fds_count)
377     {
378         item = KDBUS_PART_NEXT(item);
379         item->type = KDBUS_MSG_FDS;
380         item->size = KDBUS_PART_HEADER_SIZE + (sizeof(int) * fds_count);
381         memcpy(item->fds, unix_fds, sizeof(int) * fds_count);
382     }
383
384         if (name)
385         {
386                 item = KDBUS_PART_NEXT(item);
387                 item->type = KDBUS_MSG_DST_NAME;
388                 item->size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
389                 strcpy(item->str, name);
390         }
391         else if (dst_id == KDBUS_DST_ID_BROADCAST)
392         {
393                 item = KDBUS_PART_NEXT(item);
394                 item->type = KDBUS_MSG_BLOOM;
395                 item->size = KDBUS_PART_HEADER_SIZE + transport->bloom_size;
396                 strncpy(item->data, dbus_message_get_interface(message), transport->bloom_size);
397         }
398
399         again:
400         if (ioctl(transport->fd, KDBUS_CMD_MSG_SEND, msg))
401         {
402                 if(errno == EINTR)
403                         goto again;
404                 if((errno == ESRCH) || (errno == ENXIO))  //when recipient is not available on the bus
405                 {
406                         if (dbus_message_get_auto_start (message))
407                         {
408                                 //todo start service here, otherwise
409                                 if(reply_with_error(DBUS_ERROR_SERVICE_UNKNOWN, "The name %s was not provided by any .service files", dbus_message_get_destination(message), message, transport->base.connection))
410                                         goto out;
411                         }
412                         else
413                                 if(reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Name \"%s\" does not exist", dbus_message_get_destination(message), message, transport->base.connection))
414                                         goto out;
415
416                 }
417                 _dbus_verbose("kdbus error sending message: err %d (%m)\n", errno);
418                 ret_size = -1;
419         }
420 out:
421     free(msg);
422
423     return ret_size;
424 }
425
426 struct nameInfo
427 {
428         __u64 uniqueId;
429         __u64 userId;
430         __u64 processId;
431 };
432
433 /**
434  * Performs kdbus query of id of the given name
435  *
436  * @param name name to query for
437  * @param fd bus file
438  * @param ownerID place to store id of the name
439  * @return 0 on success, -errno if failed
440  */
441 static int kdbus_NameQuery(char* name, int fd, struct nameInfo* pInfo)
442 {
443         struct kdbus_cmd_name_info *msg;
444         struct kdbus_item *item;
445         uint64_t size;
446         int ret;
447         uint64_t item_size;
448
449     item_size = KDBUS_PART_HEADER_SIZE + strlen(name) + 1;
450         item_size = (item_size < 56) ? 56 : item_size;  //56 bytes are needed by kernel to place a lot of unnecessary info about name, otherwise error
451     size = sizeof(struct kdbus_cmd_name_info) + item_size;
452
453         msg = malloc(size);
454         if (!msg)
455         {
456                 _dbus_verbose("Error allocating memory for: %s,%s\n", _dbus_strerror (errno), _dbus_error_from_errno (errno));
457                 return -1;
458         }
459
460         memset(msg, 0, size);
461         msg->size = size;
462         if((name[0] == ':') && (name[1] == '1') && (name[2] == '.'))  /* if name starts with ":1." it is a unique name and should be send as number */
463                 msg->id = strtoull(&name[3], NULL, 10);
464         else
465                 msg->id = 0;
466
467         item = msg->items;
468         item->type = KDBUS_NAME_INFO_ITEM_NAME;
469         item->size = item_size;
470         strcpy(item->str, name);
471
472         again:
473         if ((ret = ioctl(fd, KDBUS_CMD_NAME_QUERY, msg)))
474         {
475                 if(errno == EINTR)
476                         goto again;
477                 pInfo->uniqueId = 0;
478                 ret = -errno;
479         }
480         else
481         {
482                 pInfo->uniqueId = msg->id;
483                 pInfo->userId = msg->creds.uid;
484                 pInfo->processId = msg->creds.pid;
485         }
486
487         free(msg);
488         return ret;
489 }
490
491 /**
492  * Handles messages sent to bus daemon - "org.freedesktop.DBus" and translates them to appropriate
493  * kdbus ioctl commands. Than translate kdbus reply into dbus message and put it into recived messages queue.
494  *
495  * !!! Not all methods are handled !!! Doubt if it is even possible.
496  * If method is not handled, returns error reply org.freedesktop.DBus.Error.UnknownMethod
497  *
498  * Handled methods:
499  * - GetNameOwner
500  * - NameHasOwner
501  * - ListNames
502  *
503  * Not handled methods:
504  * - ListActivatableNames
505  * - StartServiceByName
506  * - UpdateActivationEnvironment
507  * - GetConnectionUnixUser
508  * - GetId
509  */
510 static dbus_bool_t emulateOrgFreedesktopDBus(DBusTransport *transport, DBusMessage *message)
511 {
512         int ret;
513
514         if(!strcmp(dbus_message_get_member(message), "GetNameOwner"))  //returns id of the well known name
515         {
516                 char* name = NULL;
517                 struct nameInfo info;
518
519                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
520                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
521                 if(ret == 0) //unique id of the name
522                 {
523                         char unique_name[(unsigned int)(snprintf(name, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
524                         const char* pString = unique_name;
525
526                         sprintf(unique_name, ":1.%llu", (unsigned long long int)info.uniqueId);
527                         _dbus_verbose("Unique name discovered:%s\n", unique_name);
528                         return reply_1_data(message, DBUS_TYPE_STRING, &pString, transport->connection);
529                 }
530                 else if(ret == -ENOENT)  //name has no owner
531                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owner of name '%s': no such name", name, message, transport->connection);
532                 else
533                 {
534                         _dbus_verbose("kdbus error sending name query: err %d (%m)\n", errno);
535                         return reply_with_error(DBUS_ERROR_FAILED, "Could not determine unique name for '%s'", name, message, transport->connection);
536                 }
537         }
538         else if(!strcmp(dbus_message_get_member(message), "NameHasOwner"))   //returns if name is currently registered on the bus
539         {
540                 char* name = NULL;
541                 dbus_bool_t result;
542                 struct nameInfo info;
543
544                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
545                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
546                 if((ret == 0) || (ret == -ENOENT))
547                 {
548                         result = (ret == 0) ? TRUE : FALSE;
549                         return reply_1_data(message, DBUS_TYPE_BOOLEAN, &result, transport->connection);
550                 }
551                 else
552                 {
553                         _dbus_verbose("kdbus error checking if name exists: err %d (%m)\n", errno);
554                         return reply_with_error(DBUS_ERROR_FAILED, "Could not determine whether name '%s' exists", name, message, transport->connection);
555                 }
556         }
557         else if(!strcmp(dbus_message_get_member(message), "GetConnectionUnixUser"))
558         {
559                 char* name = NULL;
560                 struct nameInfo info;
561
562                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
563                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
564                 if(ret == 0) //name found
565                 {
566                         _dbus_verbose("User id:%llu\n", (unsigned long long) info.userId);
567                         return reply_1_data(message, DBUS_TYPE_UINT32, &info.userId, transport->connection);
568                 }
569                 else if(ret == -ENOENT)  //name has no owner
570                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get UID of name '%s': no such name", name, message, transport->connection);
571                 else
572                 {
573                         _dbus_verbose("kdbus error determining UID: err %d (%m)\n", errno);
574                         return reply_with_error(DBUS_ERROR_FAILED, "Could not determine UID for '%s'", name, message, transport->connection);
575                 }
576         }
577         else if(!strcmp(dbus_message_get_member(message), "GetConnectionUnixProcessID"))
578         {
579                 char* name = NULL;
580                 struct nameInfo info;
581
582                 dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
583                 ret = kdbus_NameQuery(name, ((DBusTransportSocket*)transport)->fd, &info);
584                 if(ret == 0) //name found
585                         return reply_1_data(message, DBUS_TYPE_UINT32, &info.processId, transport->connection);
586                 else if(ret == -ENOENT)  //name has no owner
587                         return reply_with_error(DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get PID of name '%s': no such name", name, message, transport->connection);
588                 else
589                 {
590                         _dbus_verbose("kdbus error determining PID: err %d (%m)\n", errno);
591                         return reply_with_error(DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN,"Could not determine PID for '%s'", name, message, transport->connection);
592                 }
593         }
594         else if(!strcmp(dbus_message_get_member(message), "ListNames"))  //return all well known names on he bus
595         {
596                 struct kdbus_cmd_names* pCmd;
597                 uint64_t cmd_size;
598
599                 cmd_size = sizeof(struct kdbus_cmd_names) + KDBUS_ITEM_SIZE(1);
600                 pCmd = malloc(cmd_size);
601                 if(pCmd == NULL)
602                         goto out;
603                 pCmd->size = cmd_size;
604
605   again:
606                 cmd_size = 0;
607                 if(ioctl(((DBusTransportSocket*)transport)->fd, KDBUS_CMD_NAME_LIST, pCmd))
608                 {
609                         if(errno == EINTR)
610                                 goto again;
611                         if(errno == ENOBUFS)                    //buffer to small to put all names into it
612                                 cmd_size = pCmd->size;          //here kernel tells how much memory it needs
613                         else
614                         {
615                                 _dbus_verbose("kdbus error asking for name list: err %d (%m)\n",errno);
616                                 goto out;
617                         }
618                 }
619                 if(cmd_size)  //kernel needs more memory
620                 {
621                         pCmd = realloc(pCmd, cmd_size);  //prepare memory
622                         if(pCmd == NULL)
623                                 return FALSE;
624                         goto again;                                             //and try again
625                 }
626                 else
627                 {
628                         DBusMessage *reply;
629                         DBusMessageIter args;
630                         struct kdbus_cmd_name* pCmd_name;
631                         char* pName;
632
633                         reply = dbus_message_new_method_return(message);
634                         if(reply == NULL)
635                                 goto out;
636                         dbus_message_set_sender(reply, DBUS_SERVICE_DBUS);
637                         dbus_message_iter_init_append(reply, &args);
638
639                         for (pCmd_name = pCmd->names; (uint8_t *)(pCmd_name) < (uint8_t *)(pCmd) + pCmd->size; pCmd_name = KDBUS_PART_NEXT(pCmd_name))
640                         {
641                                 pName = pCmd_name->name;
642                                 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &pName))
643                                 {
644                                         dbus_message_unref(reply);
645                                         goto out;
646                                 }
647                         }
648
649                         if(add_message_to_received(reply, transport->connection))
650                         {
651                                 free(pCmd);
652                                 return TRUE;
653                         }
654                 }
655
656 out:
657                 if(pCmd)
658                         free(pCmd);
659         }
660         else if(!strcmp(dbus_message_get_member(message), "GetId"))
661         {
662                 char* path;
663                 char uuid[DBUS_UUID_LENGTH_BYTES];
664                 struct stat stats;
665                 MD5_CTX md5;
666                 DBusString binary, encoded;
667                 int ret = FALSE;
668
669                 path = &transport->address[11]; //start of kdbus bus path
670                 if(stat(path, &stats) < -1)
671                 {
672                         _dbus_verbose("kdbus error reading stats of bus: err %d (%m)\n", errno);
673                         return reply_with_error(DBUS_ERROR_FAILED, "Could not determine bus '%s' uuid", path, message, transport->connection);
674                 }
675
676                 MD5_Init(&md5);
677         MD5_Update(&md5, path, strlen(path));
678         MD5_Update(&md5, &stats.st_ctim.tv_sec, sizeof(stats.st_ctim.tv_sec));
679                 MD5_Final(uuid, &md5);
680
681                 if(!_dbus_string_init (&encoded))
682                         goto outgid;
683                 _dbus_string_init_const_len (&binary, uuid, DBUS_UUID_LENGTH_BYTES);
684                 if(!_dbus_string_hex_encode (&binary, 0, &encoded, _dbus_string_get_length (&encoded)))
685                         goto outb;
686                 path = (char*)_dbus_string_get_const_data (&encoded);
687                 ret = reply_1_data(message, DBUS_TYPE_STRING, &path, transport->connection);
688
689         outb:
690                 _dbus_string_free(&binary);
691                 _dbus_string_free(&encoded);
692         outgid:
693                 return ret;
694         }
695         else
696                 return reply_with_error(DBUS_ERROR_UNKNOWN_METHOD, NULL, (char*)dbus_message_get_member(message), message, transport->connection);
697 /*      else if(!strcmp(dbus_message_get_member(message), "ListActivatableNames"))  //todo
698         {
699
700         }
701         else if(!strcmp(dbus_message_get_member(message), "StartServiceByName"))
702         {
703
704         }
705         else if(!strcmp(dbus_message_get_member(message), "UpdateActivationEnvironment"))
706         {
707
708         }*/
709
710         return FALSE;
711 }
712
713 #if KDBUS_MSG_DECODE_DEBUG == 1
714 static char *msg_id(uint64_t id, char *buf)
715 {
716         if (id == 0)
717                 return "KERNEL";
718         if (id == ~0ULL)
719                 return "BROADCAST";
720         sprintf(buf, "%llu", (unsigned long long)id);
721         return buf;
722 }
723 #endif
724 struct kdbus_enum_table {
725         long long id;
726         const char *name;
727 };
728 #define _STRINGIFY(x) #x
729 #define STRINGIFY(x) _STRINGIFY(x)
730 #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0]))
731 #define TABLE(what) static struct kdbus_enum_table kdbus_table_##what[]
732 #define ENUM(_id) { .id=_id, .name=STRINGIFY(_id) }
733 #define LOOKUP(what)                                                            \
734         const char *enum_##what(long long id) {                                 \
735         size_t i; \
736                 for (i = 0; i < ELEMENTSOF(kdbus_table_##what); i++)    \
737                         if (id == kdbus_table_##what[i].id)                     \
738                                 return kdbus_table_##what[i].name;              \
739                 return "UNKNOWN";                                               \
740         }
741 const char *enum_MSG(long long id);
742 TABLE(MSG) = {
743         ENUM(_KDBUS_MSG_NULL),
744         ENUM(KDBUS_MSG_PAYLOAD_VEC),
745         ENUM(KDBUS_MSG_PAYLOAD_OFF),
746         ENUM(KDBUS_MSG_PAYLOAD_MEMFD),
747         ENUM(KDBUS_MSG_FDS),
748         ENUM(KDBUS_MSG_BLOOM),
749         ENUM(KDBUS_MSG_DST_NAME),
750         ENUM(KDBUS_MSG_SRC_CREDS),
751         ENUM(KDBUS_MSG_SRC_PID_COMM),
752         ENUM(KDBUS_MSG_SRC_TID_COMM),
753         ENUM(KDBUS_MSG_SRC_EXE),
754         ENUM(KDBUS_MSG_SRC_CMDLINE),
755         ENUM(KDBUS_MSG_SRC_CGROUP),
756         ENUM(KDBUS_MSG_SRC_CAPS),
757         ENUM(KDBUS_MSG_SRC_SECLABEL),
758         ENUM(KDBUS_MSG_SRC_AUDIT),
759         ENUM(KDBUS_MSG_SRC_NAMES),
760         ENUM(KDBUS_MSG_TIMESTAMP),
761         ENUM(KDBUS_MSG_NAME_ADD),
762         ENUM(KDBUS_MSG_NAME_REMOVE),
763         ENUM(KDBUS_MSG_NAME_CHANGE),
764         ENUM(KDBUS_MSG_ID_ADD),
765         ENUM(KDBUS_MSG_ID_REMOVE),
766         ENUM(KDBUS_MSG_REPLY_TIMEOUT),
767         ENUM(KDBUS_MSG_REPLY_DEAD),
768 };
769 LOOKUP(MSG);
770 const char *enum_PAYLOAD(long long id);
771 TABLE(PAYLOAD) = {
772         ENUM(KDBUS_PAYLOAD_KERNEL),
773         ENUM(KDBUS_PAYLOAD_DBUS1),
774         ENUM(KDBUS_PAYLOAD_GVARIANT),
775 };
776 LOOKUP(PAYLOAD);
777
778 /**
779  * Puts locally generated message into received data buffer.
780  * Use only during receiving phase!
781  *
782  * @param message message to load
783  * @param data place to load message
784  * @return size of message
785  */
786 static int put_message_into_data(DBusMessage *message, char* data)
787 {
788         int ret_size;
789     const DBusString *header;
790     const DBusString *body;
791     int size;
792
793     dbus_message_lock (message);
794     _dbus_message_get_network_data (message, &header, &body);
795     ret_size = _dbus_string_get_length(header);
796         memcpy(data, _dbus_string_get_const_data(header), ret_size);
797         data += ret_size;
798         size = _dbus_string_get_length(body);
799         memcpy(data, _dbus_string_get_const_data(body), size);
800         ret_size += size;
801         dbus_message_unref(message);
802
803         return ret_size;
804 }
805 /**
806  * Decodes kdbus message in order to extract dbus message and put it into data and fds.
807  * Also captures and decodes kdbus error messages and kdbus kernel broadcasts and converts
808  * all of them into dbus messages.
809  *
810  * @param msg kdbus message
811  * @param data place to copy dbus message to
812  * @param socket_transport transport
813  * @param fds place to store file descriptors received
814  * @param n_fds place to store quantity of file descriptor
815  * @return number of dbus message's bytes received or -1 on error
816  */
817 static int kdbus_decode_msg(const struct kdbus_msg* msg, char *data, DBusTransportSocket* socket_transport, int* fds, int* n_fds)
818 {
819         const struct kdbus_item *item;
820         int ret_size = 0;
821         DBusMessage *message = NULL;
822         DBusMessageIter args;
823         const char* emptyString = "";
824     const char* pString = NULL;
825         char dbus_name[(unsigned int)(snprintf((char*)pString, 0, "%llu", ULLONG_MAX) + sizeof(":1."))];
826         const char* pDBusName = dbus_name;
827 #if KDBUS_MSG_DECODE_DEBUG == 1
828         char buf[32];
829 #endif
830
831 #if KDBUS_MSG_DECODE_DEBUG == 1
832         _dbus_verbose("MESSAGE: %s (%llu bytes) flags=0x%llx, %s â†’ %s, cookie=%llu, timeout=%llu\n",
833                 enum_PAYLOAD(msg->payload_type), (unsigned long long) msg->size,
834                 (unsigned long long) msg->flags,
835                 msg_id(msg->src_id, buf), msg_id(msg->dst_id, buf),
836                 (unsigned long long) msg->cookie, (unsigned long long) msg->timeout_ns);
837 #endif
838
839         *n_fds = 0;
840
841         KDBUS_PART_FOREACH(item, msg, items)
842         {
843                 if (item->size <= KDBUS_PART_HEADER_SIZE)
844                 {
845                         _dbus_verbose("  +%s (%llu bytes) invalid data record\n", enum_MSG(item->type), item->size);
846                         break;  //??? continue (because dbus will find error) or break
847                 }
848
849                 switch (item->type)
850                 {
851                         case KDBUS_MSG_PAYLOAD_OFF:
852                                 memcpy(data, (char *)socket_transport->kdbus_mmap_ptr + item->vec.offset, item->vec.size);
853                                 data += item->vec.size;
854                                 ret_size += item->vec.size;                     
855
856                                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
857                                         enum_MSG(item->type), item->size,
858                                         (unsigned long long)item->vec.offset,
859                                         (unsigned long long)item->vec.size);
860                         break;
861
862                         case KDBUS_MSG_PAYLOAD_MEMFD:
863                         {
864                                 char *buf;
865                                 uint64_t size;
866
867                 size = item->memfd.size;
868                                 _dbus_verbose("memfd.size : %llu\n", (unsigned long long)size);
869                                 
870                                 buf = mmap(NULL, size, PROT_READ , MAP_SHARED, item->memfd.fd, 0);
871                                 if (buf == MAP_FAILED) 
872                                 {
873                                         _dbus_verbose("mmap() fd=%i failed:%m", item->memfd.fd);
874                                         return -1;
875                                 }
876
877                                 memcpy(data, buf, size); 
878                                 data += size;
879                                 ret_size += size;
880
881                                 munmap(buf, size);
882
883                 _dbus_verbose("  +%s (%llu bytes) off=%llu size=%llu\n",
884                                            enum_MSG(item->type), item->size,
885                                            (unsigned long long)item->vec.offset,
886                                            (unsigned long long)item->vec.size);
887                         break;
888                         }
889
890                         case KDBUS_MSG_FDS:
891                         {
892                                 int i;
893
894                                 *n_fds = (item->size - KDBUS_PART_HEADER_SIZE) / sizeof(int);
895                                 memcpy(fds, item->fds, *n_fds * sizeof(int));
896                     for (i = 0; i < *n_fds; i++)
897                       _dbus_fd_set_close_on_exec(fds[i]);
898                         break;
899                         }
900
901 #if KDBUS_MSG_DECODE_DEBUG == 1
902                         case KDBUS_MSG_SRC_CREDS:
903                                 _dbus_verbose("  +%s (%llu bytes) uid=%lld, gid=%lld, pid=%lld, tid=%lld, starttime=%lld\n",
904                                         enum_MSG(item->type), item->size,
905                                         item->creds.uid, item->creds.gid,
906                                         item->creds.pid, item->creds.tid,
907                                         item->creds.starttime);
908                         break;
909
910                         case KDBUS_MSG_SRC_PID_COMM:
911                         case KDBUS_MSG_SRC_TID_COMM:
912                         case KDBUS_MSG_SRC_EXE:
913                         case KDBUS_MSG_SRC_CGROUP:
914                         case KDBUS_MSG_SRC_SECLABEL:
915                         case KDBUS_MSG_DST_NAME:
916                                 _dbus_verbose("  +%s (%llu bytes) '%s' (%zu)\n",
917                                            enum_MSG(item->type), item->size, item->str, strlen(item->str));
918                                 break;
919
920                         case KDBUS_MSG_SRC_CMDLINE:
921                         case KDBUS_MSG_SRC_NAMES: {
922                                 __u64 size = item->size - KDBUS_PART_HEADER_SIZE;
923                                 const char *str = item->str;
924                                 int count = 0;
925
926                                 _dbus_verbose("  +%s (%llu bytes) ", enum_MSG(item->type), item->size);
927                                 while (size) {
928                                         _dbus_verbose("'%s' ", str);
929                                         size -= strlen(str) + 1;
930                                         str += strlen(str) + 1;
931                                         count++;
932                                 }
933
934                                 _dbus_verbose("(%d string%s)\n", count, (count == 1) ? "" : "s");
935                                 break;
936                         }
937
938                         case KDBUS_MSG_SRC_AUDIT:
939                                 _dbus_verbose("  +%s (%llu bytes) loginuid=%llu sessionid=%llu\n",
940                                            enum_MSG(item->type), item->size,
941                                            (unsigned long long)item->data64[0],
942                                            (unsigned long long)item->data64[1]);
943                                 break;
944
945                         case KDBUS_MSG_SRC_CAPS: {
946                                 int n;
947                                 const uint32_t *cap;
948                                 int i;
949
950                                 _dbus_verbose("  +%s (%llu bytes) len=%llu bytes)\n",
951                                            enum_MSG(item->type), item->size,
952                                            (unsigned long long)item->size - KDBUS_PART_HEADER_SIZE);
953
954                                 cap = item->data32;
955                                 n = (item->size - KDBUS_PART_HEADER_SIZE) / 4 / sizeof(uint32_t);
956
957                                 _dbus_verbose("    CapInh=");
958                                 for (i = 0; i < n; i++)
959                                         _dbus_verbose("%08x", cap[(0 * n) + (n - i - 1)]);
960
961                                 _dbus_verbose(" CapPrm=");
962                                 for (i = 0; i < n; i++)
963                                         _dbus_verbose("%08x", cap[(1 * n) + (n - i - 1)]);
964
965                                 _dbus_verbose(" CapEff=");
966                                 for (i = 0; i < n; i++)
967                                         _dbus_verbose("%08x", cap[(2 * n) + (n - i - 1)]);
968
969                                 _dbus_verbose(" CapInh=");
970                                 for (i = 0; i < n; i++)
971                                         _dbus_verbose("%08x", cap[(3 * n) + (n - i - 1)]);
972                                 _dbus_verbose("\n");
973                                 break;
974                         }
975
976                         case KDBUS_MSG_TIMESTAMP:
977                                 _dbus_verbose("  +%s (%llu bytes) realtime=%lluns monotonic=%lluns\n",
978                                            enum_MSG(item->type), item->size,
979                                            (unsigned long long)item->timestamp.realtime_ns,
980                                            (unsigned long long)item->timestamp.monotonic_ns);
981                                 break;
982 #endif
983
984                         case KDBUS_MSG_REPLY_TIMEOUT:
985                         case KDBUS_MSG_REPLY_DEAD:
986                                 _dbus_verbose("  +%s (%llu bytes) cookie=%llu\n",
987                                            enum_MSG(item->type), item->size, msg->cookie_reply);
988
989                                 message = generate_local_error_message(msg->cookie_reply, DBUS_ERROR_NO_REPLY, NULL);
990                                 if(message == NULL)
991                                 {
992                                         ret_size = -1;
993                                         goto out;
994                                 }
995
996                                 ret_size = put_message_into_data(message, data);
997                         break;
998
999                         case KDBUS_MSG_NAME_ADD:
1000                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1001                                         enum_MSG(item->type), (unsigned long long) item->size,
1002                                         item->name_change.name, item->name_change.old_id,
1003                                         item->name_change.new_id, item->name_change.flags);
1004
1005                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1006                                 if(message == NULL)
1007                                 {
1008                                         ret_size = -1;
1009                                         goto out;
1010                                 }
1011
1012                                 sprintf(dbus_name,":1.%llu",item->name_change.new_id);
1013                                 pString = item->name_change.name;
1014                                 _dbus_verbose ("Name added: %s\n", pString);
1015                             dbus_message_iter_init_append(message, &args);
1016                             ITER_APPEND_STR(pString)
1017                             ITER_APPEND_STR(emptyString)
1018                             ITER_APPEND_STR(pDBusName)
1019                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1020
1021                                 ret_size = put_message_into_data(message, data);
1022                         break;
1023
1024                         case KDBUS_MSG_NAME_REMOVE:
1025                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1026                                         enum_MSG(item->type), (unsigned long long) item->size,
1027                                         item->name_change.name, item->name_change.old_id,
1028                                         item->name_change.new_id, item->name_change.flags);
1029
1030                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged"); // name of the signal
1031                                 if(message == NULL)
1032                                 {
1033                                         ret_size = -1;
1034                                         goto out;
1035                                 }
1036
1037                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1038                                 pString = item->name_change.name;
1039                                 _dbus_verbose ("Name removed: %s\n", pString);
1040                             dbus_message_iter_init_append(message, &args);
1041                             ITER_APPEND_STR(pString)
1042                             ITER_APPEND_STR(pDBusName)
1043                             ITER_APPEND_STR(emptyString)
1044                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1045
1046                                 ret_size = put_message_into_data(message, data);
1047                         break;
1048
1049                         case KDBUS_MSG_NAME_CHANGE:
1050                                 _dbus_verbose("  +%s (%llu bytes) '%s', old id=%lld, new id=%lld, flags=0x%llx\n",
1051                                         enum_MSG(item->type), (unsigned long long) item->size,
1052                                         item->name_change.name, item->name_change.old_id,
1053                                         item->name_change.new_id, item->name_change.flags);
1054
1055                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1056                                 if(message == NULL)
1057                                 {
1058                                         ret_size = -1;
1059                                         goto out;
1060                                 }
1061
1062                                 sprintf(dbus_name,":1.%llu",item->name_change.old_id);
1063                                 pString = item->name_change.name;
1064                                 _dbus_verbose ("Name changed: %s\n", pString);
1065                             dbus_message_iter_init_append(message, &args);
1066                             ITER_APPEND_STR(pString)
1067                             ITER_APPEND_STR(pDBusName)
1068                             sprintf(&dbus_name[3],"%llu",item->name_change.new_id);
1069                             _dbus_verbose ("New id: %s\n", pDBusName);
1070                             ITER_APPEND_STR(pDBusName)
1071                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1072
1073                                 ret_size = put_message_into_data(message, data);
1074                         break;
1075
1076                         case KDBUS_MSG_ID_ADD:
1077                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1078                                            enum_MSG(item->type), (unsigned long long) item->size,
1079                                            (unsigned long long) item->id_change.id,
1080                                            (unsigned long long) item->id_change.flags);
1081
1082                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1083                                 if(message == NULL)
1084                                 {
1085                                         ret_size = -1;
1086                                         goto out;
1087                                 }
1088
1089                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1090                             dbus_message_iter_init_append(message, &args);
1091                             ITER_APPEND_STR(pDBusName)
1092                             ITER_APPEND_STR(emptyString)
1093                             ITER_APPEND_STR(pDBusName)
1094                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1095
1096                                 ret_size = put_message_into_data(message, data);
1097                         break;
1098
1099                         case KDBUS_MSG_ID_REMOVE:
1100                                 _dbus_verbose("  +%s (%llu bytes) id=%llu flags=%llu\n",
1101                                            enum_MSG(item->type), (unsigned long long) item->size,
1102                                            (unsigned long long) item->id_change.id,
1103                                            (unsigned long long) item->id_change.flags);
1104
1105                                 message = dbus_message_new_signal(DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameOwnerChanged");
1106                                 if(message == NULL)
1107                                 {
1108                                         ret_size = -1;
1109                                         goto out;
1110                                 }
1111
1112                                 sprintf(dbus_name,":1.%llu",item->id_change.id);
1113                             dbus_message_iter_init_append(message, &args);
1114                             ITER_APPEND_STR(pDBusName)
1115                             ITER_APPEND_STR(pDBusName)
1116                             ITER_APPEND_STR(emptyString)
1117                                 dbus_message_set_sender(message, DBUS_SERVICE_DBUS);
1118
1119                                 ret_size = put_message_into_data(message, data);
1120                         break;
1121 #if KDBUS_MSG_DECODE_DEBUG == 1
1122                         default:
1123                                 _dbus_verbose("  +%s (%llu bytes)\n", enum_MSG(item->type), item->size);
1124                         break;
1125 #endif
1126                 }
1127         }
1128
1129 #if KDBUS_MSG_DECODE_DEBUG == 1
1130
1131         if ((char *)item - ((char *)msg + msg->size) >= 8)
1132                 _dbus_verbose("invalid padding at end of message\n");
1133 #endif
1134
1135 out:
1136         if(message)
1137                 dbus_message_unref(message);
1138         return ret_size;
1139 }
1140
1141 /**
1142  * Reads message from kdbus and puts it into dbus buffer and fds
1143  *
1144  * @param transport transport
1145  * @param buffer place to copy received message to
1146  * @param fds place to store file descriptors sent in the message
1147  * @param n_fds place  to store number of file descriptors
1148  * @return size of received message on success, -1 on error
1149  */
1150 static int kdbus_read_message(DBusTransportSocket *socket_transport, DBusString *buffer, int* fds, int* n_fds)
1151 {
1152         int ret_size;
1153         uint64_t __attribute__ ((__aligned__(8))) offset;
1154         struct kdbus_msg *msg;
1155         char *data;
1156
1157         _dbus_assert (socket_transport->max_bytes_read_per_iteration >= 0);
1158         if (!_dbus_string_lengthen (buffer, socket_transport->max_bytes_read_per_iteration))
1159         {
1160                 errno = ENOMEM;
1161             return -1;
1162         }
1163         data = _dbus_string_get_data_len (buffer, 0, socket_transport->max_bytes_read_per_iteration);
1164
1165         again:
1166         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RECV, &offset) < 0)
1167         {
1168                 if(errno == EINTR)
1169                         goto again;
1170                 _dbus_verbose("kdbus error receiving message: %d (%m)\n", errno);
1171                 _dbus_string_set_length (buffer, 0);
1172                 return -1;
1173         }
1174
1175         msg = (struct kdbus_msg *)((char*)socket_transport->kdbus_mmap_ptr + offset);
1176
1177         ret_size = kdbus_decode_msg(msg, data, socket_transport, fds, n_fds);
1178         _dbus_string_set_length (buffer, ret_size);
1179
1180         again2:
1181         if (ioctl(socket_transport->fd, KDBUS_CMD_MSG_RELEASE, &offset) < 0)
1182         {
1183                 if(errno == EINTR)
1184                         goto again2;
1185                 _dbus_verbose("kdbus error freeing message: %d (%m)\n", errno);
1186                 return -1;
1187         }
1188
1189         return ret_size;
1190 }
1191
1192 static void
1193 free_watches (DBusTransport *transport)
1194 {
1195   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1196
1197   _dbus_verbose ("start\n");
1198
1199   if (socket_transport->read_watch)
1200     {
1201       if (transport->connection)
1202         _dbus_connection_remove_watch_unlocked (transport->connection,
1203                                                 socket_transport->read_watch);
1204       _dbus_watch_invalidate (socket_transport->read_watch);
1205       _dbus_watch_unref (socket_transport->read_watch);
1206       socket_transport->read_watch = NULL;
1207     }
1208
1209   if (socket_transport->write_watch)
1210     {
1211       if (transport->connection)
1212         _dbus_connection_remove_watch_unlocked (transport->connection,
1213                                                 socket_transport->write_watch);
1214       _dbus_watch_invalidate (socket_transport->write_watch);
1215       _dbus_watch_unref (socket_transport->write_watch);
1216       socket_transport->write_watch = NULL;
1217     }
1218
1219   _dbus_verbose ("end\n");
1220 }
1221
1222 static void
1223 socket_finalize (DBusTransport *transport)
1224 {
1225   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1226
1227   _dbus_verbose ("\n");
1228
1229   free_watches (transport);
1230
1231   _dbus_string_free (&socket_transport->encoded_outgoing);
1232   _dbus_string_free (&socket_transport->encoded_incoming);
1233
1234   _dbus_transport_finalize_base (transport);
1235
1236   _dbus_assert (socket_transport->read_watch == NULL);
1237   _dbus_assert (socket_transport->write_watch == NULL);
1238
1239   dbus_free (transport);
1240 }
1241
1242 static void
1243 check_write_watch (DBusTransport *transport)
1244 {
1245   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1246   dbus_bool_t needed;
1247
1248   if (transport->connection == NULL)
1249     return;
1250
1251   if (transport->disconnected)
1252     {
1253       _dbus_assert (socket_transport->write_watch == NULL);
1254       return;
1255     }
1256
1257   _dbus_transport_ref (transport);
1258
1259 #ifdef DBUS_AUTHENTICATION
1260   if (_dbus_transport_get_is_authenticated (transport))
1261 #endif
1262     needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
1263 #ifdef DBUS_AUTHENTICATION
1264   else
1265     {
1266       if (transport->send_credentials_pending)
1267         needed = TRUE;
1268       else
1269         {
1270           DBusAuthState auth_state;
1271
1272           auth_state = _dbus_auth_do_work (transport->auth);
1273
1274           /* If we need memory we install the write watch just in case,
1275            * if there's no need for it, it will get de-installed
1276            * next time we try reading.
1277            */
1278           if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
1279               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
1280             needed = TRUE;
1281           else
1282             needed = FALSE;
1283         }
1284     }
1285 #endif
1286   _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
1287                  needed, transport->connection, socket_transport->write_watch,
1288                  socket_transport->fd,
1289                  _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1290
1291   _dbus_connection_toggle_watch_unlocked (transport->connection,
1292                                           socket_transport->write_watch,
1293                                           needed);
1294
1295   _dbus_transport_unref (transport);
1296 }
1297
1298 static void
1299 check_read_watch (DBusTransport *transport)
1300 {
1301   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1302   dbus_bool_t need_read_watch;
1303
1304   _dbus_verbose ("fd = %d\n",socket_transport->fd);
1305
1306   if (transport->connection == NULL)
1307     return;
1308
1309   if (transport->disconnected)
1310     {
1311       _dbus_assert (socket_transport->read_watch == NULL);
1312       return;
1313     }
1314
1315   _dbus_transport_ref (transport);
1316
1317 #ifdef DBUS_AUTHENTICATION
1318   if (_dbus_transport_get_is_authenticated (transport))
1319 #endif
1320     need_read_watch =
1321       (_dbus_counter_get_size_value (transport->live_messages) < transport->max_live_messages_size) &&
1322       (_dbus_counter_get_unix_fd_value (transport->live_messages) < transport->max_live_messages_unix_fds);
1323 #ifdef DBUS_AUTHENTICATION
1324   else
1325     {
1326       if (transport->receive_credentials_pending)
1327         need_read_watch = TRUE;
1328       else
1329         {
1330           /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
1331            * is to avoid spinning on the file descriptor when we're waiting
1332            * to write or for some other part of the auth process
1333            */
1334           DBusAuthState auth_state;
1335
1336           auth_state = _dbus_auth_do_work (transport->auth);
1337
1338           /* If we need memory we install the read watch just in case,
1339            * if there's no need for it, it will get de-installed
1340            * next time we try reading. If we're authenticated we
1341            * install it since we normally have it installed while
1342            * authenticated.
1343            */
1344           if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
1345               auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
1346               auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
1347             need_read_watch = TRUE;
1348           else
1349             need_read_watch = FALSE;
1350         }
1351     }
1352 #endif
1353
1354   _dbus_verbose ("  setting read watch enabled = %d\n", need_read_watch);
1355   _dbus_connection_toggle_watch_unlocked (transport->connection,
1356                                           socket_transport->read_watch,
1357                                           need_read_watch);
1358
1359   _dbus_transport_unref (transport);
1360 }
1361
1362 static void
1363 do_io_error (DBusTransport *transport)
1364 {
1365   _dbus_transport_ref (transport);
1366   _dbus_transport_disconnect (transport);
1367   _dbus_transport_unref (transport);
1368 }
1369
1370 #ifdef DBUS_AUTHENTICATION
1371 /* return value is whether we successfully read any new data. */
1372 static dbus_bool_t
1373 read_data_into_auth (DBusTransport *transport,
1374                      dbus_bool_t   *oom)
1375 {
1376   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1377   DBusString *buffer;
1378   int bytes_read;
1379
1380   *oom = FALSE;
1381
1382   _dbus_auth_get_buffer (transport->auth, &buffer);
1383
1384   bytes_read = kdbus_read_message(socket_transport, buffer);
1385
1386   _dbus_auth_return_buffer (transport->auth, buffer,
1387                             bytes_read > 0 ? bytes_read : 0);
1388
1389   if (bytes_read > 0)
1390     {
1391       _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
1392       return TRUE;
1393     }
1394   else if (bytes_read < 0)
1395     {
1396       /* EINTR already handled for us */
1397
1398       if (_dbus_get_is_errno_enomem ())
1399         {
1400           *oom = TRUE;
1401         }
1402       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1403         ; /* do nothing, just return FALSE below */
1404       else
1405         {
1406           _dbus_verbose ("Error reading from remote app: %s\n",
1407                          _dbus_strerror_from_errno ());
1408           do_io_error (transport);
1409         }
1410
1411       return FALSE;
1412     }
1413   else
1414     {
1415       _dbus_assert (bytes_read == 0);
1416
1417       _dbus_verbose ("Disconnected from remote app\n");
1418       do_io_error (transport);
1419
1420       return FALSE;
1421     }
1422 }
1423
1424 /* Return value is whether we successfully wrote any bytes */
1425 static dbus_bool_t
1426 write_data_from_auth (DBusTransport *transport)
1427 {
1428   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1429   int bytes_written;
1430   const DBusString *buffer;
1431
1432   if (!_dbus_auth_get_bytes_to_send (transport->auth,
1433                                      &buffer))
1434     return FALSE;
1435
1436   bytes_written = _dbus_write_socket (socket_transport->fd,
1437                                       buffer,
1438                                       0, _dbus_string_get_length (buffer));
1439
1440   if (bytes_written > 0)
1441     {
1442       _dbus_auth_bytes_sent (transport->auth, bytes_written);
1443       return TRUE;
1444     }
1445   else if (bytes_written < 0)
1446     {
1447       /* EINTR already handled for us */
1448
1449       if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1450         ;
1451       else
1452         {
1453           _dbus_verbose ("Error writing to remote app: %s\n",
1454                          _dbus_strerror_from_errno ());
1455           do_io_error (transport);
1456         }
1457     }
1458
1459   return FALSE;
1460 }
1461
1462 /* FALSE on OOM */
1463 static dbus_bool_t
1464 exchange_credentials (DBusTransport *transport,
1465                       dbus_bool_t    do_reading,
1466                       dbus_bool_t    do_writing)
1467 {
1468   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1469   DBusError error = DBUS_ERROR_INIT;
1470
1471   _dbus_verbose ("exchange_credentials: do_reading = %d, do_writing = %d\n",
1472                   do_reading, do_writing);
1473
1474   if (do_writing && transport->send_credentials_pending)
1475     {
1476       if (_dbus_send_credentials_socket (socket_transport->fd,
1477                                          &error))
1478         {
1479           transport->send_credentials_pending = FALSE;
1480         }
1481       else
1482         {
1483           _dbus_verbose ("Failed to write credentials: %s\n", error.message);
1484           dbus_error_free (&error);
1485           do_io_error (transport);
1486         }
1487     }
1488
1489   if (do_reading && transport->receive_credentials_pending)
1490     {
1491       /* FIXME this can fail due to IO error _or_ OOM, broken
1492        * (somewhat tricky to fix since the OOM error can be set after
1493        * we already read the credentials byte, so basically we need to
1494        * separate reading the byte and storing it in the
1495        * transport->credentials). Does not really matter for now
1496        * because storing in credentials never actually fails on unix.
1497        */
1498       if (_dbus_read_credentials_socket (socket_transport->fd,
1499                                          transport->credentials,
1500                                          &error))
1501         {
1502           transport->receive_credentials_pending = FALSE;
1503         }
1504       else
1505         {
1506           _dbus_verbose ("Failed to read credentials %s\n", error.message);
1507           dbus_error_free (&error);
1508           do_io_error (transport);
1509         }
1510     }
1511
1512   if (!(transport->send_credentials_pending ||
1513         transport->receive_credentials_pending))
1514     {
1515       if (!_dbus_auth_set_credentials (transport->auth,
1516                                        transport->credentials))
1517         return FALSE;
1518     }
1519
1520   return TRUE;
1521 }
1522
1523 static dbus_bool_t
1524 do_authentication (DBusTransport *transport,
1525                    dbus_bool_t    do_reading,
1526                    dbus_bool_t    do_writing,
1527                    dbus_bool_t   *auth_completed)
1528 {
1529   dbus_bool_t oom;
1530   dbus_bool_t orig_auth_state;
1531
1532   oom = FALSE;
1533
1534   orig_auth_state = _dbus_transport_get_is_authenticated (transport);
1535
1536   /* This is essential to avoid the check_write_watch() at the end,
1537    * we don't want to add a write watch in do_iteration before
1538    * we try writing and get EAGAIN
1539    */
1540   if (orig_auth_state)
1541     {
1542       if (auth_completed)
1543         *auth_completed = FALSE;
1544       return TRUE;
1545     }
1546
1547   _dbus_transport_ref (transport);
1548
1549   while (!_dbus_transport_get_is_authenticated (transport) &&
1550          _dbus_transport_get_is_connected (transport))
1551     {
1552       if (!exchange_credentials (transport, do_reading, do_writing))
1553         {
1554           oom = TRUE;
1555           goto out;
1556         }
1557
1558       if (transport->send_credentials_pending ||
1559           transport->receive_credentials_pending)
1560         {
1561           _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
1562                          transport->send_credentials_pending,
1563                          transport->receive_credentials_pending);
1564           goto out;
1565         }
1566
1567 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
1568       switch (_dbus_auth_do_work (transport->auth))
1569         {
1570         case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
1571           _dbus_verbose (" %s auth state: waiting for input\n",
1572                          TRANSPORT_SIDE (transport));
1573           if (!do_reading || !read_data_into_auth (transport, &oom))
1574             goto out;
1575           break;
1576
1577         case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
1578           _dbus_verbose (" %s auth state: waiting for memory\n",
1579                          TRANSPORT_SIDE (transport));
1580           oom = TRUE;
1581           goto out;
1582           break;
1583
1584         case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
1585           _dbus_verbose (" %s auth state: bytes to send\n",
1586                          TRANSPORT_SIDE (transport));
1587           if (!do_writing || !write_data_from_auth (transport))
1588             goto out;
1589           break;
1590
1591         case DBUS_AUTH_STATE_NEED_DISCONNECT:
1592           _dbus_verbose (" %s auth state: need to disconnect\n",
1593                          TRANSPORT_SIDE (transport));
1594           do_io_error (transport);
1595           break;
1596
1597         case DBUS_AUTH_STATE_AUTHENTICATED:
1598           _dbus_verbose (" %s auth state: authenticated\n",
1599                          TRANSPORT_SIDE (transport));
1600           break;
1601         }
1602     }
1603
1604  out:
1605   if (auth_completed)
1606     *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
1607
1608   check_read_watch (transport);
1609   check_write_watch (transport);
1610   _dbus_transport_unref (transport);
1611
1612   if (oom)
1613     return FALSE;
1614   else
1615     return TRUE;
1616 }
1617 #endif
1618
1619 /* returns false on oom */
1620 static dbus_bool_t
1621 do_writing (DBusTransport *transport)
1622 {
1623         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1624         dbus_bool_t oom;
1625
1626 #ifdef DBUS_AUTHENTICATION
1627         /* No messages without authentication! */
1628         if (!_dbus_transport_get_is_authenticated (transport))
1629     {
1630                 _dbus_verbose ("Not authenticated, not writing anything\n");
1631                 return TRUE;
1632     }
1633 #endif
1634
1635         if (transport->disconnected)
1636     {
1637                 _dbus_verbose ("Not connected, not writing anything\n");
1638                 return TRUE;
1639     }
1640
1641 #if 1
1642         _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
1643                  _dbus_connection_has_messages_to_send_unlocked (transport->connection),
1644                  socket_transport->fd);
1645 #endif
1646
1647         oom = FALSE;
1648
1649         while (!transport->disconnected && _dbus_connection_has_messages_to_send_unlocked (transport->connection))
1650     {
1651                 int bytes_written;
1652                 DBusMessage *message;
1653                 const DBusString *header;
1654                 const DBusString *body;
1655                 int total_bytes_to_write;
1656                 const char* pDestination;
1657
1658                 message = _dbus_connection_get_message_to_send (transport->connection);
1659                 _dbus_assert (message != NULL);
1660                 dbus_message_lock (message);
1661                 _dbus_message_get_network_data (message, &header, &body);
1662                 total_bytes_to_write = _dbus_string_get_length(header) + _dbus_string_get_length(body);
1663                 pDestination = dbus_message_get_destination(message);
1664
1665                 if(pDestination)
1666                 {
1667                         if(!strcmp(pDestination, "org.freedesktop.DBus"))
1668                         {
1669                                 if(emulateOrgFreedesktopDBus(transport, message))
1670                                         bytes_written = total_bytes_to_write;
1671                                 else
1672                                         bytes_written = -1;
1673                                 goto written;
1674                         }
1675                 }
1676                 if (_dbus_auth_needs_encoding (transport->auth))
1677         {
1678                         if (_dbus_string_get_length (&socket_transport->encoded_outgoing) == 0)
1679             {
1680                                 if (!_dbus_auth_encode_data (transport->auth,
1681                                            header, &socket_transport->encoded_outgoing))
1682                 {
1683                                         oom = TRUE;
1684                                         goto out;
1685                 }
1686
1687                                 if (!_dbus_auth_encode_data (transport->auth,
1688                                            body, &socket_transport->encoded_outgoing))
1689                 {
1690                                         _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1691                                         oom = TRUE;
1692                                         goto out;
1693                 }
1694             }
1695
1696                         total_bytes_to_write = _dbus_string_get_length (&socket_transport->encoded_outgoing);
1697                         if(total_bytes_to_write > socket_transport->max_bytes_written_per_iteration)
1698                                 return -E2BIG;
1699
1700                         bytes_written = kdbus_write_msg(socket_transport, message, TRUE);
1701         }
1702                 else
1703                 {
1704                         if(total_bytes_to_write > socket_transport->max_bytes_written_per_iteration)
1705                                 return -E2BIG;
1706
1707                         bytes_written = kdbus_write_msg(socket_transport, message, FALSE);
1708                 }
1709
1710 written:
1711                 if (bytes_written < 0)
1712                 {
1713                         /* EINTR already handled for us */
1714
1715           /* For some discussion of why we also ignore EPIPE here, see
1716            * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html
1717            */
1718
1719                         if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ())
1720                                 goto out;
1721                         else
1722                         {
1723                                 _dbus_verbose ("Error writing to remote app: %s\n", _dbus_strerror_from_errno ());
1724                                 do_io_error (transport);
1725                                 goto out;
1726                         }
1727                 }
1728                 else
1729                 {
1730                         _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
1731                          total_bytes_to_write);
1732
1733                         socket_transport->message_bytes_written += bytes_written;
1734
1735                         _dbus_assert (socket_transport->message_bytes_written <=
1736                         total_bytes_to_write);
1737
1738                           if (socket_transport->message_bytes_written == total_bytes_to_write)
1739                           {
1740                                   socket_transport->message_bytes_written = 0;
1741                                   _dbus_string_set_length (&socket_transport->encoded_outgoing, 0);
1742                                   _dbus_string_compact (&socket_transport->encoded_outgoing, 2048);
1743
1744                                   _dbus_connection_message_sent_unlocked (transport->connection,
1745                                                                                                                   message);
1746                           }
1747                 }
1748     }
1749
1750         out:
1751         if (oom)
1752                 return FALSE;
1753         return TRUE;
1754 }
1755
1756 /* returns false on out-of-memory */
1757 static dbus_bool_t
1758 do_reading (DBusTransport *transport)
1759 {
1760   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1761   DBusString *buffer;
1762   int bytes_read;
1763   dbus_bool_t oom = FALSE;
1764   int *fds, n_fds;
1765
1766   _dbus_verbose ("fd = %d\n",socket_transport->fd);
1767
1768 #ifdef DBUS_AUTHENTICATION
1769   /* No messages without authentication! */
1770   if (!_dbus_transport_get_is_authenticated (transport))
1771     return TRUE;
1772 #endif
1773
1774  again:
1775
1776   /* See if we've exceeded max messages and need to disable reading */
1777   check_read_watch (transport);
1778
1779   _dbus_assert (socket_transport->read_watch != NULL ||
1780                 transport->disconnected);
1781
1782   if (transport->disconnected)
1783     goto out;
1784
1785   if (!dbus_watch_get_enabled (socket_transport->read_watch))
1786     return TRUE;
1787
1788   if (!_dbus_message_loader_get_unix_fds(transport->loader, &fds, &n_fds))
1789   {
1790       _dbus_verbose ("Out of memory reading file descriptors\n");
1791       oom = TRUE;
1792       goto out;
1793   }
1794   _dbus_message_loader_get_buffer (transport->loader, &buffer);
1795
1796   if (_dbus_auth_needs_decoding (transport->auth))
1797   {
1798           bytes_read = kdbus_read_message(socket_transport,  &socket_transport->encoded_incoming, fds, &n_fds);
1799
1800       _dbus_assert (_dbus_string_get_length (&socket_transport->encoded_incoming) == bytes_read);
1801
1802       if (bytes_read > 0)
1803       {
1804           if (!_dbus_auth_decode_data (transport->auth,
1805                                        &socket_transport->encoded_incoming,
1806                                        buffer))
1807           {
1808               _dbus_verbose ("Out of memory decoding incoming data\n");
1809               _dbus_message_loader_return_buffer (transport->loader,
1810                                               buffer,
1811                                               _dbus_string_get_length (buffer));
1812               oom = TRUE;
1813               goto out;
1814           }
1815
1816           _dbus_string_set_length (&socket_transport->encoded_incoming, 0);
1817           _dbus_string_compact (&socket_transport->encoded_incoming, 2048);
1818       }
1819   }
1820   else
1821           bytes_read = kdbus_read_message(socket_transport, buffer, fds, &n_fds);
1822
1823   if (bytes_read >= 0 && n_fds > 0)
1824     _dbus_verbose("Read %i unix fds\n", n_fds);
1825
1826   _dbus_message_loader_return_buffer (transport->loader,
1827                                       buffer,
1828                                       bytes_read < 0 ? 0 : _dbus_string_get_length (buffer));
1829   _dbus_message_loader_return_unix_fds(transport->loader, fds, bytes_read < 0 ? 0 : n_fds);
1830
1831   if (bytes_read < 0)
1832     {
1833       /* EINTR already handled for us */
1834
1835       if (_dbus_get_is_errno_enomem ())
1836         {
1837           _dbus_verbose ("Out of memory in read()/do_reading()\n");
1838           oom = TRUE;
1839           goto out;
1840         }
1841       else if (_dbus_get_is_errno_eagain_or_ewouldblock ())
1842         goto out;
1843       else
1844         {
1845           _dbus_verbose ("Error reading from remote app: %s\n",
1846                          _dbus_strerror_from_errno ());
1847           do_io_error (transport);
1848           goto out;
1849         }
1850     }
1851   else if (bytes_read == 0)
1852     {
1853       _dbus_verbose ("Disconnected from remote app\n");
1854       do_io_error (transport);
1855       goto out;
1856     }
1857   else
1858     {
1859       _dbus_verbose (" read %d bytes\n", bytes_read);
1860
1861       if (!_dbus_transport_queue_messages (transport))
1862         {
1863           oom = TRUE;
1864           _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
1865           goto out;
1866         }
1867
1868       /* Try reading more data until we get EAGAIN and return, or
1869        * exceed max bytes per iteration.  If in blocking mode of
1870        * course we'll block instead of returning.
1871        */
1872       goto again;
1873     }
1874
1875  out:
1876   if (oom)
1877     return FALSE;
1878   return TRUE;
1879 }
1880
1881 static dbus_bool_t
1882 unix_error_with_read_to_come (DBusTransport *itransport,
1883                               DBusWatch     *watch,
1884                               unsigned int   flags)
1885 {
1886    DBusTransportSocket *transport = (DBusTransportSocket *) itransport;
1887
1888    if (!((flags & DBUS_WATCH_HANGUP) || (flags & DBUS_WATCH_ERROR)))
1889       return FALSE;
1890
1891   /* If we have a read watch enabled ...
1892      we -might have data incoming ... => handle the HANGUP there */
1893    if (watch != transport->read_watch && _dbus_watch_get_enabled (transport->read_watch))
1894       return FALSE;
1895
1896    return TRUE;
1897 }
1898
1899 static dbus_bool_t
1900 socket_handle_watch (DBusTransport *transport,
1901                    DBusWatch     *watch,
1902                    unsigned int   flags)
1903 {
1904   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1905
1906   _dbus_assert (watch == socket_transport->read_watch ||
1907                 watch == socket_transport->write_watch);
1908   _dbus_assert (watch != NULL);
1909
1910   /* If we hit an error here on a write watch, don't disconnect the transport yet because data can
1911    * still be in the buffer and do_reading may need several iteration to read
1912    * it all (because of its max_bytes_read_per_iteration limit).
1913    */
1914   if (!(flags & DBUS_WATCH_READABLE) && unix_error_with_read_to_come (transport, watch, flags))
1915     {
1916       _dbus_verbose ("Hang up or error on watch\n");
1917       _dbus_transport_disconnect (transport);
1918       return TRUE;
1919     }
1920
1921   if (watch == socket_transport->read_watch &&
1922       (flags & DBUS_WATCH_READABLE))
1923     {
1924 #ifdef DBUS_AUTHENTICATION
1925       dbus_bool_t auth_finished;
1926 #endif
1927 #if 1
1928       _dbus_verbose ("handling read watch %p flags = %x\n",
1929                      watch, flags);
1930 #endif
1931 #ifdef DBUS_AUTHENTICATION
1932       if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
1933         return FALSE;
1934
1935       /* We don't want to do a read immediately following
1936        * a successful authentication.  This is so we
1937        * have a chance to propagate the authentication
1938        * state further up.  Specifically, we need to
1939        * process any pending data from the auth object.
1940        */
1941       if (!auth_finished)
1942         {
1943 #endif
1944           if (!do_reading (transport))
1945             {
1946               _dbus_verbose ("no memory to read\n");
1947               return FALSE;
1948             }
1949 #ifdef DBUS_AUTHENTICATION
1950         }
1951       else
1952         {
1953           _dbus_verbose ("Not reading anything since we just completed the authentication\n");
1954         }
1955 #endif
1956     }
1957   else if (watch == socket_transport->write_watch &&
1958            (flags & DBUS_WATCH_WRITABLE))
1959     {
1960 #if 1
1961       _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
1962                      _dbus_connection_has_messages_to_send_unlocked (transport->connection));
1963 #endif
1964 #ifdef DBUS_AUTHENTICATION
1965       if (!do_authentication (transport, FALSE, TRUE, NULL))
1966         return FALSE;
1967 #endif
1968       if (!do_writing (transport))
1969         {
1970           _dbus_verbose ("no memory to write\n");
1971           return FALSE;
1972         }
1973
1974       /* See if we still need the write watch */
1975       check_write_watch (transport);
1976     }
1977 #ifdef DBUS_ENABLE_VERBOSE_MODE
1978   else
1979     {
1980       if (watch == socket_transport->read_watch)
1981         _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
1982                        flags);
1983       else if (watch == socket_transport->write_watch)
1984         _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
1985                        flags);
1986       else
1987         _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
1988                        watch, dbus_watch_get_socket (watch));
1989     }
1990 #endif /* DBUS_ENABLE_VERBOSE_MODE */
1991
1992   return TRUE;
1993 }
1994
1995 static void
1996 socket_disconnect (DBusTransport *transport)
1997 {
1998   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
1999
2000   _dbus_verbose ("\n");
2001
2002   free_watches (transport);
2003
2004   _dbus_close_socket (socket_transport->fd, NULL);
2005   socket_transport->fd = -1;
2006 }
2007
2008 static dbus_bool_t
2009 socket_connection_set (DBusTransport *transport)
2010 {
2011   DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2012
2013   _dbus_watch_set_handler (socket_transport->write_watch,
2014                            _dbus_connection_handle_watch,
2015                            transport->connection, NULL);
2016
2017   _dbus_watch_set_handler (socket_transport->read_watch,
2018                            _dbus_connection_handle_watch,
2019                            transport->connection, NULL);
2020
2021   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2022                                             socket_transport->write_watch))
2023     return FALSE;
2024
2025   if (!_dbus_connection_add_watch_unlocked (transport->connection,
2026                                             socket_transport->read_watch))
2027     {
2028       _dbus_connection_remove_watch_unlocked (transport->connection,
2029                                               socket_transport->write_watch);
2030       return FALSE;
2031     }
2032
2033   check_read_watch (transport);
2034   check_write_watch (transport);
2035
2036   return TRUE;
2037 }
2038
2039 /**
2040  * @todo We need to have a way to wake up the select sleep if
2041  * a new iteration request comes in with a flag (read/write) that
2042  * we're not currently serving. Otherwise a call that just reads
2043  * could block a write call forever (if there are no incoming
2044  * messages).
2045  */
2046 static  void
2047 kdbus_do_iteration (DBusTransport *transport,
2048                    unsigned int   flags,
2049                    int            timeout_milliseconds)
2050 {
2051         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2052         DBusPollFD poll_fd;
2053         int poll_res;
2054         int poll_timeout;
2055
2056         _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
2057                  flags & DBUS_ITERATION_DO_READING ? "read" : "",
2058                  flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
2059                  timeout_milliseconds,
2060                  socket_transport->read_watch,
2061                  socket_transport->write_watch,
2062                  socket_transport->fd);
2063
2064   /* the passed in DO_READING/DO_WRITING flags indicate whether to
2065    * read/write messages, but regardless of those we may need to block
2066    * for reading/writing to do auth.  But if we do reading for auth,
2067    * we don't want to read any messages yet if not given DO_READING.
2068    */
2069
2070    poll_fd.fd = socket_transport->fd;
2071    poll_fd.events = 0;
2072
2073    if (_dbus_transport_get_is_authenticated (transport))
2074    {
2075       /* This is kind of a hack; if we have stuff to write, then try
2076        * to avoid the poll. This is probably about a 5% speedup on an
2077        * echo client/server.
2078        *
2079        * If both reading and writing were requested, we want to avoid this
2080        * since it could have funky effects:
2081        *   - both ends spinning waiting for the other one to read
2082        *     data so they can finish writing
2083        *   - prioritizing all writing ahead of reading
2084        */
2085       if ((flags & DBUS_ITERATION_DO_WRITING) &&
2086           !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
2087           !transport->disconnected &&
2088           _dbus_connection_has_messages_to_send_unlocked (transport->connection))
2089       {
2090          do_writing (transport);
2091
2092          if (transport->disconnected ||
2093               !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
2094             goto out;
2095       }
2096
2097       /* If we get here, we decided to do the poll() after all */
2098       _dbus_assert (socket_transport->read_watch);
2099       if (flags & DBUS_ITERATION_DO_READING)
2100              poll_fd.events |= _DBUS_POLLIN;
2101
2102       _dbus_assert (socket_transport->write_watch);
2103       if (flags & DBUS_ITERATION_DO_WRITING)
2104          poll_fd.events |= _DBUS_POLLOUT;
2105    }
2106    else
2107    {
2108       DBusAuthState auth_state;
2109
2110       auth_state = _dbus_auth_do_work (transport->auth);
2111
2112       if (transport->receive_credentials_pending || auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
2113              poll_fd.events |= _DBUS_POLLIN;
2114
2115       if (transport->send_credentials_pending || auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
2116              poll_fd.events |= _DBUS_POLLOUT;
2117    }
2118
2119    if (poll_fd.events)
2120    {
2121       if (flags & DBUS_ITERATION_BLOCK)
2122              poll_timeout = timeout_milliseconds;
2123       else
2124              poll_timeout = 0;
2125
2126       /* For blocking selects we drop the connection lock here
2127        * to avoid blocking out connection access during a potentially
2128        * indefinite blocking call. The io path is still protected
2129        * by the io_path_cond condvar, so we won't reenter this.
2130        */
2131       if (flags & DBUS_ITERATION_BLOCK)
2132       {
2133          _dbus_verbose ("unlock pre poll\n");
2134          _dbus_connection_unlock (transport->connection);
2135       }
2136
2137     again:
2138       poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
2139
2140       if (poll_res < 0 && _dbus_get_is_errno_eintr ())
2141       {
2142          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2143          goto again;
2144       }
2145
2146       if (flags & DBUS_ITERATION_BLOCK)
2147       {
2148          _dbus_verbose ("lock post poll\n");
2149          _dbus_connection_lock (transport->connection);
2150       }
2151
2152       if (poll_res >= 0)
2153       {
2154          if (poll_res == 0)
2155             poll_fd.revents = 0; /* some concern that posix does not guarantee this;
2156                                   * valgrind flags it as an error. though it probably
2157                                   * is guaranteed on linux at least.
2158                                   */
2159
2160          if (poll_fd.revents & _DBUS_POLLERR)
2161             do_io_error (transport);
2162          else
2163          {
2164             dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
2165             dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
2166 #ifdef DBUS_AUTHENTICATION
2167               dbus_bool_t authentication_completed;
2168 #endif
2169
2170             _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
2171                              need_read, need_write);
2172 #ifdef DBUS_AUTHENTICATION
2173               do_authentication (transport, need_read, need_write,
2174                                  &authentication_completed);
2175
2176               /* See comment in socket_handle_watch. */
2177               if (authentication_completed)
2178                 goto out;
2179 #endif
2180             if (need_read && (flags & DBUS_ITERATION_DO_READING))
2181                do_reading (transport);
2182             if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
2183                do_writing (transport);
2184          }
2185       }
2186       else
2187          _dbus_verbose ("Error from _dbus_poll(): %s\n", _dbus_strerror_from_errno ());
2188    }
2189
2190  out:
2191   /* We need to install the write watch only if we did not
2192    * successfully write everything. Note we need to be careful that we
2193    * don't call check_write_watch *before* do_writing, since it's
2194    * inefficient to add the write watch, and we can avoid it most of
2195    * the time since we can write immediately.
2196    *
2197    * However, we MUST always call check_write_watch(); DBusConnection code
2198    * relies on the fact that running an iteration will notice that
2199    * messages are pending.
2200    */
2201    check_write_watch (transport);
2202
2203    _dbus_verbose (" ... leaving do_iteration()\n");
2204 }
2205
2206 static void
2207 socket_live_messages_changed (DBusTransport *transport)
2208 {
2209   /* See if we should look for incoming messages again */
2210   check_read_watch (transport);
2211 }
2212
2213 static const DBusTransportVTable kdbus_vtable = {
2214   socket_finalize,
2215   socket_handle_watch,
2216   socket_disconnect,
2217   socket_connection_set,
2218   kdbus_do_iteration,
2219   socket_live_messages_changed,
2220   socket_get_socket_fd
2221 };
2222
2223 /**
2224  * Creates a new transport for the given kdbus file descriptor.  The file
2225  * descriptor must be nonblocking.
2226  *
2227  * @param fd the file descriptor.
2228  * @param address the transport's address
2229  * @returns the new transport, or #NULL if no memory.
2230  */
2231 static DBusTransport*
2232 _dbus_transport_new_for_socket_kdbus (int       fd,
2233                                           const DBusString *address)
2234 {
2235         DBusTransportSocket *socket_transport;
2236
2237   socket_transport = dbus_new0 (DBusTransportSocket, 1);
2238   if (socket_transport == NULL)
2239     return NULL;
2240
2241   if (!_dbus_string_init (&socket_transport->encoded_outgoing))
2242     goto failed_0;
2243
2244   if (!_dbus_string_init (&socket_transport->encoded_incoming))
2245     goto failed_1;
2246
2247   socket_transport->write_watch = _dbus_watch_new (fd,
2248                                                  DBUS_WATCH_WRITABLE,
2249                                                  FALSE,
2250                                                  NULL, NULL, NULL);
2251   if (socket_transport->write_watch == NULL)
2252     goto failed_2;
2253
2254   socket_transport->read_watch = _dbus_watch_new (fd,
2255                                                 DBUS_WATCH_READABLE,
2256                                                 FALSE,
2257                                                 NULL, NULL, NULL);
2258   if (socket_transport->read_watch == NULL)
2259     goto failed_3;
2260
2261   if (!_dbus_transport_init_base (&socket_transport->base,
2262                                   &kdbus_vtable,
2263                                   NULL, address))
2264     goto failed_4;
2265
2266 #ifdef DBUS_AUTHENTICATION
2267 #ifdef HAVE_UNIX_FD_PASSING
2268   _dbus_auth_set_unix_fd_possible(socket_transport->base.auth, _dbus_socket_can_pass_unix_fd(fd));
2269 #endif
2270 #endif
2271
2272   socket_transport->fd = fd;
2273   socket_transport->message_bytes_written = 0;
2274
2275   /* These values should probably be tunable or something. */
2276   socket_transport->max_bytes_read_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2277   socket_transport->max_bytes_written_per_iteration = DBUS_MAXIMUM_MESSAGE_LENGTH;
2278
2279   socket_transport->kdbus_mmap_ptr = NULL;
2280   socket_transport->memfd = -1;
2281   
2282   return (DBusTransport*) socket_transport;
2283
2284  failed_4:
2285   _dbus_watch_invalidate (socket_transport->read_watch);
2286   _dbus_watch_unref (socket_transport->read_watch);
2287  failed_3:
2288   _dbus_watch_invalidate (socket_transport->write_watch);
2289   _dbus_watch_unref (socket_transport->write_watch);
2290  failed_2:
2291   _dbus_string_free (&socket_transport->encoded_incoming);
2292  failed_1:
2293   _dbus_string_free (&socket_transport->encoded_outgoing);
2294  failed_0:
2295   dbus_free (socket_transport);
2296   return NULL;
2297 }
2298
2299
2300 /**
2301  * Opens a connection to the kdbus bus
2302  *
2303  * This will set FD_CLOEXEC for the socket returned.
2304  *
2305  * @param path the path to UNIX domain socket
2306  * @param error return location for error code
2307  * @returns connection file descriptor or -1 on error
2308  */
2309 static int _dbus_connect_kdbus (const char *path, DBusError *error)
2310 {
2311         int fd;
2312
2313         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2314         _dbus_verbose ("connecting to kdbus bus %s\n", path);
2315
2316         fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK);
2317         if (fd < 0)
2318                 dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno));
2319
2320         return fd;
2321 }
2322
2323 /**
2324  * maps memory pool for messages received by the kdbus transport
2325  *
2326  * @param transport transport
2327  * @returns #TRUE on success, otherwise FALSE
2328  */
2329 static dbus_bool_t kdbus_mmap(DBusTransport* transport)
2330 {
2331         DBusTransportSocket *socket_transport = (DBusTransportSocket*) transport;
2332
2333         socket_transport->kdbus_mmap_ptr = mmap(NULL, RECEIVE_POOL_SIZE, PROT_READ, MAP_SHARED, socket_transport->fd, 0);
2334         if (socket_transport->kdbus_mmap_ptr == MAP_FAILED)
2335                 return FALSE;
2336
2337         return TRUE;
2338 }
2339
2340 /**
2341  * Creates a new transport for kdbus.
2342  * This creates a client-side of a transport.
2343  *
2344  * @param path the path to the bus.
2345  * @param error address where an error can be returned.
2346  * @returns a new transport, or #NULL on failure.
2347  */
2348 static DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error)
2349 {
2350         int fd;
2351         DBusTransport *transport;
2352         DBusString address;
2353
2354         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2355
2356         if (!_dbus_string_init (&address))
2357     {
2358                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2359                 return NULL;
2360     }
2361
2362         fd = -1;
2363
2364         if ((!_dbus_string_append (&address, "kdbus:path=")) || (!_dbus_string_append (&address, path)))
2365     {
2366                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2367                 goto failed_0;
2368     }
2369
2370         fd = _dbus_connect_kdbus (path, error);
2371         if (fd < 0)
2372     {
2373                 _DBUS_ASSERT_ERROR_IS_SET (error);
2374                 goto failed_0;
2375     }
2376
2377         _dbus_verbose ("Successfully connected to kdbus bus %s\n", path);
2378
2379         transport = _dbus_transport_new_for_socket_kdbus (fd, &address);
2380         if (transport == NULL)
2381     {
2382                 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2383                 goto failed_1;
2384     }
2385
2386         _dbus_string_free (&address);
2387
2388         return transport;
2389
2390         failed_1:
2391                 _dbus_close_socket (fd, NULL);
2392         failed_0:
2393                 _dbus_string_free (&address);
2394         return NULL;
2395 }
2396
2397
2398 /**
2399  * Opens kdbus transport if method from address entry is kdbus
2400  *
2401  * @param entry the address entry to try opening
2402  * @param transport_p return location for the opened transport
2403  * @param error error to be set
2404  * @returns result of the attempt
2405  */
2406 DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry  *entry,
2407                                                            DBusTransport    **transport_p,
2408                                                            DBusError         *error)
2409 {
2410         const char *method;
2411
2412         method = dbus_address_entry_get_method (entry);
2413         _dbus_assert (method != NULL);
2414
2415         if (strcmp (method, "kdbus") == 0)
2416     {
2417                 const char *path = dbus_address_entry_get_value (entry, "path");
2418
2419                 if (path == NULL)
2420         {
2421                         _dbus_set_bad_address (error, "kdbus", "path", NULL);
2422                         return DBUS_TRANSPORT_OPEN_BAD_ADDRESS;
2423         }
2424
2425         *transport_p = _dbus_transport_new_for_kdbus (path, error);
2426
2427         if (*transport_p == NULL)
2428         {
2429                 _DBUS_ASSERT_ERROR_IS_SET (error);
2430                 return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
2431         }
2432         else
2433         {
2434                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2435                 return DBUS_TRANSPORT_OPEN_OK;
2436         }
2437     }
2438         else
2439     {
2440                 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2441                 return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
2442     }
2443 }
2444
2445 static struct kdbus_policy *make_policy_name(const char *name)
2446 {
2447         struct kdbus_policy *p;
2448         __u64 size;
2449
2450         size = offsetof(struct kdbus_policy, name) + strlen(name) + 1;
2451         p = malloc(size);
2452         if (!p)
2453                 return NULL;
2454         memset(p, 0, size);
2455         p->size = size;
2456         p->type = KDBUS_POLICY_NAME;
2457         strcpy(p->name, name);
2458
2459         return p;
2460 }
2461
2462 static struct kdbus_policy *make_policy_access(__u64 type, __u64 bits, __u64 id)
2463 {
2464         struct kdbus_policy *p;
2465         __u64 size = sizeof(*p);
2466
2467         p = malloc(size);
2468         if (!p)
2469                 return NULL;
2470
2471         memset(p, 0, size);
2472         p->size = size;
2473         p->type = KDBUS_POLICY_ACCESS;
2474         p->access.type = type;
2475         p->access.bits = bits;
2476         p->access.id = id;
2477
2478         return p;
2479 }
2480
2481 static void append_policy(struct kdbus_cmd_policy *cmd_policy, struct kdbus_policy *policy, __u64 max_size)
2482 {
2483         struct kdbus_policy *dst = (struct kdbus_policy *) ((char *) cmd_policy + cmd_policy->size);
2484
2485         if (cmd_policy->size + policy->size > max_size)
2486                 return;
2487
2488         memcpy(dst, policy, policy->size);
2489         cmd_policy->size += KDBUS_ALIGN8(policy->size);
2490         free(policy);
2491 }
2492
2493 /**
2494  * Registers kdbus policy for given connection.
2495  *
2496  * Policy sets rights of the name (unique or well known) on the bus. Without policy it is
2497  * not possible to send or receive messages. It must be set separately for unique id and
2498  * well known name of the connection. It is set after registering on the bus, but before
2499  * requesting for name. The policy is valid for the given name, not for the connection.
2500  *
2501  * Name of the policy equals name on the bus.
2502  *
2503  * @param name name of the policy = name of the connection
2504  * @param connection the connection
2505  * @param error place to store errors
2506  *
2507  * @returns #TRUE on success
2508  */
2509 dbus_bool_t bus_register_policy_kdbus(const char* name, DBusConnection *connection, DBusError *error)
2510 {
2511         struct kdbus_cmd_policy *cmd_policy;
2512         struct kdbus_policy *policy;
2513         int size = 0xffff;
2514         int fd;
2515
2516         if(!dbus_connection_get_socket(connection, &fd))
2517         {
2518                 dbus_set_error (error, "Failed to get fd for registering policy", NULL);
2519                 return FALSE;
2520         }
2521
2522         cmd_policy = alloca(size);
2523         memset(cmd_policy, 0, size);
2524
2525         policy = (struct kdbus_policy *) cmd_policy->policies;
2526         cmd_policy->size = offsetof(struct kdbus_cmd_policy, policies);
2527
2528         policy = make_policy_name(name);
2529         append_policy(cmd_policy, policy, size);
2530
2531         policy = make_policy_access(KDBUS_POLICY_ACCESS_USER, KDBUS_POLICY_OWN, getuid());
2532         append_policy(cmd_policy, policy, size);
2533
2534         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_RECV, 0);
2535         append_policy(cmd_policy, policy, size);
2536
2537         policy = make_policy_access(KDBUS_POLICY_ACCESS_WORLD, KDBUS_POLICY_SEND, 0);
2538         append_policy(cmd_policy, policy, size);
2539
2540         if (ioctl(fd, KDBUS_CMD_EP_POLICY_SET, cmd_policy) < 0)
2541         {
2542                 dbus_set_error(error,_dbus_error_from_errno (errno), "Error setting EP policy: %s", _dbus_strerror (errno));
2543                 return FALSE;
2544         }
2545
2546         _dbus_verbose("Policy %s set correctly\n", name);
2547         return TRUE;
2548 }
2549
2550 /**
2551  * Kdbus part of dbus_bus_register.
2552  * Shouldn't be used separately because it needs to be surrounded
2553  * by other functions as it is done in dbus_bus_register.
2554  *
2555  * @param name place to store unique name given by bus
2556  * @param connection the connection
2557  * @param error place to store errors
2558  * @returns #TRUE on success
2559  */
2560 dbus_bool_t bus_register_kdbus(char* name, DBusConnection *connection, DBusError *error)
2561 {
2562         struct kdbus_cmd_hello __attribute__ ((__aligned__(8))) hello;
2563         int fd;
2564
2565         hello.conn_flags = KDBUS_HELLO_ACCEPT_FD/* |
2566                            KDBUS_HELLO_ATTACH_COMM |
2567                            KDBUS_HELLO_ATTACH_EXE |
2568                            KDBUS_HELLO_ATTACH_CMDLINE |
2569                            KDBUS_HELLO_ATTACH_CAPS |
2570                            KDBUS_HELLO_ATTACH_CGROUP |
2571                            KDBUS_HELLO_ATTACH_SECLABEL |
2572                            KDBUS_HELLO_ATTACH_AUDIT*/;
2573         hello.size = sizeof(struct kdbus_cmd_hello);
2574         hello.pool_size = RECEIVE_POOL_SIZE;
2575
2576         if(!dbus_connection_get_socket(connection, &fd))
2577         {
2578                 dbus_set_error (error, "failed to get fd for bus registration", NULL);
2579                 return FALSE;
2580         }
2581         if (ioctl(fd, KDBUS_CMD_HELLO, &hello))
2582         {
2583                 dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno));
2584                 return FALSE;
2585         }
2586
2587         sprintf(name, "%llu", (unsigned long long)hello.id);
2588         _dbus_verbose("-- Our peer ID is: %s\n", name);
2589         ((DBusTransportSocket*)dbus_connection_get_transport(connection))->bloom_size = hello.bloom_size;
2590
2591         if(!kdbus_mmap(dbus_connection_get_transport(connection)))
2592         {
2593                 dbus_set_error(error,_dbus_error_from_errno (errno), "Error when mmap: %s", _dbus_strerror (errno));
2594                 return FALSE;
2595         }
2596
2597         return TRUE;
2598 }
2599
2600 /**
2601  * kdbus version of dbus_bus_request_name.
2602  *
2603  * Asks the bus to assign the given name to this connection.
2604  *
2605  * Use same flags as original dbus version with one exception below.
2606  * Result flag #DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER is currently
2607  * never returned by kdbus, instead DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
2608  * is returned by kdbus.
2609  *
2610  * @param connection the connection
2611  * @param name the name to request
2612  * @param flags flags
2613  * @param error location to store the error
2614  * @returns a result code, -1 if error is set
2615  */
2616 int bus_request_name_kdbus(DBusConnection *connection, const char *name, const uint64_t flags, DBusError *error)
2617 {
2618         struct kdbus_cmd_name *cmd_name;
2619         int fd;
2620         uint64_t size = sizeof(*cmd_name) + strlen(name) + 1;
2621         uint64_t flags_kdbus = 0;
2622
2623         cmd_name = alloca(size);
2624
2625         memset(cmd_name, 0, size);
2626         strcpy(cmd_name->name, name);
2627         cmd_name->size = size;
2628
2629         if(flags & DBUS_NAME_FLAG_ALLOW_REPLACEMENT)
2630                 flags_kdbus |= KDBUS_NAME_ALLOW_REPLACEMENT;
2631         if(!(flags & DBUS_NAME_FLAG_DO_NOT_QUEUE))
2632                 flags_kdbus |= KDBUS_NAME_QUEUE;
2633         if(flags & DBUS_NAME_FLAG_REPLACE_EXISTING)
2634                 flags_kdbus |= KDBUS_NAME_REPLACE_EXISTING;
2635
2636         cmd_name->conn_flags = flags_kdbus;
2637
2638         if(!dbus_connection_get_socket(connection, &fd))
2639         {
2640                 dbus_set_error (error, "failed to get fd for name request", NULL);
2641                 return -1;
2642         }
2643
2644         _dbus_verbose("Request name - flags sent: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
2645
2646         _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2647         if (ioctl(fd, KDBUS_CMD_NAME_ACQUIRE, cmd_name))
2648         {
2649                 dbus_set_error(error,_dbus_error_from_errno (errno), "error acquiring name: %s", _dbus_strerror (errno));
2650                 if(errno == EEXIST)
2651                         return DBUS_REQUEST_NAME_REPLY_EXISTS;
2652                 return -1;
2653         }
2654
2655         _dbus_verbose("Request name - received flag: 0x%llx       !!!!!!!!!\n", cmd_name->conn_flags);
2656
2657         if(cmd_name->conn_flags & KDBUS_NAME_IN_QUEUE)
2658                 return DBUS_REQUEST_NAME_REPLY_IN_QUEUE;
2659         else
2660                 return DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER;
2661         /*todo now 1 code is never returned -  DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
2662          * because kdbus never returns it now
2663          */
2664 }
2665
2666 /**
2667  * Checks if the connection's transport is kdbus on the basis of its address
2668  *
2669  * @param pointer to the connection
2670  * @returns TRUE if kdbus transport, otherwise FALSE
2671  */
2672 dbus_bool_t dbus_transport_is_kdbus(DBusConnection *connection)
2673 {
2674         const char* address = _dbus_connection_get_address(connection);
2675
2676         if(address)
2677                 if(address == strstr(address, "kdbus:path="))
2678                                 return TRUE;
2679         return FALSE;
2680 }
2681
2682 /**
2683  * Seeks key in rule string, and duplicates value of the key into pValue.
2684  * If value is "org.freedesktop.DBus" it is indicated by returning -1, because it
2685  * needs to be handled in different manner.
2686  * Value is duplicated from rule string to newly allocated memory pointe by pValue,
2687  * so it must be freed after use.
2688  *
2689  * @param rule rule to look through
2690  * @param key key to look for
2691  * @param pValue pointer to value of the key found
2692  * @return length of the value string, 0 means not found, -1 means "org.freedesktop.DBus"
2693  */
2694 static int parse_match_key(const char *rule, const char* key, char** pValue)
2695 {
2696         const char* pBegin;
2697         const char* pValueEnd;
2698         int value_length = 0;
2699
2700         pBegin = strstr(rule, key);
2701         if(pBegin)
2702         {
2703                 pBegin += strlen(key);
2704                 pValueEnd = strchr(pBegin, '\'');
2705                 if(pValueEnd)
2706                 {
2707                         value_length = pValueEnd - pBegin;
2708                         *pValue = strndup(pBegin, value_length);
2709                         if(*pValue)
2710                         {
2711                                 if(strcmp(*pValue, "org.freedesktop.DBus") == 0)
2712                                         value_length = -1;
2713                                 _dbus_verbose ("found for key: %s value:'%s'\n", key, *pValue);
2714                         }
2715                 }
2716         }
2717         return value_length;
2718 }
2719
2720 /**
2721  * Adds a match rule to match broadcast messages going through the message bus.
2722  * Do no affect messages addressed directly.
2723  *
2724  * The "rule" argument is the string form of a match rule.
2725  *
2726  * In kdbus function do not blocks.
2727  *
2728  * Upper function returns nothing because of blocking issues
2729  * so there is no point to return true or false here.
2730  *
2731  * Only part of the dbus's matching capabilities is implemented in kdbus now, because of different mechanism.
2732  * Current mapping:
2733  * interface match key mapped to bloom
2734  * sender match key mapped to src_name
2735  * also handled org.freedesktop.dbus members: NameOwnerChanged, NameLost, NameAcquired
2736  *
2737  * @param connection connection to the message bus
2738  * @param rule textual form of match rule
2739  * @param error location to store any errors - may be NULL
2740  */
2741 void dbus_bus_add_match_kdbus (DBusConnection *connection, const char *rule, DBusError *error)
2742 {
2743         struct kdbus_cmd_match* pCmd_match;
2744         struct kdbus_item *pItem;
2745         int fd;
2746         __u64 src_id = KDBUS_MATCH_SRC_ID_ANY;
2747         uint64_t size;
2748         unsigned int kernel_item = 0;
2749         int name_size;
2750         char* pName = NULL;
2751         char* pInterface = NULL;
2752         __u64 bloom_size = ((DBusTransportSocket*)dbus_connection_get_transport(connection))->bloom_size;
2753
2754         dbus_connection_get_socket(connection, &fd);
2755
2756         /*parsing rule and calculating size of command*/
2757         size = sizeof(struct kdbus_cmd_match);
2758
2759         if(strstr(rule, "member='NameOwnerChanged'"))
2760         {
2761                 kernel_item = KDBUS_MATCH_NAME_CHANGE;
2762                 size += KDBUS_ITEM_SIZE(1);
2763         }
2764         else if(strstr(rule, "member='NameLost'"))
2765         {
2766                 kernel_item = KDBUS_MATCH_NAME_REMOVE;
2767                 size += KDBUS_ITEM_SIZE(1);
2768         }
2769         else if(strstr(rule, "member='NameAcquired'"))
2770         {
2771                 kernel_item = KDBUS_MATCH_NAME_ADD;
2772                 size += KDBUS_ITEM_SIZE(1);
2773         }
2774
2775         name_size = parse_match_key(rule, "interface='", &pInterface);
2776         if((name_size == -1) && (kernel_item == 0))   //means org.freedesktop.DBus without specified member
2777         {
2778                 kernel_item = ~0;
2779                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2;  /* 3 above name related items plus 2 id related items*/
2780         }
2781         else if(name_size > 0)                  /*actual size is not important for interface because bloom size is defined by bus*/
2782                 size += KDBUS_PART_HEADER_SIZE + bloom_size;
2783
2784         name_size = parse_match_key(rule, "sender='", &pName);
2785         if((name_size == -1) && (kernel_item == 0))  //means org.freedesktop.DBus without specified name - same as interface few line above
2786         {
2787                 kernel_item = ~0;
2788                 size += KDBUS_ITEM_SIZE(1)*3 + KDBUS_ITEM_SIZE(sizeof(__u64))*2; /* 3 above     name related items plus 2 id related items*/
2789         }
2790         else if(name_size > 0)
2791         {
2792                 if(!strncmp(pName, ":1.", 3)) /*if name is unique name it must be converted to unique id*/
2793                 {
2794                         src_id = strtoull(&pName[3], NULL, 10);
2795                         free(pName);
2796                         pName = NULL;
2797                 }
2798                 else
2799                         size += KDBUS_ITEM_SIZE(name_size + 1);  //well known name
2800         }
2801
2802         pCmd_match = alloca(size);
2803         if(pCmd_match == NULL)
2804                 goto out;
2805
2806         pCmd_match->id = 0;
2807         pCmd_match->size = size;
2808         pCmd_match->cookie = strtoull(dbus_bus_get_unique_name(connection), NULL , 10);
2809
2810         pItem = pCmd_match->items;
2811         if(kernel_item == ~0)  //all signals from kernel
2812         {
2813                 pCmd_match->src_id = 0;
2814                 pItem->type = KDBUS_MATCH_NAME_CHANGE;
2815                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2816                 pItem = KDBUS_PART_NEXT(pItem);
2817                 pItem->type = KDBUS_MATCH_NAME_ADD;
2818                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2819                 pItem = KDBUS_PART_NEXT(pItem);
2820                 pItem->type = KDBUS_MATCH_NAME_REMOVE;
2821                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2822                 pItem = KDBUS_PART_NEXT(pItem);
2823                 pItem->type = KDBUS_MATCH_ID_ADD;
2824                 pItem->size = KDBUS_PART_HEADER_SIZE + sizeof(__u64);
2825                 pItem = KDBUS_PART_NEXT(pItem);
2826                 pItem->type = KDBUS_MATCH_ID_REMOVE;
2827                 pItem->size = KDBUS_PART_HEADER_SIZE + sizeof(__u64);
2828         }
2829         else if(kernel_item) //only one item
2830         {
2831                 pCmd_match->src_id = 0;
2832                 pItem->type = kernel_item;
2833                 pItem->size = KDBUS_PART_HEADER_SIZE + 1;
2834         }
2835         else
2836         {
2837                 pCmd_match->src_id = src_id;
2838                 if(pName)
2839                 {
2840                         pItem->type = KDBUS_MATCH_SRC_NAME;
2841                         pItem->size = KDBUS_PART_HEADER_SIZE + name_size + 1;
2842                         strcpy(pItem->str, pName);
2843                         pItem = KDBUS_PART_NEXT(pItem);
2844                 }
2845
2846                 if(pInterface)
2847                 {
2848                         pItem->type = KDBUS_MATCH_BLOOM;
2849                         pItem->size = KDBUS_PART_HEADER_SIZE + bloom_size;
2850                         strncpy(pItem->data, pInterface, bloom_size);
2851                 }
2852         }
2853
2854         if(ioctl(fd, KDBUS_CMD_MATCH_ADD, pCmd_match))
2855         {
2856                 if(error)
2857                         dbus_set_error(error,_dbus_error_from_errno (errno), "error adding match: %s", _dbus_strerror (errno));
2858                 _dbus_verbose("Failed adding match bus rule %s,\nerror: %d, %m\n", rule, errno);
2859         }
2860         else
2861                 _dbus_verbose("Added match bus rule %s\n", rule);
2862
2863 out:
2864         if(pName)
2865                 free(pName);
2866         if(pInterface)
2867                 free(pInterface);
2868 }
2869
2870 /**
2871  * Opposing to dbus, in kdbus removes all match rules with given
2872  * cookie, which now is equal to uniqe id.
2873  *
2874  * In kdbus this function will not block
2875  *
2876  * @param connection connection to the message bus
2877  * @param error location to store any errors - may be NULL
2878  */
2879 void dbus_bus_remove_match_kdbus (DBusConnection *connection, DBusError *error)
2880 {
2881         struct kdbus_cmd_match __attribute__ ((__aligned__(8))) cmd;
2882         int fd;
2883
2884         dbus_connection_get_socket(connection, &fd);
2885         cmd.cookie = strtoull(dbus_bus_get_unique_name(connection), NULL , 10);
2886         cmd.id = cmd.cookie;
2887         cmd.size = sizeof(struct kdbus_cmd_match);
2888
2889         if(ioctl(fd, KDBUS_CMD_MATCH_ADD, &cmd))
2890         {
2891                 if(error)
2892                         dbus_set_error(error,_dbus_error_from_errno (errno), "error removing match: %s", _dbus_strerror (errno));
2893                 _dbus_verbose("Failed removing match rule; error: %d, %m\n", errno);
2894         }
2895         else
2896                 _dbus_verbose("Match rule removed correctly.\n");
2897 }