This commit is contained in:
Joon Park 2020-03-07 04:02:13 -05:00
parent d0c68f55e4
commit cd2b367e25
4 changed files with 136 additions and 96 deletions

View File

@ -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<uint8> data;
uint32 wpos;
uint32 wsize;
uint64 wpos;
uint64 wsize;
std::vector<packet> 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<uint8> 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");
}

View File

@ -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, []()
{

View File

@ -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;
}
}
}

View File

@ -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)