diff --git a/lib/cluster/legacy.c b/lib/cluster/legacy.c
index f3daee808d..d93613d4c4 100644
--- a/lib/cluster/legacy.c
+++ b/lib/cluster/legacy.c
@@ -1,946 +1,946 @@
 /*
  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <crm_internal.h>
 #include <crm/cluster/internal.h>
 #include <bzlib.h>
 #include <crm/common/ipc.h>
 #include <crm/cluster.h>
 #include <crm/common/mainloop.h>
 #include <sys/utsname.h>
 #include <sys/socket.h>
 #include <netdb.h>
 
 #if SUPPORT_COROSYNC
 #  include <corosync/confdb.h>
 #  include <corosync/corodefs.h>
 #  include <corosync/cpg.h>
 #  include <corosync/cfg.h>
 #endif
 
 #if HAVE_CMAP
 #  include <corosync/cmap.h>
 #endif
 
 #if SUPPORT_CMAN
 #  include <libcman.h>
 cman_handle_t pcmk_cman_handle = NULL;
 #endif
 
 int ais_membership_timer = 0;
 gboolean ais_membership_force = FALSE;
 int plugin_dispatch(gpointer user_data);
 
 int ais_fd_sync = -1;
 int ais_fd_async = -1;          /* never send messages via this channel */
 void *ais_ipc_ctx = NULL;
 
 hdb_handle_t ais_ipc_handle = 0;
 
 static gboolean
 plugin_get_details(uint32_t * id, char **uname)
 {
     struct iovec iov;
     int retries = 0;
     int rc = CS_OK;
     cs_ipc_header_response_t header;
     struct crm_ais_nodeid_resp_s answer;
 
     static uint32_t local_id = 0;
     static char *local_uname = NULL;
 
     if(local_id) {
         if(id) *id = local_id;
         if(uname) *uname = strdup(local_uname);
         return TRUE;
     }
 
     header.error = CS_OK;
     header.id = crm_class_nodeid;
     header.size = sizeof(cs_ipc_header_response_t);
 
     iov.iov_base = &header;
     iov.iov_len = header.size;
 
   retry:
     errno = 0;
     rc = coroipcc_msg_send_reply_receive(ais_ipc_handle, &iov, 1, &answer, sizeof(answer));
     if (rc == CS_OK) {
         CRM_CHECK(answer.header.size == sizeof(struct crm_ais_nodeid_resp_s),
                   crm_err("Odd message: id=%d, size=%d, error=%d",
                           answer.header.id, answer.header.size, answer.header.error));
         CRM_CHECK(answer.header.id == crm_class_nodeid,
                   crm_err("Bad response id: %d", answer.header.id));
     }
 
     if ((rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) && retries < 20) {
         retries++;
         crm_info("Peer overloaded: Re-sending message (Attempt %d of 20)", retries);
         sleep(retries);         /* Proportional back off */
         goto retry;
     }
 
     if (rc != CS_OK) {
         crm_err("Sending nodeid request: FAILED (rc=%d): %s", rc, ais_error2text(rc));
         return FALSE;
 
     } else if (answer.header.error != CS_OK) {
         crm_err("Bad response from peer: (rc=%d): %s", rc, ais_error2text(rc));
         return FALSE;
     }
 
     crm_info("Server details: id=%u uname=%s cname=%s", answer.id, answer.uname, answer.cname);
 
     local_id = answer.id;
     local_uname = strdup(answer.uname);
 
     if(id) *id = local_id;
     if(uname) *uname = strdup(local_uname);
     return TRUE;
 }
 
 bool
 send_plugin_text(int class, struct iovec *iov)
 {
     int rc = CS_OK;
     int retries = 0;
     int buf_len = sizeof(cs_ipc_header_response_t);
     char *buf = malloc(buf_len);
     AIS_Message *ais_msg = (AIS_Message*)iov[0].iov_base;
-    cs_ipc_header_response_t *header = (cs_ipc_header_response_t *) buf;
+    cs_ipc_header_response_t *header = (cs_ipc_header_response_t *)(void*)buf;
 
     CRM_ASSERT(buf != NULL);
     /* There are only 6 handlers registered to crm_lib_service in plugin.c */
     CRM_CHECK(class < 6, crm_err("Invalid message class: %d", class);
               return FALSE);
 
     do {
         if (rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) {
             retries++;
             crm_info("Peer overloaded or membership in flux:"
                      " Re-sending message (Attempt %d of 20)", retries);
             sleep(retries);     /* Proportional back off */
         }
 
         errno = 0;
         rc = coroipcc_msg_send_reply_receive(ais_ipc_handle, iov, 1, buf, buf_len);
 
     } while ((rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) && retries < 20);
 
     if (rc == CS_OK) {
         CRM_CHECK(header->size == sizeof(cs_ipc_header_response_t),
                   crm_err("Odd message: id=%d, size=%d, class=%d, error=%d",
                           header->id, header->size, class, header->error));
 
         CRM_ASSERT(buf_len >= header->size);
         CRM_CHECK(header->id == CRM_MESSAGE_IPC_ACK,
                   crm_err("Bad response id (%d) for request (%d)", header->id,
                           ais_msg->header.id));
         CRM_CHECK(header->error == CS_OK, rc = header->error);
 
     } else {
         crm_perror(LOG_ERR, "Sending plugin message %d FAILED: %s (%d)",
                    ais_msg->id, ais_error2text(rc), rc);
     }
 
     free(iov[0].iov_base);
     free(iov);
     free(buf);
 
     return (rc == CS_OK);
 }
 
 void
 terminate_cs_connection(crm_cluster_t *cluster)
 {
     crm_notice("Disconnecting from Corosync");
 
     if (is_classic_ais_cluster()) {
         if (ais_ipc_handle) {
             crm_trace("Disconnecting plugin");
             coroipcc_service_disconnect(ais_ipc_handle);
             ais_ipc_handle = 0;
         } else {
             crm_info("No plugin connection");
         }
     }
     cluster_disconnect_cpg(cluster);
 
 #  if SUPPORT_CMAN
     if (is_cman_cluster()) {
         if (pcmk_cman_handle) {
             crm_info("Disconnecting cman");
             if (cman_stop_notification(pcmk_cman_handle) >= 0) {
                 crm_info("Destroying cman");
                 cman_finish(pcmk_cman_handle);
             }
 
         } else {
             crm_info("No cman connection");
         }
     }
 #  endif
     ais_fd_async = -1;
     ais_fd_sync = -1;
 }
 
 void
 plugin_handle_membership(AIS_Message *msg)
 {
     if (msg->header.id == crm_class_members || msg->header.id == crm_class_quorum) {
         xmlNode *member = NULL;
         const char *value = NULL;
         gboolean quorate = FALSE;
         xmlNode *xml = string2xml(msg->data);
 
         if (xml == NULL) {
             crm_err("Invalid membership update: %s", msg->data);
             return;
         }
 
         value = crm_element_value(xml, "quorate");
         CRM_CHECK(value != NULL, crm_log_xml_err(xml, "No quorum value:"); return);
         if (crm_is_true(value)) {
             quorate = TRUE;
         }
 
         value = crm_element_value(xml, "id");
         CRM_CHECK(value != NULL, crm_log_xml_err(xml, "No membership id"); return);
         crm_peer_seq = crm_int_helper(value, NULL);
 
         if (quorate != crm_have_quorum) {
             crm_notice("Membership %s: quorum %s", value, quorate ? "acquired" : "lost");
             crm_have_quorum = quorate;
 
         } else {
             crm_info("Membership %s: quorum %s", value, quorate ? "retained" : "still lost");
         }
 
         for (member = __xml_first_child(xml); member != NULL; member = __xml_next(member)) {
             const char *id_s = crm_element_value(member, "id");
             const char *addr = crm_element_value(member, "addr");
             const char *uname = crm_element_value(member, "uname");
             const char *state = crm_element_value(member, "state");
             const char *born_s = crm_element_value(member, "born");
             const char *seen_s = crm_element_value(member, "seen");
             const char *votes_s = crm_element_value(member, "votes");
             const char *procs_s = crm_element_value(member, "processes");
 
             int votes = crm_int_helper(votes_s, NULL);
             unsigned int id = crm_int_helper(id_s, NULL);
             unsigned int procs = crm_int_helper(procs_s, NULL);
 
             /* TODO: These values will contain garbage if version < 0.7.1 */
             uint64_t born = crm_int_helper(born_s, NULL);
             uint64_t seen = crm_int_helper(seen_s, NULL);
 
             crm_update_peer(__FUNCTION__, id, born, seen, votes, procs, uname, uname, addr, state);
         }
         free_xml(xml);
     }
 }
 
 static void
 plugin_default_deliver_message(cpg_handle_t handle,
                                const struct cpg_name *groupName,
                                uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
 {
     uint32_t kind = 0;
     const char *from = NULL;
     char *data = pcmk_message_common_cs(handle, nodeid, pid, msg, &kind, &from);
 
     free(data);
 }
 
 int
 plugin_dispatch(gpointer user_data)
 {
     int rc = CS_OK;
     crm_cluster_t *cluster = (crm_cluster_t *) user_data;
 
     do {
         char *buffer = NULL;
 
         rc = coroipcc_dispatch_get(ais_ipc_handle, (void **)&buffer, 0);
         if (rc == CS_ERR_TRY_AGAIN || rc == CS_ERR_QUEUE_FULL) {
             return 0;
         }
         if (rc != CS_OK) {
             crm_perror(LOG_ERR, "Receiving message body failed: (%d) %s", rc, ais_error2text(rc));
             return -1;
         }
         if (buffer == NULL) {
             /* NULL is a legal "no message afterall" value */
             return 0;
         }
         /*
         cpg_deliver_fn_t(cpg_handle_t handle, const struct cpg_name *group_name,
                          uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len);
         */
         if (cluster && cluster->cpg.cpg_deliver_fn) {
             cluster->cpg.cpg_deliver_fn(0, NULL, 0, 0, buffer, 0);
 
         } else {
             plugin_default_deliver_message(0, NULL, 0, 0, buffer, 0);
         }
 
         coroipcc_dispatch_put(ais_ipc_handle);
 
     } while (ais_ipc_handle);
 
     return 0;
 }
 
 static void
 plugin_destroy(gpointer user_data)
 {
     crm_err("AIS connection terminated");
     ais_fd_sync = -1;
     crm_exit(ENOTCONN);
 }
 
 #  if SUPPORT_CMAN
 
 static int
 pcmk_cman_dispatch(gpointer user_data)
 {
     int rc = cman_dispatch(pcmk_cman_handle, CMAN_DISPATCH_ALL);
 
     if (rc < 0) {
         crm_err("Connection to cman failed: %d", rc);
         pcmk_cman_handle = 0;
         return FALSE;
     }
     return TRUE;
 }
 
 #    define MAX_NODES 256
 
 static void
 cman_event_callback(cman_handle_t handle, void *privdata, int reason, int arg)
 {
     int rc = 0, lpc = 0, node_count = 0;
 
     cman_cluster_t cluster;
     static cman_node_t cman_nodes[MAX_NODES];
 
     gboolean(*dispatch) (unsigned long long, gboolean) = privdata;
 
     switch (reason) {
         case CMAN_REASON_STATECHANGE:
 
             memset(&cluster, 0, sizeof(cluster));
             rc = cman_get_cluster(pcmk_cman_handle, &cluster);
             if (rc < 0) {
                 crm_err("Couldn't query cman cluster details: %d %d", rc, errno);
                 return;
             }
 
             crm_peer_seq = cluster.ci_generation;
             if (arg != crm_have_quorum) {
                 crm_notice("Membership %llu: quorum %s", crm_peer_seq, arg ? "acquired" : "lost");
                 crm_have_quorum = arg;
 
             } else {
                 crm_info("Membership %llu: quorum %s", crm_peer_seq,
                          arg ? "retained" : "still lost");
             }
 
             rc = cman_get_nodes(pcmk_cman_handle, MAX_NODES, &node_count, cman_nodes);
             if (rc < 0) {
                 crm_err("Couldn't query cman node list: %d %d", rc, errno);
                 return;
             }
 
             for (lpc = 0; lpc < node_count; lpc++) {
                 crm_node_t *peer = NULL;
 
                 if (cman_nodes[lpc].cn_nodeid == 0) {
                     /* Never allow node ID 0 to be considered a member #315711 */
                     /* Skip entirely, its a qdisk */
                     continue;
                 }
 
                 peer = crm_get_peer(cman_nodes[lpc].cn_nodeid, cman_nodes[lpc].cn_name);
                 if(cman_nodes[lpc].cn_member) {
                     crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_MEMBER, crm_peer_seq);
 
                 } else if(peer->state) {
                     crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0);
 
                 } else {
                     crm_info("State of node %s[%u] is still unknown", peer->uname, peer->id);
                 }
             }
 
             if (dispatch) {
                 dispatch(crm_peer_seq, crm_have_quorum);
             }
             break;
 
         case CMAN_REASON_TRY_SHUTDOWN:
             /* Always reply with a negative - pacemaker needs to be stopped first */
             crm_notice("CMAN wants to shut down: %s", arg ? "forced" : "optional");
             cman_replyto_shutdown(pcmk_cman_handle, 0);
             break;
 
         case CMAN_REASON_CONFIG_UPDATE:
             /* Ignore */
             break;
     }
 }
 #  endif
 
 gboolean
 init_cman_connection(gboolean(*dispatch) (unsigned long long, gboolean), void (*destroy) (gpointer))
 {
 #  if SUPPORT_CMAN
     int rc = -1, fd = -1;
     cman_cluster_t cluster;
 
     struct mainloop_fd_callbacks cman_fd_callbacks = {
         .dispatch = pcmk_cman_dispatch,
         .destroy = destroy,
     };
 
     crm_info("Configuring Pacemaker to obtain quorum from cman");
 
     memset(&cluster, 0, sizeof(cluster));
 
     pcmk_cman_handle = cman_init(dispatch);
     if (pcmk_cman_handle == NULL || cman_is_active(pcmk_cman_handle) == FALSE) {
         crm_err("Couldn't connect to cman");
         goto cman_bail;
     }
 
     rc = cman_start_notification(pcmk_cman_handle, cman_event_callback);
     if (rc < 0) {
         crm_err("Couldn't register for cman notifications: %d %d", rc, errno);
         goto cman_bail;
     }
 
     /* Get the current membership state */
     cman_event_callback(pcmk_cman_handle, dispatch, CMAN_REASON_STATECHANGE,
                         cman_is_quorate(pcmk_cman_handle));
 
     fd = cman_get_fd(pcmk_cman_handle);
 
     mainloop_add_fd("cman", G_PRIORITY_MEDIUM, fd, dispatch, &cman_fd_callbacks);
 
   cman_bail:
     if (rc < 0) {
         cman_finish(pcmk_cman_handle);
         return FALSE;
     }
 #  else
     crm_err("cman qorum is not supported in this build");
     crm_exit(DAEMON_RESPAWN_STOP);
 #  endif
     return TRUE;
 }
 
 #  ifdef SUPPORT_COROSYNC
 
 gboolean
 cluster_connect_quorum(gboolean(*dispatch) (unsigned long long, gboolean),
                        void (*destroy) (gpointer))
 {
     crm_err("The Corosync quorum API is not supported in this build");
     crm_exit(DAEMON_RESPAWN_STOP);
     return TRUE;
 }
 
 static gboolean
 init_cs_connection_classic(crm_cluster_t * cluster)
 {
     int rc;
     int pid = 0;
     char *pid_s = NULL;
     const char *name = NULL;
     crm_node_t *peer = NULL;
     enum crm_proc_flag proc = 0;
 
     struct mainloop_fd_callbacks ais_fd_callbacks = {
         .dispatch = plugin_dispatch,
         .destroy = cluster->destroy,
     };
 
     crm_info("Creating connection to our Corosync plugin");
     rc = coroipcc_service_connect(COROSYNC_SOCKET_NAME, PCMK_SERVICE_ID,
                                   AIS_IPC_MESSAGE_SIZE, AIS_IPC_MESSAGE_SIZE, AIS_IPC_MESSAGE_SIZE,
                                   &ais_ipc_handle);
     if (ais_ipc_handle) {
         coroipcc_fd_get(ais_ipc_handle, &ais_fd_async);
     } else {
         crm_info("Connection to our Corosync plugin (%d) failed: %s (%d)",
                  PCMK_SERVICE_ID, strerror(errno), errno);
         return FALSE;
     }
     if (ais_fd_async <= 0 && rc == CS_OK) {
         crm_err("No context created, but connection reported 'ok'");
         rc = CS_ERR_LIBRARY;
     }
     if (rc != CS_OK) {
         crm_info("Connection to our Corosync plugin (%d) failed: %s (%d)", PCMK_SERVICE_ID,
                  ais_error2text(rc), rc);
     }
 
     if (rc != CS_OK) {
         return FALSE;
     }
 
     if (ais_fd_callbacks.destroy == NULL) {
         ais_fd_callbacks.destroy = plugin_destroy;
     }
 
     mainloop_add_fd("corosync-plugin", G_PRIORITY_MEDIUM, ais_fd_async, cluster, &ais_fd_callbacks);
     crm_info("AIS connection established");
 
     pid = getpid();
     pid_s = crm_itoa(pid);
     send_cluster_text(crm_class_cluster, pid_s, TRUE, NULL, crm_msg_ais);
     free(pid_s);
 
     cluster->nodeid = get_local_nodeid(0);
 
     name = get_local_node_name();
     plugin_get_details(NULL, &(cluster->uname));
     if (safe_str_neq(name, cluster->uname)) {
         crm_crit("Node name mismatch!  Corosync supplied %s but our lookup returned %s",
                  cluster->uname, name);
         crm_notice
             ("Node name mismatches usually occur when assigned automatically by DHCP servers");
         crm_exit(ENOTUNIQ);
     }
 
     proc = text2proc(crm_system_name);
     peer = crm_get_peer(cluster->nodeid, cluster->uname);
     crm_update_peer_proc(__FUNCTION__, peer, proc|crm_proc_plugin, ONLINESTATUS);
 
     return TRUE;
 }
 
 static int
 pcmk_mcp_dispatch(const char *buffer, ssize_t length, gpointer userdata)
 {
     xmlNode *msg = string2xml(buffer);
 
     if (msg && is_classic_ais_cluster()) {
         xmlNode *node = NULL;
 
         for (node = __xml_first_child(msg); node != NULL; node = __xml_next(node)) {
             int id = 0;
             int children = 0;
             const char *uname = crm_element_value(node, "uname");
 
             crm_element_value_int(node, "id", &id);
             crm_element_value_int(node, "processes", &children);
             if (id == 0) {
                 crm_log_xml_err(msg, "Bad Update");
             } else {
                 crm_node_t *peer = crm_get_peer(id, uname);
 
                 crm_update_peer_proc(__FUNCTION__, peer, children, NULL);
             }
         }
     }
 
     free_xml(msg);
     return 0;
 }
 
 static void
 pcmk_mcp_destroy(gpointer user_data)
 {
     void (*callback) (gpointer data) = user_data;
 
     if (callback) {
         callback(NULL);
     }
 }
 
 gboolean
 init_cs_connection(crm_cluster_t * cluster)
 {
     int retries = 0;
 
     static struct ipc_client_callbacks mcp_callbacks = {
         .dispatch = pcmk_mcp_dispatch,
         .destroy = pcmk_mcp_destroy
     };
 
     while (retries < 5) {
         int rc = init_cs_connection_once(cluster);
 
         retries++;
         switch (rc) {
             case CS_OK:
                 if (getenv("HA_mcp") && get_cluster_type() != pcmk_cluster_cman) {
                     xmlNode *poke = create_xml_node(NULL, "poke");
                     mainloop_io_t *ipc =
                         mainloop_add_ipc_client(CRM_SYSTEM_MCP, G_PRIORITY_MEDIUM, 0,
                                                 cluster->destroy, &mcp_callbacks);
 
                     crm_ipc_send(mainloop_get_ipc_client(ipc), poke, 0, 0, NULL);
                     free_xml(poke);
                 }
                 return TRUE;
                 break;
             case CS_ERR_TRY_AGAIN:
             case CS_ERR_QUEUE_FULL:
                 sleep(retries);
                 break;
             default:
                 return FALSE;
         }
     }
 
     crm_err("Retry count exceeded: %d", retries);
     return FALSE;
 }
 
 char *
 classic_node_name(uint32_t nodeid)
 {
     return NULL;                /* Always use the uname() default for localhost.  No way to look up peers */
 }
 
 char *
 cman_node_name(uint32_t nodeid)
 {
     char *name = NULL;
 
 #  if SUPPORT_CMAN
     cman_node_t us;
     cman_handle_t cman;
 
     cman = cman_init(NULL);
     if (cman != NULL && cman_is_active(cman)) {
         us.cn_name[0] = 0;
         cman_get_node(cman, nodeid, &us);
         name = strdup(us.cn_name);
         crm_info("Using CMAN node name %s for %u", name, nodeid);
     }
 
     cman_finish(cman);
 #  endif
 
     if (name == NULL) {
         crm_debug("Unable to get node name for nodeid %u", nodeid);
     }
     return name;
 }
 
 extern int set_cluster_type(enum cluster_type_e type);
 
 gboolean
 init_cs_connection_once(crm_cluster_t * cluster)
 {
     crm_node_t *peer = NULL;
     enum cluster_type_e stack = get_cluster_type();
 
     crm_peer_init();
 
     /* Here we just initialize comms */
     switch (stack) {
         case pcmk_cluster_classic_ais:
             if (init_cs_connection_classic(cluster) == FALSE) {
                 return FALSE;
             }
             break;
         case pcmk_cluster_cman:
             if (cluster_connect_cpg(cluster) == FALSE) {
                 return FALSE;
             }
             cluster->uname = cman_node_name(0 /* CMAN_NODEID_US */ );
             break;
         case pcmk_cluster_heartbeat:
             crm_info("Could not find an active corosync based cluster");
             return FALSE;
             break;
         default:
             crm_err("Invalid cluster type: %s (%d)", name_for_cluster_type(stack), stack);
             return FALSE;
             break;
     }
 
     crm_info("Connection to '%s': established", name_for_cluster_type(stack));
 
     cluster->nodeid = get_local_nodeid(0);
     if(cluster->nodeid == 0) {
         crm_err("Could not establish local nodeid");
         return FALSE;
     }
 
     cluster->uname = get_node_name(0);
     if(cluster->uname == NULL) {
         crm_err("Could not establish local node name");
         return FALSE;
     }
 
     /* Ensure the local node always exists */
     peer = crm_get_peer(cluster->nodeid, cluster->uname);
     cluster->uuid = get_corosync_uuid(peer);
 
     return TRUE;
 }
 
 gboolean
 check_message_sanity(const AIS_Message * msg, const char *data)
 {
     gboolean sane = TRUE;
     int dest = msg->host.type;
     int tmp_size = msg->header.size - sizeof(AIS_Message);
 
     if (sane && msg->header.size == 0) {
         crm_warn("Message with no size");
         sane = FALSE;
     }
 
     if (sane && msg->header.error != CS_OK) {
         crm_warn("Message header contains an error: %d", msg->header.error);
         sane = FALSE;
     }
 
     if (sane && ais_data_len(msg) != tmp_size) {
         crm_warn("Message payload size is incorrect: expected %d, got %d", ais_data_len(msg),
                  tmp_size);
         sane = TRUE;
     }
 
     if (sane && ais_data_len(msg) == 0) {
         crm_warn("Message with no payload");
         sane = FALSE;
     }
 
     if (sane && data && msg->is_compressed == FALSE) {
         int str_size = strlen(data) + 1;
 
         if (ais_data_len(msg) != str_size) {
             int lpc = 0;
 
             crm_warn("Message payload is corrupted: expected %d bytes, got %d",
                      ais_data_len(msg), str_size);
             sane = FALSE;
             for (lpc = (str_size - 10); lpc < msg->size; lpc++) {
                 if (lpc < 0) {
                     lpc = 0;
                 }
                 crm_debug("bad_data[%d]: %d / '%c'", lpc, data[lpc], data[lpc]);
             }
         }
     }
 
     if (sane == FALSE) {
         crm_err("Invalid message %d: (dest=%s:%s, from=%s:%s.%d, compressed=%d, size=%d, total=%d)",
                 msg->id, ais_dest(&(msg->host)), msg_type2text(dest),
                 ais_dest(&(msg->sender)), msg_type2text(msg->sender.type),
                 msg->sender.pid, msg->is_compressed, ais_data_len(msg), msg->header.size);
 
     } else {
         crm_trace
             ("Verified message %d: (dest=%s:%s, from=%s:%s.%d, compressed=%d, size=%d, total=%d)",
              msg->id, ais_dest(&(msg->host)), msg_type2text(dest), ais_dest(&(msg->sender)),
              msg_type2text(msg->sender.type), msg->sender.pid, msg->is_compressed,
              ais_data_len(msg), msg->header.size);
     }
 
     return sane;
 }
 #endif
 
 static int
 get_config_opt(confdb_handle_t config,
                hdb_handle_t object_handle, const char *key, char **value, const char *fallback)
 {
     size_t len = 0;
     char *env_key = NULL;
     const char *env_value = NULL;
     char buffer[256];
 
     if (*value) {
         free(*value);
         *value = NULL;
     }
 
     if (object_handle > 0) {
         if (CS_OK == confdb_key_get(config, object_handle, key, strlen(key), &buffer, &len)) {
             *value = strdup(buffer);
         }
     }
 
     if (*value) {
         crm_info("Found '%s' for option: %s", *value, key);
         return 0;
     }
 
     env_key = crm_concat("HA", key, '_');
     env_value = getenv(env_key);
     free(env_key);
 
     if (*value) {
         crm_info("Found '%s' in ENV for option: %s", *value, key);
         *value = strdup(env_value);
         return 0;
     }
 
     if (fallback) {
         crm_info("Defaulting to '%s' for option: %s", fallback, key);
         *value = strdup(fallback);
 
     } else {
         crm_info("No default for option: %s", key);
     }
 
     return -1;
 }
 
 static confdb_handle_t
 config_find_init(confdb_handle_t config)
 {
     cs_error_t rc = CS_OK;
     confdb_handle_t local_handle = OBJECT_PARENT_HANDLE;
 
     rc = confdb_object_find_start(config, local_handle);
     if (rc == CS_OK) {
         return local_handle;
     } else {
         crm_err("Couldn't create search context: %d", rc);
     }
     return 0;
 }
 
 static hdb_handle_t
 config_find_next(confdb_handle_t config, const char *name, confdb_handle_t top_handle)
 {
     cs_error_t rc = CS_OK;
     hdb_handle_t local_handle = 0;
 
     if (top_handle == 0) {
         crm_err("Couldn't search for %s: no valid context", name);
         return 0;
     }
 
     crm_trace("Searching for %s in " HDB_X_FORMAT, name, top_handle);
     rc = confdb_object_find(config, top_handle, name, strlen(name), &local_handle);
     if (rc != CS_OK) {
         crm_info("No additional configuration supplied for: %s", name);
         local_handle = 0;
     } else {
         crm_info("Processing additional %s options...", name);
     }
     return local_handle;
 }
 
 enum cluster_type_e
 find_corosync_variant(void)
 {
     confdb_handle_t config;
     enum cluster_type_e found = pcmk_cluster_unknown;
 
     int rc;
     char *value = NULL;
     confdb_handle_t top_handle = 0;
     hdb_handle_t local_handle = 0;
     static confdb_callbacks_t callbacks = { };
 
     rc = confdb_initialize(&config, &callbacks);
     if (rc != CS_OK) {
         crm_debug("Could not initialize Cluster Configuration Database API instance error %d", rc);
         return found;
     }
 
     top_handle = config_find_init(config);
     local_handle = config_find_next(config, "service", top_handle);
     while (local_handle) {
         get_config_opt(config, local_handle, "name", &value, NULL);
         if (safe_str_eq("pacemaker", value)) {
             found = pcmk_cluster_classic_ais;
 
             get_config_opt(config, local_handle, "ver", &value, "0");
             crm_trace("Found Pacemaker plugin version: %s", value);
             break;
         }
 
         local_handle = config_find_next(config, "service", top_handle);
     }
 
     if (found == pcmk_cluster_unknown) {
         top_handle = config_find_init(config);
         local_handle = config_find_next(config, "quorum", top_handle);
         get_config_opt(config, local_handle, "provider", &value, NULL);
 
         if (safe_str_eq("quorum_cman", value)) {
             crm_trace("Found CMAN quorum provider");
             found = pcmk_cluster_cman;
         }
     }
     free(value);
 
     confdb_finalize(config);
     if (found == pcmk_cluster_unknown) {
         crm_err
             ("Corosync is running, but Pacemaker could not find the CMAN or Pacemaker plugin loaded");
         found = pcmk_cluster_invalid;
     }
     return found;
 }
 
 gboolean
 crm_is_corosync_peer_active(const crm_node_t * node)
 {
     enum crm_proc_flag proc = crm_proc_none;
 
     if (node == NULL) {
         crm_trace("NULL");
         return FALSE;
 
     } else if (safe_str_neq(node->state, CRM_NODE_MEMBER)) {
         crm_trace("%s: state=%s", node->uname, node->state);
         return FALSE;
 
     } else if (is_cman_cluster() && (node->processes & crm_proc_cpg)) {
         /* If we can still talk to our peer process on that node,
          * then its also part of the corosync membership
          */
         crm_trace("%s: processes=%.8x", node->uname, node->processes);
         return TRUE;
 
     } else if (is_classic_ais_cluster()) {
         if (node->processes < crm_proc_none) {
             crm_debug("%s: unknown process list, assuming active for now", node->uname);
             return TRUE;
 
         } else if (is_set(node->processes, crm_proc_none)) {
             crm_debug("%s: all processes are inactive", node->uname);
             return FALSE;
 
         } else if (is_not_set(node->processes, crm_proc_plugin)) {
             crm_trace("%s: processes=%.8x", node->uname, node->processes);
             return FALSE;
         }
     }
 
     proc = text2proc(crm_system_name);
     if (proc > crm_proc_none && (node->processes & proc) == 0) {
         crm_trace("%s: proc %.8x not in %.8x", node->uname, proc, node->processes);
         return FALSE;
     }
 
     return TRUE;
 }
