ssize_t segmentTree<T>::allocSt(const ssize_t cnt) { if(cnt <= 0) { return -1; } ssize_t depTmp = log(cnt); if(depTmp < 0) { return -1; } if(!checkPow(cnt)) { depTmp++; } depTmp++; ssize_t nodeTots = (1 << depTmp) - 1; /*nodes needed */ nodeTots++; /*add empty node at head*/ tree = new T[nodeTots]; if(!tree) { return -1; } memset(tree, 0, nodeTots); deps = depTmp; /*store cnt*/ nodes = nodeTots; elems = cnt; return 0; };
void NodeConnection::Listener() { try { while(this->Socket != SOCKET_ERROR) { Packet packet; packet.getCommand(this->Socket); //printf("%s\n", packet.command); //this printf are not really thread save, and they are only needed for debug if (!strcmp(packet.command, "pong")) //just a keep alive { packet.sendData(this->Socket); //resending it }else if(!strcmp(packet.command,"version")) { packet_version version(packet); this->Version = version.version; }else if(!strcmp(packet.command,"verack")) { packet_verack verack(packet); verack.sendData(this->Socket); //empty addr for now packet_addr addr; addr.addr_list.clear(); addr.encodeData(); addr.setChecksum_Lenght_Magic(); addr.sendData(this->Socket); //empty inv for now, this should be the whole list of object hash bool finished = false; vector<sTag> inventory; std::shared_lock<std::shared_timed_mutex> mlock(bitmrc->sharedObj.mutex_); for (int i = 0; i < bitmrc->sharedObj.Dim; i++) { hash_table<ustring>::linked_node * cur = bitmrc->sharedObj.Table[i]; while (cur != NULL) { sTag hash; memcpy(hash.ch, cur->hash.c_str(), 32); inventory.push_back(hash); cur = cur->next; } } mlock.unlock(); unsigned int i = 0; while (!finished) { packet_inv inv; while (i < 50000 && i < inventory.size()) { inv.inventory.push_back(inventory[i]); i++; } inv.encodeData(); inv.setChecksum_Lenght_Magic(); inv.sendData(this->Socket); if (i == inventory.size()) finished = true; } this->state = 2; }else if(!strcmp(packet.command,"addr")) { packet_addr addr(packet); for(unsigned int i=0;i<addr.addr_list.size();i++) { if(addr.addr_list[i].IPv6_4[11] == 0xff && addr.addr_list[i].IPv6_4[10] == 0xff) { char buf[40]; sprintf(buf,"%i.%i.%i.%i", addr.addr_list[i].IPv6_4[12], addr.addr_list[i].IPv6_4[13], addr.addr_list[i].IPv6_4[14], addr.addr_list[i].IPv6_4[15]); string ip(buf); //printf("%s\n",buf); sprintf(buf, "%i", addr.addr_list[i].port); string port(buf); NodeConnection *tmp_node= new NodeConnection(ip,port, this->bitmrc); this->bitmrc->connectNode(tmp_node); } } }else if(!strcmp(packet.command,"inv")) { packet_inv inv(packet); packet_getdata needed; for (unsigned int i = 0; i < inv.inventory.size(); i++) { ustring tag; for (int j = 0; j < 32; j++) { tag += inv.inventory[i].ch[j]; } if (this->bitmrc->sharedObj.searchByHash(tag).empty()) { needed.inventory.push_back(inv.inventory[i]); } } if (!needed.inventory.empty()) { needed.encodeData(); needed.setChecksum_Lenght_Magic(); Packets.push(needed); } }else if(!strcmp(packet.command,"getdata")) { packet_getdata getdata(packet); for (unsigned int i = 0; i < getdata.inventory.size(); i++) { ustring tag; for (int j = 0; j < 32; j++) { tag += getdata.inventory[i].ch[j]; } ustring ObjPayload = this->bitmrc->sharedObj.searchByHash(tag); if (!ObjPayload.empty()) { object obj; memset(obj.command, 0x00, sizeof obj.command); strncpy(obj.command, "object", 7); obj.message_payload = ObjPayload; obj.setChecksum_Lenght_Magic(); Packets.push(obj); } } }else if(!strcmp(packet.command,"object")) { object obj(packet); bool check = checkPow(obj.message_payload, obj.Time); //if not ignore if (check) { ustring invHash = this->bitmrc->inventoryHash(obj.message_payload); int present = this->bitmrc->sharedObj.insert(obj.message_payload, invHash); sTag tag; memcpy(tag.ch, invHash.c_str(), 32); this->bitmrc->new_inv.push(tag); if (obj.objectType == type_getpubkey) { packet_getpubkey getpubkey(obj); std::shared_lock<std::shared_timed_mutex> mlock(this->bitmrc->mutex_priv); for (unsigned int i = 0; i < this->bitmrc->PrivAddresses.size(); i++) { ustring tag = this->bitmrc->PrivAddresses[i].getTag(); if (getpubkey.tag == tag) { if(this->bitmrc->PrivAddresses[i].getLastPubKeyRequest() + 60 * 60 * 24 * 4 < time(NULL)) this->bitmrc->sendObj(this->bitmrc->PrivAddresses[i].encodePubKey(),true); //else //printf("PubKey already shared recently"); } } mlock.unlock(); } else if (obj.objectType == type_pubkey) { packet_pubkey pubkey(obj); std::shared_lock<std::shared_timed_mutex> mlock(this->bitmrc->mutex_pub); for (unsigned int i = 0; i < this->bitmrc->PubAddresses.size(); i++) { if (!this->bitmrc->PubAddresses[i].waitingPubKey()) continue; ustring tag = this->bitmrc->PubAddresses[i].getTag(); if (pubkey.tag == tag) { this->bitmrc->PubAddresses[i].decodeFromObj(pubkey); } } mlock.unlock(); } else if (obj.objectType == type_msg) { packet_msg msg(obj); if (this->bitmrc->decryptMsg(msg)) //it takes like 1-4 milliseconds { //printf("Message accepted\n"); } } else if (obj.objectType == type_broadcast) { packet_broadcast broadcast(obj); if (this->bitmrc->decryptMsg(broadcast)) { //printf("broadcast decrypted\n"); } } } } } }catch(int e) { switch(e) { case CONNECTION_CLOSED: case CONNECTION_ERROR: this->Close(); return; } } }