You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
4.9 KiB
230 lines
4.9 KiB
#include "../types.h" |
|
|
|
static constexpr bool disable_encryption = false; |
|
|
|
const dvlnet_udp::buffer_t &dvlnet_udp::packet::data() |
|
{ |
|
if (!have_decrypted || !have_encrypted) |
|
ABORT(); |
|
return encrypted_buffer; |
|
} |
|
|
|
dvlnet_udp::packet_type dvlnet_udp::packet::type() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
return m_type; |
|
} |
|
|
|
dvlnet_udp::plr_t dvlnet_udp::packet::src() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
return m_src; |
|
} |
|
|
|
dvlnet_udp::plr_t dvlnet_udp::packet::dest() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
return m_dest; |
|
} |
|
|
|
const dvlnet_udp::buffer_t &dvlnet_udp::packet::message() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (m_type != PT_MESSAGE) |
|
throw dvlnet_udp::packet_exception(); |
|
return m_message; |
|
} |
|
|
|
dvlnet_udp::turn_t dvlnet_udp::packet::turn() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (m_type != PT_TURN) |
|
throw dvlnet_udp::packet_exception(); |
|
return m_turn; |
|
} |
|
|
|
dvlnet_udp::cookie_t dvlnet_udp::packet::cookie() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (m_type != PT_JOIN_REQUEST && m_type != PT_JOIN_ACCEPT) |
|
throw dvlnet_udp::packet_exception(); |
|
return m_cookie; |
|
} |
|
|
|
dvlnet_udp::plr_t dvlnet_udp::packet::newplr() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (m_type != PT_JOIN_ACCEPT) |
|
throw dvlnet_udp::packet_exception(); |
|
return m_newplr; |
|
} |
|
|
|
dvlnet_udp::plr_t dvlnet_udp::packet::oldplr() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (m_type != PT_LEAVE_GAME) |
|
throw dvlnet_udp::packet_exception(); |
|
return m_oldplr; |
|
} |
|
|
|
const dvlnet_udp::buffer_t &dvlnet_udp::packet::info() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (m_type != PT_JOIN_ACCEPT) |
|
throw dvlnet_udp::packet_exception(); |
|
return m_info; |
|
} |
|
|
|
void dvlnet_udp::packet_in::create(dvlnet_udp::buffer_t buf) |
|
{ |
|
if (have_encrypted || have_decrypted) |
|
ABORT(); |
|
encrypted_buffer = std::move(buf); |
|
have_encrypted = true; |
|
} |
|
|
|
void dvlnet_udp::packet_in::decrypt() |
|
{ |
|
if (!have_encrypted) |
|
ABORT(); |
|
if (have_decrypted) |
|
return; |
|
if (!disable_encryption) { |
|
if (encrypted_buffer.size() < crypto_secretbox_NONCEBYTES + |
|
crypto_secretbox_MACBYTES + sizeof(packet_type) + 2 * sizeof(plr_t)) |
|
throw dvlnet_udp::packet_exception(); |
|
auto pktlen = encrypted_buffer.size() - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES; |
|
decrypted_buffer.resize(pktlen); |
|
if (crypto_secretbox_open_easy(decrypted_buffer.data(), |
|
encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, |
|
encrypted_buffer.size() - crypto_secretbox_NONCEBYTES, |
|
encrypted_buffer.data(), |
|
key.data())) |
|
throw dvlnet_udp::packet_exception(); |
|
} else { |
|
if (encrypted_buffer.size() < sizeof(packet_type) + 2 * sizeof(plr_t)) |
|
throw dvlnet_udp::packet_exception(); |
|
decrypted_buffer = encrypted_buffer; |
|
} |
|
|
|
process_data(); |
|
|
|
have_decrypted = true; |
|
} |
|
|
|
void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, |
|
dvlnet_udp::plr_t s, |
|
dvlnet_udp::plr_t d, |
|
dvlnet_udp::buffer_t m) |
|
{ |
|
if (have_encrypted || have_decrypted) |
|
ABORT(); |
|
if (t != PT_MESSAGE) |
|
ABORT(); |
|
have_decrypted = true; |
|
m_type = t; |
|
m_src = s; |
|
m_dest = d; |
|
m_message = std::move(m); |
|
} |
|
|
|
void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, |
|
dvlnet_udp::plr_t s, |
|
dvlnet_udp::plr_t d, |
|
dvlnet_udp::turn_t u) |
|
{ |
|
if (have_encrypted || have_decrypted) |
|
ABORT(); |
|
if (t != PT_TURN) |
|
ABORT(); |
|
have_decrypted = true; |
|
m_type = t; |
|
m_src = s; |
|
m_dest = d; |
|
m_turn = u; |
|
} |
|
|
|
void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, |
|
dvlnet_udp::plr_t s, |
|
dvlnet_udp::plr_t d, |
|
dvlnet_udp::cookie_t c) |
|
{ |
|
if (have_encrypted || have_decrypted) |
|
ABORT(); |
|
if (t != PT_JOIN_REQUEST) |
|
ABORT(); |
|
have_decrypted = true; |
|
m_type = t; |
|
m_src = s; |
|
m_dest = d; |
|
m_cookie = c; |
|
} |
|
|
|
void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, |
|
dvlnet_udp::plr_t s, |
|
dvlnet_udp::plr_t d, |
|
dvlnet_udp::cookie_t c, |
|
dvlnet_udp::plr_t n, |
|
dvlnet_udp::buffer_t i) |
|
{ |
|
if (have_encrypted || have_decrypted) |
|
ABORT(); |
|
if (t != PT_JOIN_ACCEPT) |
|
ABORT(); |
|
have_decrypted = true; |
|
m_type = t; |
|
m_src = s; |
|
m_dest = d; |
|
m_cookie = c; |
|
m_newplr = n; |
|
m_info = i; |
|
} |
|
|
|
void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, |
|
dvlnet_udp::plr_t s, |
|
dvlnet_udp::plr_t d, |
|
dvlnet_udp::plr_t o) |
|
{ |
|
if (have_encrypted || have_decrypted) |
|
ABORT(); |
|
if (t != PT_LEAVE_GAME) |
|
ABORT(); |
|
have_decrypted = true; |
|
m_type = t; |
|
m_src = s; |
|
m_dest = d; |
|
m_oldplr = o; |
|
} |
|
|
|
void dvlnet_udp::packet_out::encrypt() |
|
{ |
|
if (!have_decrypted) |
|
ABORT(); |
|
if (have_encrypted) |
|
return; |
|
|
|
process_data(); |
|
|
|
if (!disable_encryption) { |
|
auto len_cleartext = encrypted_buffer.size(); |
|
encrypted_buffer.insert(encrypted_buffer.begin(), crypto_secretbox_NONCEBYTES, 0); |
|
encrypted_buffer.insert(encrypted_buffer.end(), crypto_secretbox_MACBYTES, 0); |
|
randombytes_buf(encrypted_buffer.data(), crypto_secretbox_NONCEBYTES); |
|
if (crypto_secretbox_easy(encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, |
|
encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, |
|
len_cleartext, |
|
encrypted_buffer.data(), |
|
key.data())) |
|
ABORT(); |
|
} |
|
have_encrypted = true; |
|
}
|
|
|