typename T2::iterator copy_safe_apart(size_t n, const T1 & tab_src, T2 & tab_dst, size_t offset_src=0, size_t offset_dst=0) { _dbg5("copy (tab) n="<<n); if (n<1) return tab_dst.begin(); // could write both blocks below with lambda, in C++17TODO when decomposition declarations is available // source auto src_rb = tab_src.begin() + offset_src; // rb = range begin _check_input( offset_src < tab_src.size() ); _check_input( n <= tab_src.size() - offset_src ); // subtracting offset_src is valid since above auto src_rl = tab_src.begin() + offset_src + n -1; // range last _dbg5("Source range src_rb="<<to_debug(src_rb)<<" ... src_rl="<<to_debug(src_rl)); _check_abort( src_rl <= tab_src.end() ); // dest auto dst_rb = tab_dst.begin() + offset_dst; // rb = range begin _check_input( offset_dst < tab_dst.size() ); _check_input( n <= tab_dst.size() - offset_dst ); // subtracting offset_dst is valid since above auto dst_rl = tab_dst.begin() + offset_dst + n -1; // range last _dbg5("Destintion range dst_rb="<<to_debug(dst_rb)<<" ... dst_rl="<<to_debug(dst_rl)); _check_abort( dst_rl <= tab_dst.end() ); bool overlap = test_ranges_overlap_inclusive_noempty(src_rb, src_rl, dst_rb, dst_rl); _dbg5("overlap=" << overlap); _check_input(!overlap); copy_iter_and_check_no_overlap( src_rb, src_rl, dst_rb, n ); _dbg5("Copy done."); return dst_rb; }
size_t c_tuntap_linux_obj::send_to_tun_separated_addresses(const unsigned char *const data, size_t size, const std::array<unsigned char, IPV6_LEN> &src_binary_address, const std::array<unsigned char, IPV6_LEN> &dst_binary_address) { _check_input(size >= 8); std::array<boost::asio::const_buffer, 4> buffers; buffers.at(0) = boost::asio::buffer(data, 8); // version, traffic, flow label, payload length, next header, hop limit buffers.at(1) = boost::asio::buffer(src_binary_address.data(), src_binary_address.size()); buffers.at(2) = boost::asio::buffer(dst_binary_address.data(), dst_binary_address.size()); buffers.at(3) = boost::asio::buffer(data + 8, size - 8); // 8 bytes are filled in buffers.at(0) boost::system::error_code ec; return m_tun_stream.write_some(buffers, ec); }
void c_tuntap_linux_obj::set_tun_parameters(const std::array<unsigned char, IPV6_LEN> &binary_address, int prefix_len, uint32_t mtu) { c_haship_addr address(c_haship_addr::tag_constr_by_array_uchar(), binary_address); _goal("Configuring tuntap options: IP address: " << address << "/" << prefix_len << " MTU=" << mtu); as_zerofill< ifreq > ifr; // the if request ifr.ifr_flags = IFF_TUN | IFF_NO_PI; strncpy(ifr.ifr_name, "galaxy%d", IFNAMSIZ); int errcode_ioctl = sys_fun.ioctl(m_tun_fd, TUNSETIFF, static_cast<void *>(&ifr)); _check_sys(errcode_ioctl != -1); _check_input(binary_address[0] == 0xFD); _check_input(binary_address[1] == 0x42); t_syserr err; err = sys_fun.NetPlatform_addAddress(ifr.ifr_name, binary_address.data(), prefix_len, Sockaddr_AF_INET6); if (err.my_code != 0) throw std::runtime_error("NetPlatform_addAddress error"); err = sys_fun.NetPlatform_setMTU(ifr.ifr_name, mtu); if (err.my_code != 0) throw std::runtime_error("NetPlatform_setMTU error"); m_tun_stream.release(); m_tun_stream.assign(m_tun_fd); _goal("Configuring tuntap options - done"); }
size_t c_tuntap_linux_obj::read_from_tun_separated_addresses(unsigned char *const data, size_t size, std::array<unsigned char, IPV6_LEN> &src_binary_address, std::array<unsigned char, IPV6_LEN> &dst_binary_address) { _check_input(size >= 8); // field sizes based on rfc2460 // https://tools.ietf.org/html/rfc2460 std::array<boost::asio::mutable_buffer, 4> buffers; buffers.at(0) = boost::asio::buffer(data, 8); // version, traffic, flow label, payload length, next header, hop limit buffers.at(1) = boost::asio::buffer(src_binary_address.data(), src_binary_address.size()); buffers.at(2) = boost::asio::buffer(dst_binary_address.data(), dst_binary_address.size()); buffers.at(3) = boost::asio::buffer(data + 8, size - 8); // 8 bytes are filled in buffers.at(0) try { return m_tun_stream.read_some(buffers) - src_binary_address.size() - dst_binary_address.size(); } catch (const std::exception &) { return 0; } }
c_galaxysrv_peers::t_peering_reference_parse c_galaxysrv_peers::parse_peer_reference(const string & simple) const{ // @TODO not using std::regex since it had compatibility problems. Consider using when possible (bug#J446). const char separator='@', group_open='(', group_close=')'; const string literal_anyone = "anyone"; reasonable_size(simple); _note("Parsing: "<<simple); _check_input(simple.size()>=3); // some reasonable sized not-empty string size_t pos1 = simple.find(separator); // was there any "@" if (pos1 == string::npos) { // must be one-part format "VIRTUAL" (only contains the ID/ipv6, no cables) vector<string> ret_id( { simple } ); // e.g. "fd42:f6c4:9d19:f128:30df:b289:aef0:25f5,score=-300" vector<string> ret_cable{ }; // make sure this part does not contain ( or ) etc _check_input( string::npos == simple.find(group_open) ); _check_input( string::npos == simple.find(group_close) ); _check_input( simple.size()>0 ); return std::make_pair(std::move(ret_id), std::move(ret_cable)); } else { // format "VIRTUAL@(CABLE)" possibly with more "@(CABLE)" string part1 = simple.substr(0,pos1); // the VIRTUAL // make sure this part does not contain ( or ) _check_input( string::npos == part1.find(group_open) ); _check_input( string::npos == part1.find(group_close) ); _check_input( part1.size()>0 ); vector<string> ret_id; if (part1 != literal_anyone) { ret_id.push_back( part1 ); // e.g. "fd42:f6c4:9d19:f128:30df:b289:aef0:25f5,score=-300" } // else, it is 'anyone' VIRTUAL - so it is reported by empty string // fd42::25f5@(udp:p.meshnet.pl:9042,cost=500)@(shm:test)@(tcp:[fe80::d44e]:9042) // B // B.............................X // X@(B // B.......X@ // X@(B // B.....................end vector<string> ret_cable; // will parse additional groups "@(....)" selecting their index posB...posX const size_t size = simple.size(), size_before=size-1; _check(size_before < size); _check_input(pos1+2 < size); _check_input(simple.at(pos1+0)==separator); // theck the '@' out of "@(" that we just found _check_input(simple.at(pos1+1)==group_open); // theck the '(' out of "@(" that we just found size_t posB = pos1+2; // begin, poiting after "@(" _info(join_string_sep(posB," < ",size)); while (posB < size_before) { auto posX = simple.find(group_close,posB); // find ")" _dbg3("posX=" << posX << " posB="<<posB); if (posX == string::npos) { _info("Hit end because posX="<<posX); posX = size_before; } string partX = simple.substr(posB, posX-posB); _dbg3("posX=" << posX << " posB="<<posB<<" given " <<partX); // make sure this part does not contain ( or ), e.g. "CABLE(" as result of parsing "VIRTUAL@(CABLE(CABLE)" _check_input( string::npos == partX.find(group_open) ); _check_input( string::npos == partX.find(group_close) ); _check_input( partX.size()>0 ); ret_cable.push_back( std::move(partX) ); posB=posX; _check_input(simple.at(posB)==group_close); // ")" ++posB; if (!(posB<size)) break; // end is possible after last "....@(...)" // otherwise we open new group: _check_input(simple.at(posB)==separator); // ")@" ++posB; _check_input(simple.at(posB)==group_open); // ")@(" after this ++posB; } return std::make_pair(std::move(ret_id), std::move(ret_cable)); } // other format }
/****************************************************************************** // Read user input from standard in // Input: // Output: // n: number of cities // adjMtx: the adjacency matrix, note the memory should be freed later // Return: // 1 success; 0 failed alloc memory ******************************************************************************/ int read_input(int *n, int **adjMtx) { int i; int value; int idx = 0; int cnt = 0; int sz = INT_MAX; char str[SIZE]; //possible overflow //read number of cities while (1) { printf("please input the cities:\n"); scanf("%s", str); sz = INT_MAX; if (_isalldigit(str) == 1) { sz = _atoi(str); } //the first parameter should be a number between min cities and max cities if (sz <= MIN_CITIES || sz >= MAX_CITIES) { printf("first parameter %s isn't in [%d, %d]\n", str, MIN_CITIES, MAX_CITIES); } else { break; } } //init number of cities *n = sz; //build adjMtx *adjMtx = (int*)malloc(sz*sz*sizeof(int)); if (*adjMtx == NULL) { printf("not enough memory\n"); return 0; } //read other inputs while (++idx < sz) { while (1) { printf("please input [%d] elements for [%d]th line of half matrix:\n", idx, idx); cnt = 0; i = idx; while (i--) { scanf("%s", str); if (_check_input(str) == 0) { printf("input must be a number without sign or character x: %s\n", str); scanf("%*[^\n]"); //discard other inputs in this line if error occurs break; } else { value = _inputtoi(str); (*adjMtx)[idx*sz + cnt] = value; //A(i, j) (*adjMtx)[cnt*sz + idx] = value; //A(j, i) ++cnt; } } if (cnt == idx) //inputs for this line are complete { scanf("%*[^\n]"); //discard more in the tail break; } } } //init diagnol matrix values for (i = 0; i < sz; ++i) { (*adjMtx)[i*sz + i] = 0; } //check all values //for (i = 0; i < sz * sz; ++i) //{ // printf("%d\t", (*adjMtx)[i]); // if ((i+1)%sz == 0) // printf("\n"); //} return 1; }