static int handle_fakeid_announce(void *object, const uint8_t *source_pubkey, const uint8_t *data, uint16_t length) { Onion_Client *onion_c = object; if (length < FAKEID_DATA_MIN_LENGTH) return 1; if (length > FAKEID_DATA_MAX_LENGTH) return 1; int friend_num = onion_friend_num(onion_c, source_pubkey); if (friend_num == -1) return 1; uint64_t no_replay; memcpy(&no_replay, data + 1, sizeof(uint64_t)); net_to_host((uint8_t *) &no_replay, sizeof(no_replay)); if (no_replay <= onion_c->friends_list[friend_num].last_noreplay) return 1; onion_c->friends_list[friend_num].last_noreplay = no_replay; if (onion_c->friends_list[friend_num].dht_pk_callback) onion_c->friends_list[friend_num].dht_pk_callback(onion_c->friends_list[friend_num].dht_pk_callback_object, onion_c->friends_list[friend_num].dht_pk_callback_number, data + 1 + sizeof(uint64_t)); onion_set_friend_DHT_pubkey(onion_c, friend_num, data + 1 + sizeof(uint64_t)); onion_c->friends_list[friend_num].last_seen = unix_time(); uint16_t len_nodes = length - FAKEID_DATA_MIN_LENGTH; if (len_nodes != 0) { Node_format nodes[MAX_SENT_NODES]; int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, data + 1 + sizeof(uint64_t) + crypto_box_PUBLICKEYBYTES, len_nodes, 1); if (num_nodes <= 0) return 1; int i; for (i = 0; i < num_nodes; ++i) { uint8_t family = nodes[i].ip_port.ip.family; if (family == AF_INET || family == AF_INET6) { DHT_getnodes(onion_c->dht, &nodes[i].ip_port, nodes[i].client_id, onion_c->friends_list[friend_num].fake_client_id); } else if (family == TCP_INET || family == TCP_INET6) { if (onion_c->friends_list[friend_num].tcp_relay_node_callback) { void *obj = onion_c->friends_list[friend_num].tcp_relay_node_callback_object; uint32_t number = onion_c->friends_list[friend_num].tcp_relay_node_callback_number; onion_c->friends_list[friend_num].tcp_relay_node_callback(obj, number, nodes[i].ip_port, nodes[i].client_id); } } } } return 0; }
static int handle_packet(void *object, int number, const uint8_t *data, uint16_t length, void *userdata) { if (length == 0) { return -1; } Friend_Connections *const fr_c = (Friend_Connections *)object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) { return -1; } if (data[0] == PACKET_ID_FRIEND_REQUESTS) { if (fr_c->fr_request_callback) { fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length, userdata); } return 0; } if (data[0] == PACKET_ID_ALIVE) { friend_con->ping_lastrecv = mono_time_get(fr_c->mono_time); return 0; } if (data[0] == PACKET_ID_SHARE_RELAYS) { Node_format nodes[MAX_SHARED_RELAYS]; const int n = unpack_nodes(nodes, MAX_SHARED_RELAYS, nullptr, data + 1, length - 1, 1); if (n == -1) { return -1; } for (int j = 0; j < n; ++j) { friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key); } return 0; } for (unsigned i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { if (friend_con->callbacks[i].data_callback) { friend_con->callbacks[i].data_callback( friend_con->callbacks[i].callback_object, friend_con->callbacks[i].callback_id, data, length, userdata); } friend_con = get_conn(fr_c, number); if (!friend_con) { return -1; } } return 0; }
static int handle_announce_response(void *object, IP_Port source, const uint8_t *packet, uint16_t length) { Onion_Client *onion_c = object; if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) return 1; uint16_t len_nodes = length - ONION_ANNOUNCE_RESPONSE_MIN_SIZE; uint8_t public_key[crypto_box_PUBLICKEYBYTES]; IP_Port ip_port; uint32_t path_num; uint32_t num = check_sendback(onion_c, packet + 1, public_key, &ip_port, &path_num); if (num > onion_c->num_friends) return 1; uint8_t plain[1 + ONION_PING_ID_SIZE + len_nodes]; int len = -1; if (num == 0) { len = decrypt_data(public_key, onion_c->c->self_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain); } else { if (onion_c->friends_list[num - 1].status == 0) return 1; len = decrypt_data(public_key, onion_c->friends_list[num - 1].temp_secret_key, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH, packet + 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES, length - (1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + crypto_box_NONCEBYTES), plain); } if ((uint32_t)len != sizeof(plain)) return 1; if (client_add_to_list(onion_c, num, public_key, ip_port, plain[0], plain + 1, path_num) == -1) return 1; if (len_nodes != 0) { Node_format nodes[MAX_SENT_NODES]; int num_nodes = unpack_nodes(nodes, MAX_SENT_NODES, 0, plain + 1 + ONION_PING_ID_SIZE, len_nodes, 0); if (num_nodes <= 0) return 1; if (client_ping_nodes(onion_c, num, nodes, num_nodes, source) == -1) return 1; } //TODO: LAN vs non LAN ips?, if we are connected only to LAN, are we offline? onion_c->last_packet_recv = unix_time(); return 0; }
/* * Unpack everything * At the end you'll have: * - A list of nodes * - A list of resources (each with any dependencies on other resources) * - A list of constraints between resources and nodes * - A list of constraints between start/stop actions * - A list of nodes that need to be stonith'd * - A list of nodes that need to be shutdown * - A list of the possible stop/start actions (without dependencies) */ gboolean cluster_status(pe_working_set_t *data_set) { xmlNode * config = get_object_root( XML_CIB_TAG_CRMCONFIG, data_set->input); xmlNode * cib_nodes = get_object_root( XML_CIB_TAG_NODES, data_set->input); xmlNode * cib_resources = get_object_root( XML_CIB_TAG_RESOURCES, data_set->input); xmlNode * cib_status = get_object_root( XML_CIB_TAG_STATUS, data_set->input); const char *value = crm_element_value( data_set->input, XML_ATTR_HAVE_QUORUM); crm_debug_3("Beginning unpack"); /* reset remaining global variables */ if(data_set->input == NULL) { return FALSE; } if(data_set->now == NULL) { data_set->now = new_ha_date(TRUE); } if(data_set->input != NULL && crm_element_value(data_set->input, XML_ATTR_DC_UUID) != NULL) { /* this should always be present */ data_set->dc_uuid = crm_element_value_copy( data_set->input, XML_ATTR_DC_UUID); } clear_bit_inplace(data_set->flags, pe_flag_have_quorum); if(crm_is_true(value)) { set_bit_inplace(data_set->flags, pe_flag_have_quorum); } data_set->op_defaults = get_object_root(XML_CIB_TAG_OPCONFIG, data_set->input); data_set->rsc_defaults = get_object_root(XML_CIB_TAG_RSCCONFIG, data_set->input); unpack_config(config, data_set); if(is_set(data_set->flags, pe_flag_have_quorum) == FALSE && data_set->no_quorum_policy != no_quorum_ignore) { crm_warn("We do not have quorum" " - fencing and resource management disabled"); } unpack_nodes(cib_nodes, data_set); unpack_resources(cib_resources, data_set); unpack_status(cib_status, data_set); return TRUE; }
static int handle_packet(void *object, int number, uint8_t *data, uint16_t length, void *userdata) { if (length == 0) return -1; Friend_Connections *fr_c = object; Friend_Conn *friend_con = get_conn(fr_c, number); if (!friend_con) return -1; if (data[0] == PACKET_ID_FRIEND_REQUESTS) { if (fr_c->fr_request_callback) fr_c->fr_request_callback(fr_c->fr_request_object, friend_con->real_public_key, data, length); return 0; } else if (data[0] == PACKET_ID_ALIVE) { friend_con->ping_lastrecv = unix_time(); return 0; } else if (data[0] == PACKET_ID_SHARE_RELAYS) { Node_format nodes[MAX_SHARED_RELAYS]; int n; if ((n = unpack_nodes(nodes, MAX_SHARED_RELAYS, NULL, data + 1, length - 1, 1)) == -1) return -1; int j; for (j = 0; j < n; j++) { friend_add_tcp_relay(fr_c, number, nodes[j].ip_port, nodes[j].public_key); } return 0; } unsigned int i; for (i = 0; i < MAX_FRIEND_CONNECTION_CALLBACKS; ++i) { if (friend_con->callbacks[i].data_callback) friend_con->callbacks[i].data_callback( friend_con->callbacks[i].data_callback_object, friend_con->callbacks[i].data_callback_id, data, length, userdata); friend_con = get_conn(fr_c, number); if (!friend_con) return -1; } return 0; }
/* * Unpack everything * At the end you'll have: * - A list of nodes * - A list of resources (each with any dependencies on other resources) * - A list of constraints between resources and nodes * - A list of constraints between start/stop actions * - A list of nodes that need to be stonith'd * - A list of nodes that need to be shutdown * - A list of the possible stop/start actions (without dependencies) */ gboolean cluster_status(pe_working_set_t * data_set) { xmlNode *config = get_xpath_object("//"XML_CIB_TAG_CRMCONFIG, data_set->input, LOG_TRACE); xmlNode *cib_nodes = get_xpath_object("//"XML_CIB_TAG_NODES, data_set->input, LOG_TRACE); xmlNode *cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE); xmlNode *cib_status = get_xpath_object("//"XML_CIB_TAG_STATUS, data_set->input, LOG_TRACE); xmlNode *cib_tags = get_xpath_object("//"XML_CIB_TAG_TAGS, data_set->input, LOG_TRACE); const char *value = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM); crm_trace("Beginning unpack"); pe_dataset = data_set; /* reset remaining global variables */ data_set->failed = create_xml_node(NULL, "failed-ops"); if (data_set->input == NULL) { return FALSE; } if (data_set->now == NULL) { data_set->now = crm_time_new(NULL); } if (data_set->dc_uuid == NULL && data_set->input != NULL && crm_element_value(data_set->input, XML_ATTR_DC_UUID) != NULL) { /* this should always be present */ data_set->dc_uuid = crm_element_value_copy(data_set->input, XML_ATTR_DC_UUID); } clear_bit(data_set->flags, pe_flag_have_quorum); if (crm_is_true(value)) { set_bit(data_set->flags, pe_flag_have_quorum); } data_set->op_defaults = get_xpath_object("//"XML_CIB_TAG_OPCONFIG, data_set->input, LOG_TRACE); data_set->rsc_defaults = get_xpath_object("//"XML_CIB_TAG_RSCCONFIG, data_set->input, LOG_TRACE); unpack_config(config, data_set); if (is_not_set(data_set->flags, pe_flag_quick_location) && is_not_set(data_set->flags, pe_flag_have_quorum) && data_set->no_quorum_policy != no_quorum_ignore) { crm_warn("Fencing and resource management disabled due to lack of quorum"); } unpack_nodes(cib_nodes, data_set); if(is_not_set(data_set->flags, pe_flag_quick_location)) { unpack_remote_nodes(cib_resources, data_set); } unpack_resources(cib_resources, data_set); unpack_tags(cib_tags, data_set); if(is_not_set(data_set->flags, pe_flag_quick_location)) { unpack_status(cib_status, data_set); } set_bit(data_set->flags, pe_flag_have_status); return TRUE; }