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