Пример #1
0
 explicit
 enumerated_value_range(span<const T> v)
 noexcept
     : _begin(v.data())
     , _end(v.data()+v.size())
 {
     assert(_begin <= _end);
 }
Пример #2
0
		void random_bytes(span<char> buffer)
		{
#if TORRENT_USE_CRYPTOAPI
			HCRYPTPROV prov;

			if (!CryptAcquireContext(&prov, NULL, NULL
				, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
			{
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(GetLastError(), system_category()));
#else
				std::terminate();
#endif
			}

			if (!CryptGenRandom(prov, int(buffer.size())
				, reinterpret_cast<BYTE*>(buffer.data())))
			{
				CryptReleaseContext(prov, 0);
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(GetLastError(), system_category()));
#else
				std::terminate();
#endif
			}

			CryptReleaseContext(prov, 0);
#elif defined TORRENT_USE_LIBCRYPTO
#ifdef TORRENT_MACOS_DEPRECATED_LIBCRYPTO
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
			int r = RAND_bytes(reinterpret_cast<unsigned char*>(buffer.data())
				, int(buffer.size()));
			if (r != 1)
			{
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(int(::ERR_get_error()), system_category()));
#else
				std::terminate();
#endif
			}
#ifdef TORRENT_MACOS_DEPRECATED_LIBCRYPTO
#pragma clang diagnostic pop
#endif
#else
			for (auto& b : buffer) b = char(random(0xff));
#endif
		}
Пример #3
0
bool CommObject::SendFrame(span<const std::uint8_t> frame)
{
    if (frame.size() > CommMaxFrameSize)
    {
        LOGF(LOG_LEVEL_ERROR, "Frame payload is too long. Allowed: %d, Requested: '%d'.", CommMaxFrameSize, frame.size());
        return false;
    }

    uint8_t cmd[ComPrefferedBufferSize];
    cmd[0] = TransmitterSendFrame;
    memcpy(cmd + 1, frame.data(), frame.size());
    uint8_t remainingBufferSize;

    const bool status = (this->_low.WriteRead(CommTransmitter,           //
                             span<const uint8_t>(cmd, 1 + frame.size()), //
                             span<uint8_t>(&remainingBufferSize, 1)      //
                             ) == I2CResult::OK);
    if (!status)
    {
        LOG(LOG_LEVEL_ERROR, "[comm] Failed to send frame");
    }

    if (remainingBufferSize == 0xff)
    {
        LOG(LOG_LEVEL_ERROR, "[comm] Frame was not accepted by the transmitter.");
    }

    return status && remainingBufferSize != 0xff;
}
Пример #4
0
	int count_trailing_ones_hw(span<std::uint32_t const> buf)
	{
		auto const num = int(buf.size());
		std::uint32_t const* ptr = buf.data();

		TORRENT_ASSERT(num >= 0);
		TORRENT_ASSERT(ptr != nullptr);

		for (int i = num - 1; i >= 0; i--)
		{
			if (ptr[i] == 0xffffffff) continue;

#if TORRENT_HAS_BUILTIN_CTZ
			std::uint32_t const v = ~aux::network_to_host(ptr[i]);
			return (num - i - 1) * 32 + __builtin_ctz(v);
#elif defined _MSC_VER
			std::uint32_t const v = ~aux::network_to_host(ptr[i]);
			DWORD pos;
			_BitScanForward(&pos, v);
			return (num - i - 1) * 32 + pos;
#else
			TORRENT_ASSERT_FAIL();
			return -1;
#endif
		}

		return num * 32;
	}
Пример #5
0
		void random_bytes(span<char> buffer)
		{
#ifdef TORRENT_BUILD_SIMULATOR
			// simulator

			for (auto& b : buffer) b = char(random(0xff));

#elif TORRENT_USE_CRYPTOAPI
			// windows

			aux::crypt_gen_random(buffer);

#elif TORRENT_USE_DEV_RANDOM
			// /dev/random

			static dev_random dev;
			dev.read(buffer);

#elif defined TORRENT_USE_LIBCRYPTO
			// openssl

			int r = RAND_bytes(reinterpret_cast<unsigned char*>(buffer.data())
				, int(buffer.size()));
			if (r != 1) aux::throw_ex<system_error>(errors::no_entropy);
#else
			// fallback

			for (auto& b : buffer) b = char(random(0xff));
#endif
		}
Пример #6
0
		void update(span<char const> data)
		{
			if (CryptHashData(m_hash, reinterpret_cast<BYTE const*>(data.data()), int(data.size()), 0) == false)
			{
				throw_ex<system_error>(error_code(GetLastError(), system_category()));
			}
		}
