Пример #1
0
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
	}
}
Пример #2
0
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);
	}
}
Пример #3
0
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;
	}
}
Пример #4
0
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()));
}
Пример #5
0
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;
}
Пример #6
0
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);
}
Пример #7
0
 /** Get the size of the data (in bytes) */
 size_t size() const { return m_blob ? m_blob->size() : 0; }
Пример #8
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;
    }
Пример #9
0
void P2PFolder::send_message(const blob& message) {
	counter_.add_up(message.size());
	ws_service_.send_message(conn_.connection_handle, message);
}