#![allow(unused)]
use crate::kcp2k::Kcp2KMode;
use crate::kcp2k_config::Kcp2KConfig;
use crate::kcp2k_connection::Kcp2kConnection;
use log::info;
use revel_cell::arc::Arc;
use socket2::{SockAddr, Socket};
use std::fmt::{Display, Formatter};
use std::hash::{DefaultHasher, Hash, Hasher};
use std::io::Error;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
pub(crate) enum Kcp2KConnectionStates {
None = 0,
Authenticated = 1,
Connected = 2,
Disconnected = 3,
}
#[derive(Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
pub(crate) enum Kcp2KReliableHeader {
None = 0,
Hello = 1,
Ping = 2,
Data = 3,
}
impl Into<u8> for Kcp2KReliableHeader {
fn into(self) -> u8 {
self as u8
}
}
impl From<u8> for Kcp2KReliableHeader {
fn from(value: u8) -> Self {
match value {
1 => Kcp2KReliableHeader::Hello,
2 => Kcp2KReliableHeader::Ping,
3 => Kcp2KReliableHeader::Data,
_ => Kcp2KReliableHeader::None,
}
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
pub(crate) enum Kcp2KUnreliableHeader {
Data = 4,
Disconnect = 5,
Ping = 6,
}
impl Into<u8> for Kcp2KUnreliableHeader {
fn into(self) -> u8 {
self as u8
}
}
impl From<u8> for Kcp2KUnreliableHeader {
fn from(value: u8) -> Self {
match value {
4 => Kcp2KUnreliableHeader::Data,
5 => Kcp2KUnreliableHeader::Disconnect,
6 => Kcp2KUnreliableHeader::Ping,
_ => Kcp2KUnreliableHeader::Disconnect,
}
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
#[repr(u8)]
pub enum Kcp2KChannel {
None = 0,
Reliable = 1,
Unreliable = 2,
}
impl Into<u8> for Kcp2KChannel {
fn into(self) -> u8 {
self as u8
}
}
impl From<u8> for Kcp2KChannel {
fn from(value: u8) -> Self {
match value {
1 => Kcp2KChannel::Reliable,
2 => Kcp2KChannel::Unreliable,
_ => Kcp2KChannel::Reliable,
}
}
}
#[derive(Clone)]
pub enum Kcp2KError {
None(String), DnsResolve(String), Timeout(String), Congestion(String), InvalidReceive(String), InvalidSend(String), ConnectionClosed(String), Unexpected(String), SendError(String), ConnectionNotFound(String), }
impl Display for Kcp2KError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Kcp2KError::None(msg) => write!(f, "None: {}", msg),
Kcp2KError::DnsResolve(msg) => write!(f, "DnsResolve: {}", msg),
Kcp2KError::Timeout(msg) => write!(f, "Timeout: {}", msg),
Kcp2KError::Congestion(msg) => write!(f, "Congestion: {}", msg),
Kcp2KError::InvalidReceive(msg) => write!(f, "InvalidReceive: {}", msg),
Kcp2KError::InvalidSend(msg) => write!(f, "InvalidSend: {}", msg),
Kcp2KError::ConnectionClosed(msg) => write!(f, "ConnectionClosed: {}", msg),
Kcp2KError::Unexpected(msg) => write!(f, "Unexpected: {}", msg),
Kcp2KError::SendError(msg) => write!(f, "SendError: {}", msg),
Kcp2KError::ConnectionNotFound(msg) => write!(f, "ConnectionNotFound: {}", msg),
}
}
}
impl Default for Kcp2KError {
fn default() -> Self {
Kcp2KError::None("None".to_string())
}
}
pub type CallbackFuncType = fn(&Kcp2kConnection, Callback);
#[derive(Debug)]
pub enum CallbackType {
OnConnected,
OnData,
OnError,
OnDisconnected,
}
pub struct Callback {
pub r#type: CallbackType,
pub conn_id: u64,
pub channel: Kcp2KChannel,
pub data: Vec<u8>,
pub error: Kcp2KError,
}
impl Display for Callback {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self.r#type {
CallbackType::OnConnected => {
write!(f, "OnConnected: id {} ", self.conn_id)
}
CallbackType::OnData => {
write!(f, "OnData: id {} {:?} {:?}", self.conn_id, self.channel, self.data.to_vec())
}
CallbackType::OnDisconnected => {
write!(f, "OnDisconnected: id {}", self.conn_id)
}
CallbackType::OnError => {
write!(f, "OnError: id {} - {}", self.conn_id, self.error)
}
}
}
}
impl Default for Callback {
fn default() -> Self {
Self {
r#type: CallbackType::OnError,
conn_id: 0,
channel: Kcp2KChannel::None,
data: Vec::new(),
error: Kcp2KError::default(),
}
}
}
pub(crate) fn configure_socket_buffers(socket: &Socket, config: &Kcp2KConfig) -> Result<(), Error> {
let initial_receive = socket.recv_buffer_size()?;
let initial_send = socket.send_buffer_size()?;
socket.set_recv_buffer_size(config.recv_buffer_size)?;
socket.set_send_buffer_size(config.send_buffer_size)?;
info!(
"[KCP2K] RecvBuf = {}=>{} ({}x) SendBuf = {}=>{} ({}x)",
initial_receive,
socket.recv_buffer_size()?,
socket.recv_buffer_size()? / initial_receive,
initial_send,
socket.send_buffer_size()?,
socket.send_buffer_size()? / initial_send
);
Ok(())
}
pub(crate) fn connection_hash(sock_addr: &SockAddr) -> u64 {
let mut hasher = DefaultHasher::new();
sock_addr.hash(&mut hasher);
hasher.finish()
}
pub(crate) fn generate_cookie() -> u32 {
let start = SystemTime::now();
let since_the_epoch = start.duration_since(UNIX_EPOCH).expect("Time went backwards");
let nanos = since_the_epoch.as_nanos();
let cookie_val = (nanos as u32)
^ ((nanos >> 32) as u32) ^ ((nanos >> 64) as u32)
^ ((nanos >> 96) as u32);
cookie_val
}