void Downloader::NeededChunk::put_block(uint32_t offset, const blob& content) { auto inserted = file_map_.insert({offset, content.size()}).second; if(inserted) { #ifndef FOPEN_BACKEND std::copy(content.begin(), content.end(), mapped_file_.data()+offset); #else if(wrapped_file_.ios().tellp() != offset) wrapped_file_.ios().seekp(offset); wrapped_file_.ios().write((char*)content.data(), content.size()); #endif } }
void P2PFolder::handle_message(const blob& message_raw) { V1Parser::message_type message_type = parser_.parse_MessageType(message_raw); counter_.add_down(message_raw.size()); if(ready()) { switch(message_type) { case V1Parser::CHOKE: handle_Choke(message_raw); break; case V1Parser::UNCHOKE: handle_Unchoke(message_raw); break; case V1Parser::INTERESTED: handle_Interested(message_raw); break; case V1Parser::NOT_INTERESTED: handle_NotInterested(message_raw); break; case V1Parser::HAVE_META: handle_HaveMeta(message_raw); break; case V1Parser::HAVE_CHUNK: handle_HaveChunk(message_raw); break; case V1Parser::META_REQUEST: handle_MetaRequest(message_raw); break; case V1Parser::META_REPLY: handle_MetaReply(message_raw); break; case V1Parser::META_CANCEL: handle_MetaCancel(message_raw); break; case V1Parser::BLOCK_REQUEST: handle_BlockRequest(message_raw); break; case V1Parser::BLOCK_REPLY: handle_BlockReply(message_raw); break; case V1Parser::BLOCK_CANCEL: handle_BlockCancel(message_raw); break; default: throw protocol_error(); } }else{ handle_Handshake(message_raw); } }
void Downloader::put_block(const blob& ct_hash, uint32_t offset, const blob& data, std::shared_ptr<RemoteFolder> from) { log_->trace() << log_tag() << BOOST_CURRENT_FUNCTION; auto needed_block_it = needed_chunks_.find(ct_hash); if(needed_block_it == needed_chunks_.end()) return; auto& requests = needed_block_it->second->requests; for(auto request_it = requests.begin(); request_it != requests.end();) { bool incremented_already = false; if(request_it->second.offset == offset // Chunk position incorrect && request_it->second.size == data.size() // Chunk size incorrect && request_it->first == from) { // Requested node != replied. Well, it isn't critical, but will be useful to ban "fake" peers incremented_already = true; request_it = requests.erase(request_it); needed_block_it->second->put_block(offset, data); if(needed_block_it->second->full()) { exchange_group_.fs_dir()->put_chunk(ct_hash, needed_block_it->second->get_chunk()); } // TODO: catch "invalid hash" exception here periodic_maintain_.invoke_post(); } if(!incremented_already) ++request_it; } }
blob Base64::from(const blob& data) const { std::string transformed; CryptoPP::StringSource(data.data(), data.size(), true, new CryptoPP::Base64Decoder( new CryptoPP::StringSink(transformed) ) ); return blob(std::make_move_iterator(transformed.begin()), std::make_move_iterator(transformed.end())); }
void P2PFolder::post_block(const blob& ct_hash, uint32_t offset, const blob& block) { V1Parser::BlockReply message; message.ct_hash = ct_hash; message.offset = offset; message.content = block; send_message(parser_.gen_BlockReply(message)); counter_.add_up_blocks(block.size()); log_->debug() << log_tag() << "==> BLOCK_REPLY:" << " ct_hash=" << ct_hash_readable(ct_hash) << " offset=" << offset; }
void print(const blob & x, const char * prefix, ...) { va_list ap; va_start(ap, prefix); if(!x.exists()) { if(prefix) vprintf(prefix, ap); printf("(non-existent)\n"); va_end(ap); return; } for(size_t i = 0; i < x.size(); i += 16) { size_t m = i + 16; if(prefix) vprintf(prefix, ap); for(size_t j = i; j < m; j++) { if(j < x.size()) printf("%02x ", x[j]); else printf(" "); if((i % 16) == 8) printf(" "); } printf(" |"); for(size_t j = i; j < m; j++) { if(j < x.size()) printf("%c", isprint(x[j]) ? x[j] : '.'); else printf(" "); } printf("|\n"); } va_end(ap); }
/** Get the size of the data (in bytes) */ size_t size() const { return m_blob ? m_blob->size() : 0; }
ter doapply () override { std::uint32_t const utxflags = mtxn.getflags (); std::uint32_t const uflagsin = mtxnaccount->getfieldu32 (sfflags); std::uint32_t uflagsout = uflagsin; std::uint32_t const usetflag = mtxn.getfieldu32 (sfsetflag); std::uint32_t const uclearflag = mtxn.getfieldu32 (sfclearflag); if ((usetflag != 0) && (usetflag == uclearflag)) { m_journal.trace << "malformed transaction: set and clear same flag"; return teminvalid_flag; } // legacy accountset flags bool bsetrequiredest = (utxflags & txflag::requiredesttag) || (usetflag == asfrequiredest); bool bclearrequiredest = (utxflags & tfoptionaldesttag) || (uclearflag == asfrequiredest); bool bsetrequireauth = (utxflags & tfrequireauth) || (usetflag == asfrequireauth); bool bclearrequireauth = (utxflags & tfoptionalauth) || (uclearflag == asfrequireauth); bool bsetdisallowxrp = (utxflags & tfdisallowxrp) || (usetflag == asfdisallowxrp); bool bcleardisallowxrp = (utxflags & tfallowxrp) || (uclearflag == asfdisallowxrp); if (utxflags & tfaccountsetmask) { m_journal.trace << "malformed transaction: invalid flags set."; return teminvalid_flag; } // // requireauth // if (bsetrequireauth && bclearrequireauth) { m_journal.trace << "malformed transaction: contradictory flags set."; return teminvalid_flag; } if (bsetrequireauth && !(uflagsin & lsfrequireauth)) { if (!mengine->view().dirisempty (getownerdirindex (mtxnaccountid))) { m_journal.trace << "retry: owner directory not empty."; return (mparams & tapretry) ? terowners : tecowners; } m_journal.trace << "set requireauth."; uflagsout |= lsfrequireauth; } if (bclearrequireauth && (uflagsin & lsfrequireauth)) { m_journal.trace << "clear requireauth."; uflagsout &= ~lsfrequireauth; } // // requiredesttag // if (bsetrequiredest && bclearrequiredest) { m_journal.trace << "malformed transaction: contradictory flags set."; return teminvalid_flag; } if (bsetrequiredest && !(uflagsin & lsfrequiredesttag)) { m_journal.trace << "set lsfrequiredesttag."; uflagsout |= lsfrequiredesttag; } if (bclearrequiredest && (uflagsin & lsfrequiredesttag)) { m_journal.trace << "clear lsfrequiredesttag."; uflagsout &= ~lsfrequiredesttag; } // // disallowxrp // if (bsetdisallowxrp && bcleardisallowxrp) { m_journal.trace << "malformed transaction: contradictory flags set."; return teminvalid_flag; } if (bsetdisallowxrp && !(uflagsin & lsfdisallowxrp)) { m_journal.trace << "set lsfdisallowxrp."; uflagsout |= lsfdisallowxrp; } if (bcleardisallowxrp && (uflagsin & lsfdisallowxrp)) { m_journal.trace << "clear lsfdisallowxrp."; uflagsout &= ~lsfdisallowxrp; } // // disablemaster // if ((usetflag == asfdisablemaster) && !(uflagsin & lsfdisablemaster)) { if (!mtxnaccount->isfieldpresent (sfregularkey)) return tecno_regular_key; m_journal.trace << "set lsfdisablemaster."; uflagsout |= lsfdisablemaster; } if ((uclearflag == asfdisablemaster) && (uflagsin & lsfdisablemaster)) { m_journal.trace << "clear lsfdisablemaster."; uflagsout &= ~lsfdisablemaster; } if (usetflag == asfnofreeze) { m_journal.trace << "set nofreeze flag"; uflagsout |= lsfnofreeze; } // anyone may set global freeze if (usetflag == asfglobalfreeze) { m_journal.trace << "set globalfreeze flag"; uflagsout |= lsfglobalfreeze; } // if you have set nofreeze, you may not clear globalfreeze // this prevents those who have set nofreeze from using // globalfreeze strategically. if ((usetflag != asfglobalfreeze) && (uclearflag == asfglobalfreeze) && ((uflagsout & lsfnofreeze) == 0)) { m_journal.trace << "clear globalfreeze flag"; uflagsout &= ~lsfglobalfreeze; } // // track transaction ids signed by this account in its root // if ((usetflag == asfaccounttxnid) && !mtxnaccount->isfieldpresent (sfaccounttxnid)) { m_journal.trace << "set accounttxnid"; mtxnaccount->makefieldpresent (sfaccounttxnid); } if ((uclearflag == asfaccounttxnid) && mtxnaccount->isfieldpresent (sfaccounttxnid)) { m_journal.trace << "clear accounttxnid"; mtxnaccount->makefieldabsent (sfaccounttxnid); } // // emailhash // if (mtxn.isfieldpresent (sfemailhash)) { uint128 const uhash = mtxn.getfieldh128 (sfemailhash); if (!uhash) { m_journal.trace << "unset email hash"; mtxnaccount->makefieldabsent (sfemailhash); } else { m_journal.trace << "set email hash"; mtxnaccount->setfieldh128 (sfemailhash, uhash); } } // // walletlocator // if (mtxn.isfieldpresent (sfwalletlocator)) { uint256 const uhash = mtxn.getfieldh256 (sfwalletlocator); if (!uhash) { m_journal.trace << "unset wallet locator"; mtxnaccount->makefieldabsent (sfwalletlocator); } else { m_journal.trace << "set wallet locator"; mtxnaccount->setfieldh256 (sfwalletlocator, uhash); } } // // messagekey // if (mtxn.isfieldpresent (sfmessagekey)) { blob messagekey = mtxn.getfieldvl (sfmessagekey); if (messagekey.empty ()) { m_journal.debug << "set message key"; mtxnaccount->makefieldabsent (sfmessagekey); } if (messagekey.size () > public_bytes_max) { m_journal.trace << "message key too long"; return telbad_public_key; } else { m_journal.debug << "set message key"; mtxnaccount->setfieldvl (sfmessagekey, messagekey); } } // // domain // if (mtxn.isfieldpresent (sfdomain)) { blob const domain = mtxn.getfieldvl (sfdomain); if (domain.size () > domain_bytes_max) { m_journal.trace << "domain too long"; return telbad_domain; } if (domain.empty ()) { m_journal.trace << "unset domain"; mtxnaccount->makefieldabsent (sfdomain); } else { m_journal.trace << "set domain"; mtxnaccount->setfieldvl (sfdomain, domain); } } // // transferrate // if (mtxn.isfieldpresent (sftransferrate)) { std::uint32_t urate = mtxn.getfieldu32 (sftransferrate); if (!urate || urate == quality_one) { m_journal.trace << "unset transfer rate"; mtxnaccount->makefieldabsent (sftransferrate); } else if (urate > quality_one) { m_journal.trace << "set transfer rate"; mtxnaccount->setfieldu32 (sftransferrate, urate); } else { m_journal.trace << "bad transfer rate"; return tembad_transfer_rate; } } if (uflagsin != uflagsout) mtxnaccount->setfieldu32 (sfflags, uflagsout); return tessuccess; }
void P2PFolder::send_message(const blob& message) { counter_.add_up(message.size()); ws_service_.send_message(conn_.connection_handle, message); }