Пример #7
0
	void iterate_every_other_element(span<int, dynamic_range> av)
	{
		// pick every other element

		auto length = av.size() / 2;
#if _MSC_VER > 1800
		auto bounds = strided_bounds<1>({ length }, { 2 });
#else
		auto bounds = strided_bounds<1>(index<1>{ length }, index<1>{ 2 });
#endif
		strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);

		CHECK(strided.size() == length);
		CHECK(strided.bounds().index_bounds()[0] == length);
		for (auto i = 0; i < strided.size(); ++i)
		{
			CHECK(strided[i] == av[2 * i + 1]);
		}

		int idx = 0;
		for (auto num : strided)
		{
			CHECK(num == av[2 * idx + 1]);
			idx++;
		}
	}
	bool udp_tracker_connection::on_announce_response(span<char const> buf)
	{
		if (buf.size() < 20) return false;

		buf = buf.subspan(8);
		restart_read_timeout();

		tracker_response resp;

		resp.interval = aux::read_int32(buf);
		resp.min_interval = 60;
		resp.incomplete = aux::read_int32(buf);
		resp.complete = aux::read_int32(buf);
		int const num_peers = int(buf.size()) / 6;
		if ((buf.size() % 6) != 0)
		{
			fail(error_code(errors::invalid_tracker_response_length));
			return false;
		}

		boost::shared_ptr<request_callback> cb = requester();
#ifndef TORRENT_DISABLE_LOGGING
		if (cb)
		{
			cb->debug_log("<== UDP_TRACKER_RESPONSE [ url: %s ]", tracker_req().url.c_str());
		}
#endif

		if (!cb)
		{
			close();
			return true;
		}

		std::vector<peer_entry> peer_list;
		resp.peers4.reserve(num_peers);
		for (int i = 0; i < num_peers; ++i)
		{
			ipv4_peer_entry e;
			memcpy(&e.ip[0], buf.data(), 4);
			buf = buf.subspan(4);
			e.port = aux::read_uint16(buf);
			resp.peers4.push_back(e);
		}

		std::list<address> ip_list;
		for (std::vector<tcp::endpoint>::const_iterator i = m_endpoints.begin()
			, end(m_endpoints.end()); i != end; ++i)
		{
			ip_list.push_back(i->address());
		}

		cb->tracker_response(tracker_req(), m_target.address(), ip_list
			, resp);

		close();
		return true;
	}
Пример #9
0
	inline void crypt_gen_random(span<char> buffer)
	{
		static HCRYPTPROV provider = crypt_acquire_provider(PROV_RSA_FULL);
		if (!CryptGenRandom(provider, int(buffer.size())
			, reinterpret_cast<BYTE*>(buffer.data())))
		{
			throw_ex<system_error>(error_code(GetLastError(), system_category()));
		}
	}
Пример #10
0
	entry::entry(span<char const> v)
		: m_type(undefined_t)
	{
#if TORRENT_USE_ASSERTS
		m_type_queried = true;
#endif
		new(&data) string_type(v.data(), v.size());
		m_type = string_t;
	}
Пример #11
0
	allocation_slot stack_allocator::copy_buffer(span<char const> buf)
	{
		int const ret = int(m_storage.size());
		int const size = int(buf.size());
		if (size < 1) return {};
		m_storage.resize(ret + size);
		std::memcpy(&m_storage[ret], buf.data(), numeric_cast<std::size_t>(size));
		return allocation_slot(ret);
	}
Пример #12
0
	// allocate an uninitialized buffer of the specified size
	// and copy the initialization range into the start of the buffer
	buffer(std::size_t const size, span<char const> initialize)
		: buffer(size)
	{
		TORRENT_ASSERT(initialize.size() <= size);
		if (!initialize.empty())
		{
			std::memcpy(m_begin, initialize.data(), (std::min)(initialize.size(), size));
		}
	}
Пример #13
0
void GLVertexBuffer::upload(span<const byte> a_data)
{
	assert(GLStateBuffer::isBegun());
	assert(m_initialized);
	if (!a_data.empty())
	{
		glBindBuffer(GLenum(m_bufferType), m_id);
		glBufferData(GLenum(m_bufferType), a_data.length_bytes(), a_data.data(), GLenum(m_drawUsage));
	}
}
Пример #14
0
		void update(span<char const> data)
		{
			if (CryptHashData(m_hash, reinterpret_cast<BYTE const*>(data.data()), int(data.size()), 0) == false)
			{
#ifndef BOOST_NO_EXCEPTIONS
				throw system_error(error_code(GetLastError(), system_category()));
#else
				std::terminate();
#endif
			}
		}
