unsigned char parser::pop_byte_u() { if (! (m_data_now < m_data_end) ) _throw_error( format_error_read() ); if (! ((m_data_end - m_data_now) >= 1) ) _throw_error( format_error_read() ); assert( (m_data_now < m_data_end) && (m_data_now >= m_data_begin) ); unsigned char c = *m_data_now; ++m_data_now; return c; }
void parser::skip_bytes_n(size_t size) { if (!size) return; if (! (m_data_now < m_data_end) ) _throw_error( format_error_read() ); // we run outside of string // casting below is ok, because std::ptrdiff_t is 64 bits signed value, and size_t is 64 bits unsigned value. // and we are sure that this ptrdiff > 0 because of earlier above condition if (! ( static_cast<size_t>(m_data_end - m_data_now) >= size) ) _throw_error( format_error_read() ); assert( (m_data_now < m_data_end) && (m_data_now >= m_data_begin) ); assert( (m_data_now + size <= m_data_end) ); // auto from = m_data_now; m_data_now += size; // *** move }
c_haship_addr::c_haship_addr(tag_constr_by_addr_bin, const t_ipv6bin & data ) { if (! ( this->size() == data.size() ) ) { ostringstream oss; oss << "Trying to set hip address from binary data " << to_debug_b(data); _throw_error( std::runtime_error(oss.str()) ); } for (size_t i=0; i<this->size(); ++i) this->at(i) = data.at(i); }
bool c_ip46_addr::operator== (const c_ip46_addr &rhs) const { if (this->m_tag == t_tag::tag_none) { _throw_error( std::invalid_argument("lhs: m_tag == tag_none") ); } if (rhs.m_tag == t_tag::tag_none) { _throw_error( std::invalid_argument("rhs: m_tag == tag_none") ); } if (this->m_tag != rhs.m_tag) { return false; } if (this->m_tag == t_tag::tag_ipv4) { return !memcmp(&this->m_ip_data.in4.sin_addr, &rhs.m_ip_data.in4.sin_addr, sizeof(in_addr)); } else { return !memcmp(&this->m_ip_data.in6.sin6_addr, &rhs.m_ip_data.in6.sin6_addr, sizeof(in6_addr)); } }
size_t c_tun_device_linux::read_from_tun(void *buf, size_t count) { // TODO throw if error _info("Reading from tuntap"); ssize_t ret = read(m_tun_fd, buf, count); // <-- read data from TUN _info("Reading from tuntap - ret="<<ret); if (ret == -1) _throw_error( std::runtime_error("Read from tun error") ); assert (ret >= 0); return static_cast<size_t>(ret); }
void c_the_program::init_library_sodium() { _fact(mo_file_reader::gettext("L_starting_lib_libsodium")); if (sodium_init() == -1) { _throw_error( std::runtime_error(mo_file_reader::gettext("L_lisodium_init_err")) ); } _info(mo_file_reader::gettext("L_libsodium_ready")); }
void parser::pop_bytes_n_into_buff(size_t size, char * buff) { if (! (m_data_now < m_data_end) ) _throw_error( format_error_read() ); // we run outside of string // casting below is ok, because std::ptrdiff_t is 64 bits signed value, and size_t is 64 bits unsigned value. // and we are sure that this ptrdiff > 0 because of earlier above condition if (! ( static_cast<size_t>(m_data_end - m_data_now) >= size) ) _throw_error( format_error_read() ); assert(buff!=nullptr); assert( (m_data_now < m_data_end) && (m_data_now >= m_data_begin) ); assert( (m_data_now + size <= m_data_end) ); auto range1 = m_data_now; m_data_now += size; // *** move auto range2 = m_data_now; if ((range2 - range1) != size) { throw std::out_of_range("Variable overlap detected"); } std::copy(range1, range2, buff); // copy the result into output }
bool c_ip46_addr::operator< (const c_ip46_addr &rhs) const { if (this->m_tag == t_tag::tag_none) { _throw_error( std::invalid_argument("lhs: m_tag == tag_none") ); } if (rhs.m_tag == t_tag::tag_none) { _throw_error( std::invalid_argument("rhs: m_tag == tag_none") ); } if (this->m_tag == t_tag::tag_ipv4 && rhs.m_tag == t_tag::tag_ipv6) { return true; } else if (this->m_tag == t_tag::tag_ipv6 && rhs.m_tag == t_tag::tag_ipv4) { return false; } int ret = 0; if (rhs.m_tag == t_tag::tag_ipv4) { ret = memcmp(&this->m_ip_data.in4.sin_addr, &rhs.m_ip_data.in4.sin_addr, sizeof(in_addr)); } else { ret = memcmp(&this->m_ip_data.in6.sin6_addr, &rhs.m_ip_data.in6.sin6_addr, sizeof(in6_addr)); } if (ret < 0) return true; else return false; }
size_t c_udp_wrapper_linux::receive_data(void *data_buf, const size_t data_buf_size, c_ip46_addr &from_address) { sockaddr_in6 from_addr_raw; // peering address of peer (socket sender), raw format socklen_t from_addr_raw_size = sizeof(from_addr_raw); // ^ size of it auto size_read = recvfrom(m_socket, data_buf, data_buf_size, 0, reinterpret_cast<sockaddr*>( & from_addr_raw), & from_addr_raw_size); if (from_addr_raw_size == sizeof(sockaddr_in6)) { // the message arrive from IP pasted into sockaddr_in6 format _erro("NOT IMPLEMENTED yet - recognizing IP of ipv6 peer"); // peeripv6-TODO(r)(easy) // trivial } else if (from_addr_raw_size == sizeof(sockaddr_in)) { // the message arrive from IP pasted into sockaddr_in (ipv4) format sockaddr_in addr = * reinterpret_cast<sockaddr_in*>(& from_addr_raw); // mem-cast-TODO(p) confirm reinterpret from_address.set_ip4(addr); } else { _throw_error( std::runtime_error("Data arrived from unknown socket address type") ); } return size_read; }
c_haship_addr::c_haship_addr(tag_constr_by_addr_dot, const t_ipv6dot & addr_string) { _dbg1("******************PARSING IP: addr_string " << addr_string); // use boost asio for parsing boost::asio::ip::address_v6 asio_addr_v6; try { asio_addr_v6 = boost::asio::ip::address_v6::from_string(addr_string); boost::asio::ip::address_v6::bytes_type asio_addr_bytes = asio_addr_v6.to_bytes(); assert (asio_addr_bytes.size() == 16); // 16 = 128/8 for (int i = 0; i < 128 / 8; ++i) { this->at(i) = asio_addr_bytes.at(i); } } catch (boost::exception &err) { _throw_error(std::invalid_argument("The IP address looks invalid ["+addr_string+"]")); } _dbg1("Parsed string addr :" << asio_addr_v6.to_string()); _dbg1("Parsed bytes addr :" << *this); }
void test_shortstring_end(std::ostream &dbgout) { trivialserialize::generator gen(50); vector<string> test_varstring = { string("ABC"), string(""), }; for (auto val : test_varstring) gen.push_varstring(val); const string input = gen.str(); trivialserialize::parser parser( trivialserialize::parser::tag_caller_must_keep_this_string_valid() , input ); for (auto val_expected : test_varstring) { auto val_given = parser.pop_varstring(); dbgout<<"varstring decoded: [" << val_given << "] with size=" << val_given.size() << endl; bool ok = ( val_given == val_expected ); if (!ok) _throw_error( std::runtime_error("Failed test for expected value " + (val_expected)) ); } }
bool c_ip46_addr::is_ipv4(const string &ipstr) { as_zerofill< addrinfo > hint; struct addrinfo *result = nullptr; hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_NUMERICHOST; int ret = getaddrinfo(ipstr.c_str(), nullptr, &hint, &result); if (ret) { _throw_error( std::invalid_argument("unknown address format") ); } auto result_deleter = [&](struct addrinfo *result){freeaddrinfo(result);}; std::unique_ptr<struct addrinfo, decltype(result_deleter)> result_ptr(result, result_deleter); if(result_ptr->ai_family == AF_INET) { return true; } else if (result_ptr->ai_family == AF_INET6) { return false; } _assert(false); }
void c_rpc_server::c_session::execute_rpc_command(const std::string &input_message) { try { nlohmann::json j = nlohmann::json::parse(input_message); const std::string cmd_name = j.begin().value(); _dbg("cmd name " << cmd_name); // calling rpc function const std::string response = m_rpc_server_ptr->m_rpc_functions_map.at(cmd_name)(input_message); // serialize response assert(response.size() <= std::numeric_limits<uint16_t>::max()); uint16_t size = static_cast<uint16_t>(response.size()); m_write_data.resize(size + 2); ///< 2 first bytes for size m_write_data.at(0) = static_cast<char>(size >> 8); m_write_data.at(1) = static_cast<char>(size & 0xFF); for (size_t i = 0; i < response.size(); ++i) m_write_data.at(i + 2) = response.at(i); // send response _dbg("send packet"); _dbg(m_write_data); std::array<unsigned char, crypto_auth_hmacsha512_BYTES> hash; int ret = crypto_auth_hmacsha512(hash.data(), reinterpret_cast<unsigned char *>(&m_write_data.at(2)), size, m_rpc_server_ptr->m_hmac_key.data()); if (ret != 0) _throw_error(std::runtime_error("crypto_auth_hmacsha512 error")); _dbg("hmac"); //for (const auto & byte : hash) std::cout << std::hex << "0x" << static_cast<int>(byte) << " "; //std::cout << std::dec << std::endl; std::array<boost::asio::const_buffer, 2> buffers = { {boost::asio::buffer(m_write_data.data(), m_write_data.size()), boost::asio::buffer(hash.data(), hash.size())} }; m_socket.async_write_some(buffers, [this](const boost::system::error_code& error, std::size_t bytes_transferred) { write_handler(error, bytes_transferred); }); } catch (const std::exception &e) { _erro( "exception in execute_rpc_command " << e.what() ); _erro( "close connection\n" ); delete_me(); return; } }
void c_peering_udp::send_data_RAW_udp(const char * data, size_t data_size, int udp_socket) { _UNUSED(udp_socket); _info("UDP send to peer RAW. To IP: " << m_peering_addr << ", RAW-DATA: " << to_debug_b(std::string(data,data_size)) ); //#ifdef __linux__ switch (m_peering_addr.get_ip_type()) { case c_ip46_addr::t_tag::tag_ipv4 : { m_udp_wrapper.get().send_data(m_peering_addr, data, data_size); } break; case c_ip46_addr::t_tag::tag_ipv6 : { m_udp_wrapper.get().send_data(m_peering_addr, data, data_size); } break; default: { std::ostringstream oss; oss << m_peering_addr; // TODO _throw_error( std::runtime_error(string("Invalid IP type (when trying to send RAW udp): ") + oss.str()) ); } } //#endif }
int c_tun_device_apple::get_tun_fd() const { if (m_tun_fd<0) _throw_error(std::runtime_error("Using not ready (m_tun_fd) tuntap device")); return m_tun_fd; }
int c_tun_device::get_tun_fd() const { _throw_error(std::runtime_error("Trying to get tun_fd of a basic generic tun device.")); }
size_t c_tun_device_linux::write_to_tun(void *buf, size_t count) { // TODO throw if error auto ret = write(m_tun_fd, buf, count); if (ret == -1) _throw_error( std::runtime_error("Write to tun error") ); assert (ret >= 0); return static_cast<size_t>(ret); }
void c_peering::send_data(const char * data, size_t data_size) { UNUSED(data); UNUSED(data_size); _throw_error( std::runtime_error("Used abstract send_data() that does nothing") ); }
void c_peering_udp::send_data(const char * data, size_t data_size) { UNUSED(data); UNUSED(data_size); _throw_error( std::runtime_error("Use send_data_udp") ); }
void parser::pop_byte_skip(char c) { // read expected character (e.g. a delimiter) unsigned char was = pop_byte_u(); unsigned char expected = static_cast<unsigned char>(c); if (was != expected) _throw_error( format_error_read_delimiter() ); }