diff --git a/lib/common/ipc.c b/lib/common/ipc.c
index 3d347068b5..b951218a49 100644
--- a/lib/common/ipc.c
+++ b/lib/common/ipc.c
@@ -1,1237 +1,1237 @@
 /*
  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <crm_internal.h>
 
 #include <sys/param.h>
 
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <grp.h>
 
 #include <errno.h>
 #include <fcntl.h>
 #include <bzlib.h>
 
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 #include <crm/common/ipc.h>
 #include <crm/common/ipcs.h>
 
 #define PCMK_IPC_VERSION 1
 
 struct crm_ipc_response_header {
     struct qb_ipc_response_header qb;
     uint32_t size_uncompressed;
     uint32_t size_compressed;
     uint32_t flags;
     uint8_t  version; /* Protect against version changes for anyone that might bother to statically link us */
 };
 
 static int hdr_offset = 0;
 static int ipc_buffer_max = 0;
 static unsigned int pick_ipc_buffer(int max);
 
 static inline void
 crm_ipc_init(void)
 {
     if (hdr_offset == 0) {
         hdr_offset = sizeof(struct crm_ipc_response_header);
     }
     if (ipc_buffer_max == 0) {
         ipc_buffer_max = pick_ipc_buffer(0);
     }
 }
 
 int
 crm_ipc_default_buffer_size(void)
 {
     return pick_ipc_buffer(0);
 }
 
 static char *
 generateReference(const char *custom1, const char *custom2)
 {
     static uint ref_counter = 0;
     const char *local_cust1 = custom1;
     const char *local_cust2 = custom2;
     int reference_len = 4;
     char *since_epoch = NULL;
 
     reference_len += 20;        /* too big */
     reference_len += 40;        /* too big */
 
     if (local_cust1 == NULL) {
         local_cust1 = "_empty_";
     }
     reference_len += strlen(local_cust1);
 
     if (local_cust2 == NULL) {
         local_cust2 = "_empty_";
     }
     reference_len += strlen(local_cust2);
 
     since_epoch = calloc(1, reference_len);
 
     if (since_epoch != NULL) {
         sprintf(since_epoch, "%s-%s-%ld-%u",
                 local_cust1, local_cust2, (unsigned long)time(NULL), ref_counter++);
     }
 
     return since_epoch;
 }
 
 xmlNode *
 create_request_adv(const char *task, xmlNode * msg_data,
                    const char *host_to, const char *sys_to,
                    const char *sys_from, const char *uuid_from, const char *origin)
 {
     char *true_from = NULL;
     xmlNode *request = NULL;
     char *reference = generateReference(task, sys_from);
 
     if (uuid_from != NULL) {
         true_from = generate_hash_key(sys_from, uuid_from);
     } else if (sys_from != NULL) {
         true_from = strdup(sys_from);
     } else {
         crm_err("No sys from specified");
     }
 
     /* host_from will get set for us if necessary by CRMd when routed */
     request = create_xml_node(NULL, __FUNCTION__);
     crm_xml_add(request, F_CRM_ORIGIN, origin);
     crm_xml_add(request, F_TYPE, T_CRM);
     crm_xml_add(request, F_CRM_VERSION, CRM_FEATURE_SET);
     crm_xml_add(request, F_CRM_MSG_TYPE, XML_ATTR_REQUEST);
     crm_xml_add(request, F_CRM_REFERENCE, reference);
     crm_xml_add(request, F_CRM_TASK, task);
     crm_xml_add(request, F_CRM_SYS_TO, sys_to);
     crm_xml_add(request, F_CRM_SYS_FROM, true_from);
 
     /* HOSTTO will be ignored if it is to the DC anyway. */
     if (host_to != NULL && strlen(host_to) > 0) {
         crm_xml_add(request, F_CRM_HOST_TO, host_to);
     }
 
     if (msg_data != NULL) {
         add_message_xml(request, F_CRM_DATA, msg_data);
     }
     free(reference);
     free(true_from);
 
     return request;
 }
 
 /*
  * This method adds a copy of xml_response_data
  */
 xmlNode *
 create_reply_adv(xmlNode * original_request, xmlNode * xml_response_data, const char *origin)
 {
     xmlNode *reply = NULL;
 
     const char *host_from = crm_element_value(original_request, F_CRM_HOST_FROM);
     const char *sys_from = crm_element_value(original_request, F_CRM_SYS_FROM);
     const char *sys_to = crm_element_value(original_request, F_CRM_SYS_TO);
     const char *type = crm_element_value(original_request, F_CRM_MSG_TYPE);
     const char *operation = crm_element_value(original_request, F_CRM_TASK);
     const char *crm_msg_reference = crm_element_value(original_request, F_CRM_REFERENCE);
 
     if (type == NULL) {
         crm_err("Cannot create new_message, no message type in original message");
         CRM_ASSERT(type != NULL);
         return NULL;
 #if 0
     } else if (strcasecmp(XML_ATTR_REQUEST, type) != 0) {
         crm_err("Cannot create new_message, original message was not a request");
         return NULL;
 #endif
     }
     reply = create_xml_node(NULL, __FUNCTION__);
     if (reply == NULL) {
         crm_err("Cannot create new_message, malloc failed");
         return NULL;
     }
 
     crm_xml_add(reply, F_CRM_ORIGIN, origin);
     crm_xml_add(reply, F_TYPE, T_CRM);
     crm_xml_add(reply, F_CRM_VERSION, CRM_FEATURE_SET);
     crm_xml_add(reply, F_CRM_MSG_TYPE, XML_ATTR_RESPONSE);
     crm_xml_add(reply, F_CRM_REFERENCE, crm_msg_reference);
     crm_xml_add(reply, F_CRM_TASK, operation);
 
     /* since this is a reply, we reverse the from and to */
     crm_xml_add(reply, F_CRM_SYS_TO, sys_from);
     crm_xml_add(reply, F_CRM_SYS_FROM, sys_to);
 
     /* HOSTTO will be ignored if it is to the DC anyway. */
     if (host_from != NULL && strlen(host_from) > 0) {
         crm_xml_add(reply, F_CRM_HOST_TO, host_from);
     }
 
     if (xml_response_data != NULL) {
         add_message_xml(reply, F_CRM_DATA, xml_response_data);
     }
 
     return reply;
 }
 
 /* Libqb based IPC */
 
 /* Server... */
 
 GHashTable *client_connections = NULL;
 
 crm_client_t *
 crm_client_get(qb_ipcs_connection_t * c)
 {
     if (client_connections) {
         return g_hash_table_lookup(client_connections, c);
     }
 
     crm_trace("No client found for %p", c);
     return NULL;
 }
 
 crm_client_t *
 crm_client_get_by_id(const char *id)
 {
     gpointer key;
     crm_client_t *client;
     GHashTableIter iter;
 
     if (client_connections && id) {
         g_hash_table_iter_init(&iter, client_connections);
         while (g_hash_table_iter_next(&iter, &key, (gpointer *) & client)) {
             if (strcmp(client->id, id) == 0) {
                 return client;
             }
         }
     }
 
     crm_trace("No client found with id=%s", id);
     return NULL;
 }
 
 const char *
 crm_client_name(crm_client_t * c)
 {
     if (c == NULL) {
         return "null";
     } else if (c->name == NULL && c->id == NULL) {
         return "unknown";
     } else if (c->name == NULL) {
         return c->id;
     } else {
         return c->name;
     }
 }
 
 void
 crm_client_init(void)
 {
     if (client_connections == NULL) {
         crm_trace("Creating client hash table");
         client_connections = g_hash_table_new(g_direct_hash, g_direct_equal);
     }
 }
 
 void
 crm_client_cleanup(void)
 {
     if (client_connections != NULL) {
         int active = g_hash_table_size(client_connections);
 
         if (active) {
             crm_err("Exiting with %d active connections", active);
         }
         g_hash_table_destroy(client_connections); client_connections = NULL;
     }
 }
 
 void
 crm_client_disconnect_all(qb_ipcs_service_t *service)
 {
     qb_ipcs_connection_t *c = qb_ipcs_connection_first_get(service);
 
     while (c != NULL) {
         qb_ipcs_connection_t *last = c;
 
         c = qb_ipcs_connection_next_get(service, last);
 
         /* There really shouldn't be anyone connected at this point */
         crm_notice("Disconnecting client %p, pid=%d...", last, crm_ipcs_client_pid(last));
         qb_ipcs_disconnect(last);
         qb_ipcs_connection_unref(last);
     }
 }
 
 crm_client_t *
 crm_client_new(qb_ipcs_connection_t * c, uid_t uid_client, gid_t gid_client)
 {
     static uid_t uid_server = 0;
     static gid_t gid_cluster = 0;
 
     crm_client_t *client = NULL;
 
     CRM_LOG_ASSERT(c);
     if (c == NULL) {
         return NULL;
     }
 
     if (gid_cluster == 0) {
         uid_server = getuid();
         if(crm_user_lookup(CRM_DAEMON_USER, NULL, &gid_cluster) < 0) {
             static bool have_error = FALSE;
             if(have_error == FALSE) {
                 crm_warn("Could not find group for user %s", CRM_DAEMON_USER);
                 have_error = TRUE;
             }
         }
     }
 
     if(gid_cluster != 0 && gid_client != 0) {
         uid_t best_uid = -1; /* Passing -1 to chown(2) means don't change */
 
         if(uid_client == 0 || uid_server == 0) { /* Someone is priveliged, but the other may not be */
             best_uid = QB_MAX(uid_client, uid_server);
             crm_trace("Allowing user %u to clean up after disconnect", best_uid);
         }
 
         crm_trace("Giving access to group %u", gid_cluster);
         qb_ipcs_connection_auth_set(c, best_uid, gid_cluster, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
     }
 
     crm_client_init();
 
     /* TODO: Do our own auth checking, return NULL if unauthorized */
     client = calloc(1, sizeof(crm_client_t));
 
     client->ipcs = c;
     client->kind = CRM_CLIENT_IPC;
     client->pid = crm_ipcs_client_pid(c);
 
     client->id = crm_generate_uuid();
 
     crm_info("Connecting %p for uid=%d gid=%d pid=%u id=%s", c, uid_client, gid_client, client->pid, client->id);
 
 #if ENABLE_ACL
     client->user = uid2username(uid_client);
 #endif
 
     g_hash_table_insert(client_connections, c, client);
     return client;
 }
 
 void
 crm_client_destroy(crm_client_t * c)
 {
     if (c == NULL) {
         return;
     }
 
     if (client_connections) {
         if (c->ipcs) {
             crm_trace("Destroying %p/%p (%d remaining)",
                       c, c->ipcs, crm_hash_table_size(client_connections) - 1);
             g_hash_table_remove(client_connections, c->ipcs);
 
         } else {
             crm_trace("Destroying remote connection %p (%d remaining)",
                       c, crm_hash_table_size(client_connections) - 1);
             g_hash_table_remove(client_connections, c->id);
         }
     }
 
     if (c->event_timer) {
         g_source_remove(c->event_timer);
     }
 
     crm_info("Destroying %d events", g_list_length(c->event_queue));
     while (c->event_queue) {
         struct iovec *event = c->event_queue->data;
 
         c->event_queue = g_list_remove(c->event_queue, event);
         free(event[0].iov_base);
         free(event[1].iov_base);
         free(event);
     }
 
     free(c->id);
     free(c->name);
     free(c->user);
     if (c->remote) {
         if (c->remote->auth_timeout) {
             g_source_remove(c->remote->auth_timeout);
         }
         free(c->remote->buffer);
         free(c->remote);
     }
     free(c);
 }
 
 int
 crm_ipcs_client_pid(qb_ipcs_connection_t * c)
 {
     struct qb_ipcs_connection_stats stats;
 
     stats.client_pid = 0;
     qb_ipcs_connection_stats_get(c, &stats, 0);
     return stats.client_pid;
 }
 
 xmlNode *
 crm_ipcs_recv(crm_client_t * c, void *data, size_t size, uint32_t * id, uint32_t * flags)
 {
     xmlNode *xml = NULL;
     char *uncompressed = NULL;
     char *text = ((char *)data) + sizeof(struct crm_ipc_response_header);
     struct crm_ipc_response_header *header = data;
 
     if (id) {
         *id = ((struct qb_ipc_response_header *)data)->id;
     }
     if (flags) {
         *flags = header->flags;
     }
 
     if(header->version > PCMK_IPC_VERSION) {
         crm_err("Filtering incompatible v%d IPC message, we only support versions <= %d",
                 header->version, PCMK_IPC_VERSION);
         return NULL;
     }
 
     if (header->size_compressed) {
         int rc = 0;
         unsigned int size_u = 1 + header->size_uncompressed;
         uncompressed = calloc(1, size_u);
 
         crm_trace("Decompressing message data %d bytes into %d bytes",
                   header->size_compressed, size_u);
 
         rc = BZ2_bzBuffToBuffDecompress(uncompressed, &size_u, text, header->size_compressed, 1, 0);
         text = uncompressed;
 
         if (rc != BZ_OK) {
             crm_err("Decompression failed: %s (%d)", bz2_strerror(rc), rc);
             free(uncompressed);
             return NULL;
         }
     }
 
     CRM_ASSERT(text[header->size_uncompressed - 1] == 0);
 
     crm_trace("Received %.200s", text);
     xml = string2xml(text);
 
     free(uncompressed);
     return xml;
 }
 
 ssize_t crm_ipcs_flush_events(crm_client_t * c);
 
 static gboolean
 crm_ipcs_flush_events_cb(gpointer data)
 {
     crm_client_t *c = data;
 
     c->event_timer = 0;
     crm_ipcs_flush_events(c);
     return FALSE;
 }
 
 ssize_t
 crm_ipcs_flush_events(crm_client_t * c)
 {
     int sent = 0;
     ssize_t rc = 0;
     int queue_len = 0;
 
     if (c == NULL) {
         return pcmk_ok;
 
     } else if (c->event_timer) {
         /* There is already a timer, wait until it goes off */
         crm_trace("Timer active for %p - %d", c->ipcs, c->event_timer);
         return pcmk_ok;
     }
 
     queue_len = g_list_length(c->event_queue);
     while (c->event_queue && sent < 100) {
         struct crm_ipc_response_header *header = NULL;
         struct iovec *event = c->event_queue->data;
 
         rc = qb_ipcs_event_sendv(c->ipcs, event, 2);
         if (rc < 0) {
             break;
         }
 
         sent++;
         header = event[0].iov_base;
         if (header->size_compressed) {
             crm_trace("Event %d to %p[%d] (%d compressed bytes) sent",
                       header->qb.id, c->ipcs, c->pid, rc);
         } else {
             crm_trace("Event %d to %p[%d] (%d bytes) sent: %.120s",
                       header->qb.id, c->ipcs, c->pid, rc, event[1].iov_base);
         }
 
         c->event_queue = g_list_remove(c->event_queue, event);
         free(event[0].iov_base);
         free(event[1].iov_base);
         free(event);
     }
 
     queue_len -= sent;
     if (sent > 0 || c->event_queue) {
         crm_trace("Sent %d events (%d remaining) for %p[%d]: %s (%d)",
                   sent, queue_len, c->ipcs, c->pid, pcmk_strerror(rc < 0 ? rc : 0), rc);
     }
 
     if (c->event_queue) {
         if (queue_len % 100 == 0 && queue_len > 99) {
             crm_warn("Event queue for %p[%d] has grown to %d", c->ipcs, c->pid, queue_len);
 
         } else if (queue_len > 500) {
             crm_err("Evicting slow client %p[%d]: event queue reached %d entries",
                     c->ipcs, c->pid, queue_len);
             qb_ipcs_disconnect(c->ipcs);
             return rc;
         }
 
         c->event_timer = g_timeout_add(1000 + 100 * queue_len, crm_ipcs_flush_events_cb, c);
     }
 
     return rc;
 }
 
 ssize_t
 crm_ipc_prepare(uint32_t request, xmlNode * message, struct iovec ** result, int32_t max_send_size)
 {
     static int biggest = 0;
     struct iovec *iov;
     unsigned int total = 0;
     char *compressed = NULL;
     char *buffer = dump_xml_unformatted(message);
     struct crm_ipc_response_header *header = calloc(1, sizeof(struct crm_ipc_response_header));
 
     CRM_ASSERT(result != NULL);
 
     crm_ipc_init();
 
     if (max_send_size == 0) {
         max_send_size = ipc_buffer_max;
     }
 
     CRM_LOG_ASSERT(max_send_size != 0);
 
     *result = NULL;
     iov = calloc(2, sizeof(struct iovec));
 
 
     iov[0].iov_len = hdr_offset;
     iov[0].iov_base = header;
 
     header->version = PCMK_IPC_VERSION;
     header->size_uncompressed = 1 + strlen(buffer);
     total = iov[0].iov_len + header->size_uncompressed;
 
     if (total < max_send_size) {
         iov[1].iov_base = buffer;
         iov[1].iov_len = header->size_uncompressed;
 
     } else {
         unsigned int new_size = 0;
 
         if (crm_compress_string
             (buffer, header->size_uncompressed, max_send_size, &compressed, &new_size)) {
 
             header->flags |= crm_ipc_compressed;
             header->size_compressed = new_size;
 
             iov[1].iov_len = header->size_compressed;
             iov[1].iov_base = compressed;
 
             free(buffer);
 
             if (header->size_compressed > biggest) {
                 biggest = 2 * QB_MAX(header->size_compressed, biggest);
             }
 
         } else {
             ssize_t rc = -EMSGSIZE;
 
             crm_log_xml_trace(message, "EMSGSIZE");
             biggest = 2 * QB_MAX(header->size_uncompressed, biggest);
 
             crm_err
                 ("Could not compress the message into less than the configured ipc limit (%d bytes)."
                  "Set PCMK_ipc_buffer to a higher value (%d bytes suggested)", max_send_size,
                  biggest);
 
             free(compressed);
             free(buffer);
             free(header);
             free(iov);
 
             return rc;
         }
     }
 
     header->qb.size = iov[0].iov_len + iov[1].iov_len;
     header->qb.id = (int32_t)request;    /* Replying to a specific request */
 
     *result = iov;
     return header->qb.size;
 }
 
 ssize_t
 crm_ipcs_sendv(crm_client_t * c, struct iovec * iov, enum crm_ipc_flags flags)
 {
     ssize_t rc;
     static uint32_t id = 1;
     struct crm_ipc_response_header *header = iov[0].iov_base;
 
     if (flags & crm_ipc_proxied) {
         /* _ALL_ replies to proxied connections need to be sent as events */
         flags |= crm_ipc_server_event;
     }
 
     if (flags & crm_ipc_server_event) {
         header->qb.id = id++;   /* We don't really use it, but doesn't hurt to set one */
 
         if (flags & crm_ipc_server_free) {
             crm_trace("Sending the original to %p[%d]", c->ipcs, c->pid);
             c->event_queue = g_list_append(c->event_queue, iov);
 
         } else {
             struct iovec *iov_copy = calloc(2, sizeof(struct iovec));
 
             crm_trace("Sending a copy to %p[%d]", c->ipcs, c->pid);
             iov_copy[0].iov_len = iov[0].iov_len;
             iov_copy[0].iov_base = malloc(iov[0].iov_len);
             memcpy(iov_copy[0].iov_base, iov[0].iov_base, iov[0].iov_len);
 
             iov_copy[1].iov_len = iov[1].iov_len;
             iov_copy[1].iov_base = malloc(iov[1].iov_len);
             memcpy(iov_copy[1].iov_base, iov[1].iov_base, iov[1].iov_len);
 
             c->event_queue = g_list_append(c->event_queue, iov_copy);
         }
 
     } else {
         CRM_LOG_ASSERT(header->qb.id != 0);     /* Replying to a specific request */
 
         rc = qb_ipcs_response_sendv(c->ipcs, iov, 2);
         if (rc < header->qb.size) {
             crm_notice("Response %d to %p[%d] (%d bytes) failed: %s (%d)",
                        header->qb.id, c->ipcs, c->pid, header->qb.size, pcmk_strerror(rc), rc);
 
         } else {
             crm_trace("Response %d sent, %d bytes to %p[%d]", header->qb.id, rc, c->ipcs, c->pid);
         }
 
         if (flags & crm_ipc_server_free) {
             free(iov[0].iov_base);
             free(iov[1].iov_base);
             free(iov);
         }
     }
 
     if (flags & crm_ipc_server_event) {
         rc = crm_ipcs_flush_events(c);
     } else {
         crm_ipcs_flush_events(c);
     }
 
     if (rc == -EPIPE || rc == -ENOTCONN) {
         crm_trace("Client %p disconnected", c->ipcs);
     }
 
     return rc;
 }
 
 ssize_t
 crm_ipcs_send(crm_client_t * c, uint32_t request, xmlNode * message,
               enum crm_ipc_flags flags)
 {
     struct iovec *iov = NULL;
     ssize_t rc = 0;
 
     if(c == NULL) {
         return -EDESTADDRREQ;
     }
     crm_ipc_init();
 
     rc = crm_ipc_prepare(request, message, &iov, ipc_buffer_max);
     if (rc > 0) {
         rc = crm_ipcs_sendv(c, iov, flags | crm_ipc_server_free);
 
     } else {
         free(iov);
         crm_notice("Message to %p[%d] failed: %s (%d)",
                    c->ipcs, c->pid, pcmk_strerror(rc), rc);
     }
 
     return rc;
 }
 
 void
 crm_ipcs_send_ack(crm_client_t * c, uint32_t request, uint32_t flags, const char *tag, const char *function,
                   int line)
 {
     if (flags & crm_ipc_client_response) {
         xmlNode *ack = create_xml_node(NULL, tag);
 
         crm_trace("Ack'ing msg from %s (%p)", crm_client_name(c), c);
         c->request_id = 0;
         crm_xml_add(ack, "function", function);
         crm_xml_add_int(ack, "line", line);
         crm_ipcs_send(c, request, ack, flags);
         free_xml(ack);
     }
 }
 
 /* Client... */
 
 #define MIN_MSG_SIZE    12336   /* sizeof(struct qb_ipc_connection_response) */
 #define MAX_MSG_SIZE    128*1024 /* 128k default */
 
 struct crm_ipc_s {
     struct pollfd pfd;
 
     /* the max size we can send/receive over ipc */
     int max_buf_size;
     /* Size of the allocated 'buffer' */
     int buf_size;
     int msg_size;
     int need_reply;
     char *buffer;
     char *name;
 
     qb_ipcc_connection_t *ipc;
 
 };
 
 static unsigned int
 pick_ipc_buffer(int max)
 {
     static int global_max = 0;
 
     if(global_max == 0) {
         const char *env = getenv("PCMK_ipc_buffer");
 
         if (env) {
             global_max = crm_parse_int(env, "0");
         } else {
             global_max = MAX_MSG_SIZE;
         }
     }
 
     return QB_MAX(max, global_max);
 }
 
 crm_ipc_t *
 crm_ipc_new(const char *name, size_t max_size)
 {
     crm_ipc_t *client = NULL;
 
     client = calloc(1, sizeof(crm_ipc_t));
 
     client->name = strdup(name);
     client->buf_size = pick_ipc_buffer(max_size);
     client->buffer = malloc(client->buf_size);
 
     /* Clients initiating connection pick the max buf size */
     client->max_buf_size = client->buf_size;
 
     client->pfd.fd = -1;
     client->pfd.events = POLLIN;
     client->pfd.revents = 0;
 
     return client;
 }
 
 bool
 crm_ipc_connect(crm_ipc_t * client)
 {
     client->need_reply = FALSE;
     client->ipc = qb_ipcc_connect(client->name, client->buf_size);
 
     if (client->ipc == NULL) {
         crm_perror(LOG_INFO, "Could not establish %s connection", client->name);
         return FALSE;
     }
 
     client->pfd.fd = crm_ipc_get_fd(client);
     if (client->pfd.fd < 0) {
         crm_perror(LOG_INFO, "Could not obtain file descriptor for %s connection", client->name);
         return FALSE;
     }
 
     qb_ipcc_context_set(client->ipc, client);
 
 #ifdef HAVE_IPCS_GET_BUFFER_SIZE
     client->max_buf_size = qb_ipcc_get_buffer_size(client->ipc);
     if (client->max_buf_size < client->buf_size) {
         free(client->buffer);
         client->buffer = calloc(1, client->max_buf_size);
         client->buf_size = client->max_buf_size;
     }
 #endif
 
     return TRUE;
 }
 
 void
 crm_ipc_close(crm_ipc_t * client)
 {
     if (client) {
         crm_trace("Disconnecting %s IPC connection %p (%p.%p)", client->name, client, client->ipc);
 
         if (client->ipc) {
             qb_ipcc_connection_t *ipc = client->ipc;
 
             client->ipc = NULL;
             qb_ipcc_disconnect(ipc);
         }
     }
 }
 
 void
 crm_ipc_destroy(crm_ipc_t * client)
 {
     if (client) {
         if (client->ipc && qb_ipcc_is_connected(client->ipc)) {
             crm_notice("Destroying an active IPC connection to %s", client->name);
             /* The next line is basically unsafe
              *
              * If this connection was attached to mainloop and mainloop is active,
              *   the 'disconnected' callback will end up back here and we'll end
              *   up free'ing the memory twice - something that can still happen
              *   even without this if we destroy a connection and it closes before
              *   we call exit
              */
             /* crm_ipc_close(client); */
         }
         crm_trace("Destroying IPC connection to %s: %p", client->name, client);
         free(client->buffer);
         free(client->name);
         free(client);
     }
 }
 
 int
 crm_ipc_get_fd(crm_ipc_t * client)
 {
     int fd = 0;
 
     CRM_ASSERT(client != NULL);
     if (client->ipc && qb_ipcc_fd_get(client->ipc, &fd) == 0) {
         return fd;
     }
 
     crm_perror(LOG_ERR, "Could not obtain file IPC descriptor for %s", client->name);
     return -EINVAL;
 }
 
 bool
 crm_ipc_connected(crm_ipc_t * client)
 {
     bool rc = FALSE;
 
     if (client == NULL) {
         crm_trace("No client");
         return FALSE;
 
     } else if (client->ipc == NULL) {
         crm_trace("No connection");
         return FALSE;
 
     } else if (client->pfd.fd < 0) {
         crm_trace("Bad descriptor");
         return FALSE;
     }
 
     rc = qb_ipcc_is_connected(client->ipc);
     if (rc == FALSE) {
         client->pfd.fd = -EINVAL;
     }
     return rc;
 }
 
 int
 crm_ipc_ready(crm_ipc_t * client)
 {
     CRM_ASSERT(client != NULL);
 
     if (crm_ipc_connected(client) == FALSE) {
         return -ENOTCONN;
     }
 
     client->pfd.revents = 0;
     return poll(&(client->pfd), 1, 0);
 }
 
 static int
 crm_ipc_decompress(crm_ipc_t * client)
 {
-    struct crm_ipc_response_header *header = (struct crm_ipc_response_header *)client->buffer;
+    struct crm_ipc_response_header *header = (struct crm_ipc_response_header *)(void*)client->buffer;
 
     if (header->size_compressed) {
         int rc = 0;
         unsigned int size_u = 1 + header->size_uncompressed;
         /* never let buf size fall below our max size required for ipc reads. */
         unsigned int new_buf_size = QB_MAX((hdr_offset + size_u), client->max_buf_size);
         char *uncompressed = calloc(1, new_buf_size);
 
         crm_trace("Decompressing message data %d bytes into %d bytes",
                  header->size_compressed, size_u);
 
         rc = BZ2_bzBuffToBuffDecompress(uncompressed + hdr_offset, &size_u,
                                         client->buffer + hdr_offset, header->size_compressed, 1, 0);
 
         if (rc != BZ_OK) {
             crm_err("Decompression failed: %s (%d)", bz2_strerror(rc), rc);
             free(uncompressed);
             return -EILSEQ;
         }
 
         /*
          * This assert no longer holds true.  For an identical msg, some clients may
          * require compression, and others may not. If that same msg (event) is sent
          * to multiple clients, it could result in some clients receiving a compressed
          * msg even though compression was not explicitly required for them.
          *
          * CRM_ASSERT((header->size_uncompressed + hdr_offset) >= ipc_buffer_max);
          */
         CRM_ASSERT(size_u == header->size_uncompressed);
 
         memcpy(uncompressed, client->buffer, hdr_offset);       /* Preserve the header */
-        header = (struct crm_ipc_response_header *)uncompressed;
+        header = (struct crm_ipc_response_header *)(void*)uncompressed;
 
         free(client->buffer);
         client->buf_size = new_buf_size;
         client->buffer = uncompressed;
     }
 
     CRM_ASSERT(client->buffer[hdr_offset + header->size_uncompressed - 1] == 0);
     return pcmk_ok;
 }
 
 long
 crm_ipc_read(crm_ipc_t * client)
 {
     struct crm_ipc_response_header *header = NULL;
 
     CRM_ASSERT(client != NULL);
     CRM_ASSERT(client->ipc != NULL);
     CRM_ASSERT(client->buffer != NULL);
 
     crm_ipc_init();
 
     client->buffer[0] = 0;
     client->msg_size = qb_ipcc_event_recv(client->ipc, client->buffer, client->buf_size - 1, 0);
     if (client->msg_size >= 0) {
         int rc = crm_ipc_decompress(client);
 
         if (rc != pcmk_ok) {
             return rc;
         }
 
-        header = (struct crm_ipc_response_header *)client->buffer;
+        header = (struct crm_ipc_response_header *)(void*)client->buffer;
         if(header->version > PCMK_IPC_VERSION) {
             crm_err("Filtering incompatible v%d IPC message, we only support versions <= %d",
                     header->version, PCMK_IPC_VERSION);
             return -EBADMSG;
         }
 
         crm_trace("Received %s event %d, size=%d, rc=%d, text: %.100s",
                   client->name, header->qb.id, header->qb.size, client->msg_size,
                   client->buffer + hdr_offset);
 
     } else {
         crm_trace("No message from %s received: %s", client->name, pcmk_strerror(client->msg_size));
     }
 
     if (crm_ipc_connected(client) == FALSE || client->msg_size == -ENOTCONN) {
         crm_err("Connection to %s failed", client->name);
     }
 
     if (header) {
         /* Data excluding the header */
         return header->size_uncompressed;
     }
     return -ENOMSG;
 }
 
 const char *
 crm_ipc_buffer(crm_ipc_t * client)
 {
     CRM_ASSERT(client != NULL);
     return client->buffer + sizeof(struct crm_ipc_response_header);
 }
 
 const char *
 crm_ipc_name(crm_ipc_t * client)
 {
     CRM_ASSERT(client != NULL);
     return client->name;
 }
 
 static int
 internal_ipc_send_recv(crm_ipc_t * client, const void *iov)
 {
     int rc = 0;
 
     do {
         rc = qb_ipcc_sendv_recv(client->ipc, iov, 2, client->buffer, client->buf_size, -1);
     } while (rc == -EAGAIN && crm_ipc_connected(client));
 
     return rc;
 }
 
 static int
 internal_ipc_send_request(crm_ipc_t * client, const void *iov, int ms_timeout)
 {
     int rc = 0;
     time_t timeout = time(NULL) + 1 + (ms_timeout / 1000);
 
     do {
         rc = qb_ipcc_sendv(client->ipc, iov, 2);
     } while (rc == -EAGAIN && time(NULL) < timeout && crm_ipc_connected(client));
 
     return rc;
 }
 
 static int
 internal_ipc_get_reply(crm_ipc_t * client, int request_id, int ms_timeout)
 {
     time_t timeout = time(NULL) + 1 + (ms_timeout / 1000);
     int rc = 0;
 
     crm_ipc_init();
 
     /* get the reply */
     crm_trace("client %s waiting on reply to msg id %d", client->name, request_id);
     do {
 
         rc = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, 1000);
         if (rc > 0) {
             struct crm_ipc_response_header *hdr = NULL;
 
             int rc = crm_ipc_decompress(client);
 
             if (rc != pcmk_ok) {
                 return rc;
             }
 
-            hdr = (struct crm_ipc_response_header *)client->buffer;
+            hdr = (struct crm_ipc_response_header *)(void*)client->buffer;
             if (hdr->qb.id == request_id) {
                 /* Got it */
                 break;
             } else if (hdr->qb.id < request_id) {
                 xmlNode *bad = string2xml(crm_ipc_buffer(client));
 
                 crm_err("Discarding old reply %d (need %d)", hdr->qb.id, request_id);
                 crm_log_xml_notice(bad, "OldIpcReply");
 
             } else {
                 xmlNode *bad = string2xml(crm_ipc_buffer(client));
 
                 crm_err("Discarding newer reply %d (need %d)", hdr->qb.id, request_id);
                 crm_log_xml_notice(bad, "ImpossibleReply");
                 CRM_ASSERT(hdr->qb.id <= request_id);
             }
         } else if (crm_ipc_connected(client) == FALSE) {
             crm_err("Server disconnected client %s while waiting for msg id %d", client->name,
                     request_id);
             break;
         }
 
     } while (time(NULL) < timeout);
 
     return rc;
 }
 
 int
 crm_ipc_send(crm_ipc_t * client, xmlNode * message, enum crm_ipc_flags flags, int32_t ms_timeout,
              xmlNode ** reply)
 {
     long rc = 0;
     struct iovec *iov;
     static uint32_t id = 0;
     static int factor = 8;
     struct crm_ipc_response_header *header;
 
     crm_ipc_init();
 
     if (client == NULL) {
         crm_notice("Invalid connection");
         return -ENOTCONN;
 
     } else if (crm_ipc_connected(client) == FALSE) {
         /* Don't even bother */
         crm_notice("Connection to %s closed", client->name);
         return -ENOTCONN;
     }
 
     if (ms_timeout == 0) {
         ms_timeout = 5000;
     }
 
     if (client->need_reply) {
         crm_trace("Trying again to obtain pending reply from %s", client->name);
         rc = qb_ipcc_recv(client->ipc, client->buffer, client->buf_size, ms_timeout);
         if (rc < 0) {
             crm_warn("Sending to %s (%p) is disabled until pending reply is received", client->name,
                      client->ipc);
             return -EALREADY;
 
         } else {
             crm_notice("Lost reply from %s (%p) finally arrived, sending re-enabled", client->name,
                        client->ipc);
             client->need_reply = FALSE;
         }
     }
 
     id++;
     CRM_LOG_ASSERT(id != 0); /* Crude wrap-around detection */
     rc = crm_ipc_prepare(id, message, &iov, ipc_buffer_max);
     if(rc < 0) {
         return rc;
     }
 
     header = iov[0].iov_base;
     header->flags |= flags;
 
     if(is_set(flags, crm_ipc_proxied)) {
         /* Don't look for a synchronous response */
         clear_bit(flags, crm_ipc_client_response);
     }
 
     if(header->size_compressed) {
         if(factor < 10 && (ipc_buffer_max / 10) < (rc / factor)) {
             crm_notice("Compressed message exceeds %d0%% of the configured ipc limit (%d bytes), "
                        "consider setting PCMK_ipc_buffer to %d or higher",
                        factor, ipc_buffer_max, 2*ipc_buffer_max);
             factor++;
         }
     }
 
     crm_trace("Sending from client: %s request id: %d bytes: %u timeout:%d msg...",
               client->name, header->qb.id, header->qb.size, ms_timeout);
 
     if (ms_timeout > 0 || is_not_set(flags, crm_ipc_client_response)) {
 
         rc = internal_ipc_send_request(client, iov, ms_timeout);
 
         if (rc <= 0) {
             crm_trace("Failed to send from client %s request %d with %u bytes...",
                       client->name, header->qb.id, header->qb.size);
             goto send_cleanup;
 
         } else if (is_not_set(flags, crm_ipc_client_response)) {
             crm_trace("Message sent, not waiting for reply to %d from %s to %u bytes...",
                       header->qb.id, client->name, header->qb.size);
 
             goto send_cleanup;
         }
 
         rc = internal_ipc_get_reply(client, header->qb.id, ms_timeout);
         if (rc < 0) {
             /* No reply, for now, disable sending
              *
              * The alternative is to close the connection since we don't know
              * how to detect and discard out-of-sequence replies
              *
              * TODO - implement the above
              */
             client->need_reply = TRUE;
         }
 
     } else {
         rc = internal_ipc_send_recv(client, iov);
     }
 
     if (rc > 0) {
-        struct crm_ipc_response_header *hdr = (struct crm_ipc_response_header *)client->buffer;
+        struct crm_ipc_response_header *hdr = (struct crm_ipc_response_header *)(void*)client->buffer;
 
         crm_trace("Received response %d, size=%d, rc=%ld, text: %.200s", hdr->qb.id, hdr->qb.size,
                   rc, crm_ipc_buffer(client));
 
         if (reply) {
             *reply = string2xml(crm_ipc_buffer(client));
         }
 
     } else {
         crm_trace("Response not received: rc=%ld, errno=%d", rc, errno);
     }
 
   send_cleanup:
     if (crm_ipc_connected(client) == FALSE) {
         crm_notice("Connection to %s closed: %s (%ld)", client->name, pcmk_strerror(rc), rc);
 
     } else if (rc == -ETIMEDOUT) {
         crm_warn("Request %d to %s (%p) failed: %s (%ld) after %dms",
                  header->qb.id, client->name, client->ipc, pcmk_strerror(rc), rc, ms_timeout);
         crm_write_blackbox(0, NULL);
 
     } else if (rc <= 0) {
         crm_warn("Request %d to %s (%p) failed: %s (%ld)",
                  header->qb.id, client->name, client->ipc, pcmk_strerror(rc), rc);
     }
 
     free(header);
     free(iov[1].iov_base);
     free(iov);
     return rc;
 }
 
 /* Utils */
 
 xmlNode *
 create_hello_message(const char *uuid,
                      const char *client_name, const char *major_version, const char *minor_version)
 {
     xmlNode *hello_node = NULL;
     xmlNode *hello = NULL;
 
     if (uuid == NULL || strlen(uuid) == 0
         || client_name == NULL || strlen(client_name) == 0
         || major_version == NULL || strlen(major_version) == 0
         || minor_version == NULL || strlen(minor_version) == 0) {
         crm_err("Missing fields, Hello message will not be valid.");
         return NULL;
     }
 
     hello_node = create_xml_node(NULL, XML_TAG_OPTIONS);
     crm_xml_add(hello_node, "major_version", major_version);
     crm_xml_add(hello_node, "minor_version", minor_version);
     crm_xml_add(hello_node, "client_name", client_name);
     crm_xml_add(hello_node, "client_uuid", uuid);
 
     crm_trace("creating hello message");
     hello = create_request(CRM_OP_HELLO, hello_node, NULL, NULL, client_name, uuid);
     free_xml(hello_node);
 
     return hello;
 }