Пример #15
0
void item::assign(entry v, span<char const> salt
	, sequence_number const seq
	, public_key const& pk, signature const& sig)
{

	m_pk = pk;
	m_sig = sig;
	m_salt.assign(salt.data(), salt.size());
	m_seq = seq;
	m_mutable = true;
	m_value = std::move(v);
}
Пример #16
0
	inline void crypt_gen_random(span<char> buffer)
	{
		static HCRYPTPROV provider = crypt_acquire_provider(PROV_RSA_FULL);
		if (!CryptGenRandom(provider, int(buffer.size())
			, reinterpret_cast<BYTE*>(buffer.data())))
		{
#ifndef BOOST_NO_EXCEPTIONS
			throw system_error(error_code(GetLastError(), system_category()));
#else
			std::terminate();
#endif
		}
	}
	bool udp_tracker_connection::on_scrape_response(span<char const> buf)
	{
		using namespace libtorrent::aux;

		restart_read_timeout();
		int const action = aux::read_int32(buf);
		std::uint32_t const transaction = read_uint32(buf);

		if (transaction != m_transaction_id)
		{
			fail(error_code(errors::invalid_tracker_transaction_id));
			return false;
		}

		if (action == action_error)
		{
			fail(error_code(errors::tracker_failure), -1
				, std::string(buf.data(), buf.size()).c_str());
			return true;
		}

		if (action != action_scrape)
		{
			fail(error_code(errors::invalid_tracker_action));
			return true;
		}

		if (buf.size() < 12)
		{
			fail(error_code(errors::invalid_tracker_response_length));
			return true;
		}

		int const complete = aux::read_int32(buf);
		int const downloaded = aux::read_int32(buf);
		int const incomplete = aux::read_int32(buf);

		boost::shared_ptr<request_callback> cb = requester();
		if (!cb)
		{
			close();
			return true;
		}

		cb->tracker_scrape_response(tracker_req()
			, complete, incomplete, downloaded, -1);

		close();
		return true;
	}
Пример #18
0
void item::assign(entry v, span<char const> salt
	, sequence_number const seq, public_key const& pk, secret_key const& sk)
{
	char buffer[1000];
	int bsize = bencode(buffer, v);
	TORRENT_ASSERT(bsize <= 1000);
	m_sig = sign_mutable_item(span<char const>(buffer, bsize)
		, salt, seq, pk, sk);
	m_salt.assign(salt.data(), salt.size());
	m_pk = pk;
	m_seq = seq;
	m_mutable = true;
	m_value = std::move(v);
}
Пример #19
0
bool item::assign(bdecode_node const& v, span<char const> salt
	, sequence_number const seq, public_key const& pk, signature const& sig)
{
	TORRENT_ASSERT(v.data_section().size() <= 1000);
	if (!verify_mutable_item(v.data_section(), salt, seq, pk, sig))
		return false;
	m_pk = pk;
	m_sig = sig;
	if (salt.size() > 0)
		m_salt.assign(salt.data(), salt.size());
	else
		m_salt.clear();
	m_seq = seq;
	m_mutable = true;

	m_value = v;
	return true;
}
Пример #20
0
	int count_trailing_ones_sw(span<std::uint32_t const> buf)
	{
		auto const num = int(buf.size());
		std::uint32_t const* ptr = buf.data();

		TORRENT_ASSERT(num >= 0);
		TORRENT_ASSERT(ptr != nullptr);

		for (int i = num - 1; i >= 0; i--)
		{
			if (ptr[i] == 0xffffffff) continue;
			std::uint32_t v = ~aux::network_to_host(ptr[i]);

			for (int k = 0; k < 32; ++k, v >>= 1)
			{
				if ((v & 1) == 0) continue;
				return (num - i - 1) * 32 + k;
			}
		}

		return num * 32;
	}
Пример #21
0
void BufferObject::set_subdata(GLintptr offset, span<const gsl::byte> data) {
  bind();
  GL(glBufferSubData(GLenum(target_), offset, data.size(), data.data()));
}
Пример #22
0
 void assign(span<char const> s)
 {
     TORRENT_ASSERT(s.size() >= N / 8);
     size_t const sl = s.size() < size() ? s.size() : size();
     std::memcpy(m_number, s.data(), sl);
 }
	bool udp_tracker_connection::on_receive(udp::endpoint const& ep
		, span<char const> const buf)
	{
#ifndef TORRENT_DISABLE_LOGGING
		boost::shared_ptr<request_callback> cb = requester();
#endif

		// ignore resposes before we've sent any requests
		if (m_state == action_error)
		{
#ifndef TORRENT_DISABLE_LOGGING
			if (cb) cb->debug_log("<== UDP_TRACKER [ m_action == error ]");
#endif
			return false;
		}

		if (m_abort)
		{
#ifndef TORRENT_DISABLE_LOGGING
			if (cb) cb->debug_log("<== UDP_TRACKER [ aborted]");
#endif
			return false;
		}

		// ignore packet not sent from the tracker
		// if m_target is inaddr_any, it suggests that we
		// sent the packet through a proxy only knowing
		// the hostname, in which case this packet might be for us
		if (!is_any(m_target.address()) && m_target != ep)
		{
#ifndef TORRENT_DISABLE_LOGGING
			if (cb) cb->debug_log("<== UDP_TRACKER [ unexpected source IP: %s "
				"expected: %s ]"
				, print_endpoint(ep).c_str()
				, print_endpoint(m_target).c_str());
#endif
			return false;
		}

#ifndef TORRENT_DISABLE_LOGGING
		if (cb) cb->debug_log("<== UDP_TRACKER_PACKET [ size: %d ]"
			, int(buf.size()));
#endif

		// ignore packets smaller than 8 bytes
		if (buf.size() < 8) return false;

		span<const char> ptr = buf;
		int const action = aux::read_int32(ptr);
		std::uint32_t const transaction = aux::read_uint32(ptr);

#ifndef TORRENT_DISABLE_LOGGING
		if (cb) cb->debug_log("*** UDP_TRACKER_PACKET [ action: %d ]", action);
#endif

		// ignore packets with incorrect transaction id
		if (m_transaction_id != transaction)
		{
#ifndef TORRENT_DISABLE_LOGGING
		if (cb) cb->debug_log("*** UDP_TRACKER_PACKET [ tid: %x ]"
				, int(transaction));
#endif
			return false;
		}

		if (action == action_error)
		{
			fail(error_code(errors::tracker_failure), -1
				, std::string(buf.data(), buf.size()).c_str());
			return true;
		}

		// ignore packets that's not a response to our message
		if (action != m_state)
		{
#ifndef TORRENT_DISABLE_LOGGING
			if (cb) cb->debug_log("*** UDP_TRACKER_PACKET [ unexpected action: %d "
				" expected: %d ]", action, m_state);
#endif
			return false;
		}

		restart_read_timeout();

#ifndef TORRENT_DISABLE_LOGGING
		if (cb)
			cb->debug_log("*** UDP_TRACKER_RESPONSE [ tid: %x ]"
				, int(transaction));
#endif

		switch (m_state)
		{
			case action_connect:
				return on_connect_response(buf);
			case action_announce:
				return on_announce_response(buf);
			case action_scrape:
				return on_scrape_response(buf);
			default: break;
		}
		return false;
	}
