Line data Source code
1 : /* 2 : Copyright 2018-2024, Barcelona Supercomputing Center (BSC), Spain 3 : Copyright 2015-2024, Johannes Gutenberg Universitaet Mainz, Germany 4 : 5 : This software was partially supported by the 6 : EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). 7 : 8 : This software was partially supported by the 9 : ADA-FS project under the SPPEXA project funded by the DFG. 10 : 11 : This file is part of GekkoFS. 12 : 13 : GekkoFS is free software: you can redistribute it and/or modify 14 : it under the terms of the GNU General Public License as published by 15 : the Free Software Foundation, either version 3 of the License, or 16 : (at your option) any later version. 17 : 18 : GekkoFS is distributed in the hope that it will be useful, 19 : but WITHOUT ANY WARRANTY; without even the implied warranty of 20 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 : GNU General Public License for more details. 22 : 23 : You should have received a copy of the GNU General Public License 24 : along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. 25 : 26 : SPDX-License-Identifier: GPL-3.0-or-later 27 : */ 28 : 29 : #include <common/rpc/rpc_util.hpp> 30 : 31 : extern "C" { 32 : #include <unistd.h> 33 : #include <sys/socket.h> 34 : #include <netdb.h> 35 : } 36 : 37 : #include <system_error> 38 : 39 : 40 : using namespace std; 41 : 42 : namespace gkfs::rpc { 43 : 44 : /** 45 : * converts std bool to mercury bool 46 : * @param state 47 : * @return 48 : */ 49 : hg_bool_t 50 102 : bool_to_merc_bool(const bool state) { 51 102 : return state ? static_cast<hg_bool_t>(HG_TRUE) 52 102 : : static_cast<hg_bool_t>(HG_FALSE); 53 : } 54 : 55 : 56 : /** 57 : * Returns the machine's hostname 58 : * @return 59 : */ 60 : string 61 344 : get_my_hostname(bool short_hostname) { 62 344 : char hostname[1024]; 63 344 : auto ret = gethostname(hostname, 1024); 64 344 : if(ret == 0) { 65 688 : string hostname_s(hostname); 66 344 : if(!short_hostname) 67 0 : return hostname_s; 68 : // get short hostname 69 344 : auto pos = hostname_s.find("."s); 70 344 : if(pos != string::npos) 71 0 : hostname_s = hostname_s.substr(0, pos); 72 688 : return hostname_s; 73 : } else 74 344 : return ""s; 75 : } 76 : 77 : #ifdef GKFS_ENABLE_UNUSED_FUNCTIONS 78 : string 79 : get_host_by_name(const string& hostname) { 80 : int err = 0; 81 : struct addrinfo hints; 82 : memset(&hints, 0, sizeof(struct addrinfo)); 83 : hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG); 84 : hints.ai_family = AF_UNSPEC; 85 : hints.ai_socktype = SOCK_RAW; 86 : 87 : struct addrinfo* addr = nullptr; 88 : 89 : err = getaddrinfo(hostname.c_str(), nullptr, &hints, &addr); 90 : if(err) { 91 : throw runtime_error("Error getting address info for '" + hostname + 92 : "': " + gai_strerror(err)); 93 : } 94 : 95 : char addr_str[INET6_ADDRSTRLEN]; 96 : 97 : err = getnameinfo(addr->ai_addr, addr->ai_addrlen, addr_str, 98 : INET6_ADDRSTRLEN, nullptr, 0, 99 : (NI_NUMERICHOST | NI_NOFQDN)); 100 : if(err) { 101 : throw runtime_error("Error on getnameinfo(): "s + gai_strerror(err)); 102 : } 103 : freeaddrinfo(addr); 104 : return addr_str; 105 : } 106 : #endif 107 : 108 : /** 109 : * @brief Get the bit from a bit vector 110 : * 111 : * @param data 112 : * @param position 113 : * @return the bit 114 : */ 115 : bool 116 174 : get_bitset(const std::vector<uint8_t>& data, const uint16_t position) { 117 174 : return (data[(position) / 8] & 1 << ((position) % 8)); 118 : } 119 : 120 : /** 121 : * @brief Get the bit from a bit vector 122 : * 123 : * @param data 124 : * @param position 125 : */ 126 : void 127 105 : set_bitset(std::vector<uint8_t>& data, const uint16_t position) { 128 105 : data[(position) / 8] |= 1 << ((position) % 8); // set 129 105 : } 130 : 131 : std::string 132 78 : base64_encode(const std::vector<uint8_t>& data) { 133 78 : static const std::string base64_chars = 134 78 : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 135 : 136 78 : std::ostringstream encoded; 137 78 : uint32_t buffer = 0; 138 78 : int padding = 0; 139 : 140 162 : for(uint8_t byte : data) { 141 84 : buffer = (buffer << 8) | byte; 142 84 : padding += 8; 143 169 : while(padding >= 6) { 144 85 : padding -= 6; 145 85 : encoded << base64_chars[(buffer >> padding) & 0x3F]; 146 : } 147 : } 148 : 149 78 : if(padding > 0) { 150 78 : buffer <<= 6 - padding; 151 78 : encoded << base64_chars[buffer & 0x3F]; 152 : } 153 : 154 231 : while(encoded.str().length() % 4 != 0) { 155 153 : encoded << '='; 156 : } 157 : 158 78 : return encoded.str(); 159 : } 160 : 161 : std::vector<uint8_t> 162 69 : base64_decode(const std::string& encoded) { 163 69 : static const std::string base64_chars = 164 69 : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 165 : 166 138 : std::vector<uint8_t> data; 167 69 : uint32_t buffer = 0; 168 69 : int padding = 0; 169 69 : size_t count = 0; 170 : 171 214 : for(char c : encoded) { 172 214 : if(c == '=') 173 : break; 174 : 175 145 : std::size_t value = base64_chars.find(c); 176 145 : if(value == std::string::npos) 177 0 : continue; 178 : 179 145 : buffer = (buffer << 6) | value; 180 145 : padding += 6; 181 : 182 145 : if(padding >= 8) { 183 75 : padding -= 8; 184 75 : data.push_back(static_cast<uint8_t>((buffer >> padding) & 0xFF)); 185 75 : count++; 186 : } 187 : } 188 : 189 : // Handle padding characters 190 69 : if(padding > 0 && padding < 6 && (buffer & ((1 << padding) - 1)) == 0) { 191 : // Remove the padding bits 192 69 : buffer >>= padding; 193 69 : padding = 0; 194 69 : data.push_back(static_cast<uint8_t>((buffer >> 8) & 0xFF)); 195 69 : count++; 196 : } 197 : 198 69 : if(count == 0 || padding % 8 != 0) 199 0 : return {}; 200 : 201 69 : return data; 202 : } 203 : 204 : std::string 205 78 : compress_bitset(const std::vector<uint8_t>& bytes) { 206 78 : return base64_encode(bytes); 207 : } 208 : 209 : std::vector<uint8_t> 210 69 : decompress_bitset(const std::string& compressedString) { 211 69 : return base64_decode(compressedString); 212 : } 213 : 214 : 215 : } // namespace gkfs::rpc