diff --git a/check_input.cpp b/check_input.cpp index 54f94ea..89173ec 100644 --- a/check_input.cpp +++ b/check_input.cpp @@ -30,7 +30,7 @@ GameType check_server(char* ip_text, char* port_text) { std::string code = connect_code::encode(addr, std::to_string(port)); /* Create server socket and wait for client to connect */ - Server* server = new Server(4, ES_UDP, addr.data(), port); + Server* server = new Server(check_ip_ver(addr.data()), ES_UDP, addr.data(), port); server->create_socket(); display_text_centered("Your code is " + code + "\nWaiting for connection..."); std::string response = ""; diff --git a/connect_code.cpp b/connect_code.cpp index 28db62f..24d221e 100644 --- a/connect_code.cpp +++ b/connect_code.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,6 +6,15 @@ #include #include "includes/connect_code.hpp" #include "includes/numeric_base.hpp" +#include "includes/easysock.h" + +#if defined(_WIN32) + #include + #include +#else + #include + #include +#endif namespace connect_code { @@ -44,13 +54,67 @@ namespace connect_code { uint32_t addr_val = (std::stoul(octets[0]) << 24) + (std::stoul(octets[1]) << 16) + (std::stoul(octets[2]) << 8) + (std::stoul(octets[3])); return std::to_string(addr_val); } + + /* Expand an IPv6 address (expand '::' into ':0000:', for example). + This is done by first converting the address into a binary representation, + and then printing every character of the binary representation into a string. */ + std::string expand_ip6_addr(std::string addr) { + char ip6_string[40]; // 32 characters + 7 colons + struct in6_addr* ip6_s_ptr = (struct in6_addr *)malloc(sizeof(in6_addr)); // Struct pointer, to store the binary representation of the address + inet_pton(AF_INET6, addr.data(), ip6_s_ptr); // Convert the string representation into a binary form + + /* This abomination, converts the binary representation into a string. + It uses sprintf to print every byte in the binary representation into a string. + The bytes are formatted as 2-character hexadecimal values. */ + sprintf(ip6_string, + "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + ip6_s_ptr->s6_addr[0], ip6_s_ptr->s6_addr[1], + ip6_s_ptr->s6_addr[2], ip6_s_ptr->s6_addr[3], + ip6_s_ptr->s6_addr[4], ip6_s_ptr->s6_addr[5], + ip6_s_ptr->s6_addr[6], ip6_s_ptr->s6_addr[7], + ip6_s_ptr->s6_addr[8], ip6_s_ptr->s6_addr[9], + ip6_s_ptr->s6_addr[10], ip6_s_ptr->s6_addr[11], + ip6_s_ptr->s6_addr[12], ip6_s_ptr->s6_addr[13], + ip6_s_ptr->s6_addr[14], ip6_s_ptr->s6_addr[15]); + + return std::string(ip6_string); + } std::string encode(std::string address, std::string port) { + std::string addr_coded; /* Convert the address to decimal, and convert that to hex */ - std::string addr_coded = dotted_dec_to_dec(address); - addr_coded = base_convert(addr_coded, 10, 32); - + if (check_ip_ver(address.data()) == 4) { + /* I don't really have a reason to use my own function (dotted_dec_to_dec() + and dec_to_dotted_dec()), to convert the IP address from text to binary. + The inet_pton() and inet_ntop() functions can do this just fine, and also + take care of edge cases. Maybe someday, I might change this code. I could probably + repurpose the functions for something else, though. */ + + /* First, convert the address into a 32-bit integer (the integer is stored as a string). + Then, convert the address into base-32. */ + addr_coded = dotted_dec_to_dec(address); + addr_coded = base_convert(addr_coded, 10, 32); + } + if (check_ip_ver(address.data()) == 6) { + /* First, expand the address into the full 39-character format (32 hex values + 7 colons). + Then, tokenize the string, using colons as the delimiters. + Finally, take each token in the string, and convert it from base-16 to base-32, appending a '-' as a delimiter. */ + std::string addr_expanded = expand_ip6_addr(address); + std::string addr_coded = ""; + std::vector addr_tokenized = tokenize_str(addr_expanded, ":"); + for (int i = 0; i < addr_tokenized.size(); i++ ) { + addr_coded += base_convert(addr_tokenized[i], 16, 32); + addr_coded += "-"; + } + /* TODO - Check if the IP address is actually converted properly, and test if the server socket is created correctly. + Also do the same for client side, and check client-server connection. */ + + std::cout << addr_coded << std::endl; + abort(); + + } + /* Convert the port to hex */ std::string port_coded = base_convert(port, 10, 32); std::string ret_val = addr_coded + "_" + port_coded;