Пример #24
0
    void CopeOtExtSender::send(
        span<ZpNumber> messages,
        Channel& chl)
    {
        auto fieldSize = messages[0].mField->bitCount();

        // round up
        u64 numOtExt = roundUpTo(messages.size() * fieldSize, 128);
        u64 numSuperBlocks = (numOtExt / 128 + copeSuperBlkSize - 1) / copeSuperBlkSize;
        //u64 numBlocks = numSuperBlocks * copeSuperBlkSize;

        // a uNum that will be used to transpose the sender's matrix
        std::array<block, copeSuperBlkSize> t;
        std::vector<std::array<block, copeSuperBlkSize>> u(128 * copeCommStepSize);

        //std::array<block, 128> choiceMask;
        block delta = *(block*)mBaseChoiceBits.data();

        //for (u64 i = 0; i < 128; ++i)
        //{
        //    if (mBaseChoiceBits[i]) choiceMask[i] = AllOneBlock;
        //    else choiceMask[i] = ZeroBlock;
        //}


        auto* mIter = messages.data();

        block * uIter = (block*)u.data() + copeSuperBlkSize * 128 * copeCommStepSize;
        block * uEnd = uIter;

        ZpField field;
        field.setParameters(ZpParam128);

        std::vector<ZpNumber> g;
        //qq.reserve(copeSuperBlkSize * field.bitCount());
        //for (u64 i = 0; i < copeSuperBlkSize * field.bitCount(); ++i)
        //    qq.emplace_back(field);

        std::cout << IoStream::lock;
        g.reserve(field.bitCount());
        for (u64 i = 0; i < field.bitCount(); ++i)
        {
            g.emplace_back(field, 2);
            g[i].powEq(i);
            std::cout << "g[" << i << "] " << g[i] << std::endl;
        }

        std::cout << IoStream::unlock;

        std::array<ZpNumber, copeSuperBlkSize> q
         {
            ZpNumber(field),ZpNumber(field),ZpNumber(field),ZpNumber(field),
            ZpNumber(field), ZpNumber(field), ZpNumber(field), ZpNumber(field)
        };

        ZpNumber uNum(field);

        for (u64 superBlkIdx = 0; superBlkIdx < numSuperBlocks; ++superBlkIdx)
        {

            if (uIter == uEnd)
            {
                u64 step = std::min<u64>(numSuperBlocks - superBlkIdx, (u64)copeCommStepSize);
                chl.recv((u8*)u.data(), step * copeSuperBlkSize * 128 * sizeof(block));
                uIter = (block*)u.data();
            }

            for (u64 j = 0; j < copeSuperBlkSize; ++j)
            {
                //qq[j] = 0;
                mIter[j] = 0;
            }
            std::cout << IoStream::lock;

            // transpose 128 columns at at time. Each column will be 128 * copeSuperBlkSize = 1024 bits long.
            for (u64 colIdx = 0; colIdx < 128; ++colIdx)
            {
                // generate the columns using AES-NI in counter mode.
                mGens[colIdx].mAes.ecbEncCounterMode(mGens[colIdx].mBlockIdx, copeSuperBlkSize, t.data());
                mGens[colIdx].mBlockIdx += copeSuperBlkSize;

                for (u64 i = 0; i < copeSuperBlkSize; ++i)
                {
                    q[i].fromBytes((u8*)&t[i]);
                }

                if (this->mBaseChoiceBits[colIdx])
                {
                    for (u64 i = 0; i < copeSuperBlkSize; ++i)
                    {
                        uNum.fromBytes((u8*)&uIter[i]);
                        q[i] -= uNum;
                    }
                }



                for (u64 i = 0; i < copeSuperBlkSize; ++i)
                {
                    //std::cout <<  (mBaseChoiceBits[colIdx]? "t0x" : "t0 ") <<"[" << i << "][" << colIdx << "] = " << q[i] <<"   " << mBaseChoiceBits[colIdx] << "\n\n"<<std::endl;
                    std::cout << "q[" << colIdx << "][" << i << "] = " << q[i] << std::endl;
                    q[i] *= g[colIdx];

                    mIter[i] += q[i];
                }

                uIter += 8;
            }
            std::cout << IoStream::unlock;

            mIter += 8;

        }


        static_assert(gOtExtBaseOtCount == 128, "expecting 128");
    }
	bool utp_socket_manager::incoming_packet(std::weak_ptr<utp_socket_interface> socket
		, udp::endpoint const& ep, span<char const> p)
	{
//		UTP_LOGV("incoming packet size:%d\n", size);

		if (p.size() < sizeof(utp_header)) return false;

		utp_header const* ph = reinterpret_cast<utp_header const*>(p.data());

//		UTP_LOGV("incoming packet version:%d\n", int(ph->get_version()));

		if (ph->get_version() != 1) return false;

		const time_point receive_time = clock_type::now();

		// parse out connection ID and look for existing
		// connections. If found, forward to the utp_stream.
		std::uint16_t id = ph->connection_id;

		// first test to see if it's the same socket as last time
		// in most cases it is
		if (m_last_socket
			&& utp_match(m_last_socket, ep, id))
		{
			return utp_incoming_packet(m_last_socket, p, ep, receive_time);
		}

		std::pair<socket_map_t::iterator, socket_map_t::iterator> r =
			m_utp_sockets.equal_range(id);

		for (; r.first != r.second; ++r.first)
		{
			if (!utp_match(r.first->second, ep, id)) continue;
			bool ret = utp_incoming_packet(r.first->second, p, ep, receive_time);
			if (ret) m_last_socket = r.first->second;
			return ret;
		}

//		UTP_LOGV("incoming packet id:%d source:%s\n", id, print_endpoint(ep).c_str());

		if (!m_sett.get_bool(settings_pack::enable_incoming_utp))
			return false;

		// if not found, see if it's a SYN packet, if it is,
		// create a new utp_stream
		if (ph->get_type() == ST_SYN)
		{
			// possible SYN flood. Just ignore
			if (int(m_utp_sockets.size()) > m_sett.get_int(settings_pack::connections_limit) * 2)
				return false;

//			UTP_LOGV("not found, new connection id:%d\n", m_new_connection);

			std::shared_ptr<socket_type> c(new (std::nothrow) socket_type(m_ios));
			if (!c) return false;

			TORRENT_ASSERT(m_new_connection == -1);
			// create the new socket with this ID
			m_new_connection = id;

			instantiate_connection(m_ios, aux::proxy_settings(), *c
				, m_ssl_context, this, true, false);

			utp_stream* str = nullptr;
#ifdef TORRENT_USE_OPENSSL
			if (is_ssl(*c))
				str = &c->get<ssl_stream<utp_stream>>()->next_layer();
			else
#endif
				str = c->get<utp_stream>();

			TORRENT_ASSERT(str);
			int link_mtu, utp_mtu;
			mtu_for_dest(ep.address(), link_mtu, utp_mtu);
			utp_init_mtu(str->get_impl(), link_mtu, utp_mtu);
			utp_init_socket(str->get_impl(), socket);
			bool ret = utp_incoming_packet(str->get_impl(), p, ep, receive_time);
			if (!ret) return false;
			m_cb(c);
			// the connection most likely changed its connection ID here
			// we need to move it to the correct ID
			return true;
		}

		if (ph->get_type() == ST_RESET) return false;

		// #error send reset

		return false;
	}
