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