diff --git a/lib/common/remote.c b/lib/common/remote.c
index acffccb717..d707a96e84 100644
--- a/lib/common/remote.c
+++ b/lib/common/remote.c
@@ -1,907 +1,907 @@
 /*
  * Copyright (c) 2008 Andrew Beekhof
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  * 
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  * 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 #include <crm_internal.h>
 #include <crm/crm.h>
 
 #include <sys/param.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <netdb.h>
 
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <glib.h>
 
 #include <bzlib.h>
 
 #include <crm/common/ipcs.h>
 #include <crm/common/xml.h>
 #include <crm/common/mainloop.h>
 
 #ifdef HAVE_GNUTLS_GNUTLS_H
 #  undef KEYFILE
 #  include <gnutls/gnutls.h>
 
 const int psk_tls_kx_order[] = {
     GNUTLS_KX_DHE_PSK,
     GNUTLS_KX_PSK,
 };
 
 const int anon_tls_kx_order[] = {
     GNUTLS_KX_ANON_DH,
     GNUTLS_KX_DHE_RSA,
     GNUTLS_KX_DHE_DSS,
     GNUTLS_KX_RSA,
     0
 };
 #endif
 
 /* Swab macros from linux/swab.h */
 #ifdef HAVE_LINUX_SWAB_H
 #  include <linux/swab.h>
 #else
 /*
  * casts are necessary for constants, because we never know how for sure
  * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
  */
 #define ___swab16(x) ((__u16)(                                  \
         (((__u16)(x) & (__u16)0x00ffU) << 8) |                  \
         (((__u16)(x) & (__u16)0xff00U) >> 8)))
 
 #define ___swab32(x) ((__u32)(                                  \
         (((__u32)(x) & (__u32)0x000000ffUL) << 24) |            \
         (((__u32)(x) & (__u32)0x0000ff00UL) <<  8) |            \
         (((__u32)(x) & (__u32)0x00ff0000UL) >>  8) |            \
         (((__u32)(x) & (__u32)0xff000000UL) >> 24)))
 
 #define ___swab64(x) ((__u64)(                                  \
         (((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) |   \
         (((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) |   \
         (((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) |   \
         (((__u64)(x) & (__u64)0x00000000ff000000ULL) <<  8) |   \
         (((__u64)(x) & (__u64)0x000000ff00000000ULL) >>  8) |   \
         (((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) |   \
         (((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) |   \
         (((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56)))
 #endif
 
 #define REMOTE_MSG_VERSION 1
 #define ENDIAN_LOCAL 0xBADADBBD
 
 struct crm_remote_header_v0 
 {
     uint32_t endian;    /* Detect messages from hosts with different endian-ness */
     uint32_t version;
     uint64_t id;
     uint64_t flags;
     uint32_t size_total;
     uint32_t payload_offset;
     uint32_t payload_compressed;
     uint32_t payload_uncompressed;
 
         /* New fields get added here */
 
 } __attribute__ ((packed));
 
 static struct crm_remote_header_v0 *
 crm_remote_header(crm_remote_t * remote)
 {
     struct crm_remote_header_v0 *header = (struct crm_remote_header_v0 *)remote->buffer;
     if(remote->buffer_offset < sizeof(struct crm_remote_header_v0)) {
         return NULL;
 
     } else if(header->endian != ENDIAN_LOCAL) {
         uint32_t endian = __swab32(header->endian);
 
         CRM_LOG_ASSERT(endian == ENDIAN_LOCAL);
         if(endian != ENDIAN_LOCAL) {
             crm_err("Invalid message detected, endian mismatch: %lx is neither %lx nor the swab'd %lx",
                     ENDIAN_LOCAL, header->endian, endian);
             return NULL;
         }
 
         header->id = __swab64(header->id);
         header->flags = __swab64(header->flags);
         header->endian = __swab32(header->endian);
 
         header->version = __swab32(header->version);
         header->size_total = __swab32(header->size_total);
         header->payload_offset = __swab32(header->payload_offset);
         header->payload_compressed = __swab32(header->payload_compressed);
         header->payload_uncompressed = __swab32(header->payload_uncompressed);
     }
 
     return header;
 }
 
 #ifdef HAVE_GNUTLS_GNUTLS_H
 
 int
 crm_initiate_client_tls_handshake(crm_remote_t * remote, int timeout_ms)
 {
     int rc = 0;
     int pollrc = 0;
     time_t start = time(NULL);
 
     do {
         rc = gnutls_handshake(*remote->tls_session);
         if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN) {
             pollrc = crm_remote_ready(remote, 1000);
             if (pollrc < 0) {
                 /* poll returned error, there is no hope */
                 rc = -1;
             }
         }
 
     } while (((time(NULL) - start) < (timeout_ms / 1000)) &&
              (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN));
 
     if (rc < 0) {
         crm_trace("gnutls_handshake() failed with %d", rc);
     }
     return rc;
 }
 
 void *
 crm_create_anon_tls_session(int csock, int type /* GNUTLS_SERVER, GNUTLS_CLIENT */ ,
                             void *credentials)
 {
     gnutls_session_t *session = gnutls_malloc(sizeof(gnutls_session_t));
 
     gnutls_init(session, type);
 #  ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT
 /*      http://www.manpagez.com/info/gnutls/gnutls-2.10.4/gnutls_81.php#Echo-Server-with-anonymous-authentication */
     gnutls_priority_set_direct(*session, "NORMAL:+ANON-DH", NULL);
 /*	gnutls_priority_set_direct (*session, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); */
 #  else
     gnutls_set_default_priority(*session);
     gnutls_kx_set_priority(*session, anon_tls_kx_order);
 #  endif
     gnutls_transport_set_ptr(*session, (gnutls_transport_ptr_t) GINT_TO_POINTER(csock));
     switch (type) {
         case GNUTLS_SERVER:
             gnutls_credentials_set(*session, GNUTLS_CRD_ANON,
                                    (gnutls_anon_server_credentials_t) credentials);
             break;
         case GNUTLS_CLIENT:
             gnutls_credentials_set(*session, GNUTLS_CRD_ANON,
                                    (gnutls_anon_client_credentials_t) credentials);
             break;
     }
 
     return session;
 }
 
 void *
 create_psk_tls_session(int csock, int type /* GNUTLS_SERVER, GNUTLS_CLIENT */ , void *credentials)
 {
     gnutls_session_t *session = gnutls_malloc(sizeof(gnutls_session_t));
 
     gnutls_init(session, type);
 #  ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT
     gnutls_priority_set_direct(*session, "NORMAL:+DHE-PSK:+PSK", NULL);
 #  else
     gnutls_set_default_priority(*session);
     gnutls_kx_set_priority(*session, psk_tls_kx_order);
 #  endif
     gnutls_transport_set_ptr(*session, (gnutls_transport_ptr_t) GINT_TO_POINTER(csock));
     switch (type) {
         case GNUTLS_SERVER:
             gnutls_credentials_set(*session, GNUTLS_CRD_PSK,
                                    (gnutls_psk_server_credentials_t) credentials);
             break;
         case GNUTLS_CLIENT:
             gnutls_credentials_set(*session, GNUTLS_CRD_PSK,
                                    (gnutls_psk_client_credentials_t) credentials);
             break;
     }
 
     return session;
 }
 
 static int
 crm_send_tls(gnutls_session_t * session, const char *buf, size_t len)
 {
     const char *unsent = buf;
     int rc = 0;
     int total_send;
 
     if (buf == NULL) {
         return -1;
     }
 
     total_send = len;
     crm_trace("Message size: %d", len);
 
     while (TRUE) {
         rc = gnutls_record_send(*session, unsent, len);
 
         if (rc == GNUTLS_E_INTERRUPTED || rc == GNUTLS_E_AGAIN) {
             crm_debug("Retry");
 
         } else if (rc < 0) {
             crm_err("Connection terminated rc = %d", rc);
             break;
 
         } else if (rc < len) {
             crm_debug("Only sent %d of %d bytes", rc, len);
             len -= rc;
             unsent += rc;
         } else {
             crm_debug("Sent %d bytes", rc);
             break;
         }
     }
 
     return rc < 0 ? rc : total_send;
 }
 #endif
 
 static int
 crm_send_plaintext(int sock, const char *buf, size_t len)
 {
 
     int rc = 0;
     const char *unsent = buf;
     int total_send;
 
     if (buf == NULL) {
         return -1;
     }
     total_send = len;
 
     crm_trace("Message on socket %d: size=%d", sock, len);
   retry:
     rc = write(sock, unsent, len);
     if (rc < 0) {
         switch (errno) {
             case EINTR:
             case EAGAIN:
                 crm_trace("Retry");
                 goto retry;
             default:
                 crm_perror(LOG_ERR, "Could only write %d of the remaining %d bytes", rc, (int)len);
                 break;
         }
 
     } else if (rc < len) {
         crm_trace("Only sent %d of %d remaining bytes", rc, len);
         len -= rc;
         unsent += rc;
         goto retry;
 
     } else {
         crm_trace("Sent %d bytes: %.100s", rc, buf);
     }
 
     return rc < 0 ? rc : total_send;
 
 }
 
 static int
 crm_remote_sendv(crm_remote_t * remote, struct iovec * iov, int iovs)
 {
     int lpc = 0;
     int rc = -ESOCKTNOSUPPORT;
 
     for(; lpc < iovs; lpc++) {
         if (remote->tcp_socket) {
             rc = crm_send_plaintext(remote->tcp_socket, iov[lpc].iov_base, iov[lpc].iov_len);
 #ifdef HAVE_GNUTLS_GNUTLS_H
 
         } else if (remote->tls_session) {
             rc = crm_send_tls(remote->tls_session, iov[lpc].iov_base, iov[lpc].iov_len);
 #endif
         } else {
             crm_err("Unsupported connection type");
         }
     }
     return rc;
 }
 
 int
 crm_remote_send(crm_remote_t * remote, xmlNode * msg)
 {
     int rc = -1;
     static uint64_t id = 0;
     char *xml_text = dump_xml_unformatted(msg);
 
     struct iovec iov[2];
     struct crm_remote_header_v0 *header;
 
     if (xml_text == NULL) {
         crm_err("Invalid XML, can not send msg");
         return -1;
     }
 
     header = calloc(1, sizeof(struct crm_remote_header_v0));
     iov[0].iov_base = header;
     iov[0].iov_len = sizeof(struct crm_remote_header_v0);
 
     iov[1].iov_base = xml_text;
     iov[1].iov_len = 1 + strlen(xml_text);
 
     id++;
     header->id = id;
     header->endian = ENDIAN_LOCAL;
     header->version = REMOTE_MSG_VERSION;
     header->payload_offset = iov[0].iov_len;
     header->payload_uncompressed = iov[1].iov_len;
     header->size_total = iov[0].iov_len + iov[1].iov_len;
 
     crm_trace("Sending len[0]=%d, start=%x\n",
-              (int)iov[0].iov_len, *(int*)xml_text);
+              (int)iov[0].iov_len, *(int*)(void*)xml_text);
     rc = crm_remote_sendv(remote, iov, 2);
     if (rc < 0) {
         crm_err("Failed to send remote msg, rc = %d", rc);
     }
 
     free(iov[0].iov_base);
     free(iov[1].iov_base);
     return rc;
 }
 
 
 /*!
  * \internal
  * \brief handles the recv buffer and parsing out msgs.
  * \note new_data is owned by this function once it is passed in.
  */
 xmlNode *
 crm_remote_parse_buffer(crm_remote_t * remote)
 {
     xmlNode *xml = NULL;
     struct crm_remote_header_v0 *header = crm_remote_header(remote);
 
     if (remote->buffer == NULL || header == NULL) {
         return NULL;
     }
 
     /* take ownership of the buffer */
     remote->buffer_offset = 0;
 
     /* Support compression on the receiving end now, in case we ever want to add it later */
     if (header->payload_compressed) {
         int rc = 0;
         unsigned int size_u = 1 + header->payload_uncompressed;
         char *uncompressed = calloc(1, header->payload_offset + size_u);
 
         crm_trace("Decompressing message data %d bytes into %d bytes",
                  header->payload_compressed, size_u);
 
         rc = BZ2_bzBuffToBuffDecompress(uncompressed + header->payload_offset, &size_u,
                                         remote->buffer + header->payload_offset,
                                         header->payload_compressed, 1, 0);
 
         if (rc != BZ_OK && header->version > REMOTE_MSG_VERSION) {
             crm_warn("Couldn't decompress v%d message, we only understand v%d",
                      header->version, REMOTE_MSG_VERSION);
             free(uncompressed);
             return NULL;
 
         } else if (rc != BZ_OK) {
             crm_err("Decompression failed: %s (%d)", bz2_strerror(rc), rc);
             free(uncompressed);
             return NULL;
         }
 
         CRM_ASSERT(size_u == header->payload_uncompressed);
 
         memcpy(uncompressed, remote->buffer, header->payload_offset);       /* Preserve the header */
         remote->buffer_size = header->payload_offset + size_u;
 
         free(remote->buffer);
         remote->buffer = uncompressed;
         header = crm_remote_header(remote);
     }
 
     CRM_LOG_ASSERT(remote->buffer[sizeof(struct crm_remote_header_v0) + header->payload_uncompressed - 1] == 0);
 
     xml = string2xml(remote->buffer + header->payload_offset);
     if (xml == NULL && header->version > REMOTE_MSG_VERSION) {
         crm_warn("Couldn't parse v%d message, we only understand v%d",
                  header->version, REMOTE_MSG_VERSION);
 
     } else if (xml == NULL) {
         crm_err("Couldn't parse: '%.120s'", remote->buffer + header->payload_offset);
     }
 
     return xml;
 }
 
 /*!
  * \internal
  * \brief Determine if a remote session has data to read
  *
  * \retval 0, timeout occured.
  * \retval positive, data is ready to be read
  * \retval negative, session has ended
  */
 int
 crm_remote_ready(crm_remote_t * remote, int timeout /* ms */ )
 {
     struct pollfd fds = { 0, };
     int sock = 0;
     int rc = 0;
     time_t start;
 
     if (remote->tcp_socket) {
         sock = remote->tcp_socket;
 #ifdef HAVE_GNUTLS_GNUTLS_H
     } else if (remote->tls_session) {
         void *sock_ptr = gnutls_transport_get_ptr(*remote->tls_session);
 
         sock = GPOINTER_TO_INT(sock_ptr);
 #endif
     } else {
         crm_err("Unsupported connection type");
     }
 
     if (sock <= 0) {
         crm_trace("No longer connected");
         return -ENOTCONN;
     }
 
     start = time(NULL);
     errno = 0;
     do {
         fds.fd = sock;
         fds.events = POLLIN;
 
         /* If we got an EINTR while polling, and we have a
          * specific timeout we are trying to honor, attempt
          * to adjust the timeout to the closest second. */
         if (errno == EINTR && (timeout > 0)) {
             timeout = timeout - ((time(NULL) - start) * 1000);
             if (timeout < 1000) {
                 timeout = 1000;
             }
         }
 
         rc = poll(&fds, 1, timeout);
     } while (rc < 0 && errno == EINTR);
 
     return rc;
 }
 
 
 /*!
  * \internal
  * \brief Read bytes off non blocking remote connection.
  *
  * \note only use with NON-Blocking sockets. Should only be used after polling socket.
  *       This function will return once max_size is met, the socket read buffer
  *       is empty, or an error is encountered.
  *
  * \retval number of bytes received
  */
 static size_t
 crm_remote_recv_once(crm_remote_t * remote)
 {
     int rc = 0;
     size_t read_len = sizeof(struct crm_remote_header_v0);
     struct crm_remote_header_v0 *header = crm_remote_header(remote);
 
     if(header) {
         /* Stop at the end of the current message */
         read_len = header->size_total;
     }
 
     /* automatically grow the buffer when needed */
     if(remote->buffer_size < read_len) {
            remote->buffer_size = 2 * read_len;
         crm_trace("Expanding buffer to %u bytes", remote->buffer_size);
 
         remote->buffer = realloc(remote->buffer, remote->buffer_size + 1);
         CRM_ASSERT(remote->buffer != NULL);
     }
 
     if (remote->tcp_socket) {
         errno = 0;
         rc = read(remote->tcp_socket,
                   remote->buffer + remote->buffer_offset,
                   remote->buffer_size - remote->buffer_offset);
         if(rc < 0) {
             rc = -errno;
         }
 
 #ifdef HAVE_GNUTLS_GNUTLS_H
     } else if (remote->tls_session) {
         rc = gnutls_record_recv(*(remote->tls_session),
                                 remote->buffer + remote->buffer_offset,
                                 remote->buffer_size - remote->buffer_offset);
         if (rc == GNUTLS_E_INTERRUPTED) {
             rc = -EINTR;
         } else if (rc == GNUTLS_E_AGAIN) {
             rc = -EAGAIN;
         } else if (rc < 0) {
             crm_debug("TLS receive failed: %s (%d)", gnutls_strerror(rc), rc);
             rc = -pcmk_err_generic;
         }
 #endif
     } else {
         crm_err("Unsupported connection type");
         return -ESOCKTNOSUPPORT;
     }
 
     /* process any errors. */
     if (rc > 0) {
         remote->buffer_offset += rc;
         /* always null terminate buffer, the +1 to alloc always allows for this. */
         remote->buffer[remote->buffer_offset] = '\0';
         crm_trace("Received %u more bytes, %u total", rc, remote->buffer_offset);
 
     } else if (rc == -EINTR || rc == -EAGAIN) {
         crm_trace("non-blocking, exiting read: %s (%d)", pcmk_strerror(rc), rc);
 
     } else if (rc == 0) {
         crm_debug("EOF encoutered after %u bytes", remote->buffer_offset);
         return -ENOTCONN;
 
     } else {
         crm_debug("Error receiving message after %u bytes: %s (%d)",
                   remote->buffer_offset, pcmk_strerror(rc), rc);
         return -ENOTCONN;
     }
 
     header = crm_remote_header(remote);
     if(header) {
         if(remote->buffer_offset < header->size_total) {
             crm_trace("Read less than the advertised length: %u < %u bytes",
                       remote->buffer_offset, header->size_total);
         } else {
             crm_trace("Read full message of %u bytes", remote->buffer_offset);
             return remote->buffer_offset;
         }
     }
 
     return -EAGAIN;
 }
 
 /*!
  * \internal
  * \brief Read data off the socket until at least one full message is present or timeout occures.
  * \retval TRUE message read
  * \retval FALSE full message not read
  */
 
 gboolean
 crm_remote_recv(crm_remote_t * remote, int total_timeout /*ms */ , int *disconnected)
 {
     int rc;
     time_t start = time(NULL);
     int remaining_timeout = 0;
 
     if (total_timeout == 0) {
         total_timeout = 10000;
     } else if (total_timeout < 0) {
         total_timeout = 60000;
     }
     *disconnected = 0;
 
     remaining_timeout = total_timeout;
     while ((remaining_timeout > 0) && !(*disconnected)) {
 
         /* read some more off the tls buffer if we still have time left. */
         crm_trace("waiting to receive remote msg, starting timeout %d, remaining_timeout %d",
                   total_timeout, remaining_timeout);
         rc = crm_remote_ready(remote, remaining_timeout);
 
         if (rc == 0) {
             crm_err("poll timed out (%d ms) while waiting to receive msg", remaining_timeout);
             return FALSE;
 
         } else if(rc < 0) {
             crm_debug("poll() failed: %s (%d)", pcmk_strerror(rc), rc);
 
         } else {
             rc = crm_remote_recv_once(remote);
             if(rc > 0) {
                 return TRUE;
             } else if (rc < 0) {
                 crm_debug("recv() failed: %s (%d)", pcmk_strerror(rc), rc);
             }
         }
 
         if(rc == -ENOTCONN) {
             *disconnected = 1;
             return FALSE;
         }
 
         remaining_timeout = remaining_timeout - ((time(NULL) - start) * 1000);
     }
 
     return FALSE;
 }
 
 struct tcp_async_cb_data {
     gboolean success;
     int sock;
     void *userdata;
     void (*callback) (void *userdata, int sock);
     int timeout;                /*ms */
     time_t start;
 };
 
 static gboolean
 check_connect_finished(gpointer userdata)
 {
     struct tcp_async_cb_data *cb_data = userdata;
     int rc = 0;
     int sock = cb_data->sock;
     int error = 0;
 
     fd_set rset, wset;
     socklen_t len = sizeof(error);
     struct timeval ts = { 0, };
 
     if (cb_data->success == TRUE) {
         goto dispatch_done;
     }
 
     FD_ZERO(&rset);
     FD_SET(sock, &rset);
     wset = rset;
 
     crm_trace("fd %d: checking to see if connect finished", sock);
     rc = select(sock + 1, &rset, &wset, NULL, &ts);
 
     if (rc < 0) {
         rc = errno;
         if ((errno == EINPROGRESS) || (errno == EAGAIN)) {
             /* reschedule if there is still time left */
             if ((time(NULL) - cb_data->start) < (cb_data->timeout / 1000)) {
                 goto reschedule;
             } else {
                 rc = -ETIMEDOUT;
             }
         }
         crm_trace("fd %d: select failed %d connect dispatch ", rc);
         goto dispatch_done;
     } else if (rc == 0) {
         if ((time(NULL) - cb_data->start) < (cb_data->timeout / 1000)) {
             goto reschedule;
         }
         crm_debug("fd %d: timeout during select", sock);
         rc = -ETIMEDOUT;
         goto dispatch_done;
     } else {
         crm_trace("fd %d: select returned success", sock);
         rc = 0;
     }
 
     /* can we read or write to the socket now? */
     if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset)) {
         if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
             crm_trace("fd %d: call to getsockopt failed", sock);
             rc = -1;
             goto dispatch_done;
         }
 
         if (error) {
             crm_trace("fd %d: error returned from getsockopt: %d", sock, error);
             rc = -1;
             goto dispatch_done;
         }
     } else {
         crm_trace("neither read nor write set after select");
         rc = -1;
         goto dispatch_done;
     }
 
   dispatch_done:
     if (!rc) {
         crm_trace("fd %d: connected", sock);
         /* Success, set the return code to the sock to report to the callback */
         rc = cb_data->sock;
         cb_data->sock = 0;
     } else {
         close(sock);
     }
 
     if (cb_data->callback) {
         cb_data->callback(cb_data->userdata, rc);
     }
     free(cb_data);
     return FALSE;
 
   reschedule:
 
     /* will check again next interval */
     return TRUE;
 }
 
 static int
 internal_tcp_connect_async(int sock,
                            const struct sockaddr *addr, socklen_t addrlen, int timeout /* ms */ ,
                            void *userdata, void (*callback) (void *userdata, int sock))
 {
     int rc = 0;
     int flag = 0;
     int interval = 500;
     struct tcp_async_cb_data *cb_data = NULL;
 
     if ((flag = fcntl(sock, F_GETFL)) >= 0) {
         if (fcntl(sock, F_SETFL, flag | O_NONBLOCK) < 0) {
             crm_err("fcntl() write failed");
             return -1;
         }
     }
 
     rc = connect(sock, addr, addrlen);
 
     if (rc < 0 && (errno != EINPROGRESS) && (errno != EAGAIN)) {
         return -1;
     }
 
     cb_data = calloc(1, sizeof(struct tcp_async_cb_data));
     cb_data->userdata = userdata;
     cb_data->callback = callback;
     cb_data->sock = sock;
     cb_data->timeout = timeout;
     cb_data->start = time(NULL);
 
     if (rc == 0) {
         /* The connect was successful immediately, we still return to mainloop
          * and let this callback get called later. This avoids the user of this api
          * to have to account for the fact the callback could be invoked within this
          * function before returning. */
         cb_data->success = TRUE;
         interval = 1;
     }
 
     /* Check connect finished is mostly doing a non-block poll on the socket
      * to see if we can read/write to it. Once we can, the connect has completed.
      * This method allows us to connect to the server without blocking mainloop.
      *
      * This is a poor man's way of polling to see when the connection finished.
      * At some point we should figure out a way to use a mainloop fd callback for this.
      * Something about the way mainloop is currently polling prevents this from working at the
      * moment though. */
     crm_trace("fd %d: scheduling to check if connect finished in %dms second", sock, interval);
     g_timeout_add(interval, check_connect_finished, cb_data);
 
     return 0;
 }
 
 static int
 internal_tcp_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
 {
     int flag = 0;
     int rc = connect(sock, addr, addrlen);
 
     if (rc == 0) {
         if ((flag = fcntl(sock, F_GETFL)) >= 0) {
             if (fcntl(sock, F_SETFL, flag | O_NONBLOCK) < 0) {
                 crm_err("fcntl() write failed");
                 return -1;
             }
         }
     }
 
     return rc;
 }
 
 /*!
  * \internal
  * \brief tcp connection to server at specified port
  * \retval negative, failed to connect.
  */
 int
 crm_remote_tcp_connect_async(const char *host, int port, int timeout,   /*ms */
                              void *userdata, void (*callback) (void *userdata, int sock))
 {
     char buffer[256];
     struct addrinfo *res = NULL;
     struct addrinfo *rp = NULL;
     struct addrinfo hints;
     const char *server = host;
     int ret_ga;
     int sock = -1;
 
     /* getaddrinfo */
     memset(&hints, 0, sizeof(struct addrinfo));
     hints.ai_family = AF_UNSPEC;        /* Allow IPv4 or IPv6 */
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_flags = AI_CANONNAME;
 
     crm_debug("Looking up %s", server);
     ret_ga = getaddrinfo(server, NULL, &hints, &res);
     if (ret_ga) {
         crm_err("getaddrinfo: %s", gai_strerror(ret_ga));
         return -1;
     }
 
     if (!res || !res->ai_addr) {
         crm_err("getaddrinfo failed");
         goto async_cleanup;
     }
 
     for (rp = res; rp != NULL; rp = rp->ai_next) {
         struct sockaddr *addr = rp->ai_addr;
 
         if (!addr) {
             continue;
         }
 
         if (rp->ai_canonname) {
             server = res->ai_canonname;
         }
         crm_debug("Got address %s for %s", server, host);
 
         /* create socket */
         sock = socket(rp->ai_family, SOCK_STREAM, IPPROTO_TCP);
         if (sock == -1) {
             crm_err("Socket creation failed for remote client connection.");
             continue;
         }
 
         memset(buffer, 0, DIMOF(buffer));
         if (addr->sa_family == AF_INET6) {
-            struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)addr;
+            struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)(void*)addr;
 
             addr_in->sin6_port = htons(port);
             inet_ntop(addr->sa_family, &addr_in->sin6_addr, buffer, DIMOF(buffer));
 
         } else {
-            struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+            struct sockaddr_in *addr_in = (struct sockaddr_in *)(void*)addr;
 
             addr_in->sin_port = htons(port);
             inet_ntop(addr->sa_family, &addr_in->sin_addr, buffer, DIMOF(buffer));
         }
 
         crm_info("Attempting to connect to remote server at %s:%d", buffer, port);
 
         if (callback) {
             if (internal_tcp_connect_async
                 (sock, rp->ai_addr, rp->ai_addrlen, timeout, userdata, callback) == 0) {
                 sock = 0;
                 goto async_cleanup; /* Success for now, we'll hear back later in the callback */
             }
 
         } else {
             if (internal_tcp_connect(sock, rp->ai_addr, rp->ai_addrlen) == 0) {
                 break;          /* Success */
             }
         }
 
         close(sock);
         sock = -1;
     }
 
 async_cleanup:
 
     if (res) {
         freeaddrinfo(res);
     }
     return sock;
 }
 
 int
 crm_remote_tcp_connect(const char *host, int port)
 {
     return crm_remote_tcp_connect_async(host, port, -1, NULL, NULL);
 }
diff --git a/lrmd/tls_backend.c b/lrmd/tls_backend.c
index 1600353443..014999d0a2 100644
--- a/lrmd/tls_backend.c
+++ b/lrmd/tls_backend.c
@@ -1,402 +1,402 @@
 /*
  * Copyright (c) 2012 David Vossel <dvossel@redhat.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
 #include <crm_internal.h>
 
 #include <glib.h>
 #include <unistd.h>
 
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 #include <crm/common/mainloop.h>
 
 #include <lrmd_private.h>
 
 #include <netdb.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/ip.h>
 #include <arpa/inet.h>
 
 #ifdef HAVE_GNUTLS_GNUTLS_H
 #  define LRMD_REMOTE_AUTH_TIMEOUT 10000
 gnutls_psk_server_credentials_t psk_cred_s;
 gnutls_dh_params_t dh_params;
 static int ssock = -1;
 extern int lrmd_call_id;
 
 static void
 debug_log(int level, const char *str)
 {
     fputs(str, stderr);
 }
 
 static int
 lrmd_remote_client_msg(gpointer data)
 {
     int id = 0;
     int rc = 0;
     int disconnected = 0;
     xmlNode *request = NULL;
     crm_client_t *client = data;
 
     if (client->remote->tls_handshake_complete == FALSE) {
         int rc = 0;
 
         /* Muliple calls to handshake will be required, this callback
          * will be invoked once the client sends more handshake data. */
         do {
             rc = gnutls_handshake(*client->remote->tls_session);
 
             if (rc < 0 && rc != GNUTLS_E_AGAIN) {
                 crm_err("Remote lrmd tls handshake failed");
                 return -1;
             }
         } while (rc == GNUTLS_E_INTERRUPTED);
 
         if (rc == 0) {
             crm_debug("Remote lrmd tls handshake completed");
             client->remote->tls_handshake_complete = TRUE;
             if (client->remote->auth_timeout) {
                 g_source_remove(client->remote->auth_timeout);
             }
             client->remote->auth_timeout = 0;
         }
         return 0;
     }
 
     rc = crm_remote_ready(client->remote, 0);
     if (rc == 0) {
         /* no msg to read */
         return 0;
     } else if (rc < 0) {
         crm_info("Client disconnected during remote client read");
         return -1;
     }
 
     crm_remote_recv(client->remote, -1, &disconnected);
 
     request = crm_remote_parse_buffer(client->remote);
     while (request) {
         crm_element_value_int(request, F_LRMD_REMOTE_MSG_ID, &id);
         crm_trace("processing request from remote client with remote msg id %d", id);
         if (!client->name) {
             const char *value = crm_element_value(request, F_LRMD_CLIENTNAME);
 
             if (value) {
                 client->name = strdup(value);
             }
         }
 
         lrmd_call_id++;
         if (lrmd_call_id < 1) {
             lrmd_call_id = 1;
         }
 
         crm_xml_add(request, F_LRMD_CLIENTID, client->id);
         crm_xml_add(request, F_LRMD_CLIENTNAME, client->name);
         crm_xml_add_int(request, F_LRMD_CALLID, lrmd_call_id);
 
         process_lrmd_message(client, id, request);
         free_xml(request);
 
         /* process all the messages in the current buffer */
         request = crm_remote_parse_buffer(client->remote);
     }
 
     if (disconnected) {
         crm_info("Client disconnect detected in tls msg dispatcher.");
         return -1;
     }
 
     return 0;
 }
 
 static void
 lrmd_remote_client_destroy(gpointer user_data)
 {
     crm_client_t *client = user_data;
 
     if (client == NULL) {
         return;
     }
 
     ipc_proxy_remove_provider(client);
     client_disconnect_cleanup(client->id);
 
     crm_notice("LRMD client disconnecting remote client - name: %s id: %s",
                client->name ? client->name : "<unknown>", client->id);
 
     if (client->remote->tls_session) {
         void *sock_ptr;
         int csock;
 
         sock_ptr = gnutls_transport_get_ptr(*client->remote->tls_session);
         csock = GPOINTER_TO_INT(sock_ptr);
 
         gnutls_bye(*client->remote->tls_session, GNUTLS_SHUT_RDWR);
         gnutls_deinit(*client->remote->tls_session);
         gnutls_free(client->remote->tls_session);
         close(csock);
     }
 
     crm_client_destroy(client);
 
     return;
 }
 
 static gboolean
 lrmd_auth_timeout_cb(gpointer data)
 {
     crm_client_t *client = data;
 
     client->remote->auth_timeout = 0;
 
     if (client->remote->tls_handshake_complete == TRUE) {
         return FALSE;
     }
 
     mainloop_del_fd(client->remote->source);
     client->remote->source = NULL;
     crm_err("Remote client authentication timed out");
 
     return FALSE;
 }
 
 static int
 lrmd_remote_listen(gpointer data)
 {
     int csock = 0;
     int flag = 0;
     unsigned laddr;
     struct sockaddr_in addr;
     gnutls_session_t *session = NULL;
     crm_client_t *new_client = NULL;
 
     static struct mainloop_fd_callbacks lrmd_remote_fd_cb = {
         .dispatch = lrmd_remote_client_msg,
         .destroy = lrmd_remote_client_destroy,
     };
 
     /* accept the connection */
     laddr = sizeof(addr);
     csock = accept(ssock, (struct sockaddr *)&addr, &laddr);
     crm_debug("New remote connection from %s", inet_ntoa(addr.sin_addr));
 
     if (csock == -1) {
         crm_err("accept socket failed");
         return TRUE;
     }
 
     if ((flag = fcntl(csock, F_GETFL)) >= 0) {
         if (fcntl(csock, F_SETFL, flag | O_NONBLOCK) < 0) {
             crm_err("fcntl() write failed");
             close(csock);
             return TRUE;
         }
     } else {
         crm_err("fcntl() read failed");
         close(csock);
         return TRUE;
     }
 
     session = create_psk_tls_session(csock, GNUTLS_SERVER, psk_cred_s);
     if (session == NULL) {
         crm_err("TLS session creation failed");
         close(csock);
         return TRUE;
     }
 
     new_client = calloc(1, sizeof(crm_client_t));
     new_client->remote = calloc(1, sizeof(crm_remote_t));
     new_client->kind = CRM_CLIENT_TLS;
     new_client->remote->tls_session = session;
     new_client->id = crm_generate_uuid();
     new_client->remote->auth_timeout =
         g_timeout_add(LRMD_REMOTE_AUTH_TIMEOUT, lrmd_auth_timeout_cb, new_client);
     crm_notice("LRMD client connection established. %p id: %s", new_client, new_client->id);
 
     new_client->remote->source =
         mainloop_add_fd("lrmd-remote-client", G_PRIORITY_DEFAULT, csock, new_client,
                         &lrmd_remote_fd_cb);
     g_hash_table_insert(client_connections, new_client->id, new_client);
 
     return TRUE;
 }
 
 static void
 lrmd_remote_connection_destroy(gpointer user_data)
 {
     crm_notice("Remote tls server disconnected");
     return;
 }
 
 static int
 lrmd_tls_server_key_cb(gnutls_session_t session, const char *username, gnutls_datum_t * key)
 {
     return lrmd_tls_set_key(key);
 }
 
 static int
 bind_and_listen(struct addrinfo *addr)
 {
     int optval;
     int fd;
     int rc;
     char buffer[256] = { 0, };
 
     if (addr->ai_family == AF_INET6) {
-        struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)addr->ai_addr;
+        struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)(void*)addr->ai_addr;
         inet_ntop(addr->ai_family, &addr_in->sin6_addr, buffer, DIMOF(buffer));
 
     } else {
-        struct sockaddr_in *addr_in = (struct sockaddr_in *)addr->ai_addr;
+        struct sockaddr_in *addr_in = (struct sockaddr_in *)(void*)addr->ai_addr;
         inet_ntop(addr->ai_family, &addr_in->sin_addr, buffer, DIMOF(buffer));
     }
 
     crm_trace("Attempting to bind on address %s", buffer);
 
     fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
     if (fd < 0) {
         return -1;
     }
 
     /* reuse address */
     optval = 1;
     rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
     if (rc < 0) {
         crm_perror(LOG_INFO, "Couldn't allow the reuse of local addresses by our remote listener, bind address %s", buffer);
         close(fd);
         return -1;
     }
 
     if (addr->ai_family == AF_INET6) {
         optval = 0;
         rc = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval));
         if (rc < 0) {
             crm_perror(LOG_INFO, "Couldn't disable IPV6 only on address %s", buffer);
             close(fd);
             return -1;
         }
     }
 
     if (bind(fd, addr->ai_addr, addr->ai_addrlen) != 0) {
         close(fd);
         return -1;
     }
 
     if (listen(fd, 10) == -1) {
         crm_err("Can not start listen on address %s", buffer);
         close(fd);
         return -1;
     }
 
     crm_notice("Listening on address %s", buffer);
 
     return fd;
 }
 
 int
 lrmd_init_remote_tls_server(int port)
 {
     int rc;
     int filter;
     struct addrinfo hints, *res = NULL, *iter;
     char port_str[16];
 
     static struct mainloop_fd_callbacks remote_listen_fd_callbacks = {
         .dispatch = lrmd_remote_listen,
         .destroy = lrmd_remote_connection_destroy,
     };
 
     crm_notice("Starting a tls listener on port %d.", port);
     gnutls_global_init();
     gnutls_global_set_log_function(debug_log);
 
     gnutls_dh_params_init(&dh_params);
     gnutls_dh_params_generate2(dh_params, 1024);
     gnutls_psk_allocate_server_credentials(&psk_cred_s);
     gnutls_psk_set_server_credentials_function(psk_cred_s, lrmd_tls_server_key_cb);
     gnutls_psk_set_server_dh_params(psk_cred_s, dh_params);
 
     memset(&hints, 0, sizeof(struct addrinfo));
     hints.ai_flags = AI_PASSIVE; /* Only return socket addresses with wildcard INADDR_ANY or IN6ADDR_ANY_INIT */
     hints.ai_family = AF_UNSPEC; /* Return IPv6 or IPv4 */
     hints.ai_socktype = SOCK_STREAM;
     hints.ai_protocol = IPPROTO_TCP;
 
     snprintf(port_str, sizeof(port_str), "%d", port);
     rc = getaddrinfo(NULL, port_str, &hints, &res);
     if (rc) {
         crm_err("getaddrinfo: %s", gai_strerror(rc));
         return -1;
     }
 
     iter = res;
     filter = AF_INET6;
     /* Try IPv6 addresses first, then IPv4 */
     while (iter) {
         if (iter->ai_family == filter) {
             ssock = bind_and_listen(iter);
         }
         if (ssock != -1) {
             break;
         }
 
         iter = iter->ai_next;
         if (iter == NULL && filter == AF_INET6) {
             iter = res;
             filter = AF_INET;
         }
     }
 
     if (ssock < 0) {
         crm_err("unable to bind to address");
         goto init_remote_cleanup;
     }
 
     mainloop_add_fd("lrmd-remote", G_PRIORITY_DEFAULT, ssock, NULL, &remote_listen_fd_callbacks);
 
     rc = ssock;
   init_remote_cleanup:
     if (rc < 0) {
         close(ssock);
         ssock = 0;
     }
     freeaddrinfo(res);
     return rc;
 
 }
 
 void
 lrmd_tls_server_destroy(void)
 {
     if (psk_cred_s) {
         gnutls_psk_free_server_credentials(psk_cred_s);
         psk_cred_s = 0;
     }
 
     if (ssock > 0) {
         close(ssock);
         ssock = 0;
     }
 }
 #endif