Пример #26
0
 constexpr span(const span<OtherElementType, OtherExtent> &other)
     : data_(reinterpret_cast<pointer>(other.data())), size_(other.size()) {
   assert(extent == dynamic_extent || other.size() == extent);
 }
Пример #27
0
bool dht_tracker::incoming_packet(udp::endpoint const& ep
                                  , span<char const> const buf)
{
    int const buf_size = int(buf.size());
    if (buf_size <= 20
            || buf.front() != 'd'
            || buf.back() != 'e') return false;

    m_counters.inc_stats_counter(counters::dht_bytes_in, buf_size);
    // account for IP and UDP overhead
    m_counters.inc_stats_counter(counters::recv_ip_overhead_bytes
                                 , ep.address().is_v6() ? 48 : 28);
    m_counters.inc_stats_counter(counters::dht_messages_in);

    if (m_settings.ignore_dark_internet && ep.address().is_v4())
    {
        address_v4::bytes_type b = ep.address().to_v4().to_bytes();

        // these are class A networks not available to the public
        // if we receive messages from here, that seems suspicious
        static std::uint8_t const class_a[] = { 3, 6, 7, 9, 11, 19, 21, 22, 25
                                                , 26, 28, 29, 30, 33, 34, 48, 51, 56
                                              };

        if (std::find(std::begin(class_a), std::end(class_a), b[0]) != std::end(class_a))
        {
            m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
            return true;
        }
    }

    if (!m_blocker.incoming(ep.address(), clock_type::now(), m_log))
    {
        m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
        return true;
    }

    TORRENT_ASSERT(buf_size > 0);

    int pos;
    error_code err;
    int ret = bdecode(buf.data(), buf.data() + buf_size, m_msg, err, &pos, 10, 500);
    if (ret != 0)
    {
        m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
#ifndef TORRENT_DISABLE_LOGGING
        m_log->log_packet(dht_logger::incoming_message, buf, ep);
#endif
        return false;
    }

    if (m_msg.type() != bdecode_node::dict_t)
    {
        m_counters.inc_stats_counter(counters::dht_messages_in_dropped);
#ifndef TORRENT_DISABLE_LOGGING
        m_log->log_packet(dht_logger::incoming_message, buf, ep);
#endif
        // it's not a good idea to send a response to an invalid messages
        return false;
    }

#ifndef TORRENT_DISABLE_LOGGING
    m_log->log_packet(dht_logger::incoming_message, buf, ep);
#endif

    libtorrent::dht::msg m(m_msg, ep);
    m_dht.incoming(m);
#if TORRENT_USE_IPV6
    m_dht6.incoming(m);
#endif
    return true;
}
Пример #28
0
    void DrrnPsiClient::recv(Channel s0, Channel s1, span<block> inputs)
    {
        if (inputs.size() != mClientSetSize)
            throw std::runtime_error(LOCATION);

        Matrix<u64> bins(mNumSimpleBins, mBinSize);
        std::vector<u64> binSizes(mNumSimpleBins);
        u64 cuckooSlotsPerBin = (mCuckooParams.numBins() + mNumSimpleBins) / mNumSimpleBins;

        // Simple hashing with a PRP
        std::vector<block> hashs(inputs.size());
        AES hasher(mHashingSeed);
        u64 numCuckooBins = mCuckooParams.numBins();
        for (u64 i = 0; i < u64(inputs.size());)
        {
            auto min = std::min<u64>(inputs.size() - i, 8);
            auto end = i + min;
            hasher.ecbEncBlocks(inputs.data() + i, min, hashs.data() + i);
            for (; i < end; ++i)
            {
                hashs[i] = hashs[i] ^ inputs[i];
                for (u64 j = 0; j < mCuckooParams.mNumHashes; ++j)
                {
                    u64 idx = CuckooIndex<>::getHash(hashs[i], j, numCuckooBins) * mNumSimpleBins / mCuckooParams.numBins();

                    // insert this item in this bin. pack together the hash index and input index
                    bins(idx, binSizes[idx]++) = (j << 56) | i;
                }

                //if (!i)
                //{
                //    ostreamLock(std::cout) << "cinput[" << i << "] = " << inputs[i] << " -> " << hashs[i] << " ("
                //        << CuckooIndex<>::getHash(hashs[i], 0, numCuckooBins) << ", "
                //        << CuckooIndex<>::getHash(hashs[i], 1, numCuckooBins) << ", "
                //        << CuckooIndex<>::getHash(hashs[i], 2, numCuckooBins) << ")"
                //        << std::endl;
                //}
            }
        }



        // power of 2
        u64 numLeafBlocks = (cuckooSlotsPerBin + mBigBlockSize * 128 - 1) / (mBigBlockSize * 128);
        u64 gDepth = 2;
        u64 kDepth = std::max<u64>(gDepth, log2floor(numLeafBlocks)) - gDepth;
        u64 groupSize = (numLeafBlocks + (u64(1) << kDepth) - 1) / (u64(1) << kDepth);
        if (groupSize > 8) throw std::runtime_error(LOCATION);

        //std::cout << "kDepth:   " << kDepth << std::endl;
        //std::cout << "mBinSize: " << mBinSize << std::endl;

        u64 numQueries = mNumSimpleBins * mBinSize;
        auto permSize = numQueries * mBigBlockSize;

        // mask generation
        block rSeed = CCBlock;// mPrng.get<block>();
        AES rGen(rSeed);


        std::vector<block> shares(mClientSetSize * mCuckooParams.mNumHashes), r(permSize), piS1(permSize), s(permSize);
        //std::vector<u32> rIdxs(numQueries);
        //std::vector<u64> sharesIdx(shares.size());

        //TODO("use real masks");
        //memset(r.data(), 0, r.size() * sizeof(block));
        rGen.ecbEncCounterMode(r.size() * 0, r.size(), r.data());
        rGen.ecbEncCounterMode(r.size() * 1, r.size(), piS1.data());
        rGen.ecbEncCounterMode(r.size() * 2, r.size(), s.data());

        //auto encIter = enc.begin();
        auto shareIter = shares.begin();
        //auto shareIdxIter = sharesIdx.begin();
        u64 queryIdx = 0, dummyPermIdx = mClientSetSize * mCuckooParams.mNumHashes;

        std::unordered_map<u64, u64> inputMap;
        inputMap.reserve(mClientSetSize * mCuckooParams.mNumHashes);

        std::vector<u32> pi(permSize);
        auto piIter = pi.begin();


        u64 keySize = kDepth + 1 + groupSize;
        u64 mask = (u64(1) << 56) - 1;
        auto binIter = bins.begin();
        for (u64 bIdx = 0; bIdx < mNumSimpleBins; ++bIdx)
        {
            u64 i = 0;

            auto binOffset = (bIdx * numCuckooBins + mNumSimpleBins - 1) / mNumSimpleBins;

            std::vector<block> k0(keySize * mBinSize), k1(keySize * mBinSize);
            //std::vector<u64> idx0(mBinSize), idx1(mBinSize);
            auto k0Iter = k0.data(), k1Iter = k1.data();
            //auto idx0Iter = idx0.data(), idx1Iter = idx1.data();

            for (; i < binSizes[bIdx]; ++i)
            {
                span<block>
                    kk0(k0Iter, kDepth + 1),
                    g0(k0Iter + kDepth + 1, groupSize),
                    kk1(k1Iter, kDepth + 1),
                    g1(k1Iter + kDepth + 1, groupSize);

                k0Iter += keySize;
                k1Iter += keySize;

                u8 hashIdx = *binIter >> 56;
                u64 itemIdx = *binIter & mask;
                u64 cuckooIdx = CuckooIndex<>::getHash(hashs[itemIdx], hashIdx, numCuckooBins) - binOffset;
                ++binIter;

                auto bigBlockoffset = cuckooIdx % mBigBlockSize;
                auto bigBlockIdx = cuckooIdx / mBigBlockSize;

                BgiPirClient::keyGen(bigBlockIdx, mPrng.get<block>(), kk0, g0, kk1, g1);



                // the index of the mask that will mask this item
                auto rIdx = *piIter = itemIdx * mCuckooParams.mNumHashes + hashIdx * mBigBlockSize + bigBlockoffset;

                // the masked value that will be inputted into the PSI
                *shareIter = r[rIdx] ^ inputs[itemIdx];
                //*shareIter = inputs[itemIdx];

                //if (itemIdx == 0)
                //    ostreamLock(std::cout)
                //    << "item[" << i << "]    bin " << bIdx
                //    << " block " << bigBlockIdx 
                //    << " offset " << bigBlockoffset 
                //    << " psi " << *shareIter << std::endl;

                // This will be used to map itemed items in the intersection back to their input item
                inputMap.insert({ queryIdx, itemIdx });

                ++shareIter;
                ++piIter;
                ++queryIdx;
            }

            u64 rem = mBinSize - i;


            binIter += rem;
            for (u64 i = 0; i < rem; ++i)
            {
                *piIter++ = dummyPermIdx++;
            }

            //s0.asyncSendCopy(k0);
            //s0.asyncSendCopy(k1);
            //s1.asyncSendCopy(k1);
            //s1.asyncSendCopy(k0);

            s0.asyncSend(std::move(k0));
            s1.asyncSend(std::move(k1));

        }

        std::vector<u32> pi1(permSize), pi0(permSize), pi1Inv(permSize);
        for (u32 i = 0; i < pi1.size(); ++i) pi1[i] = i;
        PRNG prng(rSeed ^ OneBlock);
        std::random_shuffle(pi1.begin(), pi1.end(), prng);


        //std::vector<block> pi1RS(pi.size());
        for (u64 i = 0; i < permSize; ++i)
        {
            //auto pi1i = pi1[i];
            //pi1RS[i] = r[pi1i] ^ s[pi1i];

            pi1Inv[pi1[i]] = i;
            //std::cout << "pi1(r + s)[" << i << "] " << pi1RS[i] << std::endl;
        }
        std::vector<block> piS0(r.size());
        for (u64 i = 0; i < permSize; ++i)
        {
            //std::cout << "r[" << i << "] " << r[i] << std::endl;
            //std::cout << "pi(r + s)[" << i << "]=" << (r[pi[i]] ^ s[pi[i]]) << std::endl;


            pi0[i] = pi1Inv[pi[i]];
            piS0[i] = piS1[i] ^ s[pi[i]];
            //std::cout << "pi (r + s)[" << i << "] = " << (r[pi[i]] ^ s[pi[i]]) << " = " << r[pi[i]] << " ^ " << s[pi[i]] << " c " << pi[i] << std::endl;
            //std::cout << "pi`(r + s)[" << i << "] = " << pi1RS[pi0[i]]  <<" c " << pi0[pi1[i]] << std::endl;
        }

        s0.asyncSend(std::move(pi0));
        s0.asyncSend(std::move(piS0));
        //rGen.ecbEncBlocks(r.data(), r.size(), r.data());
        //for (u64 i = 0; i < shares.size(); ++i)
        //{
        //    std::cout << IoStream::lock << "cshares[" << i << "] " << shares[i] << " input[" << sharesIdx[i]<<"]" << std::endl << IoStream::unlock;
        //}
        mPsi.sendInput(shares, s0);

        mIntersection.reserve(mPsi.mIntersection.size());
        for (u64 i = 0; i < mPsi.mIntersection.size(); ++i) {
            // divide index by #hashes
            mIntersection.emplace(inputMap[mPsi.mIntersection[i]]);
        }

    }
