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; }
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; }
// 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)); } }
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; }
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 }
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; }
bool tracker_manager::incoming_packet(char const* hostname , span<char const> const buf) { TORRENT_ASSERT(is_single_thread()); // ignore packets smaller than 8 bytes if (buf.size() < 16) return false; // the first word is the action, if it's not [0, 3] // it's not a valid udp tracker response span<const char> ptr = buf; std::uint32_t const action = aux::read_uint32(ptr); if (action > 3) return false; std::uint32_t const transaction = aux::read_uint32(ptr); auto const i = m_udp_conns.find(transaction); if (i == m_udp_conns.end()) { #ifndef TORRENT_DISABLE_LOGGING // now, this may not have been meant to be a tracker response, // but chances are pretty good, so it's probably worth logging m_ses.session_log("incoming UDP tracker packet from %s has invalid " "transaction ID (%x)", hostname, int(transaction)); #endif return false; } std::shared_ptr<udp_tracker_connection> const p = i->second; // on_receive() may remove the tracker connection from the list return p->on_receive_hostname(hostname, buf); }
ImageFileInfo DetectImageFormat(span<uint8_t> data) { ImageFileInfo info; stbi__context ctx; stbi__start_mem(&ctx, &data[0], data.size_bytes()); int comp; if (stbi__bmp_info(&ctx, &info.width, &info.height, &comp)) { info.hasAlpha = (comp == 4); info.format = ImageFileFormat::BMP; return info; } TjDecompressHandle handle; if (tjDecompressHeader(handle, &data[0], data.size_bytes(), &info.width, &info.height) == 0) { info.hasAlpha = false; info.format = ImageFileFormat::JPEG; return info; } if (DetectTga(data, info)) { return info; } // Not a very good heuristic if (data.size() == 256 * 256) { info.width = 256; info.height = 256; info.hasAlpha = true; info.format = ImageFileFormat::FNTART; return info; } return info; }
bool udp_tracker_connection::on_connect_response(span<char const> buf) { // ignore packets smaller than 16 bytes if (buf.size() < 16) return false; restart_read_timeout(); // skip header buf = buf.subspan(8); // reset transaction update_transaction_id(); std::uint64_t const connection_id = aux::read_int64(buf); std::lock_guard<std::mutex> l(m_cache_mutex); connection_cache_entry& cce = m_connection_cache[m_target.address()]; cce.connection_id = connection_id; cce.expires = aux::time_now() + seconds(m_man.settings().get_int(settings_pack::udp_tracker_token_expiry)); if (0 == (tracker_req().kind & tracker_request::scrape_request)) send_udp_announce(); else if (0 != (tracker_req().kind & tracker_request::scrape_request)) send_udp_scrape(); return true; }
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())); } }
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 }
explicit enumerated_value_range(span<const T> v) noexcept : _begin(v.data()) , _end(v.data()+v.size()) { assert(_begin <= _end); }
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; }
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())); } }
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; }
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); }
bool tracker_manager::incoming_packet(udp::endpoint const& ep , span<char const> const buf) { TORRENT_ASSERT(is_single_thread()); // ignore packets smaller than 8 bytes if (buf.size() < 8) { #ifndef TORRENT_DISABLE_LOGGING if (m_ses.should_log()) { m_ses.session_log("incoming packet from %s, not a UDP tracker message " "(%d Bytes)", print_endpoint(ep).c_str(), int(buf.size())); } #endif return false; } // the first word is the action, if it's not [0, 3] // it's not a valid udp tracker response span<const char> ptr = buf; std::uint32_t const action = aux::read_uint32(ptr); if (action > 3) return false; std::uint32_t const transaction = aux::read_uint32(ptr); auto const i = m_udp_conns.find(transaction); if (i == m_udp_conns.end()) { #ifndef TORRENT_DISABLE_LOGGING if (m_ses.should_log()) { m_ses.session_log("incoming UDP tracker packet from %s has invalid " "transaction ID (%x)", print_endpoint(ep).c_str() , transaction); } #endif return false; } std::shared_ptr<udp_tracker_connection> const p = i->second; // on_receive() may remove the tracker connection from the list return p->on_receive(ep, buf); }
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 } }
void CopeOtExtSender::setBaseOts(span<block> baseRecvOts, const BitVector & choices) { if (baseRecvOts.size() != gOtExtBaseOtCount || choices.size() != gOtExtBaseOtCount) throw std::runtime_error("not supported/implemented"); mBaseChoiceBits = choices; for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i].SetSeed(baseRecvOts[i]); } }
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); }
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 } }
void CopeOtExtReceiver::setBaseOts(span<std::array<block, 2>> baseOTs) { if (baseOTs.size() != gOtExtBaseOtCount) throw std::runtime_error(LOCATION); for (u64 i = 0; i < gOtExtBaseOtCount; i++) { mGens[i][0].SetSeed(baseOTs[i][0]); mGens[i][1].SetSeed(baseOTs[i][1]); } mHasBase = true; }
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); }
// this has to be thread safe and atomic. i.e. on posix systems it has to be // turned into a series of pread() calls std::int64_t file::readv(std::int64_t file_offset, span<iovec_t const> bufs , error_code& ec, open_mode_t flags) { if (m_file_handle == INVALID_HANDLE_VALUE) { #ifdef TORRENT_WINDOWS ec = error_code(ERROR_INVALID_HANDLE, system_category()); #else ec = error_code(boost::system::errc::bad_file_descriptor, generic_category()); #endif return -1; } TORRENT_ASSERT((m_open_mode & open_mode::rw_mask) == open_mode::read_only || (m_open_mode & open_mode::rw_mask) == open_mode::read_write); TORRENT_ASSERT(!bufs.empty()); TORRENT_ASSERT(is_open()); #if TORRENT_USE_PREADV TORRENT_UNUSED(flags); std::int64_t ret = iov(&::preadv, native_handle(), file_offset, bufs, ec); #else // there's no point in coalescing single buffer writes if (bufs.size() == 1) { flags &= ~open_mode::coalesce_buffers; } iovec_t tmp; span<iovec_t const> tmp_bufs = bufs; if (flags & open_mode::coalesce_buffers) { if (!coalesce_read_buffers(tmp_bufs, tmp)) // ok, that failed, don't coalesce this read flags &= ~open_mode::coalesce_buffers; } #if TORRENT_USE_PREAD std::int64_t ret = iov(&::pread, native_handle(), file_offset, tmp_bufs, ec); #else std::int64_t ret = iov(&::read, native_handle(), file_offset, tmp_bufs, ec); #endif if (flags & open_mode::coalesce_buffers) coalesce_read_buffers_end(bufs , tmp.data(), !ec); #endif return ret; }
void GLVertexBuffer::setVertexAttributes(span<const VertexAttribute> a_attributes) { assert(GLStateBuffer::isBegun()); assert(m_initialized); assert(!a_attributes.empty()); uint64 offset = 0; uint stride = 0; if (a_attributes.size() == 1) stride = 0; else { for (uint i = 0; i < a_attributes.size(); ++i) { const VertexAttribute& attribute = a_attributes[i]; stride += attribute.numElements * (attribute.format == VertexAttribute::EFormat::UNSIGNED_BYTE ? 1 : 4); } } for (uint i = 0; i < a_attributes.size(); ++i) { const VertexAttribute& attribute = a_attributes[i]; const bool isFloatType = (attribute.format == VertexAttribute::EFormat::FLOAT) || attribute.normalize; const uint dataSize = ((attribute.format == VertexAttribute::EFormat::UNSIGNED_BYTE) ? 1 : 4) * attribute.numElements; glBindBuffer(GLenum(m_bufferType), m_id); if (isFloatType) glVertexAttribPointer(attribute.attributeIndex, attribute.numElements, GLenum(attribute.format), attribute.normalize, stride, rcast<GLvoid*>(offset)); else glVertexAttribIPointer(attribute.attributeIndex, attribute.numElements, GLenum(attribute.format), stride, rcast<GLvoid*>(offset)); glEnableVertexAttribArray(attribute.attributeIndex); offset += dataSize; } }
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; }
DecodedImage DecodeFontArt(const span<uint8_t> data) { // 256x256 image with 8bit alpha Expects(data.size() == 256 * 256); DecodedImage result; result.info.width = 256; result.info.height = 256; result.info.format = ImageFileFormat::FNTART; result.info.hasAlpha = true; result.data = std::make_unique<uint8_t[]>(256 * 256 * 4); auto *dest = result.data.get(); for (auto alpha : data) { *dest++ = 0xFF; *dest++ = 0xFF; *dest++ = 0xFF; *dest++ = alpha; } return result; }
inline void write_and_pad_program_source_header( std::ostream& output, program_source_header& header, const span<const span_size_t>& shader_source_lengths, span_size_t& spos ) { using eagine::memory::is_aligned_as; while(!is_aligned_as<program_source_header>(spos)) { output.put('\0'); ++spos; } const span_size_t size = 48; span_size_t done = 0; assert(size >= span_size(sizeof(shader_source_header))); eagine::memory::const_address hdraddr(&header); header.shader_sources.reset( hdraddr+std::ptrdiff_t(size), span_size_t(shader_source_lengths.size()) // shader count ); output.write(static_cast<const char*>(hdraddr), sizeof(header)); spos += sizeof(header); done += sizeof(header); while(done < size) { output.put('\0'); ++spos; ++done; } span_size_t algn = alignof(shader_source_header); std::ptrdiff_t offs = std::ptrdiff_t(shader_source_lengths.size())* std::ptrdiff_t(sizeof(std::ptrdiff_t)); if(offs % 16 != 0) { offs += 16 - (offs % 16); } for(span_size_t len : shader_source_lengths) { output.write( reinterpret_cast<const char*>(&offs), std::streamsize(sizeof(offs)) ); spos += sizeof(offs); done += sizeof(offs); // if changing this also change size // in write_and_pad_shader_source_header span_size_t shader_block_size = 48; shader_block_size += len; if(span_size_t misalign = shader_block_size % algn) { shader_block_size += (algn - misalign); } offs += std::ptrdiff_t(shader_block_size); offs -= std::ptrdiff_t(sizeof(std::ptrdiff_t)); } while(spos % 16 != 0) { output.put('\0'); ++spos; } }
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"); }