diff --git a/Source/core/core/network/connection.h b/Source/core/core/network/connection.h index 97266c9..cb217e3 100644 --- a/Source/core/core/network/connection.h +++ b/Source/core/core/network/connection.h @@ -13,7 +13,7 @@ namespace server { struct tcp_connection* connection; uint8* data; - uint32 length; + uint64 length; }; static const uint32 max_frame_count = 2; @@ -23,12 +23,12 @@ namespace server struct frame_data { std::vector data; - uint32 wpos; - uint32 wsize; + uint64 wpos; + uint64 wsize; std::vector packets; - uint32 rpos; - uint32 packet_count; + uint64 rpos; + uint64 packet_count; frame_data() : wpos(0), rpos(0), wsize(0), packet_count(0) { @@ -58,7 +58,7 @@ namespace server connection(connection), state(0), read_state(0), write_state(0), frame{} {} - bool enqueue(uint8* packet_data, uint32 packet_size) + bool enqueue(uint8* packet_data, uint64 packet_size) { this->begin_write(); @@ -66,8 +66,8 @@ namespace server uint32 write_idx = write_state & (0x1 << packet_queue_state_bit::active_frame); frame_data& f = frame[write_idx]; - uint32 buffer_space = f.data.size() - f.wpos; - uint32 packet_slots = f.packets.size() - f.packet_count; + uint64 buffer_space = f.data.size() - f.wpos; + uint64 packet_slots = f.packets.size() - f.packet_count; if (buffer_space >= packet_size && packet_slots >= 1) { @@ -163,21 +163,25 @@ namespace server struct byte_buffer { std::vector buffer; - uint32 capacity; - uint32 wpos; + uint64 capacity; + uint64 rpos; + uint64 rend; + uint64 wpos; - byte_buffer(uint32 capacity) : + byte_buffer(uint64 capacity) : buffer(capacity), capacity(capacity), + rpos(0), + rend(0), wpos(0) {} - uint32 size() + uint64 size() { return wpos; } - uint32 space() + uint64 free_space() { return capacity - wpos; } @@ -187,13 +191,14 @@ namespace server return buffer.data(); } - uint8* write(void* source, uint32 size) + uint8* write(void* source, uint64 size) { uint8* wptr = buffer.data() + wpos; - if (this->space() > size) + if (this->free_space() > size) { memcpy(wptr, source, size); + rpos = wpos; wpos += size; return wptr; } @@ -201,7 +206,7 @@ namespace server return nullptr; } - void erase(uint32 num_erase) + void erase(uint64 num_erase) { if (wpos >= num_erase) { @@ -299,14 +304,17 @@ namespace server { core::packet* packet = packets.dequeue(); - if (wbuffer.space() < packet->length * 2) + if (wbuffer.free_space() < packet->length * 2) { assert(false); } - uint8* data = wbuffer.write(packet->data, packet->length); + uint8* packet_data = wbuffer.write(packet->data, packet->length); + + wbuffer.rpos = packet_data - wbuffer.data(); + wbuffer.rend = wbuffer.rpos + packet->length; //crossgate::xg_dispatch_packet(std::move(*packet)); - send_handler(data, packet->length); + send_handler(wbuffer); //std::string packet_str((char*)packet->data, packet->length); @@ -356,11 +364,11 @@ namespace server void await_suspend(std::experimental::coroutine_handle<> coro) { - connection.socket.async_send(buffer, [this, coro](auto error_code, size_t bytes_read) + connection.socket.async_send(buffer, [this, coro](auto error_code, size_t bytes_sent) { this->error_code = error_code; - printf("%zd bytes read from connection %d\n", bytes_read, connection.id); - return_value = (uint32)bytes_read; + printf("%zd bytes sent to connection %d\n", bytes_sent, connection.id); + return_value = (uint32)bytes_sent; coro.resume(); }); } @@ -397,19 +405,23 @@ namespace server end = index; - uint8* data = rdata + begin; - uint32 size = end - begin; + uint8* packet_data = rdata + begin; + uint32 packet_size = end - begin; + rbuffer.rpos = begin; + rbuffer.rend = end; - if (strlen((char*)data) != size) + if (*(rdata + begin) == '\0') { printf("empty string\n"); continue; } else { - receive_handler(data, size); + // receive assumes decrypted packet is <= encrypted packet. - if (!rqueue.enqueue(data, size)) + receive_handler(rbuffer); + + if (!rqueue.enqueue(rbuffer.data() + rbuffer.rpos, rbuffer.rend - rbuffer.rpos)) { printf("enqueue failed.\n"); } diff --git a/Source/xgmsv/test_server/mmo_server.cpp b/Source/xgmsv/test_server/mmo_server.cpp index 93077ba..c81df61 100644 --- a/Source/xgmsv/test_server/mmo_server.cpp +++ b/Source/xgmsv/test_server/mmo_server.cpp @@ -51,15 +51,15 @@ namespace mmo_server } }; - auto receive_handler = [](uint8*& data, uint32& bytes_read) + auto receive_handler = [](core::byte_buffer& payload) { - crossgate::decrypt_message((char*&)data, bytes_read); + crossgate::decrypt_message(payload); }; - auto send_handler = [](uint8*& data, uint32& bytes_to_send) + auto send_handler = [](core::byte_buffer& payload) { - crossgate::decrypt_message((char*&)data, bytes_to_send); + crossgate::encrypt_message(payload); }; @@ -97,8 +97,9 @@ namespace mmo_server //crossgate::decrypt_message(packet, sizeof(packet)); char packet2[] = "Echo nr "; + //char packet3[] = "FC "; - crossgate::encrypt_message(packet2, sizeof(packet2)); + //crossgate::encrypt_message(packet3, sizeof(packet2) - 1); core::async_every(1000ms, []() { diff --git a/Source/xgmsv/test_server/xg_crypto.h b/Source/xgmsv/test_server/xg_crypto.h index a95515f..8a307be 100644 --- a/Source/xgmsv/test_server/xg_crypto.h +++ b/Source/xgmsv/test_server/xg_crypto.h @@ -8,7 +8,7 @@ namespace server char mapping_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; // decrypt stage 1 - int util_64to256(char* dst, const char* src, char* table) + int util_64to256(char* dst, const char* src, char* table, uint64 length) { unsigned int dw, dwcounter, i; char* ptr = NULL; @@ -16,7 +16,7 @@ namespace server dw = 0; dwcounter = 0; if (!dst || !src || !table) return 0; - for (i = 0; i < strlen(src); i++) { + for (i = 0; i < length; i++) { ptr = (char*)strchr(table, src[i]); if (!ptr) return 0; if (i % 4) { @@ -34,12 +34,12 @@ namespace server } // decrypt stage 2 - int remove_salt(char* dst, const char* src, size_t length) + uint64 remove_salt(char* dst, const char* src, uint64 length) { // remove conditional salt int seed = SEED % length; //38 when message_size = 49 int sum = src[seed] & 0x000000ff; - for (int i = 0; i < length; i++) + for (int i = 0; i < (length + 1); i++) // +1 for checksum { if (i < seed) { @@ -60,10 +60,10 @@ namespace server return length - 1; } - void remove_conditional_bit_reverse(char* dst, const char* src, size_t length) + void remove_conditional_bit_reverse(char* dst, const char* src, uint64 length) { // remove conditional bit reverse, seed = 4595 - for (int i = 0; i < length; i++) + for (int i = 0; i < (length + 1); i++) // +1 for checksum { //sum += packet1[i]; if (SEED % 7 == i % 5 || SEED % 2 == i % 2) @@ -74,7 +74,7 @@ namespace server { dst[i] = src[i]; } - int result = length; + uint64 result = length; } } @@ -83,7 +83,7 @@ namespace server std::string stage_1(packet.length(), 0); // 6 bit to 8 bit string - int size = util_64to256(stage_1.data(), packet.c_str(), mapping_table); + int size = util_64to256(stage_1.data(), packet.c_str(), mapping_table, packet.length()); // important trim right here stage_1 = stage_1.substr(0, size - 1); @@ -99,39 +99,28 @@ namespace server return stage_3; } - void decrypt_message(char* data, uint32 size) + void decrypt_message(core::byte_buffer& payload) { + char* buffer = (char*)payload.data() + payload.rpos; + + uint64 payload_size = payload.rend - payload.rpos; + // 6 bit to 8 bit string - size = util_64to256(data, data, mapping_table); + uint64 descrypted_size = util_64to256(buffer, buffer, mapping_table, payload_size); - data[strlen(data) - 1] = '\0'; + descrypted_size--; // -1 for checksum - size = remove_salt(data, data, strlen(data)); - remove_conditional_bit_reverse(data, data, strlen(data)); + descrypted_size = remove_salt(buffer, buffer, descrypted_size); + remove_conditional_bit_reverse(buffer, buffer, descrypted_size); - data[strlen(data) - 1] = '\0'; - - data++; - size = strlen(data) + 1; - - - // important trim right here - /* - stage_1 = stage_1.substr(0, size - 1); - - std::string stage_2(stage_1.length(), 0); - stage_2 = stage_2.substr(0, strlen(stage_2.data())); - - std::string stage_3(stage_2.length(), 0); - remove_conditional_bit_reverse(stage_3.data(), stage_2.c_str(), stage_2.length()); - stage_3 = stage_3.substr(1, strlen(stage_3.data()) - 1); - - return stage_3; - */ + buffer[descrypted_size] = '\0'; + buffer++; + payload.rpos++; + payload.rend += descrypted_size - payload_size; } - uint8 apply_conditional_bit_reverse(char* dst, const char* src, size_t length) + uint8 apply_conditional_bit_reverse(char* dst, const char* src, uint64 length) { char sum = 0; @@ -149,25 +138,25 @@ namespace server return sum; } - int apply_salt(char* dst, const char* src, size_t length, uint8 sum) + int apply_salt_and_add_checksum(char* dst, const char* src, uint64 length, uint8 checksum) { // conditional salt int seed = SEED % length; //38 when message_size = 49 - for (int i = 0; i < (length + 1); i++) + for (int i = 0; i < (length + 1); i++) // alloc for checksum { if (i < seed) { - dst[i] = src[i] + sum * (i * i % 3); + dst[i] = src[i] + checksum * (i * i % 3); } if (i == seed) { - dst[i] = sum; + dst[i] = checksum; } if (i > seed) { - dst[i] = src[i - 1] + sum * (i * i % 7); + dst[i] = src[i - 1] + checksum * (i * i % 7); } //uint64 result = out_int; @@ -176,44 +165,83 @@ namespace server return 0; } - int util_256to64(char *dst, char *src, size_t length) + int util_256to64(char *dst, char *src, char* table, uint64 length) { - unsigned int dw, dwcounter, i; + uint32 byte_counter, i; - if (!dst || !src || !mapping_table) return 0; - dw = 0; - dwcounter = 0; + uint16 reg; + + if (!dst || !src || !table) return 0; + reg = 0; + byte_counter = 0; for (i = 0; i < length; i++) { - dw = (((unsigned int)src[i] & 0xff) << ((i % 3) * 2)) | dw; - dst[dwcounter++] = mapping_table[dw & 0x3f]; - dw = (dw >> 6); + + reg = (src[i] << (8 - 2 * (i % 3))) | reg; + dst[byte_counter++] = table[(reg & 0b1111110000000000) >> (8 + 2)]; + reg = (reg << 6); + if (i % 3 == 2) { - dst[dwcounter++] = mapping_table[dw & 0x3f]; - dw = 0; + dst[byte_counter++] = table[(reg & 0b1111110000000000) >> (8 + 2)]; + reg = (reg << 6); } } - if (dw) dst[dwcounter++] = mapping_table[dw]; - dst[dwcounter] = '\0'; - return dwcounter; + if (reg) dst[byte_counter++] = table[(reg & 0b1111110000000000) >> (8 + 2)]; + dst[byte_counter] = '\0'; + return byte_counter; } - void encrypt_message(char* data, uint32 size) + void encrypt_message(core::byte_buffer& payload) { - memmove(data + 1, data, size); - size++; + char* buffer = (char*)payload.data() + payload.rpos; + const uint64 payload_size = payload.rend - payload.rpos; - data[0] = 0; + uint64 encrypted_size = payload_size + 1; // packet_length padding + char header = (char)encrypted_size; + + if (encrypted_size >= 100) + { + if (encrypted_size % 2 == 0) + { + header = encrypted_size; + } + + assert(false); + /* + *(_BYTE*)message_work_buffer2 = checksum; + message_length = odd_length_encrypt( + (char*)message_work_buffer2 + 1, + 3 * buffer_size - 1, + (unsigned __int8*)message, + strlen(message)); + */ + } + else + { + if (encrypted_size % 2 == 1) + { + header = encrypted_size + 1; + } - uint8 sum = apply_conditional_bit_reverse(data, data, size); - apply_salt(data, data, size, sum); + memmove(buffer + 1, buffer, encrypted_size); + } - data[0] = size + 1; + buffer[0] = header; + encrypted_size++; // null terminator; - char result[256]; - util_256to64(result, data, size); + char workbuf[4096]; + uint8 checksum = apply_conditional_bit_reverse(buffer, buffer, encrypted_size); + apply_salt_and_add_checksum(workbuf, buffer, encrypted_size, checksum); + + encrypted_size++; // add checksum; + encrypted_size = util_256to64(buffer, workbuf, mapping_table, encrypted_size); + buffer[encrypted_size++] = '\n'; + buffer[encrypted_size] = '\0'; + + payload.rend += encrypted_size - payload_size; + payload.wpos = payload.rend; } } } \ No newline at end of file diff --git a/Source/xgmsv/test_server/xg_packet.h b/Source/xgmsv/test_server/xg_packet.h index 4531213..fc12f87 100644 --- a/Source/xgmsv/test_server/xg_packet.h +++ b/Source/xgmsv/test_server/xg_packet.h @@ -12,13 +12,13 @@ namespace server }; +#define send_raw(str) enqueue_response((uint8*)str, sizeof(str) - 1) + void handle_echo(xg_packet* packet) { auto connection = packet->connection; - char echo_response[] = "Echo nr "; - - if (!connection->enqueue_response((uint8*)echo_response, sizeof(echo_response))) + if (!connection->send_raw("Echo nr ")) { printf("handle_echo failed.\n"); } @@ -29,7 +29,6 @@ namespace server void handle_fc(xg_packet* packet) { printf("handle_fc!\n"); - } void handle_client_login(xg_packet* packet)