Пример #29
0
item::item(public_key const& pk, span<char const> salt)
	: m_salt(salt.data(), salt.size())
	, m_pk(pk)
	, m_seq(0)
	, m_mutable(true)
{}
Пример #30
0
	TORRENT_EXTRA_EXPORT void xml_parse(span<char const> input
		, std::function<void(int,char const*,int,char const*,int)> callback)
	{
		char const* p = input.data();
		char const* end = input.data() + input.size();
		for(;p != end; ++p)
		{
			char const* start = p;
			int token;
			// look for tag start
			for(; p != end && *p != '<'; ++p);

			if (p != start)
			{
				token = xml_string;
				const int name_len = p - start;
				callback(token, start, name_len, nullptr, 0);
			}

			if (p == end) break;

			// skip '<'
			++p;
			if (p != end && p+8 < end && string_begins_no_case("![CDATA[", p))
			{
				// CDATA. match '![CDATA['
				p += 8;
				start = p;
				while (p != end && !string_begins_no_case("]]>", p-2)) ++p;

				// parse error
				if (p == end)
				{
					token = xml_parse_error;
					start = "unexpected end of file";
					callback(token, start, int(strlen(start)), nullptr, 0);
					break;
				}

				token = xml_string;
				const int name_len = p - start - 2;
				callback(token, start, name_len, nullptr, 0);
				continue;
			}

			// parse the name of the tag.
			for (start = p; p != end && *p != '>' && !is_space(*p); ++p);

			char const* tag_name_end = p;

			// skip the attributes for now
			for (; p != end && *p != '>'; ++p);

			// parse error
			if (p == end)
			{
				token = xml_parse_error;
				start = "unexpected end of file";
				callback(token, start, int(strlen(start)), nullptr, 0);
				break;
			}

			TORRENT_ASSERT(*p == '>');

			char const* tag_end = p;
			if (*start == '/')
			{
				++start;
				token = xml_end_tag;
				const int name_len = tag_name_end - start;
				callback(token, start, name_len, nullptr, 0);
			}
			else if (*(p-1) == '/')
			{
				token = xml_empty_tag;
				const int name_len = (std::min)(tag_name_end - start, p - start - 1);
				callback(token, start, name_len, nullptr, 0);
				tag_end = p - 1;
			}
			else if (*start == '?' && *(p-1) == '?')
			{
				++start;
				token = xml_declaration_tag;
				const int name_len = (std::min)(tag_name_end - start, p - start - 1);
				callback(token, start, name_len, nullptr, 0);
				tag_end = p - 1;
			}
			else if (start + 5 < p && std::memcmp(start, "!--", 3) == 0 && std::memcmp(p-2, "--", 2) == 0)
			{
				start += 3;
				token = xml_comment;
				const int name_len = tag_name_end - start - 2;
				callback(token, start, name_len, nullptr, 0);
				tag_end = p - 2;
				continue;
			}
			else
			{
				token = xml_start_tag;
				const int name_len = tag_name_end - start;
				callback(token, start, name_len, nullptr, 0);
			}

			// parse attributes
			for (char const* i = tag_name_end; i < tag_end; ++i)
			{
				char const* val_start = nullptr;

				// find start of attribute name
				for (; i != tag_end && is_space(*i); ++i);
				if (i == tag_end) break;
				start = i;
				// find end of attribute name
				for (; i != tag_end && *i != '=' && !is_space(*i); ++i);
				const int name_len = i - start;

				// look for equality sign
				for (; i != tag_end && *i != '='; ++i);

				// no equality sign found. Report this as xml_tag_content
				// instead of a series of key value pairs
				if (i == tag_end)
				{
					token = xml_tag_content;
					callback(token, start, i - start, nullptr, 0);
					break;
				}

				++i;
				for (; i != tag_end && is_space(*i); ++i);
				// check for parse error (values must be quoted)
				if (i == tag_end || (*i != '\'' && *i != '\"'))
				{
					token = xml_parse_error;
					start = "unquoted attribute value";
					callback(token, start, int(strlen(start)), nullptr, 0);
					break;
				}
				char quote = *i;
				++i;
				val_start = i;
				for (; i != tag_end && *i != quote; ++i);
				// parse error (missing end quote)
				if (i == tag_end)
				{
					token = xml_parse_error;
					start = "missing end quote on attribute";
					callback(token, start, int(strlen(start)), nullptr, 0);
					break;
				}
				const int val_len = i - val_start;
				token = xml_attribute;
				callback(token, start, name_len, val_start, val_len);
			}
		}
	}