54 Commits

Author SHA1 Message Date
a6eb7f6e97 Merge pull request 'NetChannels' (#20) from NetChannels into main
Reviewed-on: #20
2025-08-13 19:32:54 -07:00
46184df89c Fixed the logger. 2025-07-27 23:50:13 -07:00
73f7ec1a8d Optimized Request and Response classes. 2025-06-01 22:16:32 -07:00
135f855309 Merge remote-tracking branch 'origin/NetChannels' into NetChannels
# Conflicts:
#	src/io/socket/SSL.cpp
2025-05-22 23:56:22 -07:00
159428ea76 Backup. 2025-05-22 23:56:00 -07:00
c23cbc275f Backup. 2025-05-22 17:34:09 -07:00
fbd8464043 Fixed SSL and TCP Bind. 2025-05-22 07:05:11 -07:00
f52afe9c92 Fixed audio destruction and construction. 2025-05-18 23:40:09 -07:00
61fb586f86 Added frequency counter to AARCH64.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Has been cancelled
Build & Release / Linux-AARCH64-Build (push) Has been cancelled
Build & Release / Windows-AMD64-Build (push) Has been cancelled
2025-05-17 17:37:12 -07:00
c19c6269aa Fixed CI/CD for Raspberry Pi.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 4m17s
Build & Release / Linux-AMD64-Build (push) Successful in 7m12s
Build & Release / Linux-AARCH64-Build (push) Successful in 20m56s
2025-05-16 21:44:24 -07:00
0b1a0c9689 Fixed CI/CD.
Some checks failed
Build & Release / Linux-AARCH64-Build (push) Failing after 7s
Build & Release / Windows-AMD64-Build (push) Successful in 4m15s
Build & Release / Linux-AMD64-Build (push) Successful in 7m14s
2025-05-16 21:35:27 -07:00
83bb62456a Updated README.
Some checks failed
Build & Release / Linux-AARCH64-Build (push) Failing after 2s
Build & Release / Windows-AMD64-Build (push) Successful in 4m25s
Build & Release / Linux-AMD64-Build (push) Successful in 7m31s
2025-05-16 21:20:00 -07:00
f1d1a1cbb1 Updated README.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 8s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Successful in 5m9s
2025-05-16 21:18:34 -07:00
8bf4f6336f Fixed CMAKE to remove ALSA dependency. 2025-05-17 03:51:20 +01:00
25e40560b7 Updated README. 2025-05-11 19:46:25 -07:00
bce48fe121 Fixed "System::OpenURI". Added SHA256. Added URI safe Base64 methods.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 6m9s
Build & Release / Linux-AMD64-Build (push) Successful in 15m26s
Build & Release / Linux-AARCH64-Build (push) Successful in 45m54s
2025-05-11 19:43:50 -07:00
2cb01a7c65 Fixed Windows CI/CD and fixed AVX on AARCH64 again.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 5m35s
Build & Release / Linux-AMD64-Build (push) Successful in 15m24s
Build & Release / Linux-AARCH64-Build (push) Successful in 45m55s
2025-05-09 19:43:05 -07:00
3025b76bec Fixed AVX undefined symbols on AARCH64 and removed AVX from ehs::Util::Compare.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 31s
Build & Release / Linux-AMD64-Build (push) Successful in 15m25s
Build & Release / Linux-AARCH64-Build (push) Failing after 22m49s
2025-05-09 19:17:09 -07:00
0cec9789b1 Cached CPU features, added AVX2, and AVX512.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 4m42s
Build & Release / Linux-AMD64-Build (push) Successful in 15m40s
Build & Release / Linux-AARCH64-Build (push) Failing after 45m49s
2025-05-08 22:41:05 -07:00
63eba0d2db Fixed Str constructor not to check for a null-terminator if given a size of zero. 2025-05-02 07:01:40 -07:00
c5b281d73c Added String<T, N>.ParseArgs(). 2025-04-14 13:40:00 -07:00
8d28f3547c Merge remote-tracking branch 'origin/NetChannels' into NetChannels 2025-04-14 00:27:26 -07:00
a7f09382fd Fixed vector. 2025-04-14 00:22:10 -07:00
fd452f6643 Merge pull request 'NetChannels' (#19) from NetChannels into main
Reviewed-on: #19
2025-03-28 23:11:54 -07:00
c437a39e1d Added missing dependency on Windows.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 4m45s
Build & Release / Linux-AMD64-Build (push) Successful in 14m40s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m39s
2025-03-28 21:47:47 -07:00
8b53b6e4d1 Implemented ICMPv6 on Windows.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 3m34s
Build & Release / Linux-AMD64-Build (push) Successful in 14m39s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m40s
2025-03-28 21:24:13 -07:00
ff42dfd3a4 Added ICMPv6 support to Linux.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 3m31s
Build & Release / Linux-AMD64-Build (push) Successful in 14m40s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m42s
2025-03-28 20:53:48 -07:00
d8c5327180 Added ICMPv6 support to Windows.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Has been cancelled
Build & Release / Linux-AARCH64-Build (push) Has been cancelled
Build & Release / Windows-AMD64-Build (push) Has been cancelled
2025-03-28 20:47:46 -07:00
42b26045a6 Added ICMPv6 support to Linux. 2025-03-27 00:15:02 -07:00
d41f71f17d Added IPv4 ICMP support to Windows.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 5m1s
Build & Release / Linux-AMD64-Build (push) Successful in 14m41s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m40s
2025-03-26 11:45:54 -07:00
c19c0bc80b Renamed member variables and parameters.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 4m10s
Build & Release / Linux-AMD64-Build (push) Successful in 14m40s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m37s
2025-03-26 10:42:29 -07:00
86149d246a Renamed member variables and parameters.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Failing after 10s
Build & Release / Linux-AARCH64-Build (push) Failing after 14s
Build & Release / Windows-AMD64-Build (push) Successful in 4m16s
2025-03-26 10:29:20 -07:00
1e55b11eed Fixed CMakeLists.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 4m23s
Build & Release / Linux-AMD64-Build (push) Successful in 14m40s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m36s
2025-03-25 19:43:42 -07:00
ce225b2888 Fixed CMakeLists and BaseICMP.cpp.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Has been cancelled
Build & Release / Linux-AARCH64-Build (push) Has been cancelled
Build & Release / Windows-AMD64-Build (push) Has been cancelled
2025-03-25 19:42:40 -07:00
eb3d345c5a Fixed gitea workflow.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 9m49s
Build & Release / Linux-AMD64-Build (push) Successful in 14m41s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m37s
2025-03-25 19:26:10 -07:00
6cf4977a6c Fixed gitea workflow.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Has been cancelled
Build & Release / Linux-AARCH64-Build (push) Has been cancelled
Build & Release / Windows-AMD64-Build (push) Has been cancelled
2025-03-25 19:22:08 -07:00
ae226c9a84 Fixed gitea workflow.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 15s
Build & Release / Linux-AMD64-Build (push) Successful in 14m41s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m37s
2025-03-25 19:20:24 -07:00
bf3b063e96 Fixed gitea workflow.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 19s
Build & Release / Linux-AMD64-Build (push) Successful in 14m39s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m36s
2025-03-25 19:17:53 -07:00
e071877045 Fixed gitea workflow.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 14s
Build & Release / Linux-AMD64-Build (push) Successful in 14m40s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m37s
2025-03-25 19:15:32 -07:00
af90f90156 Fixed gitea workflow.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 14s
Build & Release / Linux-AMD64-Build (push) Successful in 14m39s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m37s
2025-03-25 18:49:14 -07:00
389fa61fba Merge pull request 'Fixed gitea workflow.' (#18) from NetChannels into main
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 21s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m31s
Build & Release / Linux-AMD64-Build (push) Successful in 15m15s
Reviewed-on: #18
2025-03-25 18:43:47 -07:00
16ef5bbb74 Fixed gitea workflow.
Some checks failed
Build & Release / Linux-AMD64-Build (push) Successful in 14m41s
Build & Release / Windows-AMD64-Build (push) Failing after 23s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m36s
2025-03-25 18:42:56 -07:00
a67197766e Merge pull request 'Fixed gitea workflow.' (#17) from NetChannels into main
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 25s
Build & Release / Linux-AMD64-Build (push) Failing after 11m42s
Build & Release / Linux-AARCH64-Build (push) Successful in 43m39s
Reviewed-on: #17
2025-03-25 18:37:27 -07:00
6cba7d6698 Fixed gitea workflow. 2025-03-25 18:35:52 -07:00
ae414c5c99 Merge pull request 'Added CPU::GetCacheLineSize() definition for Windows.' (#16) from NetChannels into main
Reviewed-on: #16
2025-03-25 16:50:40 -07:00
9ab62d0545 Added CPU::GetCacheLineSize() definition for Windows.
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 25s
Build & Release / Linux-AMD64-Build (push) Failing after 13m28s
Build & Release / Linux-AARCH64-Build (push) Failing after 1m0s
2025-03-25 16:45:18 -07:00
b44e55a92c Merge pull request 'NetChannels' (#15) from NetChannels into main
Reviewed-on: EventHorizonStudio/EHS#15
2025-03-23 03:22:41 -07:00
53d86eb539 Merge remote-tracking branch 'origin/NetChannels' into NetChannels
Some checks failed
Build & Release / Windows-AMD64-Build (push) Failing after 9m34s
Build & Release / Linux-AMD64-Build (push) Failing after 1m58s
Build & Release / Linux-AARCH64-Build (push) Failing after 5m21s
2025-03-23 03:11:24 -07:00
352b4d612f First commit for ICMP capabilities, added CPU::GetCacheLineSize(), and removed BaseObj from containers. 2025-03-23 03:10:35 -07:00
89925fe820 Renamed member variables and parameters. 2025-01-30 13:01:01 -08:00
16b56a7084 Made NetChannel methods public in EHC. 2025-01-30 12:32:52 -08:00
62f8a662a0 Backup. 2025-01-29 16:21:11 -08:00
39bbcd0d56 Added missing constructor for NetChannel in NetServerCh. 2025-01-28 04:28:55 -08:00
981b40d3b1 Finished implementing, now for the testing phase. 2025-01-26 21:43:17 -08:00
102 changed files with 5994 additions and 2363 deletions

View File

@@ -22,10 +22,9 @@ jobs:
- name: Building/Compiling/Installing Project
run: |
cd ${{ gitea.workspace }}
vcpkg install
mkdir build
cd build
cmake -A x64 -DCMAKE_BUILD_TYPE=Release ..
cmake -A x64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" ..
cmake --build . --config Release
cmake --install .
@@ -36,6 +35,8 @@ jobs:
mv build/Release/EHS_Dyn.dll bin
mv build/Release/StrToHash.exe bin
mv build/Release/zlib1.dll bin
mv build/Release/libcrypto-3-x64.dll bin
mv build/Release/libssl-3-x64.dll bin
mkdir lib
mv build/Release/EHS_Stc.lib lib
mv build/Release/EHS_Dyn.lib lib
@@ -56,6 +57,7 @@ jobs:
files: |-
ehs-windows-amd64.zip
api_key: '${{secrets.RELEASE_TOKEN}}'
pre_release: false
Linux-AMD64-Build:
runs-on: linux-x86_64
@@ -65,7 +67,7 @@ jobs:
- name: Installing Dependencies
run: |
sudo pacman -S --noconfirm doxygen zip alsa-lib libxcb xcb-util-cursor pipewire
sudo pacman -S --noconfirm doxygen ninja zip libxcb xcb-util-cursor pipewire
- name: Generating Documentation
run: |
@@ -74,7 +76,7 @@ jobs:
- name: Building/Compiling/Installing Project
run: |
cd ${{ gitea.workspace }}
cmake -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB .
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB .
cmake --build . --config Release
cmake --install .
@@ -101,6 +103,7 @@ jobs:
files: |-
ehs-linux-amd64.zip
api_key: '${{secrets.RELEASE_TOKEN}}'
pre_release: false
Linux-AARCH64-Build:
runs-on: linux-aarch64
@@ -109,7 +112,7 @@ jobs:
uses: actions/checkout@v3
- name: Installing Dependencies
run: sudo apt install -y doxygen zip libasound2-dev libxcb1-dev libxcb-xinput-dev libxcb-cursor-dev libpipewire-0.3-dev
run: sudo apt install -y doxygen ninja-build zip libxcb1-dev libxcb-xinput-dev libxcb-cursor-dev libpipewire-0.3-dev
- name: Generating Documentation
run: |
@@ -118,7 +121,7 @@ jobs:
- name: Building/Compiling/Installing Project
run: |
cd ${{ gitea.workspace }}
cmake -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB .
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DLINUX_WINDOW_SYSTEM:STRING=XCB .
cmake --build . --config Release
cmake --install .
@@ -145,3 +148,4 @@ jobs:
files: |-
ehs-linux-aarch64.zip
api_key: '${{secrets.RELEASE_TOKEN}}'
pre_release: false

26
Assembly.def Normal file
View File

@@ -0,0 +1,26 @@
LIBRARY EHS_Dyn
EXPORTS
?GenerateSeed_u64@HRNG@ehs@@SA_KXZ
?Generate_u64@HRNG@ehs@@SA_K_K0@Z
?Generate_u64@HRNG@ehs@@SA_KXZ
?GenerateSeed_s64@HRNG@ehs@@SA_JXZ
?Generate_s64@HRNG@ehs@@SA_J_J0@Z
?Generate_s64@HRNG@ehs@@SA_JXZ
?GenerateSeed_u32@HRNG@ehs@@SAIXZ
?Generate_u32@HRNG@ehs@@SAIII@Z
?Generate_u32@HRNG@ehs@@SAIXZ
?GenerateSeed_s32@HRNG@ehs@@SAHXZ
?Generate_s32@HRNG@ehs@@SAHHH@Z
?Generate_s32@HRNG@ehs@@SAHXZ
?GenerateSeed_u16@HRNG@ehs@@SAIXZ
?Generate_u16@HRNG@ehs@@SAGGG@Z
?Generate_u16@HRNG@ehs@@SAGXZ
?GenerateSeed_s16@HRNG@ehs@@SAFXZ
?Generate_s16@HRNG@ehs@@SAFFF@Z
?Generate_s16@HRNG@ehs@@SAFXZ
?GenerateSeed_u8@HRNG@ehs@@SAEXZ
?Generate_u8@HRNG@ehs@@SAEEE@Z
?Generate_u8@HRNG@ehs@@SAEXZ
?GenerateSeed_s8@HRNG@ehs@@SACXZ
?Generate_s8@HRNG@ehs@@SACCC@Z
?Generate_s8@HRNG@ehs@@SACXZ

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.25.1)
cmake_minimum_required(VERSION 3.30.4)
set(IS_OS_WINDOWS FALSE)
set(IS_OS_LINUX FALSE)
@@ -11,6 +11,8 @@ set(IS_ARCH_ARM FALSE)
project(EHS CXX C)
set(CMAKE_VERBOSE_MAKEFILE ON)
if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
set(IS_OS_WINDOWS TRUE)
set(USER_HOME_DIRECTORY "$ENV{USERPROFILE}")
@@ -51,6 +53,7 @@ set(EHS_SOURCES
src/Color3.cpp include/ehs/Color3.h
src/Version.cpp include/ehs/Version.h
src/Base64.cpp include/ehs/Base64.h
src/SHA256.cpp include/ehs/SHA256.h
src/Data.cpp include/ehs/Data.h
src/Range.cpp include/ehs/Range.h
src/Util.cpp include/ehs/Util.h
@@ -97,6 +100,8 @@ set(EHS_SOURCES
include/ehs/system/OS.h
include/ehs/system/Semaphore.h
include/ehs/system/System.h
include/ehs/system/AVX2.h
include/ehs/system/AVX512.h
src/json/Json.cpp include/ehs/json/Json.h
src/json/JsonBase.cpp include/ehs/json/JsonBase.h
@@ -134,7 +139,7 @@ set(EHS_SOURCES
include/ehs/io/socket/ehc/NetUtils.h
src/io/socket/EHC.cpp include/ehs/io/socket/EHC.h
src/io/socket/ehc/NetFrags.cpp include/ehs/io/socket/ehc/NetFrags.h
src/io/socket/ehc/NetFrag.cpp include/ehs/io/socket/ehc/NetFrag.h
src/io/socket/ehc/NetEnd.cpp include/ehs/io/socket/ehc/NetEnd.h
src/io/socket/ehc/NetSys.cpp include/ehs/io/socket/ehc/NetSys.h
src/io/socket/ehc/NetOp.cpp include/ehs/io/socket/ehc/NetOp.h
@@ -187,6 +192,17 @@ set(EHS_SOURCES
include/ehs/io/Directory.h
include/ehs/io/socket/ehc/NetEnc.h
src/io/socket/ehc/NetEnc.cpp
include/ehs/io/socket/ehc/NetChannel.h
src/io/socket/ehc/NetChannel.cpp
include/ehs/io/socket/ehc/NetServerCh.h
include/ehs/io/socket/ehc/NetClientCh.h
src/io/socket/ehc/NetClientCh.cpp
src/io/socket/ehc/NetServerCh.cpp
src/io/socket/ehc/NetUtils.cpp
include/ehs/io/socket/BaseICMP.h src/io/socket/BaseICMP.cpp
include/ehs/io/socket/ICMP.h
src/io/socket/QueryVar.cpp include/ehs/io/socket/QueryVar.h
src/io/socket/HeaderVar.cpp include/ehs/io/socket/HeaderVar.h
)
if (IS_OS_WINDOWS)
@@ -205,7 +221,10 @@ if (IS_OS_WINDOWS)
src/io/COM.cpp include/ehs/io/COM.h
src/system/CPU_MSVC_AMD64.asm src/HRNG_MSVC.asm src/Math_MSVC_AMD64.asm
src/io/Directory_W32.cpp include/ehs/io/Directory_W32.h
include/ehs/io/socket/ICMP_W32.h src/io/socket/ICMP_W32.cpp
src/system/AVX2_MSVC_AMD64.asm src/system/AVX512_MSVC_AMD64.asm
)
elseif (IS_OS_LINUX)
list(APPEND EHS_SOURCES
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
@@ -222,9 +241,10 @@ elseif (IS_OS_LINUX)
src/system/User.cpp include/ehs/system/User.h
src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h
src/io/Usb_LNX.cpp include/ehs/io/Usb_LNX.h
include/ehs/io/socket/ICMP_LNX.h src/io/socket/ICMP_LNX.cpp
)
#set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
set(LINUX_WINDOW_SYSTEM "XCB" CACHE STRING "Linux Window System")
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
add_compile_definitions(EHS_WS_WAYLAND)
@@ -240,17 +260,14 @@ elseif (IS_OS_LINUX)
endif ()
if (IS_ARCH_AMD64)
list(APPEND EHS_SOURCES src/system/CPU_GCC_AMD64.asm src/HRNG_GCC.asm src/Math_GCC_AMD64.asm)
list(APPEND EHS_SOURCES src/system/CPU_GCC_AMD64.asm src/HRNG_GCC.asm src/Math_GCC_AMD64.asm src/system/AVX2_GCC_AMD64.asm src/system/AVX512_GCC_AMD64.asm)
elseif (IS_ARCH_ARM64)
list(APPEND EHS_SOURCES src/system/CPU_ARM64.cpp src/HRNG_ARM64.cpp src/Math_GCC_ARM64.s)
list(APPEND EHS_SOURCES src/system/CPU_ARM64.cpp src/system/CPU_GCC_AARCH64.s src/HRNG_ARM64.cpp src/Math_GCC_ARM64.s src/system/AVX2_AARCH64.cpp src/system/AVX512_AARCH64.cpp)
endif ()
endif()
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
#message("${CMAKE_CXX_FLAGS}")
add_library(EHS_Stc STATIC ${EHS_SOURCES})
add_library(EHS_Dyn SHARED ${EHS_SOURCES})
add_library(EHS_Dyn SHARED ${EHS_SOURCES} Assembly.def)
add_executable(StrToHash src/StrToHash.cpp)
target_compile_definitions(EHS_Dyn PRIVATE EHS_LIB_EXPORT)
@@ -300,7 +317,7 @@ target_link_libraries(EHS_Dyn OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
target_link_libraries(StrToHash OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
if (IS_OS_WINDOWS)
target_link_libraries(EHS_Dyn avrt ws2_32)
target_link_libraries(EHS_Dyn avrt ws2_32 IPHLPAPI)
target_link_libraries(StrToHash ws2_32 avrt EHS_Stc)
elseif (IS_OS_LINUX)
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
@@ -311,6 +328,6 @@ elseif (IS_OS_LINUX)
target_link_libraries(StrToHash xcb xcb-cursor xcb-xfixes xcb-xinput)
endif ()
target_link_libraries(EHS_Dyn z asound pipewire-0.3)
target_link_libraries(StrToHash z asound EHS_Stc)
target_link_libraries(EHS_Dyn z pipewire-0.3)
target_link_libraries(StrToHash z EHS_Stc)
endif ()

View File

@@ -22,6 +22,7 @@ This project does not fully follow the C++ standard.
- Semaphores
- CPU information and features at runtime
- HTTP(S) Socket Layer
- ICMP & ICMPv6 Socket
- TCP Socket
- UDP Socket
- COM (Serial) IO
@@ -37,6 +38,8 @@ This project does not fully follow the C++ standard.
- Asynchronous Task System
- URI Parsing
- USB (WIP)
- Base64
- SHA256
### Supported Architectures
- AMD64

View File

@@ -12,7 +12,7 @@ namespace ehs
/// @tparam T Array data type to use.
/// @tparam N Number data type to use.
template<typename T, typename N = UInt_64>
class Array : public BaseObj
class Array
{
protected:
T* data;
@@ -20,7 +20,7 @@ namespace ehs
public:
/// Frees any data created on the heap.
~Array() override
~Array()
{
delete[] data;
}
@@ -29,7 +29,6 @@ namespace ehs
Array()
: data(nullptr), size(0)
{
AddType("Array");
}
/// Initializes an empty array with the given size.
@@ -37,7 +36,6 @@ namespace ehs
explicit Array(const N size)
: data(new T[size]), size(size)
{
AddType("Array");
}
/// Initializes this array with an initializer list object.
@@ -45,8 +43,6 @@ namespace ehs
Array(std::initializer_list<T> list)
: data(new T[list.size()]), size(list.size())
{
AddType("Array");
N i = 0;
for (auto v = list.begin(); v != list.end(); ++v)
data[i++] = std::move(*v);
@@ -58,14 +54,12 @@ namespace ehs
Array(const T* const data, const N size)
: data(new T[size]), size(size)
{
AddType("Array");
for (N i = 0; i < size; ++i)
this->data[i] = data[i];
}
Array(Array&& array) noexcept
: BaseObj(array), data(array.data), size(array.size)
: data(array.data), size(array.size)
{
array.data = nullptr;
array.size = 0;
@@ -74,7 +68,7 @@ namespace ehs
/// Copies all members from the given array object.
/// @param [in] array The array object to copy from.
Array(const Array& array)
: BaseObj((BaseObj&&)array), data(new T[array.size]), size(array.size)
: data(new T[array.size]), size(array.size)
{
for (N i = 0; i < size; ++i)
data[i] = array.data[i];
@@ -85,8 +79,6 @@ namespace ehs
if (this == &array)
return *this;
BaseObj::operator=((BaseObj&&)array);
delete[] data;
data = array.data;
size = array.size;
@@ -105,8 +97,6 @@ namespace ehs
if (this == &array)
return *this;
BaseObj::operator=(array);
delete[] data;
data = new T[array.size];
for (N i = 0; i < array.size; ++i)

View File

@@ -8,17 +8,26 @@ namespace ehs
class EHS_LIB_IO Base64
{
private:
static const char ascii[];
static constexpr UInt_8 asciiUrl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
static constexpr UInt_8 ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
public:
static Str_8 EncodeURL(const Str_8 &input);
static Str_8 Encode(const Str_8 &input);
static Str_8 DecodeURL(const Str_8 &input);
static Str_8 Decode(const Str_8 &input);
private:
static char Find(char c);
static UInt_8 FindURL(const UInt_8 &c);
static bool IsBase64(char c);
static UInt_8 Find(const UInt_8 &c);
static bool IsBase64URL(const UInt_8 &c);
static bool IsBase64(const UInt_8 &c);
};
}

View File

@@ -5,7 +5,7 @@
namespace ehs
{
class EHS_LIB_IO HRNG
class HRNG
{
public:
static UInt_64 GenerateSeed_u64();

View File

@@ -63,7 +63,7 @@ namespace ehs
/// @param [in] tags The tags to associate this log with.
/// @param [in] code The unique code to use.
/// @param [in] msg Detailed information about what happened.
Log(LogType type, const std::initializer_list<Str_8> &tags, UInt_64 code, Str_8 msg);
Log(LogType type, const Str_8 &tags, UInt_64 code, Str_8 msg);
/// Initializes members with the given information.
/// @param [in] tags The tags to associate this log with.
@@ -134,17 +134,17 @@ namespace ehs
#ifndef EHS_LOG_INT
#ifdef EHS_DEBUG
#define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg})
#define EHS_LOG_INT(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAcronym_8()) + ", " + EHS_FILE + ", " + EHS_FUNC + ", " + ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE), code, msg))
#else
#define EHS_LOG_INT(type, code, msg) ehs::Log::Raise({type, {ehs::GetAcronym_8(), EHS_FUNC}, code, msg})
#define EHS_LOG_INT(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAcronym_8()) + ", " + EHS_FUNC, code, msg))
#endif
#endif
#ifndef EHS_LOG
#ifdef EHS_DEBUG
#define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FILE, EHS_FUNC, ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE)}, code, msg})
#define EHS_LOG(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAppName_8()) + ", " + EHS_FILE + ", " + EHS_FUNC + ", " + ehs::Str_8::FromNum((ehs::UInt_32)EHS_LINE), code, msg))
#else
#define EHS_LOG(type, code, msg) ehs::Log::Raise({type, {ehs::GetAppName_8(), EHS_FUNC}, code, msg})
#define EHS_LOG(type, code, msg) ehs::Log::Raise(ehs::Log(type, ehs::Str_8(ehs::GetAppName_8()) + ", " + EHS_FUNC, code, msg))
#endif
#endif

59
include/ehs/SHA256.h Normal file
View File

@@ -0,0 +1,59 @@
#pragma once
#include "Types.h"
namespace ehs
{
class EHS_LIB_IO SHA256
{
private:
static UInt_32 ROTR(UInt_32 x, UInt_32 n);
static UInt_32 CH(UInt_32 x, UInt_32 y, UInt_32 z);
static UInt_32 MAJ(UInt_32 x, UInt_32 y, UInt_32 z);
static UInt_32 EP0(UInt_32 x);
static UInt_32 EP1(UInt_32 x);
static UInt_32 SIG0(UInt_32 x);
static UInt_32 SIG1(UInt_32 x);
static constexpr UInt_32 k[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
UInt_32 state[8];
UInt_64 bitLen;
Byte data[64];
UInt_64 dataLen;
public:
SHA256();
SHA256(SHA256 &&other) noexcept;
SHA256(const SHA256 &other);
SHA256 &operator=(SHA256 &&other) noexcept;
SHA256 &operator=(const SHA256 &other);
void Update(const Byte *data, UInt_64 len);
void Final(Byte hash[32]);
void Hash(const Byte *data, UInt_64 len, Byte hash[32]);
private:
void Transform(const Byte data[64]);
};
}

View File

@@ -21,7 +21,7 @@
namespace ehs
{
template<typename N = UInt_64>
class Serializer : public BaseObj
class Serializer
{
private:
Endianness endianness;
@@ -30,7 +30,7 @@ namespace ehs
N offset;
public:
~Serializer() override
~Serializer()
{
delete[] data;
}
@@ -38,32 +38,27 @@ namespace ehs
Serializer()
: endianness(Endianness::BE), data(nullptr), size(0), offset(0)
{
AddType("Serializer");
}
Serializer(const Endianness endianness)
: endianness(endianness), data(nullptr), size(0), offset(0)
{
AddType("Serializer");
}
Serializer(const Endianness endianness, const N size)
: endianness(endianness), data(new Byte[size]), size(size), offset(0)
{
AddType("Serializer");
}
Serializer(const Endianness endianness, const Byte* const data, const N size, const N offset = 0)
: endianness(endianness), data(new Byte[size]), size(size), offset(offset)
{
AddType("Serializer");
for (N i = 0; i < size; ++i)
this->data[i] = data[i];
}
Serializer(Serializer&& serializer) noexcept
: BaseObj((BaseObj&&)serializer), endianness(serializer.endianness), data(serializer.data),
: endianness(serializer.endianness), data(serializer.data),
size(serializer.size), offset(serializer.offset)
{
serializer.data = nullptr;
@@ -72,7 +67,7 @@ namespace ehs
}
Serializer(const Serializer& serializer)
: BaseObj(serializer), endianness(serializer.endianness), data(new Byte[serializer.size]),
: endianness(serializer.endianness), data(new Byte[serializer.size]),
size(serializer.size), offset(serializer.offset)
{
for (N i = 0; i < serializer.size; ++i)
@@ -84,8 +79,6 @@ namespace ehs
if (this == &serializer)
return *this;
BaseObj::operator=((Serializer&&)serializer);
endianness = serializer.endianness;
delete[] data;
data = serializer.data;
@@ -104,8 +97,6 @@ namespace ehs
if (this == &serializer)
return *this;
BaseObj::operator=(serializer);
endianness = serializer.endianness;
delete[] data;
@@ -1228,7 +1219,7 @@ namespace ehs
void Resize(const N newSize)
{
Byte* result = new Byte[newSize];
Util::Copy(result, data, size);
Util::Copy(result, data, newSize >= size ? size : newSize);
delete[] data;
data = result;
size = newSize;

View File

@@ -25,7 +25,7 @@ namespace ehs
/// @tparam T The character's data type to use.
/// @tparam N The number data type to use.
template<typename T = Char_8, typename N = UInt_64>
class Str : public BaseObj
class Str
{
private:
N size;
@@ -33,7 +33,7 @@ namespace ehs
public:
/// Frees any data created on the heap.
~Str() override
~Str()
{
delete[] data;
}
@@ -42,22 +42,22 @@ namespace ehs
Str()
: size(0), data(nullptr)
{
AddType("Str");
}
/// Initializes members with given C-style string.
/// @param [in] str The C-style string.
/// @param [in] size The size of the given C-style string.
Str(const T* const str, const N size)
: size((size) ? size : Len(str)), data(nullptr)
: size(size), data(nullptr)
{
if (!size)
return;
data = new T[this->size + 1];
Util::Copy(data, str, Size(true));
data[this->size] = 0;
AddType("Str");
}
/// Initializes members with given C-style string.
@@ -70,8 +70,6 @@ namespace ehs
Util::Copy(data, str, Size(true));
data[size] = 0;
AddType("Str");
}
/// Initializes string with the given size.
@@ -80,13 +78,11 @@ namespace ehs
: size(size), data(new T[size + 1])
{
data[size] = 0;
AddType("Str");
}
/// A move constructor.
Str(Str&& str) noexcept
: BaseObj((BaseObj&&)str), size(str.size), data(str.data)
: size(str.size), data(str.data)
{
str.size = 0;
str.data = nullptr;
@@ -95,7 +91,7 @@ namespace ehs
/// Copies all members from the given string object.
/// @param [in] str The string object to copy from.
Str(const Str& str)
: BaseObj(str), size(str.size), data(new T[size + 1])
: size(str.size), data(new T[size + 1])
{
Util::Copy(data, str.data, Size(true));
@@ -107,8 +103,6 @@ namespace ehs
if (this == &str)
return *this;
BaseObj::operator=((BaseObj&&)str);
size = str.size;
delete[] data;
data = str.data;
@@ -127,8 +121,6 @@ namespace ehs
if (&str == this)
return *this;
BaseObj::operator=(str);
size = str.size;
delete[] data;
@@ -925,10 +917,10 @@ namespace ehs
}
/// Splits a string into a Vector with the given separator.
/// @param [in] ide The given string as the separator.
/// @param [in] delimeter The given string as the separator.
/// @param [in] max The max amount of times to split the string.
/// @returns The resulting string object.
Vector<Str<T, N>, N> Split(const Str<T, N>& ide, const N max = 0) const
Vector<Str<T, N>, N> Split(const Str<T, N>& delimeter, const N max = 0) const
{
Vector<Str<T, N>, N> result(0, 5);
@@ -936,9 +928,9 @@ namespace ehs
for (N i = 0, c = 0; i < size; ++i)
{
if (data[i] == ide[c])
if (data[i] == delimeter[c])
{
if (++c == ide.Size())
if (++c == delimeter.Size())
{
N r = i - (c - 1) - b;
if (!r)
@@ -966,17 +958,17 @@ namespace ehs
}
/// Removes all instances of the ide.
/// @param [in] ide The string to look for.
/// @param [in] delimeter The string to look for.
/// @returns The resulting string object.
Str<T, N> RemoveAll(const Str<T, N>& ide) const
Str<T, N> RemoveAll(const Str<T, N>& delimeter) const
{
Str<T, N> result(size);
for (N i = 0, b = 0, c = 0; i < size; ++i)
{
if (data[i] == ide[c])
if (data[i] == delimeter[c])
{
if (++c == ide.Size())
if (++c == delimeter.Size())
c = 0;
}
else
@@ -995,18 +987,18 @@ namespace ehs
}
/// Replaces all instances of ide with the replacer.
/// @param [in] ide The string to look for.
/// @param [in] delimeter The string to look for.
/// @param [in] replacer The string placed.
/// @returns The resulting string object.
Str ReplaceAll(const Str& ide, const Str& replacer) const
Str ReplaceAll(const Str& delimeter, const Str& replacer) const
{
Str<T, N> result;
for (N i = 0, b = 0; i < size; ++i)
{
if (data[i] == ide[b])
if (data[i] == delimeter[b])
{
if (++b == ide.Size())
if (++b == delimeter.Size())
{
result.Push(replacer);
b = 0;
@@ -1022,20 +1014,20 @@ namespace ehs
}
/// Finds the first instance of the given string object.
/// @param [in] ide The string to look for.
/// @param [in] delimeter The string to look for.
/// @param [out] index The index of the string found. Can be a nullptr.
/// @param [in] pattern The search pattern for optimization.
/// @param [in] result What index to return where the first instance is found.
/// @returns The index where the instance was found with the result varying from the result parameter.
bool Find(const Str<T, N> &ide, N* const index = nullptr, const SearchPattern pattern = SearchPattern::LEFT_RIGHT, const IndexResult result = IndexResult::BEGINNING) const
bool Find(const Str<T, N> &delimeter, N* const index = nullptr, const SearchPattern pattern = SearchPattern::LEFT_RIGHT, const IndexResult result = IndexResult::BEGINNING) const
{
if (pattern == SearchPattern::LEFT_RIGHT)
{
for (N i = 0, c = 0; i < size; ++i)
{
if (data[i] == ide[c])
if (data[i] == delimeter[c])
{
if (++c == ide.Size())
if (++c == delimeter.Size())
{
if (result == IndexResult::BEGINNING)
{
@@ -1057,16 +1049,16 @@ namespace ehs
}
else if (pattern == SearchPattern::RIGHT_LEFT)
{
for (N i = size, c = ide.Size(); i > 0; --i)
for (N i = size, c = delimeter.Size(); i > 0; --i)
{
if (data[i - 1] == ide[c - 1])
if (data[i - 1] == delimeter[c - 1])
{
if (--c == 0)
{
if (result == IndexResult::BEGINNING)
{
if (index)
*index = i - (ide.Size() - 1);
*index = i - (delimeter.Size() - 1);
return true;
}
@@ -1086,18 +1078,18 @@ namespace ehs
}
/// Checks if the current string contains the given ide.
/// @param [in] ide The given ide to check for.
/// @param [in] delimeter The given ide to check for.
/// @param [in] pattern The search pattern to use.
/// @returns True if the current string does contain the ide.
bool Contains(const Str<T, N>& ide, const SearchPattern pattern = SearchPattern::LEFT_RIGHT) const
bool Contains(const Str<T, N>& delimeter, const SearchPattern pattern = SearchPattern::LEFT_RIGHT) const
{
if (pattern == SearchPattern::LEFT_RIGHT)
{
for (N i = 0, c = 0; i < size; ++i)
{
if (data[i] == ide[c])
if (data[i] == delimeter[c])
{
if (++c == ide.Size())
if (++c == delimeter.Size())
{
return true;
}
@@ -1106,9 +1098,9 @@ namespace ehs
}
else if (pattern == SearchPattern::RIGHT_LEFT)
{
for (N i = size, c = ide.Size(); i > 0; --i)
for (N i = size, c = delimeter.Size(); i > 0; --i)
{
if (data[i - 1] == ide[c - 1])
if (data[i - 1] == delimeter[c - 1])
{
if (--c == 0)
{
@@ -1121,6 +1113,54 @@ namespace ehs
return false;
}
Vector<Str> ParseArgs() const
{
Vector<Str> args;
T *quoteStart = nullptr;
T *spaceStart = nullptr;
for (T *i = data; i <= data + size; ++i)
{
if (*i == '\"' && !spaceStart)
{
if (quoteStart)
{
args.Push(Str(quoteStart, i - quoteStart));
quoteStart = nullptr;
}
else
{
if (i + 1 < &data[size - 1])
quoteStart = i + 1;
else
args.Push({});
}
}
else if (*i == ' ' && !quoteStart)
{
if (spaceStart)
{
args.Push(Str(spaceStart, i - spaceStart));
spaceStart = i + 1;
}
else
{
if (i + 1 < &data[size - 1])
spaceStart = i + 1;
else
args.Push({});
}
}
}
if (quoteStart)
args.Push(Str(quoteStart, &data[size - 1] - (quoteStart - 1)));
else if (spaceStart)
args.Push(Str(spaceStart, &data[size - 1] - (spaceStart - 1)));
return args;
}
/// Checks if the string represents a number. Must not have any alphabetical characters.
/// @returns The result.
bool IsNum() const

View File

@@ -14,7 +14,7 @@ namespace ehs
/// @tparam N Number data type to use.
/// @note If extra memory is set to five then each time that memory is filled it will add five extra.
template<typename T, typename N = UInt_64>
class Vector : public BaseObj
class Vector
{
protected:
N rawSize;
@@ -24,7 +24,7 @@ namespace ehs
public:
/// Frees any data created on the heap.
~Vector() override
~Vector()
{
delete[] data;
}
@@ -33,7 +33,6 @@ namespace ehs
Vector()
: rawSize(0), size(0), stride(5), data(nullptr)
{
AddType("Vector");
}
/// Initializes members for pre-allocated memory to write to later.
@@ -42,7 +41,6 @@ namespace ehs
Vector(const N size, const N stride)
: rawSize(size + stride), size(size), stride(stride), data(new T[rawSize])
{
AddType("Vector");
}
/// Initializes this vector with an initializer list object.
@@ -51,8 +49,6 @@ namespace ehs
Vector(std::initializer_list<T> list, const N stride = 5)
: rawSize(0), size(list.size()), stride(stride), data(nullptr)
{
AddType("Vector");
if (stride)
{
rawSize = list.size() / stride * stride;
@@ -78,8 +74,6 @@ namespace ehs
Vector(const T* data, const N size, const N stride)
: rawSize(0), size(size), stride(stride), data(nullptr)
{
AddType("Vector");
if (stride)
{
rawSize = size / stride * stride;
@@ -100,14 +94,14 @@ namespace ehs
/// Copies all members from the given vector object.
/// @param [in] vec The vector object to copy from.
Vector(const Vector& vec)
: BaseObj(vec), rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(new T[rawSize])
: rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(new T[rawSize])
{
for (N i = 0; i < size; ++i)
data[i] = vec.data[i];
}
Vector(Vector&& vec) noexcept
: BaseObj((BaseObj&&)vec), rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(vec.data)
: rawSize(vec.rawSize), size(vec.size), stride(vec.stride), data(vec.data)
{
vec.rawSize = 0;
vec.size = 0;
@@ -123,8 +117,6 @@ namespace ehs
if (this == &vec)
return *this;
BaseObj::operator=(vec);
rawSize = vec.rawSize;
size = vec.size;
stride = vec.stride;
@@ -143,8 +135,6 @@ namespace ehs
if (this == &vec)
return *this;
BaseObj::operator=((BaseObj&&)vec);
rawSize = vec.rawSize;
size = vec.size;
stride = vec.stride;
@@ -402,7 +392,7 @@ namespace ehs
{
if (stride)
{
rawSize = (this->size + size()) / stride * stride;
rawSize = (this->size + size) / stride * stride;
if ((this->size + size) % stride)
rawSize += stride;
}
@@ -413,7 +403,7 @@ namespace ehs
T* result = new T[rawSize];
for (N i = 0; i < size; ++i)
for (N i = 0; i < this->size; ++i)
result[i] = std::move(data[i]);
delete[] data;

View File

@@ -25,6 +25,7 @@ namespace ehs
pw_core *core;
pw_stream *input;
pw_stream *output;
spa_hook paramsHook;
static void RegistryEventGlobal(void *data, UInt_32 id, UInt_32 permissions, const char *type, UInt_32 version, const spa_dict *props);

View File

@@ -8,7 +8,7 @@ namespace ehs
class EHS_LIB_IO BaseDNS
{
public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
static Str_8 Resolve(IP type, const Str_8 &hostname);
/// Resolves a hostname to an ip address.
/// @param [in] hostname The given hostname to resolve.

View File

@@ -0,0 +1,68 @@
#pragma once
#include "ehs/Serializer.h"
#include "ehs/Types.h"
#include "ehs/io/socket/Socket.h"
namespace ehs
{
struct ICMP_Header
{
UInt_8 type;
UInt_8 code;
UInt_16 checksum;
};
struct ICMP_EchoRequest
{
UInt_16 id;
UInt_16 sequence;
};
class BaseICMP
{
private:
IP version;
public:
virtual ~BaseICMP() = default;
BaseICMP();
BaseICMP(IP version);
BaseICMP(BaseICMP &&icmp) noexcept;
BaseICMP(const BaseICMP &icmp);
BaseICMP &operator=(BaseICMP &&icmp) noexcept;
BaseICMP &operator=(const BaseICMP &icmp);
virtual void Release();
UInt_64 Send(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size);
UInt_64 Receive(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data);
void SendEchoRequest(const Str_8 &address, ICMP_EchoRequest er, const Byte *data, UInt_64 size);
virtual void SetReceiveTimeout(UInt_64 timeout);
IP GetVersion() const;
virtual bool IsValid() const;
protected:
static UInt_16 ComputeChecksumV4(UInt_16 *buffer, Size length);
private:
virtual UInt_64 SendV6(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size);
virtual UInt_64 SendV4(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size);
virtual UInt_64 ReceiveV6(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const;
virtual UInt_64 ReceiveV4(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const;
};
}

View File

@@ -12,7 +12,7 @@ namespace ehs
class EHS_LIB_IO BaseTCP
{
protected:
AddrType addrType;
IP ip;
Str_8 localAddr;
UInt_16 localPort;
Str_8 remoteHostName;
@@ -24,9 +24,9 @@ namespace ehs
bool connected;
public:
static const UInt_16 HTTPS_Port = 443;
static const UInt_16 HTTP_Port = 80;
static const UInt_16 MaxHeaderSize = 8192;
static constexpr UInt_16 HTTPS_Port = 443;
static constexpr UInt_16 HTTP_Port = 80;
static constexpr UInt_16 MaxHeaderSize = 8192;
virtual ~BaseTCP() = default;
@@ -35,7 +35,7 @@ namespace ehs
/// Properly initializes the socket.
/// @param [in] type The ip version to initialize the socket with.
BaseTCP(AddrType addrType);
BaseTCP(IP ip);
BaseTCP(BaseTCP&& tcp) noexcept;
@@ -55,7 +55,7 @@ namespace ehs
/// @param [in] address The ip address to bind to.
/// @param [in] port The port to bind to.
/// @note Used for servers.
virtual void Bind(const Str_8& address, UInt_16 port) = 0;
virtual void Bind(Str_8 address, const UInt_16 &port) = 0;
/// Listens for new incoming connections.
/// @note Used for servers.
@@ -69,7 +69,7 @@ namespace ehs
/// @param [in] address The ip address to connect to.
/// @param [in] port The port to connect to.
/// @note Used for clients.
virtual void Connect(const Str_8& address, UInt_16 port) = 0;
virtual void Connect(Str_8 address, const UInt_16 &port) = 0;
/// Sends data to the connected endpoint.
/// @param [in] buffer The data to send to the endpoint.
@@ -104,7 +104,7 @@ namespace ehs
/// Retrieves the sockets ip version.
/// @returns The ip version.
AddrType GetAddressType() const;
IP GetAddressType() const;
/// Retrieves the bound ip address.
/// @returns The ip address.
@@ -150,6 +150,8 @@ namespace ehs
virtual bool IsIPv6Only() const = 0;
virtual void SetReuse(const bool &enabled) = 0;
/// Retrieves whether or not this socket was initialized.
/// @returns The result.
virtual bool IsValid() const = 0;

View File

@@ -9,9 +9,7 @@ namespace ehs
class EHS_LIB_IO BaseUDP
{
protected:
AddrType type;
Str_8 address;
UInt_16 port;
Endpoint localEndpoint;
bool bound;
public:
@@ -22,7 +20,7 @@ namespace ehs
/// Properly initializes the socket.
/// @param [in] type The ip version to initialize the socket with.
BaseUDP(AddrType type);
BaseUDP(IP version);
BaseUDP(BaseUDP&& udp) noexcept;
@@ -40,13 +38,13 @@ namespace ehs
/// @param [in] address The ip address to bind to.
/// @param [in] port The port to bind to.
/// @note Used for servers.
virtual void Bind(AddrType type, const Str_8& address, UInt_16 port) = 0;
virtual void Bind(const Endpoint &endpoint) = 0;
/// Sends data to the endpoint.
/// @param [in] type The ip version of the endpoint.
/// @param [in] address The ip address of the endpoint.
/// @param [in] port The port of the endpoint is bound to.
virtual UInt_64 Send(AddrType type, const Str_8& address, UInt_16 port, const Byte* data, UInt_64 size) = 0;
virtual UInt_64 Send(const Endpoint &endpoint, const Byte *data, UInt_64 size) = 0;
/// Receives data from the endpoint.
/// @param [out] type The ip version of the endpoint.
@@ -55,7 +53,7 @@ namespace ehs
/// @param [out] data The incoming data from the endpoint.
/// @param [in] size The max size of the buffer in bytes to store the data.
/// @returns The size of the incoming data in bytes.
virtual UInt_64 Receive(AddrType* type, Str_8* address, UInt_16* port, Byte* data, UInt_64 size) = 0;
virtual UInt_64 Receive(Endpoint *endpoint, Byte *data, UInt_64 size) = 0;
/// Retrieves whether or not this socket is bound to an ip address and port.
/// @returns The result.
@@ -73,17 +71,7 @@ namespace ehs
virtual bool IsIPv6Only() const = 0;
/// Retrieves the bound ip version.
/// @returns The result.
AddrType GetLocalAddressType() const;
/// Retrieves the bound ip address.
/// @returns The bound ip address.
Str_8 GetLocalAddress() const;
/// Retrieves the bound port.
/// @returns The bound port.
UInt_16 GetLocalPort() const;
Endpoint GetLocalEndpoint() const;
/// Retrieves whether or not this socket was initialized.
/// @returns The result.

View File

@@ -10,7 +10,7 @@ namespace ehs
class EHS_LIB_IO DNS final : public BaseDNS
{
public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
static Str_8 Resolve(IP type, const Str_8 &hostname);
static Str_8 Resolve(const Str_8 &hostname);
};

View File

@@ -7,7 +7,7 @@ namespace ehs
class EHS_LIB_IO DNS final : public BaseDNS
{
public:
static Str_8 Resolve(AddrType type, const Str_8 &hostname);
static Str_8 Resolve(IP type, const Str_8 &hostname);
static Str_8 Resolve(const Str_8 &hostname);
};

View File

@@ -1,78 +1,41 @@
#pragma once
#include "ehs/io/socket/ehc/NetUtils.h"
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/Serializer.h"
#include "ehs/Vector.h"
#include "ehs/Array.h"
#include "Socket.h"
#include "UDP.h"
namespace ehs
{
class NetSys;
class NetServerCh;
class NetClientCh;
class NetEnd;
class EHC;
typedef bool (*ConnectCb)(EHC *, NetEnd **, Serializer<UInt_64>);
typedef void (*ConnectedCb)(EHC *, NetEnd *);
typedef void (*ActiveCb)(EHC *, NetEnd *);
typedef void (*DisconnectCb)(EHC *, NetEnd *, Serializer<UInt_64>);
typedef void (*DisconnectedCb)(EHC *, NetEnd *);
typedef void (*TimeoutCb)(EHC *, NetEnd *);
class EHC
{
private:
friend class NetEnc;
friend class NetChannel;
friend class NetServerCh;
friend class NetClientCh;
friend class NetEnd;
static const Version version;
static const UInt_64 internalSys;
static const UInt_64 connectOp;
static const UInt_64 connectedOp;
static const UInt_64 rejectedOp;
static const UInt_64 disconnectOp;
static const UInt_64 disconnectedOp;
static const UInt_64 statusUpdateOp;
static const UInt_64 pingOp;
static const UInt_64 pongOp;
static const UInt_64 latencyOp;
static const UInt_64 receivedOp;
UDP udp;
Version appVer;
EndDisp disposition;
UInt_64 hashName;
Str_8 name;
bool dropPackets;
Byte* buffer;
UInt_32 bufferSize;
Array<NetEnc *> encryptions;
Array<NetSys *> systems;
UInt_32 maxEndpoints;
UInt_64 lastTSC;
float delta;
float maxTimeout;
float resendRate;
ConnectCb connectCb;
ConnectedCb connectedCb;
ActiveCb activeCb;
DisconnectCb disconnectCb;
DisconnectedCb disconnectedCb;
TimeoutCb timeoutCb;
protected:
Vector<NetEnd*> endpoints;
Array<NetEnc *> encryptions;
Array<NetServerCh *> servers;
Array<NetClientCh *> clients;
public:
~EHC();
EHC();
EHC(const Version &ver, Str_8 name, UInt_64 maxEndpoints);
EHC(const Version &ver, Str_8 name);
EHC(IP version = IP::V6);
EHC(EHC &&sock) noexcept;
@@ -86,143 +49,47 @@ namespace ehs
void Release();
void Bind(AddrType newType, const Str_8& newAddress, UInt_16 newPort);
void Connect(AddrType rType, const Str_8& rAddress, UInt_16 rPort, Serializer<UInt_64> data);
bool Disconnect(EndDisp endDisp, const Char_8 token[64], const Str_8& msg);
void Broadcast(EndDisp endDisp, Status endStatus, bool deltaLocked, UInt_64 encHashId,
bool ensure, UInt_64 sysHashId, UInt_64 opHashId,
const Serializer<UInt_64> &payload);
void Broadcast(EndDisp endDisp, Status endStatus, bool deltaLocked, const Str_8 &encId,
bool ensure, const Str_8 &sysId, const Str_8 &opId,
const Serializer<UInt_64> &payload);
void Bind(const Endpoint &endpoint);
void Poll();
bool IsInitialized() const;
AddrType GetLocalAddressType() const;
Str_8 GetLocalAddress() const;
UInt_16 GetLocalPort() const;
Endpoint GetLocalEndpoint() const;
bool IsBound() const;
static Version GetVersion();
Version GetAppVersion() const;
EndDisp GetDisposition() const;
UInt_64 GetHashName() const;
Str_8 GetName() const;
void EnableDropPackets(bool enable);
bool IsDropPacketsEnabled() const;
bool HasEncryption(UInt_64 encHashId) const;
bool HasEncryption(const Str_8& encId) const;
bool AddEncryption(NetEnc *enc);
NetEnc* GetEncryption(UInt_64 encHashId) const;
bool HasServer(UInt_64 serverId) const;
NetEnc* GetEncryption(const Str_8& encId) const;
bool HasServer(const Str_8& serverName) const;
bool HasSystem(UInt_64 sysHashId) const;
bool AddServer(NetServerCh *server);
bool HasSystem(const Str_8& sysId) const;
NetServerCh *GetServer(UInt_64 serverId) const;
bool AddSystem(NetSys *sys);
NetServerCh *GetServer(const Str_8& serverName) const;
NetSys* GetSystem(UInt_64 sysHashId) const;
bool HasClient(UInt_64 clientId) const;
NetSys* GetSystem(const Str_8& sysId) const;
bool HasClient(const Str_8& clientName) const;
bool HasEndpoint(EndDisp endDisp, Status endStatus, const Char_8 token[64]) const;
bool AddClient(NetClientCh *channel);
bool HasEndpoint(EndDisp endDisp, Status endStatus, UInt_64 hashId) const;
NetClientCh *GetClient(UInt_64 clientId) const;
bool HasEndpoint(EndDisp endDisp, Status endStatus, const Str_8 &id) const;
bool HasEndpoint(EndDisp endDisp, const Char_8 token[64]) const;
bool HasEndpoint(EndDisp endDisp, UInt_64 hashId) const;
bool HasEndpoint(EndDisp endDisp, const Str_8 &id) const;
bool HasEndpoint(const Char_8 token[64]) const;
bool HasEndpoint(UInt_64 hashId) const;
bool HasEndpoint(const Str_8 &id) const;
bool HasEndpoint(const Str_8& rAddress, UInt_16 rPort) const;
NetEnd *GetEndpoint(EndDisp endDisp, Status endStatus, const Char_8 token[64]) const;
NetEnd *GetEndpoint(EndDisp endDisp, Status endStatus, UInt_64 hashId) const;
NetEnd *GetEndpoint(EndDisp endDisp, Status endStatus, const Str_8 &id) const;
NetEnd *GetEndpoint(EndDisp endDisp, const Char_8 token[64]) const;
NetEnd *GetEndpoint(EndDisp endDisp, UInt_64 hashId) const;
NetEnd *GetEndpoint(EndDisp endDisp, const Str_8 &id) const;
NetEnd *GetEndpoint(const Str_8& rAddress, UInt_16 rPort) const;
Array<NetEnd *> GetEndpoints(EndDisp endDisp, Status endStatus);
Array<NetEnd *> GetEndpoints(EndDisp endDisp);
UInt_64 GetEndpointsCount(EndDisp endDisp, Status endStatus);
UInt_64 GetEndpointsCount(EndDisp endDisp);
UInt_64 GetMaxEndpoints() const;
void SetMaxTimeout(float seconds);
float GetMaxTimeout() const;
void SetResendRate(float seconds);
float GetResendRate() const;
void SetConnectCb(ConnectCb cb);
void SetConnectedCb(ConnectedCb cb);
void SetActiveCb(ActiveCb cb);
void SetDisconnectCb(DisconnectCb cb);
void SetDisconnectedCb(DisconnectedCb cb);
void SetTimeoutCb(TimeoutCb cb);
NetClientCh *GetClient(const Str_8& clientName) const;
private:
void GenerateToken(Char_8 in[64]);
bool HasEncryption(UInt_64 encId) const;
void UpdateQueue(UInt_64 active);
bool HasEncryption(const Str_8& encName) const;
void UpdateQueue();
NetEnc* GetEncryption(UInt_64 encId) const;
bool RemoveEndpoint(EndDisp disposition, const Char_8 token[64]);
bool RemoveEndpoint(const Str_8& address, UInt_16 port);
bool RemoveEndpoint(const NetEnd* end);
void PollEndpoints();
NetEnc* GetEncryption(const Str_8& encName) const;
};
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "ehs/Str.h"
namespace ehs
{
class HeaderVar
{
private:
UInt_64 id;
Str_8 name;
Str_8 value;
public:
HeaderVar();
HeaderVar(Str_8 name, Str_8 value);
HeaderVar(HeaderVar &&other) noexcept;
HeaderVar(const HeaderVar &other);
HeaderVar &operator=(HeaderVar &&other) noexcept;
HeaderVar &operator=(const HeaderVar &other);
bool operator==(const HeaderVar &other) const;
bool operator!=(const HeaderVar &other) const;
bool operator==(const UInt_64 &otherId) const;
bool operator!=(const UInt_64 &otherId) const;
UInt_64 GetId() const;
Str_8 GetName() const;
Str_8 GetValue() const;
void SetValue(Str_8 value);
Str_8 ToStr() const;
};
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "ehs/system/OS.h"
#ifdef EHS_OS_WINDOWS
#include "ICMP_W32.h"
#else
#include "ICMP_LNX.h"
#endif

View File

@@ -0,0 +1,60 @@
#pragma once
#include "BaseICMP.h"
#include <netinet/in.h>
namespace ehs
{
struct PseudoICMPv6_Header
{
sockaddr_in6 src;
sockaddr_in6 dst;
UInt_32 length;
};
class ICMP final : public BaseICMP
{
private:
Int_32 hdl;
sockaddr_in6 src;
public:
~ICMP() override;
ICMP();
ICMP(IP version);
ICMP(ICMP &&icmp) noexcept;
ICMP(const ICMP &icmp);
ICMP &operator=(ICMP &&icmp) noexcept;
ICMP &operator=(const ICMP &icmp);
void Release() override;
void SetReceiveTimeout(UInt_64 timeout) override;
bool IsValid() const override;
private:
static bool IsLinkLocal(const in6_addr &addr);
static sockaddr_in6 RetrieveSrcAddress();
static UInt_32 CalculatePseudoHeaderChecksum(const PseudoICMPv6_Header &header);
UInt_16 ComputeChecksumV6(UInt_16* buffer, Size length, const sockaddr_in6& dst);
UInt_64 SendV6(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size) override;
UInt_64 SendV4(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size) override;
UInt_64 ReceiveV6(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const override;
UInt_64 ReceiveV4(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const override;
};
}

View File

@@ -0,0 +1,63 @@
#pragma once
#include "BaseICMP.h"
#include "ehs/System/OS.h"
#include <winsock2.h>
#include <WS2tcpip.h>
#include <iphlpapi.h>
namespace ehs
{
struct PseudoICMPv6_Header
{
sockaddr_in6 src;
sockaddr_in6 dst;
UInt_32 length;
};
class ICMP : public BaseICMP
{
private:
Socket hdl;
sockaddr_in6 src;
public:
~ICMP() override;
ICMP();
ICMP(IP version);
ICMP(ICMP &&icmp) noexcept;
ICMP(const ICMP &icmp);
ICMP &operator=(ICMP &&icmp) noexcept;
ICMP &operator=(const ICMP &icmp);
void Release() override;
void SetReceiveTimeout(UInt_64 timeout) override;
bool IsValid() const override;
private:
static bool IsLinkLocal(const in6_addr &addr);
static sockaddr_in6 RetrieveSrcAddress();
static UInt_32 CalculatePseudoHeaderChecksum(const PseudoICMPv6_Header &header);
UInt_16 ComputeChecksumV6(UInt_16* buffer, Size length, const sockaddr_in6& dst);
UInt_64 SendV6(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size) override;
UInt_64 SendV4(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size) override;
UInt_64 ReceiveV6(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const override;
UInt_64 ReceiveV4(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const override;
};
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "ehs/Str.h"
namespace ehs
{
class QueryVar
{
private:
UInt_64 id;
Str_8 name;
Str_8 value;
public:
QueryVar();
QueryVar(Str_8 name, Str_8 value);
QueryVar(QueryVar &&other) noexcept;
QueryVar(const QueryVar &other);
QueryVar &operator=(QueryVar &&other) noexcept;
QueryVar &operator=(const QueryVar &other);
bool operator==(const QueryVar &other) const;
bool operator!=(const QueryVar &other) const;
bool operator==(const UInt_64 &otherId) const;
bool operator!=(const UInt_64 &otherId) const;
UInt_64 GetId() const;
Str_8 GetName() const;
Str_8 GetValue() const;
void SetValue(Str_8 value);
Str_8 ToStr() const;
};
}

View File

@@ -5,6 +5,8 @@
#include "ehs/Str.h"
#include "ehs/json/Json.h"
#include "Socket.h"
#include "QueryVar.h"
#include "HeaderVar.h"
namespace ehs
{
@@ -21,8 +23,8 @@ namespace ehs
private:
Verb verb;
Str_8 rsrc;
Vector<Str_8> queries;
Vector<Str_8> header;
Vector<QueryVar> queries;
Vector<HeaderVar> header;
ContentType cType;
Str_8 body;
@@ -33,25 +35,34 @@ namespace ehs
/// Initializes this request with a given verb and URI resource.
/// @param [in] verb The type of request to make.
/// @param [in] rsrc The URI endpoint to make the request at.
Request(const Verb verb, const Str_8& rsrc);
Request(const Verb &verb, Str_8 rsrc);
/// Initializes this request with the raw request data.
/// @param [in] data The C-style string of the request.
/// @param [in] size The size of the given C-style string.
Request(const char* data, const UInt_64 size);
Request(const char *data, const UInt_64 &size);
/// Initializes this request with the raw request data.
/// @param [in] data The string of the request.
Request(const Str_8 &data);
/// Copies members from another object of the same type.
/// @param [in] req The object to copy from.
Request(const Request& req) = default;
/// Moves members from another object of the same type.
/// @param [in] other The object to move from.
Request(Request &&other) noexcept;
/// Copies members from another object of the same type.
/// @param [in] req The object to copy from.
/// @param [in] other The object to copy from.
Request(const Request &other);
/// Moves members from another object of the same type.
/// @param [in] other The object to move from.
/// @returns The request that has been assigned to.
Request& operator=(const Request& req);
Request& operator=(Request &&other) noexcept;
/// Copies members from another object of the same type.
/// @param [in] other The object to copy from.
/// @returns The request that has been assigned to.
Request& operator=(const Request &other);
/// Retrieves the verb for the request.
/// @returns The result.
@@ -59,7 +70,7 @@ namespace ehs
/// Sets the content type for the body.
/// @param [in] cType The content type to use.
void SetContentType(const ContentType cType);
void SetContentType(const ContentType &cType);
/// Retrieves the content type for the body.
/// @returns The result.
@@ -67,25 +78,60 @@ namespace ehs
/// Sets the URI resource.
/// @param [in] rsrc The resource.
void SetResource(const Str_8& rsrc);
void SetResource(Str_8 rsrc);
/// Retrieves the URI resource.
/// @returns The result.
Str_8 GetResource() const;
/// Adds a query variable to the URI.
/// @param [in] var The variable identifier.
/// @param [in] value The value of the variable.
void AddQuery(const Str_8& var, const Str_8& value);
/// Checks whether a header variable exists using the id.
/// @param [in] id The variable id to look for.
/// @returns True if the variable exists. False otherwise.
bool HasQueryVar(const UInt_64 &id) const;
/// Retrieves a query variable from the URI.
/// @param [in] var The variable identifier to look for.
/// @returns The value of the query variable. Empty if it was not found.
Str_8 GetQuery(const Str_8& var);
/// Checks whether a header variable exists using the name.
/// @param [in] name The variable name to look for.
/// @returns True if the variable exists. False otherwise.
bool HasQueryVar(const Str_8 &name) const;
/// Adds a header variable.
/// @param [in] var The variable to add to the header.
/// @returns False if the given variable name already exists. True otherwise.
bool AddQueryVar(QueryVar var);
/// Removes a header variable using the id.
/// @param [in] id The variable id to look for.
/// @returns True if the variable was found. False otherwise.
bool RemoveQueryVar(const UInt_64 &id);
/// Removes a header variable using the name.
/// @param [in] name The variable name to look for.
/// @returns True if the variable was found. False otherwise.
bool RemoveQueryVar(const Str_8 &name);
/// Retrieves a header variable using the id.
/// @param [in] id The variable id to look for.
/// @returns The variable object if found. Nullptr otherwise.
QueryVar *GetQueryVar(const UInt_64 &id) const;
/// Retrieves a header variable using the name.
/// @param [in] name The variable name to look for.
/// @returns The variable object if found. Nullptr otherwise.
QueryVar *GetQueryVar(const Str_8& name) const;
/// Retrieves a header variable value using the id.
/// @param [in] id The variable id to look for.
/// @returns The variable's value if found. Empty otherwise.
Str_8 GetQueryValue(const UInt_64 &id) const;
/// Retrieves a header variable value using the name.
/// @param [in] name The variable name to look for.
/// @returns The variable's value if found. Empty otherwise.
Str_8 GetQueryValue(const Str_8& name) const;
/// Retrieves all the query variables from the URI in a vector object.
/// @returns The result.
Vector<Str_8> GetQueries() const;
Vector<QueryVar> GetQueries() const;
/// A helper method to automatically add the required header variables for basic authentication.
/// @param [in] id The username or id.
@@ -105,19 +151,54 @@ namespace ehs
/// @param [in] token The token given by an API.
void BotAuth(const Str_8 &token);
/// Adds a header variable.
/// @param [in] var The variable identifier.
/// @param [in] value The value of the variable.
void AddToHeader(const Str_8& var, const Str_8& value);
/// Checks whether a header variable exists using the id.
/// @param [in] id The variable id to look for.
/// @returns True if the variable exists. False otherwise.
bool HasHeaderVar(const UInt_64 &id) const;
/// Retrieves a header variable.
/// @param [in] var The variable identifier to look for.
/// @returns The value of the header variable. Empty if it was not found.
Str_8 GetHeader(const Str_8& var) const;
/// Checks whether a header variable exists using the name.
/// @param [in] name The variable name to look for.
/// @returns True if the variable exists. False otherwise.
bool HasHeaderVar(const Str_8 &name) const;
/// Adds a header variable.
/// @param [in] var The variable to add to the header.
/// @returns False if the given variable name already exists. True otherwise.
bool AddHeaderVar(HeaderVar var);
/// Removes a header variable using the id.
/// @param [in] id The variable id to look for.
/// @returns True if the variable was found. False otherwise.
bool RemoveHeaderVar(const UInt_64 &id);
/// Removes a header variable using the name.
/// @param [in] name The variable name to look for.
/// @returns True if the variable was found. False otherwise.
bool RemoveHeaderVar(const Str_8 &name);
/// Retrieves a header variable using the id.
/// @param [in] id The variable id to look for.
/// @returns The variable object if found. Nullptr otherwise.
HeaderVar *GetHeaderVar(const UInt_64 &id) const;
/// Retrieves a header variable using the name.
/// @param [in] name The variable name to look for.
/// @returns The variable object if found. Nullptr otherwise.
HeaderVar *GetHeaderVar(const Str_8& name) const;
/// Retrieves a header variable value using the id.
/// @param [in] id The variable id to look for.
/// @returns The variable's value if found. Empty otherwise.
Str_8 GetHeaderValue(const UInt_64 &id) const;
/// Retrieves a header variable value using the name.
/// @param [in] name The variable name to look for.
/// @returns The variable's value if found. Empty otherwise.
Str_8 GetHeaderValue(const Str_8& name) const;
/// Retrieves all the header variables in a vector object.
/// @returns The result.
Vector<Str_8> GetHeader() const;
Vector<HeaderVar> GetHeader() const;
/// Adds a body variable.
/// @param [in] var The variable identifier.
@@ -152,9 +233,9 @@ namespace ehs
bool IsValid() const;
private:
static Str_8 VerbToStr(const Verb verb);
static Str_8 VerbToStr(const Verb &verb);
static Str_8 ContentTypeToStr(const ContentType cType);
static Str_8 ContentTypeToStr(const ContentType &cType);
static ContentType StrToContentType(const Str_8 &value);

View File

@@ -5,6 +5,7 @@
#include "ehs/Str.h"
#include "ehs/json/Json.h"
#include "Socket.h"
#include "HeaderVar.h"
namespace ehs
{
@@ -14,7 +15,7 @@ namespace ehs
UInt_32 code;
Str_8 server;
ContentType cType;
Vector<Str_8> header;
Vector<HeaderVar> header;
Str_8 body;
public:
@@ -24,29 +25,38 @@ namespace ehs
/// Initializes this response with a given code and server identifier.
/// @param [in] code The code to give.
/// @param [in] server The server identifier.
Response(const UInt_32 code, const Str_8& server);
Response(const UInt_32 &code, Str_8 server);
/// Initializes this response with the raw response data.
/// @param [in] data The C-style string of the response.
/// @param [in] size The size of the given C-style string.
Response(const char* data, const UInt_64 size);
Response(const char *data, const UInt_64 &size);
/// Initializes this response with the raw response data.
/// @param [in] data The string of the response.
Response(const Str_8 &data);
/// Moves members from another object of the same type.
/// @param [in] other The object to move from.
Response(Response &&other) noexcept;
/// Copies members from another object of the same type.
/// @param [in] res The object to copy from.
Response(const Response& res) = default;
/// @param [in] other The object to copy from.
Response(const Response &other);
/// Moves members from another object of the same type.
/// @param [in] other The object to move from.
/// @returns The response that has been assigned to.
Response &operator=(Response &&other) noexcept;
/// Copies members from another object of the same type.
/// @param [in] res The object to copy from.
/// @returns The response that has been assigned to.
Response& operator=(const Response& res);
Response& operator=(const Response &other);
/// Sets the response code to send to the endpoint.
/// @param [in] code The code for success, error or info.
void SetCode(const UInt_32 code);
void SetCode(const UInt_32 &code);
/// Retrieves the response code.
/// @returns The result.
@@ -54,7 +64,7 @@ namespace ehs
/// Sets the server identifier.
/// @param [in] server The server identifier to use.
void SetServer(const Str_8& server);
void SetServer(Str_8 server);
/// Retrieves the server identifier.
/// @returns The result.
@@ -62,25 +72,60 @@ namespace ehs
/// Sets the content type for the body.
/// @param [in] cType The content type to use.
void SetContentType(const ContentType cType);
void SetContentType(const ContentType &cType);
/// Retrieves the content type for the body.
/// @returns The result.
ContentType GetContentType() const;
/// Adds a header variable.
/// @param [in] var The variable identifier.
/// @param [in] value The value of the variable.
void AddToHeader(const Str_8& var, const Str_8& value);
/// Checks whether a header variable exists using the id.
/// @param [in] id The variable id to look for.
/// @returns True if the variable exists. False otherwise.
bool HasHeaderVar(const UInt_64 &id) const;
/// Retrieves a header variable.
/// @param [in] var The variable identifier to look for.
/// @returns The value of the header variable. Empty if it was not found.
Str_8 GetHeader(const Str_8& var) const;
/// Checks whether a header variable exists using the name.
/// @param [in] name The variable name to look for.
/// @returns True if the variable exists. False otherwise.
bool HasHeaderVar(const Str_8 &name) const;
/// Adds a header variable.
/// @param [in] var The variable to add to the header.
/// @returns False if the given variable name already exists. True otherwise.
bool AddHeaderVar(HeaderVar var);
/// Removes a header variable using the id.
/// @param [in] id The variable id to look for.
/// @returns True if the variable was found. False otherwise.
bool RemoveHeaderVar(const UInt_64 &id);
/// Removes a header variable using the name.
/// @param [in] name The variable name to look for.
/// @returns True if the variable was found. False otherwise.
bool RemoveHeaderVar(const Str_8 &name);
/// Retrieves a header variable using the id.
/// @param [in] id The variable id to look for.
/// @returns The variable object if found. Nullptr otherwise.
HeaderVar *GetHeaderVar(const UInt_64 &id) const;
/// Retrieves a header variable using the name.
/// @param [in] name The variable name to look for.
/// @returns The variable object if found. Nullptr otherwise.
HeaderVar *GetHeaderVar(const Str_8& name) const;
/// Retrieves a header variable value using the id.
/// @param [in] id The variable id to look for.
/// @returns The variable's value if found. Empty otherwise.
Str_8 GetHeaderValue(const UInt_64 &id) const;
/// Retrieves a header variable value using the name.
/// @param [in] name The variable name to look for.
/// @returns The variable's value if found. Empty otherwise.
Str_8 GetHeaderValue(const Str_8& name) const;
/// Retrieves all the header variables in a vector object.
/// @returns The result.
Vector<Str_8> GetHeader() const;
Vector<HeaderVar> GetHeader() const;
/// Adds a body variable.
/// @param [in] var The variable identifier.
@@ -115,9 +160,9 @@ namespace ehs
bool IsValid() const;
private:
static Str_8 CodeToStr(const UInt_32 code);
static Str_8 CodeToStr(const UInt_32 &code);
static Str_8 ContentTypeToStr(const ContentType cType);
static Str_8 ContentTypeToStr(const ContentType &cType);
static ContentType StrToContentType(const Str_8 &value);

View File

@@ -1,5 +1,7 @@
#pragma once
#include <openssl/types.h>
#include "ehs/EHS.h"
#include "ehs/Str.h"
#include "TCP.h"
@@ -15,15 +17,18 @@ namespace ehs
class EHS_LIB_IO SSL : public TCP
{
private:
bool server;
SSL_CTX* ctx;
::SSL* sslHdl;
X509 *cert;
EVP_PKEY* pkey;
public:
~SSL() override;
SSL();
SSL(const AddrType type);
SSL(const IP &type, const bool &server);
SSL(TCP&& tcp) noexcept;
@@ -37,19 +42,19 @@ namespace ehs
void Release() override;
void Bind(const Str_8& address, unsigned short port) override;
void Listen() override;
SSL* Accept() override;
void Connect(const Str_8& address, const UInt_16 port) override;
void Connect(Str_8 address, const UInt_16 &port) override;
UInt_64 Send(const Byte* const buffer, const UInt_32 size) override;
UInt_64 Send(const Byte* buffer, const UInt_32 size) override;
UInt_64 Receive(Byte* const buffer, const UInt_32 size) override;
UInt_64 Receive(Byte* buffer, const UInt_32 size) override;
void UseCertificate(const Byte* data, const UInt_64 size);
void UseCertificate(const Char_8* data, const UInt_32 &size);
void UsePrivateKey(const Byte* data, const UInt_64 size);
void UsePrivateKey(const Char_8* data, const UInt_32 &size);
bool IsValid();
};

View File

@@ -1,7 +1,10 @@
#pragma once
#include "ehs/Str.h"
#ifndef EHS_IPV4_HEADER
#define EHS_IPV4_HEADER 60
#include <string>
#endif
#ifndef EHS_IPV6_HEADER
@@ -22,10 +25,10 @@
namespace ehs
{
enum class AddrType
enum class IP
{
IPV6,
IPV4
V4,
V6
};
enum class ContentType
@@ -37,10 +40,19 @@ namespace ehs
APP_XML,
TEXT_PLAIN,
TEXT_HTML,
TEXT_CSS,
TEXT_XML,
IMG_X_ICON,
NONE
};
struct Endpoint
{
IP version = IP::V6;
Str_8 address;
UInt_16 port = 0;
};
#if defined(EHS_OS_WINDOWS)
typedef UInt_64 Socket;
#define EHS_INVALID_SOCKET EHS_UINT_64_MAX

View File

@@ -22,7 +22,7 @@ namespace ehs
/// Default members initialization.
TCP();
TCP(AddrType addrType);
TCP(IP IP);
TCP(TCP&& tcp) noexcept;
@@ -46,7 +46,7 @@ namespace ehs
/// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called.
void Bind(const Str_8& address, UInt_16 port) override;
void Bind(Str_8 address, const UInt_16 &port) override;
/// Listens for incoming connections. Used for servers or PtP.
void Listen() override;
@@ -58,7 +58,7 @@ namespace ehs
/// Connects to a TCP Socket that listens for incoming connections. Used for clients or PtP.
/// @param address The address of the listening TCP socket. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param port The port of the listening TCP socket.
void Connect(const Str_8& address, UInt_16 port) override;
void Connect(Str_8 address, const UInt_16 &port) override;
/// Sends data in a C-style array with raw functionality. Meaning no internal help outside of native functions besides error checking.
/// @param [in] buffer The C-style array to send.
@@ -84,15 +84,17 @@ namespace ehs
bool IsIPv6Only() const override;
void SetReuse(const bool &value) override;
bool IsValid() const override;
private:
void Bind_v6(const Str_8& address, UInt_16 port);
void Bind_v6(const Str_8 &address, const UInt_16 &port) const;
void Bind_v4(const Str_8& address, UInt_16 port);
void Bind_v4(const Str_8 &address, const UInt_16 &port) const;
void Connect_v6(const Str_8& address, UInt_16 port);
void Connect_v6(const Str_8 &address, const UInt_16 &port);
void Connect_v4(const Str_8& address, UInt_16 port);
void Connect_v4(const Str_8 &address, const UInt_16 &port);
};
}

View File

@@ -22,7 +22,7 @@ namespace ehs
/// Default members initialization.
TCP();
TCP(AddrType addrType);
TCP(IP IP);
TCP(TCP&& tcp) noexcept;
@@ -46,7 +46,7 @@ namespace ehs
/// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called.
void Bind(const Str_8& address, UInt_16 port) override;
void Bind(Str_8 address, const UInt_16 &port) override;
/// Listens for incoming connections. Used for servers or PtP.
void Listen() override;
@@ -58,7 +58,7 @@ namespace ehs
/// Connects to a TCP Socket that listens for incoming connections. Used for clients or PtP.
/// @param address The address of the listening TCP socket. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param port The port of the listening TCP socket.
void Connect(const Str_8& address, UInt_16 port) override;
void Connect(Str_8 address, const UInt_16 &port) override;
/// Sends data in a C-style array with raw functionality. Meaning no internal help outside of native functions besides error checking.
/// @param [in] buffer The C-style array to send.
@@ -84,12 +84,14 @@ namespace ehs
bool IsIPv6Only() const override;
void SetReuse(const bool &value) override;
bool IsValid() const override;
private:
void Bind_v6(const Str_8& address, UInt_16 port);
void Bind_v6(const Str_8& address, const UInt_16 &port);
void Bind_v4(const Str_8& address, UInt_16 port);
void Bind_v4(const Str_8& address, const UInt_16 &port);
void Connect_v6(const Str_8& address, UInt_16 port);

View File

@@ -19,7 +19,7 @@ namespace ehs
UDP();
/// Default members initialization.
UDP(AddrType type);
UDP(IP version);
UDP(UDP&& udp) noexcept;
@@ -41,7 +41,7 @@ namespace ehs
/// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called.
void Bind(AddrType type, const Str_8& address, UInt_16 port) override;
void Bind(const Endpoint &endpoint) override;
/// Sends data using a C-style byte array.
/// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
@@ -49,7 +49,7 @@ namespace ehs
/// @param [in] data The C-style byte array to send.
/// @param [in] size The size of the C-style byte array.
/// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6".
UInt_64 Send(AddrType type, const Str_8& address, UInt_16 port, const Byte* data, UInt_64 size) override;
UInt_64 Send(const Endpoint &endpoint, const Byte* data, UInt_64 size) override;
/// Receives data using the packet helper class.
/// @param [out] addr The Ipv4 or Ipv6 address of the sender.
@@ -58,7 +58,7 @@ namespace ehs
/// @param [in] size The size of the pre-allocated C-style byte array.
/// @returns The size of the data received.
/// @warning The provided C-style byte array must be freed when finished using.
UInt_64 Receive(AddrType* type, Str_8* address, UInt_16* port, Byte* data, UInt_64 size) override;
UInt_64 Receive(Endpoint *endpoint, Byte* data, UInt_64 size) override;
/// Sets whether or not receiving data blocks the next task.
/// @param [in] blocking Whether or not to block.

View File

@@ -19,7 +19,7 @@ namespace ehs
UDP();
/// Default members initialization.
UDP(const AddrType addrType);
UDP(const IP IP);
UDP(UDP&& udp) noexcept;
@@ -41,7 +41,7 @@ namespace ehs
/// @param [in] address The local IPv4 or IPv6 address to bind to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
/// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called.
void Bind(AddrType type, const Str_8& address, UInt_16 port) override;
void Bind(const Endpoint &endpoint) override;
/// Sends data using a C-style byte array.
/// @param [in] addr The remote Ipv4 or Ipv6 address to send to. Resolves domain names. The given address can be empty, "127.0.0.1", or "localhost" to automatically find the appropriate device.
@@ -49,7 +49,7 @@ namespace ehs
/// @param [in] data The C-style byte array to send.
/// @param [in] size The size of the C-style byte array.
/// @note The size of data to be sent cannot exceed "UDP::maxPayloadIpv4" or "UDP::maxPayloadIpv6".
UInt_64 Send(AddrType type, const Str_8& addr, UInt_16 port, const Byte* data, UInt_64 size) override;
UInt_64 Send(const Endpoint &endpoint, const Byte* data, UInt_64 size) override;
/// Receives data using the packet helper class.
/// @param [out] addr The Ipv4 or Ipv6 address of the sender.
@@ -58,7 +58,7 @@ namespace ehs
/// @param [in] size The size of the pre-allocated C-style byte array.
/// @returns The size of the data received.
/// @warning The provided C-style byte array must be freed when finished using.
UInt_64 Receive(AddrType* type, Str_8* addr, UInt_16* port, Byte* data, UInt_64 size) override;
UInt_64 Receive(Endpoint *endpoint, Byte* data, UInt_64 size) override;
/// Sets whether or not receiving data blocks the next task.
/// @param [in] blocking Whether or not to block.

View File

@@ -0,0 +1,94 @@
#pragma once
#include "ehs/Str.h"
#include "ehs/Array.h"
#include "ehs/io/socket/Socket.h"
#include "NetUtils.h"
namespace ehs
{
class EHC;
class NetEnd;
class NetSys;
class NetChannel
{
protected:
static const UInt_64 internalSys;
static const UInt_64 connectOp;
static const UInt_64 connectedOp;
static const UInt_64 rejectedOp;
static const UInt_64 disconnectOp;
static const UInt_64 disconnectedOp;
static const UInt_64 statusUpdateOp;
static const UInt_64 pingOp;
static const UInt_64 pongOp;
static const UInt_64 latencyOp;
static const UInt_64 receivedOp;
private:
friend class EHC;
EHC *owner;
UInt_64 id;
Str_8 name;
Version version;
float maxTimeout;
float resendRate;
bool dropPackets;
Array<NetSys *> systems;
public:
virtual ~NetChannel();
NetChannel();
NetChannel(Str_8 name, const Version &version);
NetChannel(NetChannel &&channel) noexcept;
NetChannel(const NetChannel &channel);
NetChannel &operator=(NetChannel &&channel) noexcept;
NetChannel &operator=(const NetChannel &channel);
EHC *GetOwner() const;
UInt_64 GetId() const;
Str_8 GetName() const;
Version GetVersion() const;
void SetMaxTimeout(float seconds);
float GetMaxTimeout() const;
void SetResendRate(float seconds);
float GetResendRate() const;
void EnableDropPackets(bool enable);
bool IsDropPacketsEnabled() const;
bool AddSystem(NetSys *sys);
bool IsValid() const;
private:
virtual void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload);
virtual void Poll(const float &delta);
protected:
bool HasSystem(UInt_64 sysId) const;
bool HasSystem(const Str_8& sysName) const;
NetSys* GetSystem(UInt_64 sysId) const;
NetSys* GetSystem(const Str_8& sysName) const;
};
}

View File

@@ -0,0 +1,81 @@
#pragma once
#include "NetChannel.h"
#include "ehs/io/socket/Socket.h"
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/io/socket/ehc/NetFrag.h"
namespace ehs
{
class NetClientCh : public NetChannel
{
private:
friend class EHC;
Endpoint remoteEndpoint;
Char_8 token[64];
NetStatus status;
UInt_64 queueSlot;
float deltaDuration;
float deltaRate;
float lastPing;
float latency;
float timeout;
UInt_64 nextSendId;
Vector<Insurance> sent;
UInt_64 nextRecvId;
Vector<NetFrag> received;
public:
~NetClientCh();
NetClientCh();
NetClientCh(Str_8 name, const Version &version, Endpoint remoteEndpoint);
NetClientCh(NetClientCh &&client) noexcept;
NetClientCh(const NetClientCh &client);
NetClientCh &operator=(NetClientCh &&client) noexcept;
NetClientCh &operator=(const NetClientCh &client);
virtual void OnConnected(Serializer<UInt_64> data);
virtual void OnActive(Serializer<UInt_64> data);
virtual void OnQueueUpdate(Serializer<UInt_64> data);
virtual void OnDisconnected(Serializer<UInt_64> data);
virtual void OnRejected(Serializer<UInt_64> data);
virtual void OnTimeout(Serializer<UInt_64> data);
void Connect(const Endpoint &endpoint, const Serializer<UInt_64>& payload);
bool Disconnect(const Serializer<UInt_64>& payload);
void Send(bool deltaLocked, UInt_64 encId, bool ensure, UInt_64 sysId, UInt_64 opId, const Serializer<UInt_64>& payload);
void Send(bool deltaLocked, const Str_8 &encName, bool ensure, const Str_8& sysName, const Str_8& opName, const Serializer<UInt_64>& payload);
NetStatus GetStatus() const;
private:
void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload) override;
void Poll(const float &delta) override;
NetFrag FragmentData(IP version, const Header& header, const Serializer<>& data);
void Send(NetEnc *enc, const Header& header, const Serializer<>& payload);
void Pong(float delta);
void RemoveInsurance(UInt_64 msgId, UInt_64 fragment);
void AddReceived(const Header& header, const Serializer<>& payload);
};
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "ehs/Str.h"
#include "ehs/Version.h"
namespace ehs
{
@@ -11,16 +12,16 @@ namespace ehs
private:
friend class EHC;
EHC *owner;
UInt_64 hashId;
Str_8 id;
UInt_64 id;
Str_8 name;
Version version;
public:
virtual ~NetEnc() = default;
NetEnc();
NetEnc(Str_8 id);
NetEnc(Str_8 name, const Version &version);
NetEnc(NetEnc &&enc) noexcept;
@@ -30,11 +31,11 @@ namespace ehs
NetEnc &operator=(const NetEnc &enc);
EHC *GetOwner() const;
UInt_64 GetId() const;
UInt_64 GetHashId() const;
Str_8 GetName() const;
Str_8 GetId() const;
Version GetVersion() const;
virtual void Encrypt(Byte *data, UInt_64 size) const;

View File

@@ -1,7 +1,7 @@
#pragma once
#include "NetUtils.h"
#include "NetFrags.h"
#include "NetFrag.h"
#include "ehs/Str.h"
#include "ehs/Vector.h"
@@ -10,27 +10,23 @@
namespace ehs
{
class EHC;
class NetServerCh;
class NetEnd
{
private:
friend class EHC;
friend class NetServerCh;
EHC* owner;
EndDisp disposition;
UInt_64 hashName;
NetServerCh* owner;
UInt_64 id;
Str_8 name;
Status status;
Architecture arch;
NetStatus status;
Char_8 token[64];
UInt_64 nextSendId;
Vector<Insurance> sent;
UInt_64 nextRecvId;
Vector<NetFrags> received;
AddrType type;
Str_8 address;
UInt_16 port;
Vector<NetFrag> received;
Endpoint endpoint;
float deltaDuration;
float deltaRate;
float timeout;
@@ -42,9 +38,9 @@ namespace ehs
public:
NetEnd();
NetEnd(EndDisp disposition, Str_8 id, Architecture arch, AddrType type, Str_8 address, UInt_16 port);
NetEnd(Str_8 id, Endpoint endpoint);
NetEnd(AddrType type, Str_8 address, UInt_16 port);
NetEnd(Endpoint endpoint);
NetEnd(NetEnd &&end) noexcept;
@@ -54,15 +50,11 @@ namespace ehs
NetEnd &operator=(const NetEnd &end);
EndDisp GetDisposition() const;
UInt_64 GetHashName() const;
UInt_64 GetId() const;
Str_8 GetName() const;
Status GetStatus() const;
Architecture GetArchitecture() const;
NetStatus GetStatus() const;
UInt_64 GetNextSendId() const;
@@ -73,7 +65,7 @@ namespace ehs
/// @param [in] sys The system hash id to execute an operation from.
/// @param [in] op The operation hash id in the system to execute.
/// @param [in] payload Additional parameters and data to send to the remote endpoint.
void Send(bool deltaLocked, UInt_64 encHashId, bool ensure, UInt_64 sys, UInt_64 op, const Serializer<UInt_64>& payload);
void Send(bool deltaLocked, UInt_64 encId, bool ensure, UInt_64 sysId, UInt_64 opId, const Serializer<UInt_64>& payload);
/// Sends data to the remote endpoint.
/// @param [in] deltaLocked Whether or not to match the remote endpoint's delta time to prevent overloading the client. This will drop data if delta time does not match.
@@ -82,13 +74,11 @@ namespace ehs
/// @param [in] sys The system string id to execute an operation from.
/// @param [in] op The operation string id in the system to execute.
/// @param [in] payload Additional parameters and data to send to the remote endpoint.
void Send(bool deltaLocked, const Str_8 &encID, bool ensure, const Str_8& sys, const Str_8& op, const Serializer<UInt_64>& payload);
void Send(bool deltaLocked, const Str_8 &encName, bool ensure, const Str_8& sysName, const Str_8& opName, const Serializer<UInt_64>& payload);
UInt_64 GetNextRecvId() const;
Str_8 GetAddress() const;
UInt_16 GetPort() const;
Endpoint GetEndpoint() const;
void SetDeltaRate(float newDeltaRate);
@@ -107,23 +97,21 @@ namespace ehs
private:
void Poll(float delta);
void SetStatus(Status newStatus);
void SetStatus(NetStatus newStatus);
void RemoveInsurance(UInt_64 msgId, UInt_64 fragment);
void AddReceived(const Header& header, const Serializer<>& payload);
Vector<NetFrags>* GetReceived();
Vector<NetFrag>* GetReceived();
void Ping(float delta);
void Pong(float delta);
void SetLatency(float newLatency);
void SetQueueSlot(UInt_64 slot);
NetFrags FragmentData(const Header& header, const Serializer<>& data);
NetFrag FragmentData(const Header& header, const Serializer<>& data);
void Send(const Header& header, const Serializer<>& payload);

View File

@@ -0,0 +1,43 @@
#pragma once
#include "NetUtils.h"
#include <ehs/Serializer.h>
namespace ehs
{
class NetFrag
{
private:
Header header;
Serializer<UInt_64>* data;
UInt_64 size;
public:
~NetFrag();
NetFrag();
NetFrag(const Header &header, const Serializer<UInt_64> &payload);
NetFrag(const Header &header, UInt_64 size);
NetFrag(NetFrag &&frags) noexcept;
NetFrag(const NetFrag &frags);
NetFrag &operator=(NetFrag &&frags) noexcept;
NetFrag &operator=(const NetFrag &frags);
operator Serializer<UInt_64> *() const;
Header GetHeader() const;
UInt_64 Size() const;
bool IsComplete() const;
Packet Combine() const;
};
}

View File

@@ -1,43 +0,0 @@
#pragma once
#include "NetUtils.h"
#include <ehs/Serializer.h>
namespace ehs
{
class NetFrags
{
private:
Header header;
Serializer<UInt_64>* data;
UInt_64 size;
public:
~NetFrags();
NetFrags();
NetFrags(const Header &header, const Serializer<UInt_64> &payload);
NetFrags(const Header &header, UInt_64 size);
NetFrags(NetFrags &&frags) noexcept;
NetFrags(const NetFrags &frags);
NetFrags &operator=(NetFrags &&frags) noexcept;
NetFrags &operator=(const NetFrags &frags);
operator Serializer<UInt_64> *() const;
Header GetHeader() const;
UInt_64 Size() const;
bool IsComplete() const;
Packet Combine() const;
};
}

View File

@@ -5,7 +5,7 @@
namespace ehs
{
class EHC;
class NetChannel;
class NetSys;
class NetEnd;
@@ -14,15 +14,15 @@ namespace ehs
private:
friend class NetSys;
UInt_64 hashId;
Str_8 id;
UInt_64 id;
Str_8 name;
public:
virtual ~NetOp() = default;
NetOp();
NetOp(Str_8 id);
NetOp(Str_8 name);
NetOp(NetOp &&op) noexcept;
@@ -32,11 +32,11 @@ namespace ehs
NetOp &operator=(const NetOp &op);
Str_8 GetId() const;
UInt_64 GetId() const;
UInt_64 GetHashId() const;
Str_8 GetName() const;
private:
virtual void Process(EHC *ehc, NetEnd *endpoint, NetSys *sys, Serializer<UInt_64> &payload);
virtual void Execute(NetChannel *channel, NetEnd *issuer, NetSys *sys, Serializer<UInt_64> &payload);
};
}

View File

@@ -0,0 +1,105 @@
#pragma once
#include "NetChannel.h"
namespace ehs
{
class NetEnd;
class NetServerCh : public NetChannel
{
private:
friend class EHC;
Vector<NetEnd *> endpoints;
UInt_64 maxEndpoints;
public:
~NetServerCh() override;
NetServerCh();
NetServerCh(Str_8 name, const Version &version, UInt_64 maxEndpoints);
NetServerCh(NetServerCh &&server) noexcept;
NetServerCh(const NetServerCh &server);
NetServerCh &operator=(NetServerCh &&server) noexcept;
NetServerCh &operator=(const NetServerCh &server);
virtual bool OnEndpointConnect(NetEnd *endpoint, Serializer<UInt_64> payload);
virtual Serializer<UInt_64> OnEndpointAccepted(NetEnd *endpoint);
virtual void OnEndpointDisconnect(NetEnd *endpoint, Serializer<UInt_64> payload);
virtual void OnEndpointTimeout(NetEnd *endpoint);
virtual void OnEndpointActive(NetEnd *endpoint);
virtual Serializer<UInt_64> OnShutdown();
void Broadcast(NetStatus endStatus, bool deltaLocked, UInt_64 encHashId,
bool ensure, UInt_64 sysHashId, UInt_64 opHashId,
const Serializer<UInt_64> &payload);
void Broadcast(NetStatus endStatus, bool deltaLocked, const Str_8 &encId,
bool ensure, const Str_8 &sysId, const Str_8 &opId,
const Serializer<UInt_64> &payload);
bool HasEndpoint(NetStatus endStatus, const Char_8 token[64]) const;
bool HasEndpoint(NetStatus endStatus, UInt_64 hashId) const;
bool HasEndpoint(NetStatus endStatus, const Str_8 &id) const;
bool HasEndpoint(const Char_8 token[64]) const;
bool HasEndpoint(UInt_64 hashId) const;
bool HasEndpoint(const Str_8 &id) const;
bool HasEndpoint(const Endpoint &endpoint) const;
NetEnd *GetEndpoint(NetStatus endStatus, const Char_8 token[64]) const;
NetEnd *GetEndpoint(NetStatus endStatus, UInt_64 hashId) const;
NetEnd *GetEndpoint(NetStatus endStatus, const Str_8 &id) const;
NetEnd *GetEndpoint(const Char_8 token[64]) const;
NetEnd *GetEndpoint(UInt_64 hashId) const;
NetEnd *GetEndpoint(const Str_8 &id) const;
NetEnd *GetEndpoint(const Endpoint &endpoint) const;
Array<NetEnd *> GetEndpoints(NetStatus endStatus);
UInt_64 GetEndpointsCount(NetStatus endStatus);
UInt_64 GetMaxEndpoints() const;
private:
void Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload) override;
void GenerateToken(Char_8 in[64]);
void UpdateQueue(UInt_64 active);
void UpdateQueue();
bool RemoveEndpoint(const Char_8 token[64]);
bool RemoveEndpoint(const Endpoint &endpoint);
bool RemoveEndpoint(const NetEnd* end);
void Poll(const float &delta) override;
void Shutdown();
};
}

View File

@@ -6,17 +6,19 @@
namespace ehs
{
class EHC;
class NetChannel;
class NetEnd;
class NetOp;
class NetSys
{
private:
friend class EHC;
friend class NetChannel;
friend class NetServerCh;
friend class NetClientCh;
UInt_64 hashId;
Str_8 id;
UInt_64 id;
Str_8 name;
Array<NetOp*> ops;
public:
@@ -24,7 +26,7 @@ namespace ehs
NetSys();
NetSys(Str_8 id);
NetSys(Str_8 name);
NetSys(NetSys &&sys) noexcept;
@@ -34,15 +36,15 @@ namespace ehs
NetSys &operator=(const NetSys &sys);
Str_8 GetId() const;
UInt_64 GetId() const;
UInt_64 GetHashId() const;
Str_8 GetName() const;
bool HasOperation(UInt_64 hashId) const;
bool HasOperation(UInt_64 id) const;
bool AddOperation(NetOp *op);
private:
void Execute(EHC *ehc, NetEnd *endpoint, UInt_64 hashId, Serializer<UInt_64> &payload);
void Execute(NetChannel *channel, NetEnd *issuer, UInt_64 opId, Serializer<UInt_64> &payload);
};
}

View File

@@ -4,33 +4,41 @@
namespace ehs
{
enum class EndDisp : UInt_8
{
ENDPOINT,
SERVICE
};
enum class Status : UInt_8
enum class NetStatus : UInt_8
{
DISCONNECTED,
ACTIVE,
PENDING,
IN_LOCAL_QUEUE,
IN_REMOTE_QUEUE,
QUEUED
};
enum class NetChannelType : UInt_8
{
SERVER,
CLIENT
};
struct Header
{
UInt_64 encHashId = 0;
Version version = {};
UInt_64 encId = 0;
Version encVer = {};
UInt_64 channelId = 0;
NetChannelType channelType = NetChannelType::SERVER;
Version channelVer = {};
UInt_64 id = 0;
UInt_64 fragments = 0;
UInt_64 fragmentCount = 0;
UInt_64 fragment = 0;
bool ensure = false;
EndDisp disposition = EndDisp::ENDPOINT;
Char_8 token[64] = {};
UInt_64 system = 0;
UInt_64 op = 0;
UInt_64 systemId = 0;
UInt_64 opId = 0;
};
void WriteHeader(const Header &header, Serializer<UInt_64> &data);
Header ReadHeader(Serializer<UInt_64> &data);
struct Packet
{
Header header;

36
include/ehs/system/AVX2.h Normal file
View File

@@ -0,0 +1,36 @@
#pragma once
#include "ehs/Types.h"
namespace ehs
{
class EHS_LIB_IO AVX2
{
public:
/// Compares two unaligned 4 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 4 elements are equal. False otherwise.
static bool CompareUnaligned(const UInt_64 *a, const UInt_64 *b);
/// Compares two unaligned 4 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 4 elements are equal. False otherwise.
static bool CompareUnaligned(const SInt_64 *a, const SInt_64 *b);
/// Compares two aligned 4 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 4 elements are equal. False otherwise.
/// @note The parameters "a", and "b" must have alignas(32).
static bool CompareAligned(const UInt_64 *a, const UInt_64 *b);
/// Compares two aligned 4 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 4 elements are equal. False otherwise.
/// @note The parameters "a", and "b" must have alignas(32).
static bool CompareAligned(const SInt_64 *a, const SInt_64 *b);
};
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include "ehs/Types.h"
namespace ehs
{
class EHS_LIB_IO AVX512
{
public:
/// Compares two unaligned 8 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 8 elements are equal. False otherwise.
static bool CompareUnaligned(const UInt_64 *a, const UInt_64 *b);
/// Compares two unaligned 8 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 8 elements are equal. False otherwise.
static bool CompareUnaligned(const SInt_64 *a, const SInt_64 *b);
/// Compares two aligned 8 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 8 elements are equal. False otherwise.
/// @note The parameters "a", and "b" must have alignas(32).
static bool CompareAligned(const UInt_64 *a, const UInt_64 *b);
/// Compares two aligned 8 element vectors using 64-bit integers.
/// @param [in] a First vector.
/// @param [in] b Second vector.
/// @returns True if all 8 elements are equal. False otherwise.
/// @note The parameters "a", and "b" must have alignas(32).
static bool CompareAligned(const SInt_64 *a, const SInt_64 *b);
};
}

View File

@@ -6,7 +6,7 @@
#define EHS_64_BIT
#elif defined(_M_ARM64) || defined(__aarch64__)
#define EHS_LITTLE_ENDIAN
#define EHS_ARCH_ARM64
#define EHS_ARCH_AARCH64
#define EHS_64_BIT
#else
#error Unsupported architecture.

View File

@@ -8,7 +8,7 @@ namespace ehs
class EHS_LIB_IO BaseSystem
{
public:
static void OpenURI(const Str_8& uri);
static void OpenURI(Str_8 uri);
static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);

View File

@@ -38,6 +38,70 @@ namespace ehs
#endif
public:
static const bool hasFPU;
static const bool hasVME;
static const bool hasDE;
static const bool hasPSE;
static const bool hasTSC;
static const bool hasMSR;
static const bool hasPAE;
static const bool hasMCE;
static const bool hasCX8;
static const bool hasAPIC;
static const bool hasSEP;
static const bool hasMTRR;
static const bool hasPGE;
static const bool hasMCA;
static const bool hasCMOV;
static const bool hasPSE_36;
static const bool hasPSN;
static const bool hasCLFSH;
static const bool hasDS;
static const bool hasACPI;
static const bool hasMMX;
static const bool hasFXSR;
static const bool hasSSE;
static const bool hasSSE2;
static const bool hasSS;
static const bool hasHTT;
static const bool hasTM;
static const bool hasIA64;
static const bool hasPBE;
static const bool hasSSE3;
static const bool hasPCLMULQDQ;
static const bool hasDTES64;
static const bool hasMONITOR;
static const bool hasVMX;
static const bool hasSMX;
static const bool hasEST;
static const bool hasTM2;
static const bool hasSSSE3;
static const bool hasCNXT_ID;
static const bool hasSDBG;
static const bool hasFMA;
static const bool hasCX16;
static const bool hasXTPR;
static const bool hasPDCM;
static const bool hasPCID;
static const bool hasDCA;
static const bool hasSSE4_1;
static const bool hasSSE4_2;
static const bool hasX2APIC;
static const bool hasMOVBE;
static const bool hasPOPCNT;
static const bool hasTSC_DEADLINE;
static const bool hasAES;
static const bool hasXSAVE;
static const bool hasOSXSAVE;
static const bool hasAVX;
static const bool hasF16C;
static const bool hasRDRND;
static const bool hasHYPERVISOR;
static const bool hasAVX2;
static const bool hasAVX512F;
static const bool hasRDSEED;
static const bool hasADX;
static Architecture GetArchitecture();
static UInt_8 PointerSize();
@@ -68,151 +132,157 @@ namespace ehs
static UInt_8 GetExtFamilyId();
/// Retrieves the CPU brand as a null-terminated ASCII string.
/// @param[out] input A 48 byte character array representing the brand.
static void GetBrand(Char_8* input);
static UInt_8 GetCacheLineSize();
static UInt_32 GetFeatureBits_1();
static bool HasFPU();
static bool HasVME();
static bool HasDE();
static bool HasPSE();
static bool HasTSC();
static bool HasMSR();
static bool HasPAE();
static bool HasMCE();
static bool HasCX8();
static bool HasAPIC();
static bool HasSEP();
static bool HasMTRR();
static bool HasPGE();
static bool HasMCA();
static bool HasCMOV();
static bool HasPAT();
static bool HasPSE_36();
static bool HasPSN();
static bool HasCLFSH();
static bool HasDS();
static bool HasACPI();
static bool HasMMX();
static bool HasFXSR();
static bool HasSSE();
static bool HasSSE2();
static bool HasSS();
static bool HasHTT();
static bool HasTM();
static bool HasIA64();
static bool HasPBE();
static UInt_32 GetFeatureBits_2();
static bool HasSSE3();
static bool HasPCLMULQDQ();
static bool HasDTES64();
static bool HasMONITOR();
static bool HasDS_CPL();
static bool HasVMX();
static bool HasSMX();
static bool HasEST();
static bool HasTM2();
static bool HasSSSE3();
static bool HasCNXT_ID();
static bool HasSDBG();
static bool HasFMA();
static bool HasCX16();
static bool HasXTPR();
static bool HasPDCM();
static bool HasPCID();
static bool HasDCA();
static bool HasSSE4_1();
static bool HasSSE4_2();
static bool HasX2APIC();
static bool HasMOVBE();
static bool HasPOPCNT();
static bool HasTSC_DEADLINE();
static bool HasAES();
static bool HasXSAVE();
static bool HasOSXSAVE();
static bool HasAVX();
static bool HasF16C();
static bool HasRDRND();
static bool HasHYPERVISOR();
static UInt_32 GetExtFeatureBits_1();
static bool HasAVX2();
static bool HasRDSEED();
static bool HasADX();
static UInt_32 GetExtFeatureBits_2();
static UInt_32 GetExtFeatureBits_3();
/// Retrieves the CPU brand as a null-terminated ASCII string.
/// @param[out] input A 48 byte character array representing the brand.
static void GetBrand(Char_8* input);
private:
static bool RetrieveFPU();
static bool RetrieveVME();
static bool RetrieveDE();
static bool RetrievePSE();
static bool RetrieveTSC();
static bool RetrieveMSR();
static bool RetrievePAE();
static bool RetrieveMCE();
static bool RetrieveCX8();
static bool RetrieveAPIC();
static bool RetrieveSEP();
static bool RetrieveMTRR();
static bool RetrievePGE();
static bool RetrieveMCA();
static bool RetrieveCMOV();
static bool RetrievePAT();
static bool RetrievePSE_36();
static bool RetrievePSN();
static bool RetrieveCLFSH();
static bool RetrieveDS();
static bool RetrieveACPI();
static bool RetrieveMMX();
static bool RetrieveFXSR();
static bool RetrieveSSE();
static bool RetrieveSSE2();
static bool RetrieveSS();
static bool RetrieveHTT();
static bool RetrieveTM();
static bool RetrieveIA64();
static bool RetrievePBE();
static bool RetrieveSSE3();
static bool RetrievePCLMULQDQ();
static bool RetrieveDTES64();
static bool RetrieveMONITOR();
static bool RetrieveDS_CPL();
static bool RetrieveVMX();
static bool RetrieveSMX();
static bool RetrieveEST();
static bool RetrieveTM2();
static bool RetrieveSSSE3();
static bool RetrieveCNXT_ID();
static bool RetrieveSDBG();
static bool RetrieveFMA();
static bool RetrieveCX16();
static bool RetrieveXTPR();
static bool RetrievePDCM();
static bool RetrievePCID();
static bool RetrieveDCA();
static bool RetrieveSSE4_1();
static bool RetrieveSSE4_2();
static bool RetrieveX2APIC();
static bool RetrieveMOVBE();
static bool RetrievePOPCNT();
static bool RetrieveTSC_DEADLINE();
static bool RetrieveAES();
static bool RetrieveXSAVE();
static bool RetrieveOSXSAVE();
static bool RetrieveAVX();
static bool RetrieveF16C();
static bool RetrieveRDRND();
static bool RetrieveHYPERVISOR();
static bool RetrieveAVX2();
static bool RetrieveAVX512F();
static bool RetrieveRDSEED();
static bool RetrieveADX();
//static Str_8 ToStr();
private:
static UInt_64 RetrieveFreq_AARCH64();
static UInt_64 RetrieveTSC_Freq();
static UInt_64 CalculateTSC_Freq();

View File

@@ -8,7 +8,7 @@ namespace ehs
class EHS_LIB_IO System : public BaseSystem
{
public:
static void OpenURI(const Str_8& uri);
static void OpenURI(Str_8 uri);
static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);

View File

@@ -7,6 +7,6 @@ namespace ehs
class EHS_LIB_IO System : public BaseSystem
{
public:
static void OpenURI(const Str_8& uri);
static void OpenURI(Str_8 uri);
};
}

View File

@@ -2,7 +2,35 @@
namespace ehs
{
const char Base64::ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Str_8 Base64::EncodeURL(const Str_8 &input)
{
UInt_64 input_length = input.Size();
// Calculate the output length
UInt_64 output_length = (input_length * 4 + 2) / 3;
// Allocate memory for the output
Str_8 result(output_length);
// Loop through the input and fill the output
for (int i = 0, j = 0; i < input_length;) {
// Take first byte and shift right by 2 bits
UInt_32 octet_a = (UInt_8)input[i++];
UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_c = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 triple = (octet_a << 16) + (octet_b << 8) + octet_c;
// Encode the 24-bits into four 6-bits integers
result[j++] = asciiUrl[(triple >> 3 * 6) & 0x3F];
result[j++] = asciiUrl[(triple >> 2 * 6) & 0x3F];
result[j++] = asciiUrl[(triple >> 1 * 6) & 0x3F];
result[j++] = asciiUrl[(triple >> 0 * 6) & 0x3F];
}
return result;
}
Str_8 Base64::Encode(const Str_8 &input)
{
@@ -18,9 +46,9 @@ namespace ehs
for (int i = 0, j = 0; i < input_length;) {
// Take first byte and shift right by 2 bits
UInt_32 octet_a = i < input_length ? input[i++] : 0;
UInt_32 octet_b = i < input_length ? input[i++] : 0;
UInt_32 octet_c = i < input_length ? input[i++] : 0;
UInt_32 octet_a = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_c = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
@@ -42,63 +70,151 @@ namespace ehs
return result;
}
Str_8 Base64::DecodeURL(const Str_8 &input)
{
Str_8 result(input.Size() * 3 / 4);
UInt_64 remaining = input.Size();
UInt_64 offsetIn = 0;
UInt_64 offsetOut = 0;
UInt_8 quartet[4];
while (remaining)
{
if (remaining >= 4)
{
for (UInt_8 i = 0; i < 4; ++i)
{
if (!IsBase64URL(input[offsetIn + i]))
return {};
quartet[i] = FindURL(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[1] << 4) | (((UInt_8*)&quartet)[2] >> 2));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[2] << 6) | ((UInt_8*)&quartet)[3]);
offsetIn += 4;
remaining -= 4;
}
else
{
for (UInt_8 i = 0; i < 4; ++i)
{
if (i < remaining)
{
if (!IsBase64URL(input[offsetIn + i]))
return {};
quartet[i] = FindURL(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
else
quartet[i] = 0;
}
result[offsetOut++] = (Char_8)((quartet[0] << 2) | (quartet[1] >> 4));
if (remaining == 3)
result[offsetOut++] = (Char_8)((quartet[1] << 4) | (quartet[2] >> 2));
offsetIn += remaining;
remaining = 0;
}
}
return result;
}
Str_8 Base64::Decode(const Str_8 &input)
{
UInt_64 in_len = input.Size();
int i = 0;
int j = 0;
int in_ = 0;
char char_array_4[4], char_array_3[3];
Str_8 ret;
Str_8 result(input.Size() * 3 / 4);
while (in_len-- && ( input[in_] != '=') && IsBase64(input[in_]))
UInt_64 remaining = input.Size();
UInt_64 offsetIn = 0;
UInt_64 offsetOut = 0;
UInt_8 quartet[4];
while (remaining)
{
char_array_4[i++] = input[in_]; in_++;
if (i ==4)
if (remaining >= 4)
{
for (i = 0; i <4; i++)
char_array_4[i] = Find(char_array_4[i]);
for (UInt_8 i = 0; i < 4; ++i)
{
if (!IsBase64(input[offsetIn + i]))
return {};
char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
quartet[i] = Find(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[1] << 4) | (((UInt_8*)&quartet)[2] >> 2));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[2] << 6) | ((UInt_8*)&quartet)[3]);
i = 0;
offsetIn += 4;
remaining -= 4;
}
else
{
for (UInt_8 i = 0; i < 4; ++i)
{
if (i < remaining)
{
if (!IsBase64(input[offsetIn + i]))
return {};
quartet[i] = Find(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
else
quartet[i] = 0;
}
result[offsetOut++] = (Char_8)((quartet[0] << 2) | (quartet[1] >> 4));
if (remaining == 3)
result[offsetOut++] = (Char_8)((quartet[1] << 4) | (quartet[2] >> 2));
offsetIn += remaining;
remaining = 0;
}
}
if (i)
{
for (j = 0; j < i; j++)
char_array_4[j] = Find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
for (j = 0; (j < i - 1); j++)
ret += char_array_3[j];
return result;
}
return ret;
UInt_8 Base64::FindURL(const UInt_8 &c)
{
for (UInt_8 i = 0; i < (UInt_8)sizeof(asciiUrl) - 1; ++i)
if (asciiUrl[i] == c)
return i;
return EHS_UINT_8_MAX;;
}
char Base64::Find(const char c)
{
for (char i = 0; i < (char)sizeof(ascii); ++i)
UInt_8 Base64::Find(const UInt_8 &c)
{
for (UInt_8 i = 0; i < (UInt_8)sizeof(ascii) - 1; ++i)
if (ascii[i] == c)
return i;
}
return EHS_SINT_8_MAX;
}
bool Base64::IsBase64(const char c)
bool Base64::IsBase64URL(const UInt_8 &c)
{
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || (c == '+') || (c == '/');
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || c == '-' || c == '_';
}
bool Base64::IsBase64(const UInt_8 &c)
{
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || c == '+' || c == '/';
}
}

View File

@@ -75,12 +75,12 @@ namespace ehs
{
}
Log::Log(LogType type, const std::initializer_list<Str_8> &tags, const UInt_64 code, Str_8 msg)
: type(type), tags(tags.size()), code(code), msg((Str_8&&)msg)
Log::Log(LogType type, const Str_8 &tags, const UInt_64 code, Str_8 msg)
: type(type), code(code), msg((Str_8&&)msg)
{
UInt_64 i = 0;
for (auto v = tags.begin(); v != tags.end(); ++v)
this->tags[i++] = *v;
const Vector<Str_8> tmpTags = tags.Split(", ");
this->tags = Array<Str_8>(&tmpTags[0], tmpTags.Size());
}
Log::Log(LogType type, Array<Str_8> tags, const UInt_64 code, Str_8 msg)

View File

@@ -36,9 +36,9 @@ namespace ehs
double Math::Sqrt(const double from)
{
#if defined(EHS_ARCH_X64)
if (CPU::HasAVX())
if (CPU::hasAVX)
return Sqrt_AVX(from);
else if (CPU::HasSSE())
else if (CPU::hasSSE)
return Sqrt_SSE2(from);
double temp = 0.0;
@@ -51,7 +51,7 @@ namespace ehs
}
return result;
#elif defined(EHS_ARCH_ARM64)
#elif defined(EHS_ARCH_AARCH64)
return Sqrt_VFP4(from);
#endif
}
@@ -59,9 +59,9 @@ namespace ehs
float Math::Sqrt(const float from)
{
#if defined(EHS_ARCH_X64)
if (CPU::HasAVX())
if (CPU::hasAVX)
return Sqrt_AVX(from);
else if (CPU::HasSSE())
else if (CPU::hasSSE)
return Sqrt_SSE(from);
float temp = 0.0f;
@@ -74,7 +74,7 @@ namespace ehs
}
return result;
#elif defined(EHS_ARCH_ARM64)
#elif defined(EHS_ARCH_AARCH64)
return Sqrt_VFP4(from);
#endif
}

209
src/SHA256.cpp Normal file
View File

@@ -0,0 +1,209 @@
#include "ehs/SHA256.h"
#include "ehs/Util.h"
namespace ehs
{
UInt_32 SHA256::ROTR(const UInt_32 x, const UInt_32 n)
{
return (x >> n) | (x << (32 - n));
}
UInt_32 SHA256::CH(const UInt_32 x, const UInt_32 y, const UInt_32 z)
{
return (x & y) ^ (~x & z);
}
UInt_32 SHA256::MAJ(const UInt_32 x, const UInt_32 y, const UInt_32 z)
{
return (x & y) ^ (x & z) ^ (y & z);
}
UInt_32 SHA256::EP0(const UInt_32 x)
{
return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22);
}
UInt_32 SHA256::EP1(const UInt_32 x)
{
return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25);
}
UInt_32 SHA256::SIG0(const UInt_32 x)
{
return ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3);
}
UInt_32 SHA256::SIG1(const UInt_32 x)
{
return ROTR(x,17) ^ ROTR(x, 19) ^ (x >> 10);
}
SHA256::SHA256()
: state{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19},
bitLen(0), data{}, dataLen(0)
{
}
SHA256::SHA256(SHA256&& other) noexcept
: state{}, bitLen(0), data{}, dataLen(0)
{
Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32));
bitLen = other.bitLen;
Util::Copy(data, other.data, sizeof(data));
dataLen = other.dataLen;
Util::Zero(other.state, sizeof(state) / sizeof(UInt_32));
other.bitLen = 0;
Util::Zero(other.data, sizeof(data));
other.dataLen = 0;
}
SHA256::SHA256(const SHA256& other)
: state{}, bitLen(0), data{}, dataLen(0)
{
Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32));
bitLen = other.bitLen;
Util::Copy(data, other.data, sizeof(data));
dataLen = other.dataLen;
}
SHA256& SHA256::operator=(SHA256&& other) noexcept
{
if (this == &other)
return *this;
Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32));
bitLen = other.bitLen;
Util::Copy(data, other.data, sizeof(data));
dataLen = other.dataLen;
Util::Zero(other.state, sizeof(state) / sizeof(UInt_32));
other.bitLen = 0;
Util::Zero(other.data, sizeof(data));
other.dataLen = 0;
return *this;
}
SHA256& SHA256::operator=(const SHA256& other)
{
if (this == &other)
return *this;
Util::Copy(state, other.state, sizeof(state) / sizeof(UInt_32));
bitLen = other.bitLen;
Util::Copy(data, other.data, sizeof(data));
dataLen = other.dataLen;
return *this;
}
void SHA256::Update(const Byte* data, const UInt_64 len)
{
for(UInt_64 i = 0; i < len; ++i)
{
this->data[dataLen++] = data[i];
if(dataLen == 64)
{
Transform(this->data);
bitLen += 512;
dataLen = 0;
}
}
}
void SHA256::Final(Byte hash[32])
{
UInt_32 i = dataLen;
/* Pad */
data[i++] = 0x80;
if(i > 56)
{
while(i < 64)
data[i++] = 0x00;
Transform(data);
i = 0;
}
while(i < 56)
data[i++] = 0x00;
/* Length in bits */
bitLen += dataLen * 8ULL;
data[63] = bitLen;
data[62] = bitLen >> 8;
data[61] = bitLen >> 16;
data[60] = bitLen >> 24;
data[59] = bitLen >> 32;
data[58] = bitLen >> 40;
data[57] = bitLen >> 48;
data[56] = bitLen >> 56;
Transform(data);
/* bigendian output */
for(i = 0; i < 4; ++i) {
hash[i] = (state[0] >> (24 - i * 8)) & 0xff;
hash[i + 4] = (state[1] >> (24 - i * 8)) & 0xff;
hash[i + 8] = (state[2] >> (24 - i * 8)) & 0xff;
hash[i + 12] = (state[3] >> (24 - i * 8)) & 0xff;
hash[i + 16] = (state[4] >> (24 - i * 8)) & 0xff;
hash[i + 20] = (state[5] >> (24 - i * 8)) & 0xff;
hash[i + 24] = (state[6] >> (24 - i * 8)) & 0xff;
hash[i + 28] = (state[7] >> (24 - i * 8)) & 0xff;
}
}
void SHA256::Hash(const Byte* data, const UInt_64 len, Byte hash[32])
{
Update(data, len);
Final(hash);
}
void SHA256::Transform(const Byte data[64])
{
UInt_32 m[64];
UInt_32 a = state[0];
UInt_32 b = state[1];
UInt_32 c = state[2];
UInt_32 d = state[3];
UInt_32 e = state[4];
UInt_32 f = state[5];
UInt_32 g = state[6];
UInt_32 h = state[7];
UInt_32 i, t1, t2;
for (i = 0; i < 16; ++i)
m[i] = (UInt_32)data[i * 4] << 24 | (UInt_32)data[i * 4 + 1] << 16 | (UInt_32)data[i * 4 + 2] << 8 | (UInt_32)data[i * 4 + 3];
for (; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
for(i = 0; i < 64; ++i)
{
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
state[5] += f;
state[6] += g;
state[7] += h;
}
}

View File

@@ -1,5 +1,9 @@
#include "ehs/Util.h"
#include "ehs/system/CPU.h"
#include "ehs/system/AVX2.h"
#include "ehs/system/AVX512.h"
namespace ehs
{
bool Util::Compare(const void* const a, const void* const b, const UInt_64 size)

View File

@@ -693,7 +693,7 @@ namespace ehs
Vector<Str_32> Console::GetArgs_32(const UInt_64 bufferSize)
{
#if defined(EHS_OS_WINDOWS)
return UTF::To_32(GetCommandLineW()).Split(U" ");
return UTF::To_32(GetCommandLineW()).ParseArgs();
#elif defined(EHS_OS_LINUX)
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
Array<Byte> data = cmdFile.ReadArray(bufferSize);
@@ -725,7 +725,7 @@ namespace ehs
Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize)
{
#if defined(EHS_OS_WINDOWS)
return Str_16(GetCommandLineW()).Split(L" ");
return Str_16(GetCommandLineW()).ParseArgs();
#elif defined(EHS_OS_LINUX)
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
Array<Byte> data = cmdFile.ReadArray(bufferSize);
@@ -755,7 +755,7 @@ namespace ehs
Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize)
{
#if defined(EHS_OS_WINDOWS)
return UTF::To_8(GetCommandLineW()).Split(" ");
return UTF::To_8(GetCommandLineW()).ParseArgs();
#elif defined(EHS_OS_LINUX)
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
Array<Byte> data = cmdFile.ReadArray(bufferSize);

View File

@@ -93,13 +93,13 @@ namespace ehs
}
AudioDevice::AudioDevice()
: id(0), loop(nullptr), context(nullptr), core(nullptr), input(nullptr), output(nullptr)
: id(0), loop(nullptr), context(nullptr), core(nullptr), input(nullptr), output(nullptr), paramsHook{}
{
}
AudioDevice::AudioDevice(AudioDevice&& device) noexcept
: BaseAudioDevice(device), id(device.id), name((Str_8 &&)device.name), loop(device.loop),
context(device.context), core(device.core), input(device.input), output(device.output)
context(device.context), core(device.core), input(device.input), output(device.output), paramsHook(device.paramsHook)
{
device.id = 0;
device.loop = nullptr;
@@ -107,11 +107,12 @@ namespace ehs
device.core = nullptr;
device.input = nullptr;
device.output = nullptr;
device.paramsHook = {};
}
AudioDevice::AudioDevice(const AudioDevice& device)
: BaseAudioDevice(device), id(device.id), name(device.name), loop(nullptr), context(nullptr), core(nullptr),
input(nullptr), output(nullptr)
input(nullptr), output(nullptr), paramsHook{}
{
}
@@ -129,6 +130,7 @@ namespace ehs
core = device.core;
input = device.input;
output = device.output;
paramsHook = device.paramsHook;
device.id = 0;
device.loop = nullptr;
@@ -136,6 +138,7 @@ namespace ehs
device.core = nullptr;
device.input = nullptr;
device.output = nullptr;
device.paramsHook = {};
return *this;
}
@@ -154,6 +157,7 @@ namespace ehs
core = nullptr;
input = nullptr;
output = nullptr;
paramsHook = {};
return *this;
}
@@ -206,14 +210,18 @@ namespace ehs
return;
}
pw_stream_connect(
output,
SInt_32 err = pw_stream_connect(
input,
PW_DIRECTION_INPUT,
id,
(pw_stream_flags)(PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS),
pod,
1
);
if (err)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to connect input stream for audio device.");
}
}
if (GetType() == AudioDeviceType::OUTPUT || GetType() == AudioDeviceType::ALL)
@@ -225,7 +233,7 @@ namespace ehs
return;
}
pw_stream_connect(
SInt_32 err = pw_stream_connect(
output,
PW_DIRECTION_OUTPUT,
id,
@@ -233,6 +241,10 @@ namespace ehs
pod,
1
);
if (err)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to connect output stream for audio device.");
}
}
static constexpr pw_stream_events streamEvents = {
@@ -240,8 +252,17 @@ namespace ehs
.param_changed = OnParamChanged
};
spa_hook streamListener = {};
pw_stream_add_listener(output, &streamListener, &streamEvents, this);
pw_stream_add_listener(output, &paramsHook, &streamEvents, this);
while (pw_stream_get_state(output, nullptr) == PW_STREAM_STATE_CONNECTING)
{
SInt_32 err = pw_loop_iterate(loop, 0);
if (err < 0)
{
EHS_LOG_INT(LogType::ERR, 3, "Failed to update audio with error #" + Str_8::FromNum(err) + ".");
return;
}
}
EHS_LOG_SUCCESS();
}
@@ -283,7 +304,15 @@ namespace ehs
return 0;
}
pw_loop_iterate(loop, 0);
if (!data || !size)
return 0;
SInt_32 err = pw_loop_iterate(loop, 0);
if (err < 0)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to update audio with error #" + Str_8::FromNum(err) + ".");
return 0;
}
if (pw_stream_get_state(output, nullptr) != PW_STREAM_STATE_STREAMING)
return 0;

View File

@@ -4,7 +4,7 @@
namespace ehs
{
Str_8 BaseDNS::Resolve(const AddrType type, const Str_8 &hostname)
Str_8 BaseDNS::Resolve(const IP type, const Str_8 &hostname)
{
EHS_LOG_INT(LogType::ERR, 0, "Unsupported Operating System.");
return {};

145
src/io/socket/BaseICMP.cpp Normal file
View File

@@ -0,0 +1,145 @@
#include "ehs/io/socket/BaseICMP.h"
#include "ehs/Serializer.h"
namespace ehs
{
BaseICMP::BaseICMP()
: version(IP::V6)
{
}
BaseICMP::BaseICMP(const IP version)
: version(version)
{
}
BaseICMP::BaseICMP(BaseICMP &&icmp) noexcept
: version(icmp.version)
{
}
BaseICMP::BaseICMP(const BaseICMP &icmp)
: version(icmp.version)
{
}
BaseICMP & BaseICMP::operator=(BaseICMP &&icmp) noexcept
{
if (this == &icmp)
return *this;
version = icmp.version;
return *this;
}
BaseICMP & BaseICMP::operator=(const BaseICMP &icmp)
{
if (this == &icmp)
return *this;
version = icmp.version;
return *this;
}
void BaseICMP::Release()
{
}
UInt_64 BaseICMP::Send(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
if (GetVersion() == IP::V6)
return SendV6(address, header, data, size);
return SendV4(address, header, data, size);
}
UInt_64 BaseICMP::Receive(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data)
{
if (GetVersion() == IP::V6)
return ReceiveV6(address, header, data);
return ReceiveV4(address, header, data);
}
void BaseICMP::SendEchoRequest(const Str_8 &address, ICMP_EchoRequest er, const Byte *data, UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return;
}
ICMP_Header header = {
version == IP::V6 ? (UInt_8)128 : (UInt_8)8,
0,
0
};
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(er);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
Send(address, header, &payload[0], payload.Size());
}
void BaseICMP::SetReceiveTimeout(UInt_64 timeout)
{
}
IP BaseICMP::GetVersion() const
{
return version;
}
bool BaseICMP::IsValid() const
{
return false;
}
UInt_16 BaseICMP::ComputeChecksumV4(UInt_16 *buffer, Size length)
{
Size sum = 0;
while (length > 1)
{
sum += *buffer++;
length -= sizeof(UInt_16);
}
if (length == 1)
sum += *(UInt_8 *)buffer;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (UInt_16)~sum;
}
UInt_64 BaseICMP::SendV6(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
return 0;
}
UInt_64 BaseICMP::SendV4(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
return 0;
}
UInt_64 BaseICMP::ReceiveV6(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const
{
return 0;
}
UInt_64 BaseICMP::ReceiveV4(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const
{
return 0;
}
}

View File

@@ -4,26 +4,26 @@
namespace ehs
{
BaseTCP::BaseTCP()
: addrType(AddrType::IPV6), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
: ip(IP::V6), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
connected(false)
{
}
BaseTCP::BaseTCP(const AddrType addrType)
: addrType(addrType), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
BaseTCP::BaseTCP(const IP ip)
: ip(ip), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
connected(false)
{
}
BaseTCP::BaseTCP(BaseTCP&& tcp) noexcept
: addrType(tcp.addrType), localAddr(std::move(tcp.localAddr)), localPort(tcp.localPort),
: ip(tcp.ip), localAddr(std::move(tcp.localAddr)), localPort(tcp.localPort),
remoteHostName(std::move(tcp.remoteHostName)), remoteAddr(std::move(tcp.remoteAddr)), remotePort(tcp.remotePort),
connection(tcp.connection), bound(tcp.bound), listening(tcp.listening), connected(tcp.connected)
{
}
BaseTCP::BaseTCP(const BaseTCP& tcp)
: addrType(tcp.addrType), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
: ip(tcp.ip), localPort(0), remotePort(0), connection(false), bound(false), listening(false),
connected(false)
{
}
@@ -33,7 +33,7 @@ namespace ehs
if (this == &tcp)
return *this;
addrType = tcp.addrType;
ip = tcp.ip;
localAddr = std::move(tcp.localAddr);
localPort = tcp.localPort;
remoteHostName = std::move(tcp.remoteHostName);
@@ -44,7 +44,7 @@ namespace ehs
listening = tcp.listening;
connected = tcp.connected;
tcp.addrType = AddrType::IPV6;
tcp.ip = IP::V6;
tcp.localPort = 0;
tcp.remotePort = 0;
tcp.connection = false;
@@ -60,7 +60,7 @@ namespace ehs
if (this == &tcp)
return *this;
addrType = tcp.addrType;
ip = tcp.ip;
localAddr = Str_8();
localPort = 0;
remoteHostName = Str_8();
@@ -108,7 +108,7 @@ namespace ehs
if (!IsValid())
return;
req.AddToHeader("Host", remoteHostName);
req.AddHeaderVar({"Host", remoteHostName});
SendStr(req.FormResult());
}
@@ -124,10 +124,10 @@ namespace ehs
Response response(header);
Str_8 encoding = response.GetHeader("Transfer-Encoding");
Str_8 encoding = response.GetHeaderValue("Transfer-Encoding");
if (!encoding.Size())
{
int bodySize = response.GetHeader("content-length").ToDecimal<int>();
int bodySize = response.GetHeaderValue("content-length").ToDecimal<int>();
if (!bodySize)
return response;
@@ -163,10 +163,10 @@ namespace ehs
if (request.GetVerb() == Verb::GET)
return request;
Str_8 encoding = request.GetHeader("Transfer-Encoding");
Str_8 encoding = request.GetHeaderValue("Transfer-Encoding");
if (!encoding.Size())
{
int bodySize = request.GetHeader("Content-Length").ToDecimal<int>();
int bodySize = request.GetHeaderValue("Content-Length").ToDecimal<int>();
if (!bodySize)
return request;
@@ -188,9 +188,9 @@ namespace ehs
return request;
}
AddrType BaseTCP::GetAddressType() const
IP BaseTCP::GetAddressType() const
{
return addrType;
return ip;
}
Str_8 BaseTCP::GetLocalAddress() const

View File

@@ -3,25 +3,23 @@
namespace ehs
{
BaseUDP::BaseUDP()
: type(AddrType::IPV6), port(0), bound(false)
: bound(false)
{
}
BaseUDP::BaseUDP(const AddrType type)
: type(type), port(0), bound(false)
BaseUDP::BaseUDP(const IP version)
: localEndpoint{version, "", 0}, bound(false)
{
}
BaseUDP::BaseUDP(BaseUDP&& udp) noexcept
: type(udp.type), address(std::move(udp.address)), port(udp.port), bound(true)
: localEndpoint((Endpoint &&)udp.localEndpoint), bound(true)
{
udp.type = AddrType::IPV6;
udp.port = 0;
udp.bound = false;
}
BaseUDP::BaseUDP(const BaseUDP& udp)
: type(udp.type), address(udp.address), port(udp.port), bound(false)
: localEndpoint(udp.localEndpoint), bound(false)
{
}
@@ -30,13 +28,9 @@ namespace ehs
if (this == &udp)
return *this;
type = udp.type;
address = std::move(udp.address);
port = udp.port;
localEndpoint = (Endpoint &&)udp.localEndpoint;
bound = udp.bound;
udp.type = AddrType::IPV6;
udp.port = 0;
udp.bound = false;
return *this;
@@ -47,9 +41,7 @@ namespace ehs
if (this == &udp)
return *this;
type = udp.type;
address = udp.address;
port = udp.port;
localEndpoint = udp.localEndpoint;
bound = false;
return *this;
@@ -60,18 +52,8 @@ namespace ehs
return bound;
}
AddrType BaseUDP::GetLocalAddressType() const
Endpoint BaseUDP::GetLocalEndpoint() const
{
return type;
}
Str_8 BaseUDP::GetLocalAddress() const
{
return address;
}
UInt_16 BaseUDP::GetLocalPort() const
{
return port;
return localEndpoint;
}
}

View File

@@ -7,14 +7,14 @@
namespace ehs
{
Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname)
Str_8 DNS::Resolve(const IP type, const Str_8 &hostname)
{
addrinfo* result = nullptr;
addrinfo req = {};
if (type == AddrType::IPV6)
if (type == IP::V6)
req.ai_family = AF_INET6;
else if (type == AddrType::IPV4)
else if (type == IP::V4)
req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);

View File

@@ -6,7 +6,7 @@
namespace ehs
{
Str_8 DNS::Resolve(const AddrType type, const Str_8 &hostname)
Str_8 DNS::Resolve(const IP type, const Str_8 &hostname)
{
WSADATA data = {};
@@ -20,9 +20,9 @@ namespace ehs
addrinfo* result = nullptr;
addrinfo req = {};
if (type == AddrType::IPV6)
if (type == IP::V6)
req.ai_family = AF_INET6;
else if (type == AddrType::IPV4)
else if (type == IP::V4)
req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
#include "ehs/io/socket/HeaderVar.h"
namespace ehs
{
HeaderVar::HeaderVar()
: id(0)
{
}
HeaderVar::HeaderVar(Str_8 name, Str_8 value)
: id(name.Hash_64()), name((Str_8 &&)name), value((Str_8 &&)value)
{
}
HeaderVar::HeaderVar(HeaderVar&& other) noexcept
: id(other.id), name((Str_8 &&)other.name), value((Str_8 &&)other.value)
{
other.id = 0;
}
HeaderVar::HeaderVar(const HeaderVar& other)
: id(other.id), name(other.name), value(other.value)
{
}
HeaderVar& HeaderVar::operator=(HeaderVar&& other) noexcept
{
if (this == &other)
return *this;
id = other.id;
name = (Str_8 &&)other.name;
value = (Str_8 &&)other.value;
other.id = 0;
return *this;
}
HeaderVar& HeaderVar::operator=(const HeaderVar& other)
{
if (this == &other)
return *this;
id = other.id;
name = other.name;
value = other.value;
return *this;
}
bool HeaderVar::operator==(const HeaderVar& other) const
{
return id == other.id;
}
bool HeaderVar::operator!=(const HeaderVar& other) const
{
return id != other.id;
}
bool HeaderVar::operator==(const UInt_64& otherId) const
{
return id == otherId;
}
bool HeaderVar::operator!=(const UInt_64& otherId) const
{
return id != otherId;
}
UInt_64 HeaderVar::GetId() const
{
return id;
}
Str_8 HeaderVar::GetName() const
{
return name;
}
Str_8 HeaderVar::GetValue() const
{
return value;
}
void HeaderVar::SetValue(Str_8 value)
{
this->value = (Str_8 &&)value;
}
Str_8 HeaderVar::ToStr() const
{
return name + ": " + value;
}
}

384
src/io/socket/ICMP_LNX.cpp Normal file
View File

@@ -0,0 +1,384 @@
#include "ehs/io/socket/ICMP_LNX.h"
#include "ehs/Serializer.h"
#include "ehs/Log.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <ifaddrs.h>
#include <unistd.h>
namespace ehs
{
ICMP::~ICMP()
{
if (close(hdl) == -1)
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
}
ICMP::ICMP()
: hdl(EHS_INVALID_SOCKET), src{}
{
}
ICMP::ICMP(const IP version)
: BaseICMP(version), src{}
{
if (version == IP::V6)
hdl = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
else
hdl = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (hdl < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to create ICMP socket with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
ICMP::ICMP(ICMP &&icmp) noexcept
: BaseICMP((BaseICMP &&)icmp), hdl(icmp.hdl), src(icmp.src)
{
icmp.hdl = EHS_INVALID_SOCKET;
icmp.src = {};
}
ICMP::ICMP(const ICMP &icmp)
: BaseICMP(icmp), hdl(icmp.hdl), src{}
{
}
ICMP & ICMP::operator=(ICMP &&icmp) noexcept
{
if (this == &icmp)
return *this;
BaseICMP::operator=((BaseICMP &&)icmp);
hdl = icmp.hdl;
src = icmp.src;
icmp.hdl = EHS_INVALID_SOCKET;
icmp.src = {};
return *this;
}
ICMP & ICMP::operator=(const ICMP &icmp)
{
if (this == &icmp)
return *this;
BaseICMP::operator=(icmp);
hdl = icmp.hdl;
src = {};
return *this;
}
void ICMP::Release()
{
if (close(hdl) == -1)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
return;
}
hdl = EHS_INVALID_SOCKET;
EHS_LOG_SUCCESS();
}
void ICMP::SetReceiveTimeout(const UInt_64 timeout)
{
timeval result = {};
result.tv_sec = (long)timeout;
result.tv_usec = 0;
if (setsockopt(hdl, SOL_SOCKET, SO_RCVTIMEO, &result, sizeof(result)) < 0)
{
EHS_LOG_INT(LogType::WARN, 0, "Failed to set receive timeout with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool ICMP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;
}
bool ICMP::IsLinkLocal(const in6_addr &addr)
{
return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80;
}
sockaddr_in6 ICMP::RetrieveSrcAddress()
{
ifaddrs *ifaddr;
sockaddr_in6 addr = {};
if (getifaddrs(&ifaddr) == -1)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to retrieve public address with error #" + Str_8::FromNum(errno) + ".");
return addr;
}
for (ifaddrs *ifa = ifaddr; ifa; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == nullptr || ifa->ifa_addr->sa_family != AF_INET6)
continue;
addr = *(sockaddr_in6 *)ifa->ifa_addr;
if (!addr.sin6_addr.s6_addr32[0] || IsLinkLocal(addr.sin6_addr))
continue;
break;
}
freeifaddrs(ifaddr);
EHS_LOG_SUCCESS();
return addr;
}
UInt_32 ICMP::CalculatePseudoHeaderChecksum(const PseudoICMPv6_Header &header)
{
UInt_32 checksum = 0;
for (UInt_8 i = 0; i < 16; ++i)
checksum += header.src.sin6_addr.s6_addr[i];
for (UInt_8 i = 0; i < 16; ++i)
checksum += header.dst.sin6_addr.s6_addr[i];
checksum += 58;
checksum += htons(header.length);
checksum = (checksum >> 16) + (checksum & 0xFFFF);
checksum += (checksum >> 16);
return checksum;
}
UInt_16 ICMP::ComputeChecksumV6(UInt_16 *buffer, Size length, const sockaddr_in6 &dst)
{
UInt_32 checksum = 0;
if (!src.sin6_addr.s6_addr32[0])
{
src = RetrieveSrcAddress();
if (!src.sin6_addr.s6_addr32[0])
{
EHS_LOG_INT(LogType::ERR, 0, "Could not retrieve a suitable global address.");
return checksum;
}
}
checksum += CalculatePseudoHeaderChecksum({src, dst, (UInt_32)length});
while (length > 1)
{
checksum += *buffer++;
length -= sizeof(UInt_16);
}
if (length == 1)
checksum += *(UInt_8 *)buffer;
// Carry over any overflow from the 16-bit result
checksum = (checksum >> 16) + (checksum & 0xFFFF);
checksum += (checksum >> 16);
// Return the 16-bit complement
return ~checksum;
}
UInt_64 ICMP::SendV6(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
header.checksum = 0;
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(header);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
sockaddr_in6 dst = {};
dst.sin6_family = AF_INET6;
inet_pton(AF_INET6, address, &(dst.sin6_addr));
header.checksum = ComputeChecksumV6((UInt_16 *)&payload[0], payload.Size(), dst);
payload.SetOffset(0);
payload.Write(header);
payload.SetOffset(payload.Size());
SInt_64 sent = sendto(hdl, payload, payload.Size(), 0, (sockaddr *)&dst, sizeof(sockaddr_in6));
if (sent < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to send packet with error #" + Str_8::FromNum(errno) + ".");
return 0;
}
EHS_LOG_SUCCESS();
return sent;
}
UInt_64 ICMP::SendV4(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
header.checksum = 0;
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(header);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
header.checksum = ComputeChecksumV4((UInt_16 *)&payload[0], payload.Size());
payload.SetOffset(0);
payload.Write(header);
payload.SetOffset(payload.Size());
sockaddr_in dst = {};
dst.sin_family = AF_INET;
inet_pton(AF_INET, address, &(dst.sin_addr));
SInt_64 sent = sendto(hdl, payload, payload.Size(), 0, (sockaddr *)&dst, sizeof(sockaddr_in));
if (sent < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to send packet with error #" + Str_8::FromNum(errno) + ".");
return 0;
}
EHS_LOG_SUCCESS();
return sent;
}
UInt_64 ICMP::ReceiveV6(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
Serializer<UInt_64> payload(Endianness::LE);
payload.Resize(1500);
sockaddr_in6 remote = {};
socklen_t from_len = sizeof(remote);
SInt_64 recv = recvfrom(hdl, payload, 1500, 0, (sockaddr *)&remote, &from_len);
if (recv < 0)
{
int code = errno;
if (code == EAGAIN)
EHS_LOG_SUCCESS();
else
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive packet with error #" + Str_8::FromNum(code) + ".");
return 0;
}
payload.Resize(recv);
char tmpAddr[INET6_ADDRSTRLEN];
if (!inet_ntop(remote.sin6_family, &remote.sin6_addr, tmpAddr, INET6_ADDRSTRLEN))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to convert IPv6 address with error #" + Str_8::FromNum(errno) + ".");
return recv;
}
address = tmpAddr;
header = payload.Read<ICMP_Header>();
data = Serializer<UInt_64>(payload.GetEndianness(), &payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
EHS_LOG_SUCCESS();
return recv;
}
UInt_64 ICMP::ReceiveV4(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
Serializer<UInt_64> payload(Endianness::LE);
payload.Resize(1500);
sockaddr_in remote = {};
socklen_t from_len = sizeof(remote);
SInt_64 recv = recvfrom(hdl, payload, 1500, 0, (sockaddr *)&remote, &from_len);
if (recv < 0)
{
int code = errno;
if (code == EAGAIN)
EHS_LOG_SUCCESS();
else
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive packet with error #" + Str_8::FromNum(code) + ".");
return 0;
}
payload.Resize(recv);
char tmpAddr[INET_ADDRSTRLEN];
if (!inet_ntop(remote.sin_family, &remote.sin_addr, tmpAddr, INET_ADDRSTRLEN))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to convert IPv4 address with error #" + Str_8::FromNum(errno) + ".");
return recv;
}
address = tmpAddr;
iphdr ipHeader = payload.Read<iphdr>();
header = payload.Read<ICMP_Header>();
data = Serializer<UInt_64>(payload.GetEndianness(), &payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
EHS_LOG_SUCCESS();
return recv;
}
}

391
src/io/socket/ICMP_W32.cpp Normal file
View File

@@ -0,0 +1,391 @@
#include "ehs/io/socket/ICMP_W32.h"
struct iphdr
{
u_char ip_hl:4, ip_v:4;
u_char ip_tos;
u_short ip_len;
u_short ip_id;
u_short ip_off;
u_char ip_ttl;
u_char ip_p;
u_short ip_sum;
in_addr ip_src, ip_dst;
};
namespace ehs
{
ICMP::~ICMP()
{
if (closesocket(hdl) == -1)
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
}
ICMP::ICMP()
: hdl(EHS_INVALID_SOCKET)
{
}
ICMP::ICMP(const IP version)
: BaseICMP(version)
{
hdl = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (hdl < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to create ICMP socket with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
ICMP::ICMP(ICMP &&icmp) noexcept
: BaseICMP((BaseICMP &&)icmp), hdl(icmp.hdl)
{
icmp.hdl = EHS_INVALID_SOCKET;
}
ICMP::ICMP(const ICMP &icmp)
: BaseICMP(icmp), hdl(icmp.hdl)
{
}
ICMP & ICMP::operator=(ICMP &&icmp) noexcept
{
if (this == &icmp)
return *this;
BaseICMP::operator=((BaseICMP &&)icmp);
hdl = icmp.hdl;
icmp.hdl = EHS_INVALID_SOCKET;
return *this;
}
ICMP & ICMP::operator=(const ICMP &icmp)
{
if (this == &icmp)
return *this;
BaseICMP::operator=(icmp);
hdl = icmp.hdl;
return *this;
}
void ICMP::Release()
{
if (closesocket(hdl) == -1)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to close socket.");
return;
}
hdl = EHS_INVALID_SOCKET;
EHS_LOG_SUCCESS();
}
void ICMP::SetReceiveTimeout(UInt_64 timeout)
{
timeval result = {};
result.tv_sec = (long)timeout;
result.tv_usec = 0;
if (setsockopt(hdl, SOL_SOCKET, SO_RCVTIMEO, (const char *)&result, sizeof(result)) < 0)
{
EHS_LOG_INT(LogType::WARN, 0, "Failed to set receive timeout with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool ICMP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;
}
bool ICMP::IsLinkLocal(const in6_addr &addr)
{
return addr.s6_addr[0] == 0xfe && (addr.s6_addr[1] & 0xc0) == 0x80;
}
sockaddr_in6 ICMP::RetrieveSrcAddress()
{
sockaddr_in6 addr = {};
UInt_32 outBufLen = 15000;
Array<Byte> buffer(outBufLen);
PIP_ADAPTER_ADDRESSES pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)&buffer[0];
if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAdapterAddresses, (PULONG)&outBufLen) == ERROR_BUFFER_OVERFLOW)
{
buffer.Resize(outBufLen);
pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)&buffer[0];
}
if (GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAdapterAddresses, (PULONG)&outBufLen) == NO_ERROR)
{
for (PIP_ADAPTER_ADDRESSES adapter = pAdapterAddresses; adapter != nullptr; adapter = adapter->Next)
{
for (PIP_ADAPTER_UNICAST_ADDRESS addrInfo = adapter->FirstUnicastAddress; addrInfo != nullptr; addrInfo = addrInfo->Next)
{
SOCKADDR *sa = addrInfo->Address.lpSockaddr;
if (sa->sa_family != AF_INET6)
continue;
sockaddr_in6 *ipv6Addr = (sockaddr_in6 *)sa;
// Skip link-local addresses
if (IN6_IS_ADDR_LINKLOCAL(&ipv6Addr->sin6_addr))
continue;
addr = *ipv6Addr;
return addr; // Return the first suitable address
}
}
}
EHS_LOG_SUCCESS();
return addr; // Return an empty sockaddr_in6 if no valid address was found
}
UInt_32 ICMP::CalculatePseudoHeaderChecksum(const PseudoICMPv6_Header &header)
{
UInt_32 checksum = 0;
for (UInt_8 i = 0; i < 16; ++i)
checksum += header.src.sin6_addr.s6_addr[i];
for (UInt_8 i = 0; i < 16; ++i)
checksum += header.dst.sin6_addr.s6_addr[i];
checksum += 58;
checksum += htons(header.length);
checksum = (checksum >> 16) + (checksum & 0xFFFF);
checksum += (checksum >> 16);
return checksum;
}
UInt_16 ICMP::ComputeChecksumV6(UInt_16 *buffer, Size length, const sockaddr_in6 &dst)
{
UInt_32 checksum = 0;
if (!src.sin6_addr.u.Word[0])
{
src = RetrieveSrcAddress();
if (!src.sin6_addr.u.Word[0])
{
EHS_LOG_INT(LogType::ERR, 0, "Could not retrieve a suitable global address.");
return checksum;
}
}
checksum += CalculatePseudoHeaderChecksum({src, dst, (UInt_32)length});
while (length > 1)
{
checksum += *buffer++;
length -= sizeof(UInt_16);
}
if (length == 1)
checksum += *(UInt_8 *)buffer;
// Carry over any overflow from the 16-bit result
checksum = (checksum >> 16) + (checksum & 0xFFFF);
checksum += (checksum >> 16);
// Return the 16-bit complement
return ~checksum;
}
UInt_64 ICMP::SendV6(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
header.checksum = 0;
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(header);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
sockaddr_in6 dst = {};
dst.sin6_family = AF_INET6;
inet_pton(AF_INET6, address, &(dst.sin6_addr));
header.checksum = ComputeChecksumV6((UInt_16 *)&payload[0], payload.Size(), dst);
payload.SetOffset(0);
payload.Write(header);
payload.SetOffset(payload.Size());
SInt_64 sent = sendto(hdl, (const char *)&payload[0], payload.Size(), 0, (sockaddr *)&dst, sizeof(sockaddr_in6));
if (sent < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to send packet with error #" + Str_8::FromNum(errno) + ".");
return 0;
}
EHS_LOG_SUCCESS();
return sent;
}
UInt_64 ICMP::SendV4(const Str_8 &address, ICMP_Header header, const Byte *data, UInt_64 size)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
header.checksum = 0;
Serializer<UInt_64> payload(Endianness::LE);
payload.Write(header);
payload.Resize(payload.Size() + size);
Util::Copy(&payload[payload.GetOffset()], data, size);
payload.SetOffset(payload.GetOffset() + size);
header.checksum = ComputeChecksumV4((UInt_16 *)&payload[0], payload.Size());
payload.SetOffset(0);
payload.Write(header);
payload.SetOffset(payload.Size());
sockaddr_in dst_addr = {};
dst_addr.sin_family = AF_INET;
inet_pton(AF_INET, address, &(dst_addr.sin_addr));
SInt_64 sent = sendto(hdl, (const char *)&payload[0], payload.Size(), 0, (sockaddr *)&dst_addr, sizeof(dst_addr));
if (sent < 0)
{
EHS_LOG_INT(LogType::ERR, 0, "Failed to send packet with error #" + Str_8::FromNum(errno) + ".");
return 0;
}
EHS_LOG_SUCCESS();
return sent;
}
UInt_64 ICMP::ReceiveV6(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
Serializer<UInt_64> payload(Endianness::LE);
payload.Resize(1500);
sockaddr_in6 remote = {};
socklen_t from_len = sizeof(remote);
SInt_64 recv = recvfrom(hdl, (char *)&payload[0], 1500, 0, (sockaddr *)&remote, &from_len);
if (recv < 0)
{
int code = errno;
if (code == EAGAIN)
EHS_LOG_SUCCESS();
else
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive packet with error #" + Str_8::FromNum(code) + ".");
return 0;
}
payload.Resize(recv);
char tmpAddr[INET6_ADDRSTRLEN];
if (!inet_ntop(remote.sin6_family, &remote.sin6_addr, tmpAddr, INET6_ADDRSTRLEN))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to convert IPv6 address with error #" + Str_8::FromNum(errno) + ".");
return recv;
}
address = tmpAddr;
header = payload.Read<ICMP_Header>();
data = Serializer<UInt_64>(payload.GetEndianness(), &payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
EHS_LOG_SUCCESS();
return recv;
}
UInt_64 ICMP::ReceiveV4(Str_8 &address, ICMP_Header &header, Serializer<UInt_64> &data) const
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 0, "Socket is not initialized.");
return 0;
}
Serializer<UInt_64> payload(Endianness::LE);
payload.Resize(1500);
sockaddr_in remote = {};
socklen_t from_len = sizeof(remote);
SInt_64 recv = recvfrom(hdl, (char *)&payload[0], 1500, 0, (sockaddr *)&remote, &from_len);
if (recv < 0)
{
int code = errno;
if (code == EAGAIN)
EHS_LOG_SUCCESS();
else
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive packet with error #" + Str_8::FromNum(code) + ".");
return 0;
}
payload.Resize(recv);
char tmpAddr[INET_ADDRSTRLEN];
if (!inet_ntop(remote.sin_family, &remote.sin_addr, tmpAddr, INET_ADDRSTRLEN))
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to convert IPv4 address with error #" + Str_8::FromNum(errno) + ".");
return recv;
}
address = tmpAddr;
iphdr ipHeader = payload.Read<iphdr>();
header = payload.Read<ICMP_Header>();
data = Serializer<UInt_64>(payload.GetEndianness(), &payload[payload.GetOffset()], payload.Size() - payload.GetOffset());
EHS_LOG_SUCCESS();
return recv;
}
}

View File

@@ -0,0 +1,96 @@
#include "ehs/io/socket/QueryVar.h"
namespace ehs
{
QueryVar::QueryVar()
: id(0)
{
}
QueryVar::QueryVar(Str_8 name, Str_8 value)
: id(name.Hash_64()), name((Str_8 &&)name), value((Str_8 &&)value)
{
}
QueryVar::QueryVar(QueryVar&& other) noexcept
: id(other.id), name((Str_8 &&)other.name), value((Str_8 &&)other.value)
{
other.id = 0;
}
QueryVar::QueryVar(const QueryVar& other)
: id(other.id), name(other.name), value(other.value)
{
}
QueryVar& QueryVar::operator=(QueryVar&& other) noexcept
{
if (this == &other)
return *this;
id = other.id;
name = (Str_8 &&)other.name;
value = (Str_8 &&)other.value;
other.id = 0;
return *this;
}
QueryVar& QueryVar::operator=(const QueryVar& other)
{
if (this == &other)
return *this;
id = other.id;
name = other.name;
value = other.value;
return *this;
}
bool QueryVar::operator==(const QueryVar& other) const
{
return id == other.id;
}
bool QueryVar::operator!=(const QueryVar& other) const
{
return id != other.id;
}
bool QueryVar::operator==(const UInt_64& otherId) const
{
return id == otherId;
}
bool QueryVar::operator!=(const UInt_64& otherId) const
{
return id != otherId;
}
UInt_64 QueryVar::GetId() const
{
return id;
}
Str_8 QueryVar::GetName() const
{
return name;
}
Str_8 QueryVar::GetValue() const
{
return value;
}
void QueryVar::SetValue(Str_8 value)
{
this->value = (Str_8 &&)value;
}
Str_8 QueryVar::ToStr() const
{
return name + "=" + value;
}
}

View File

@@ -4,16 +4,16 @@
namespace ehs
{
Request::Request()
: verb(Verb::GET), cType(ContentType::NONE)
: verb(Verb::POST), cType(ContentType::NONE)
{
}
Request::Request(const Verb verb, const Str_8& rsrc)
: verb(verb), rsrc(rsrc), cType(ContentType::NONE)
Request::Request(const Verb &verb, Str_8 rsrc)
: verb(verb), rsrc((Str_8 &&)rsrc), cType(ContentType::NONE)
{
}
Request::Request(const char* data, const UInt_64 size)
Request::Request(const char *data, const UInt_64 &size)
: verb(Verb::POST), cType(ContentType::NONE)
{
ReadData(Str_8(data, size));
@@ -25,17 +25,49 @@ namespace ehs
ReadData(data);
}
Request& Request::operator=(const Request &req)
Request::Request(Request&& other) noexcept
: verb(other.verb), rsrc((Str_8 &&)other.rsrc), queries((Vector<QueryVar> &&)other.queries),
header((Vector<HeaderVar> &&)other.header), cType(other.cType), body((Str_8 &&)other.body)
{
if (this == &req)
other.verb = Verb::POST;
other.cType = ContentType::NONE;
}
Request::Request(const Request& other)
: verb(other.verb), rsrc(other.rsrc), queries(other.queries), header(other.header), cType(other.cType),
body(other.body)
{
}
Request& Request::operator=(Request&& other) noexcept
{
if (this == &other)
return *this;
verb = req.verb;
rsrc = req.rsrc;
queries = req.queries;
header = req.header;
cType = req.cType;
body = req.body;
verb = other.verb;
rsrc = (Str_8 &&)other.rsrc;
queries = (Vector<QueryVar> &&)other.queries;
header = (Vector<HeaderVar> &&)other.header;
cType = other.cType;
body = (Str_8 &&)other.body;
other.verb = Verb::POST;
other.cType = ContentType::NONE;
return* this;
}
Request& Request::operator=(const Request &other)
{
if (this == &other)
return *this;
verb = other.verb;
rsrc = other.rsrc;
queries = other.queries;
header = other.header;
cType = other.cType;
body = other.body;
return* this;
}
@@ -45,7 +77,7 @@ namespace ehs
return verb;
}
void Request::SetContentType(const ContentType cType)
void Request::SetContentType(const ContentType &cType)
{
if (body.Size())
body.Resize(0);
@@ -58,9 +90,9 @@ namespace ehs
return cType;
}
void Request::SetResource(const Str_8& rsrc)
void Request::SetResource(Str_8 rsrc)
{
this->rsrc = rsrc;
this->rsrc = (Str_8 &&)rsrc;
}
Str_8 Request::GetResource() const
@@ -68,69 +100,179 @@ namespace ehs
return rsrc;
}
void Request::AddQuery(const Str_8& var, const Str_8& value)
bool Request::HasQueryVar(const UInt_64& id) const
{
queries.Push(var + "=" + value);
for (UInt_64 i = 0; i < queries.Size(); ++i)
if (queries[i] == id)
return true;
return false;
}
Str_8 Request::GetQuery(const Str_8& var)
bool Request::HasQueryVar(const Str_8& name) const
{
return HasQueryVar(name.Hash_64());
}
bool Request::AddQueryVar(QueryVar var)
{
if (HasQueryVar(var.GetId()))
return false;
queries.Push((QueryVar &&)var);
return true;
}
bool Request::RemoveQueryVar(const UInt_64& id)
{
for (UInt_64 i = 0; i < queries.Size(); ++i)
{
Vector<Str_8> data = queries[i].Split("=");
if (queries[i] != id)
continue;
if (data[0] == var)
return data[1];
queries.Swap(i, queries.End());
queries.Pop();
return true;
}
return "";
return false;
}
Vector<Str_8> Request::GetQueries() const
bool Request::RemoveQueryVar(const Str_8& name)
{
return RemoveQueryVar(name.Hash_64());
}
QueryVar *Request::GetQueryVar(const UInt_64& id) const
{
for (UInt_64 i = 0; i < queries.Size(); ++i)
if (queries[i] == id)
return &queries[i];
return nullptr;
}
QueryVar *Request::GetQueryVar(const Str_8& name) const
{
return GetQueryVar(name.Hash_64());
}
Str_8 Request::GetQueryValue(const UInt_64& id) const
{
for (UInt_64 i = 0; i < queries.Size(); ++i)
if (queries[i] == id)
return queries[i].GetValue();
return {};
}
Str_8 Request::GetQueryValue(const Str_8& name) const
{
return GetQueryValue(name.Hash_64());
}
Vector<QueryVar> Request::GetQueries() const
{
return queries;
}
void Request::BasicAuth(const Str_8& id, const Str_8& secret)
{
AddToHeader("Authorization", Str_8("Basic ") + Base64::Encode(id + ":" + secret));
AddHeaderVar({"Authorization", Str_8("Basic ") + Base64::Encode(id + ":" + secret)});
}
void Request::BearerAuth(const Str_8& token)
{
AddToHeader("Authorization", "Bearer " + token);
AddHeaderVar({"Authorization", "Bearer " + token});
}
void Request::BearerAuth(const Str_8& token, const Str_8& clientId)
{
AddToHeader("Authorization", "Bearer " + token);
AddToHeader("Client-Id", clientId);
AddHeaderVar({"Authorization", "Bearer " + token});
AddHeaderVar({"Client-Id", clientId});
}
void Request::BotAuth(const Str_8& token)
{
AddToHeader("Authorization", "Bot " + token);
AddHeaderVar({"Authorization", "Bot " + token});
}
void Request::AddToHeader(const Str_8& var, const Str_8& value)
bool Request::HasHeaderVar(const UInt_64& id) const
{
header.Push(var + ": " + value);
for (UInt_64 i = 0; i < header.Size(); ++i)
if (header[i] == id)
return true;
return false;
}
Str_8 Request::GetHeader(const Str_8& var) const
bool Request::HasHeaderVar(const Str_8& name) const
{
return HasHeaderVar(name.Hash_64());
}
bool Request::AddHeaderVar(HeaderVar var)
{
if (HasHeaderVar(var.GetId()))
return false;
header.Push((HeaderVar &&)var);
return true;
}
bool Request::RemoveHeaderVar(const UInt_64 &id)
{
for (UInt_64 i = 0; i < header.Size(); ++i)
{
Vector<Str_8> data = header[i].Split(": ");
if (header[i] != id)
continue;
if (data[0] == var)
return data[1];
header.Swap(i, header.End());
header.Pop();
return true;
}
return "";
return false;
}
Vector<Str_8> Request::GetHeader() const
bool Request::RemoveHeaderVar(const Str_8 &name)
{
return RemoveHeaderVar(name.Hash_64());
}
HeaderVar *Request::GetHeaderVar(const UInt_64 &id) const
{
for (UInt_64 i = 0; i < header.Size(); ++i)
if (header[i] == id)
return &header[i];
return nullptr;
}
HeaderVar *Request::GetHeaderVar(const Str_8 &name) const
{
return GetHeaderVar(name.Hash_64());
}
Str_8 Request::GetHeaderValue(const UInt_64 &id) const
{
for (UInt_64 i = 0; i < header.Size(); ++i)
if (header[i] == id)
return header[i].GetValue();
return {};
}
Str_8 Request::GetHeaderValue(const Str_8 &name) const
{
return GetHeaderValue(name.Hash_64());
}
Vector<HeaderVar> Request::GetHeader() const
{
return header;
}
@@ -200,16 +342,20 @@ namespace ehs
Str_8 result = VerbToStr(verb) + " " + rsrc;
if (queries.Size())
result += "?" + queries[0];
result += "?" + queries[0].ToStr();
for (UInt_64 i = 1; i < queries.Size(); ++i)
result += "&" + queries[i];
result += "&" + queries[i].ToStr();
result += " HTTP/1.1\r\n";
for (UInt_64 i = 0; i < header.Size(); ++i)
{
result += header[i] + "\r\n";
if (header[i] == 11245195881701120957ull || header[i] == 6556302699635904946ull ||
header[i] == 13347276190653935221ull) // Content-Length, Server, and Content-Type in order from left to right.
continue;
result += header[i].ToStr() + "\r\n";
}
result += "Content-Type: " + ContentTypeToStr(cType) + "\r\n";
@@ -227,7 +373,7 @@ namespace ehs
return rsrc.Size() || queries.Size() || header.Size() || body.Size();
}
Str_8 Request::VerbToStr(const Verb verb)
Str_8 Request::VerbToStr(const Verb &verb)
{
switch (verb)
{
@@ -244,7 +390,7 @@ namespace ehs
}
}
Str_8 Request::ContentTypeToStr(const ContentType cType)
Str_8 Request::ContentTypeToStr(const ContentType &cType)
{
switch (cType)
{
@@ -262,8 +408,12 @@ namespace ehs
return "text/plain";
case ContentType::TEXT_HTML:
return "text/html";
case ContentType::TEXT_CSS:
return "text/css";
case ContentType::TEXT_XML:
return "text/xml";
case ContentType::IMG_X_ICON:
return "image/x-icon";
default:
return "";
}
@@ -285,8 +435,12 @@ namespace ehs
return ContentType::TEXT_PLAIN;
else if (value == "text/html")
return ContentType::TEXT_HTML;
else if (value == "text/css")
return ContentType::TEXT_CSS;
else if (value == "text/xml")
return ContentType::TEXT_XML;
else if (value == "image/x-icon")
return ContentType::IMG_X_ICON;
else
return ContentType::NONE;
}
@@ -308,7 +462,14 @@ namespace ehs
{
rsrc = meta[1].Sub(0, queryIndex);
cType = ContentType::APP_FORMURLENCODED;
queries = meta[1].Sub(queryIndex + 1).Split("&");
Vector<Str_8> strQueries = meta[1].Sub(queryIndex + 1).Split("&");
for (UInt_64 i = 0; i < strQueries.Size(); ++i)
{
const Vector<Str_8> queryVar = strQueries[i].Split("=");
queries.Push({queryVar[0], queryVar[1]});
}
}
else
{
@@ -331,7 +492,9 @@ namespace ehs
if (var[0] == "Content-Length")
continue;
header.Push(lines[i]);
Vector<Str_8> headerVar = lines[i].Split(": ");
header.Push({headerVar[0], headerVar[1]});
}
}
}

View File

@@ -2,12 +2,17 @@
namespace ehs
{
Response::Response(const UInt_32 code, const Str_8& server)
: code(code), server(server), cType(ContentType::NONE)
Response::Response()
: code(0), cType(ContentType::NONE)
{
}
Response::Response(const char* data, const UInt_64 size)
Response::Response(const UInt_32 &code, Str_8 server)
: code(code), server((Str_8 &&)server), cType(ContentType::NONE)
{
}
Response::Response(const char *data, const UInt_64 &size)
: code(0), cType(ContentType::NONE)
{
ReadData(Str_8(data, size));
@@ -19,26 +24,51 @@ namespace ehs
ReadData(data);
}
Response::Response()
: code(0), cType(ContentType::NONE)
Response::Response(Response&& other) noexcept
: code(other.code), server((Str_8 &&)other.server), cType(other.cType), header((Vector<HeaderVar> &&)other.header),
body((Str_8 &&)other.body)
{
other.code = 0;
other.cType = ContentType::NONE;
}
Response::Response(const Response &other)
: code(other.code), server(other.server), cType(other.cType), header(other.header), body(other.body)
{
}
Response& Response::operator=(const Response& res)
Response& Response::operator=(Response&& other) noexcept
{
if (this == &res)
if (this == &other)
return *this;
code = res.code;
server = res.server;
cType = res.cType;
header = res.header;
body = res.body;
code = other.code;
server = (Str_8 &&)other.server;
cType = other.cType;
header = (Vector<HeaderVar> &&)other.header;
body = (Str_8 &&)other.body;
other.code = 0;
other.cType = ContentType::NONE;
return *this;
}
void Response::SetCode(const UInt_32 code)
Response& Response::operator=(const Response& other)
{
if (this == &other)
return *this;
code = other.code;
server = other.server;
cType = other.cType;
header = other.header;
body = other.body;
return *this;
}
void Response::SetCode(const UInt_32 &code)
{
this->code = code;
}
@@ -48,9 +78,9 @@ namespace ehs
return code;
}
void Response::SetServer(const Str_8& server)
void Response::SetServer(Str_8 server)
{
this->server = server;
this->server = (Str_8 &&)server;
}
Str_8 Response::GetServer() const
@@ -58,7 +88,7 @@ namespace ehs
return server;
}
void Response::SetContentType(const ContentType cType)
void Response::SetContentType(const ContentType &cType)
{
this->cType = cType;
}
@@ -68,27 +98,80 @@ namespace ehs
return cType;
}
void Response::AddToHeader(const Str_8& var, const Str_8& value)
bool Response::HasHeaderVar(const UInt_64& id) const
{
header.Push(var + ": " + value);
for (UInt_64 i = 0; i < header.Size(); ++i)
if (header[i] == id)
return true;
return false;
}
Str_8 Response::GetHeader(const Str_8& var) const
bool Response::HasHeaderVar(const Str_8& name) const
{
Str_8 lIdentity = var.GetLower();
return HasHeaderVar(name.Hash_64());
}
bool Response::AddHeaderVar(HeaderVar var)
{
if (HasHeaderVar(var.GetId()))
return false;
header.Push((HeaderVar &&)var);
return true;
}
bool Response::RemoveHeaderVar(const UInt_64& id)
{
for (UInt_64 i = 0; i < header.Size(); ++i)
{
Vector<Str_8> data = header[i].Split(": ");
if (header[i] != id)
continue;
if (data[0].GetLower() == lIdentity)
return data[1];
header.Swap(i, header.End());
header.Pop();
return true;
}
return "";
return false;
}
Vector<Str_8> Response::GetHeader() const
bool Response::RemoveHeaderVar(const Str_8& name)
{
return RemoveHeaderVar(name.Hash_64());
}
HeaderVar* Response::GetHeaderVar(const UInt_64 &id) const
{
for (UInt_64 i = 0; i < header.Size(); ++i)
if (header[i] == id)
return &header[i];
return nullptr;
}
HeaderVar *Response::GetHeaderVar(const Str_8 &name) const
{
return GetHeaderVar(name.Hash_64());
}
Str_8 Response::GetHeaderValue(const UInt_64& id) const
{
for (UInt_64 i = 0; i < header.Size(); ++i)
if (header[i] == id)
return header[i].GetValue();
return {};
}
Str_8 Response::GetHeaderValue(const Str_8& name) const
{
return GetHeaderValue(name.Hash_64());
}
Vector<HeaderVar> Response::GetHeader() const
{
return header;
}
@@ -159,14 +242,11 @@ namespace ehs
for (UInt_64 i = 0; i < header.Size(); ++i)
{
if (header[i].Find("Content-Length", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING))
continue;
else if (header[i].Find("Server", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING))
continue;
else if (header[i].Find("Content-Type", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING))
if (header[i] == 11245195881701120957ull || header[i] == 6556302699635904946ull ||
header[i] == 13347276190653935221ull) // Content-Length, Server, and Content-Type in order from left to right.
continue;
result += header[i] + "\r\n";
result += header[i].ToStr() + "\r\n";
}
result += "Content-Type: " + ContentTypeToStr(cType) + "\r\nContent-Length: " + Str_8::FromNum(body.Size()) + "\r\n\r\n" + body;
@@ -179,7 +259,7 @@ namespace ehs
return server.Size() || header.Size() || body.Size();
}
Str_8 Response::CodeToStr(const UInt_32 code)
Str_8 Response::CodeToStr(const UInt_32 &code)
{
if (code == 100)
return "Continue";
@@ -323,7 +403,7 @@ namespace ehs
return "Unused Status Code";
}
Str_8 Response::ContentTypeToStr(const ContentType cType)
Str_8 Response::ContentTypeToStr(const ContentType &cType)
{
switch (cType)
{
@@ -341,8 +421,12 @@ namespace ehs
return "text/plain";
case ContentType::TEXT_HTML:
return "text/html";
case ContentType::TEXT_CSS:
return "text/css";
case ContentType::TEXT_XML:
return "text/xml";
case ContentType::IMG_X_ICON:
return "image/x-icon";
default:
return "";
}
@@ -364,8 +448,12 @@ namespace ehs
return ContentType::TEXT_PLAIN;
else if (value == "text/html")
return ContentType::TEXT_HTML;
else if (value == "text/css")
return ContentType::TEXT_CSS;
else if (value == "text/xml")
return ContentType::TEXT_XML;
else if (value == "image/x-icon")
return ContentType::IMG_X_ICON;
else
return ContentType::NONE;
}
@@ -384,12 +472,12 @@ namespace ehs
Vector<Str_8> var = lines[i].Split(": ");
if (var[0].GetLower() == "server")
if (var[0] == "Server")
{
server = var[1];
continue;
}
else if (var[0].GetLower() == "content-type")
else if (var[0] == "Content-Type")
{
Vector<Str_8> ctData = var[1].Split(";");
@@ -397,7 +485,9 @@ namespace ehs
continue;
}
header.Push(lines[i]);
Vector<Str_8> headerVar = lines[i].Split(": ");
header.Push({headerVar[0], headerVar[1]});
}
}
}

View File

@@ -4,6 +4,8 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/opensslv.h>
#include <openssl/provider.h>
namespace ehs
{
@@ -12,6 +14,11 @@ namespace ehs
if (!IsValid())
return;
EVP_PKEY_free(pkey);
X509_free(cert);
if (sslHdl)
{
if (connection)
@@ -25,28 +32,28 @@ namespace ehs
}
SSL::SSL()
: ctx(nullptr), sslHdl(nullptr)
: server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{
}
SSL::SSL(const AddrType type)
: TCP(type), ctx(nullptr), sslHdl(nullptr)
SSL::SSL(const IP &type, const bool &server)
: TCP(type), server(server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{
SSL::Initialize();
}
SSL::SSL(TCP&& tcp) noexcept
: TCP(std::move(tcp)), ctx(nullptr), sslHdl(nullptr)
: TCP(std::move(tcp)), server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{
}
SSL::SSL(const TCP& tcp)
: TCP(tcp), ctx(nullptr), sslHdl(nullptr)
: TCP(tcp), server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{
}
SSL::SSL(const SSL& ssl)
: TCP(ssl), ctx(nullptr), sslHdl(nullptr)
: TCP(ssl), server(ssl.server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{
}
@@ -57,8 +64,11 @@ namespace ehs
TCP::operator=(ssl);
server = ssl.server;
ctx = nullptr;
sslHdl = nullptr;
cert = nullptr;
pkey = nullptr;
return *this;
}
@@ -71,6 +81,40 @@ namespace ehs
return;
SSL_library_init();
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, nullptr);
OSSL_PROVIDER_load(nullptr, "default");
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
if (server)
{
ctx = SSL_CTX_new(TLS_server_method());
if (!ctx)
{
UInt_32 code = ERR_get_error();
EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr));
}
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5");
SSL_CTX_set_ciphersuites(ctx,
"TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:"
"TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256"
);
}
else
{
ctx = SSL_CTX_new(TLS_client_method());
if (!ctx)
{
UInt_32 code = ERR_get_error();
EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr));
}
SSL_CTX_set_default_verify_paths(ctx);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, nullptr);
}
}
void SSL::Release()
@@ -80,6 +124,12 @@ namespace ehs
if (!IsValid())
return;
EVP_PKEY_free(pkey);
pkey = nullptr;
X509_free(cert);
cert = nullptr;
if (sslHdl)
{
if (connection)
@@ -97,19 +147,14 @@ namespace ehs
}
}
void SSL::Bind(const Str_8& address, unsigned short port)
void SSL::Listen()
{
if (bound)
return;
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_server_method());
sslHdl = SSL_new(ctx);
SSL_set_fd(sslHdl, hdl);
TCP::Bind(address, port);
TCP::Listen();
EHS_LOG_SUCCESS();
}
SSL* SSL::Accept()
@@ -118,13 +163,21 @@ namespace ehs
return nullptr;
TCP* tcp = TCP::Accept();
if (!tcp)
return nullptr;
SSL* client = new SSL(std::move(*tcp));
delete tcp;
client->ctx = nullptr;
client->sslHdl = SSL_new(ctx);
client->sslHdl = SSL_new(this->ctx);
if (!client->sslHdl)
{
UInt_32 code = ERR_get_error();
EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr));
return nullptr;
}
SSL_set_fd(client->sslHdl, client->hdl);
int err = SSL_accept(client->sslHdl);
@@ -134,21 +187,29 @@ namespace ehs
return {};
}
EHS_LOG_SUCCESS();
return client;
}
void SSL::Connect(const Str_8& address, const UInt_16 port)
void SSL::Connect(Str_8 address, const UInt_16 &port)
{
if (bound)
return;
TCP::Connect(address, port);
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_client_method());
sslHdl = SSL_new(ctx);
SSL_set_fd(sslHdl, hdl);
SSL_connect(sslHdl);
SSL_set_tlsext_host_name(sslHdl, &address[0]);
SInt_32 rc = SSL_connect(sslHdl);
if (rc != 1)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to connect with error #" + Str_8::FromNum(SSL_get_error(sslHdl, rc)) + ".");
return;
}
EHS_LOG_SUCCESS();
}
UInt_64 SSL::Send(const Byte* const buffer, const UInt_32 size)
@@ -157,8 +218,12 @@ namespace ehs
if (written <= 0)
{
int code = SSL_get_error(sslHdl, written);
if (code != SSL_ERROR_WANT_WRITE)
{
ERR_print_errors_fp(stderr);
EHS_LOG_INT(LogType::ERR, 0, "Failed to send data with error #" + Str_8::FromNum(code) + ".");
}
return 0;
}
@@ -171,48 +236,46 @@ namespace ehs
if (received <= 0)
{
int code = SSL_get_error(sslHdl, received);
if (code != SSL_ERROR_WANT_READ)
{
ERR_print_errors_fp(stderr);
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data with error #" + Str_8::FromNum(code) + ".");
}
return 0;
}
return received;
}
void SSL::UseCertificate(const Byte* data, const UInt_64 size)
void SSL::UseCertificate(const Char_8* data, const UInt_32 &size)
{
X509 *cert = d2i_X509(nullptr, &data, (long)size);
if (!cert)
BIO* certBio = BIO_new_mem_buf(data, (int)size);
X509 *cert = PEM_read_bio_X509(certBio, nullptr, nullptr, nullptr);
if (!SSL_CTX_use_certificate(ctx, cert))
{
EHS_LOG_INT(LogType::ERR, 0, "Invalid certificate.");
UInt_32 code = ERR_get_error();
EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr));
return;
}
if (SSL_CTX_use_certificate(ctx, cert) != 1)
BIO_free(certBio);
}
void SSL::UsePrivateKey(const Char_8* data, const UInt_32 &size)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to use certificate.");
BIO* keyBio = BIO_new_mem_buf(data, (int)size);
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(keyBio, nullptr, nullptr, nullptr);
if (!SSL_CTX_use_PrivateKey(ctx, pkey))
{
UInt_32 code = ERR_get_error();
EHS_LOG_INT(LogType::ERR, 0, ERR_error_string(code, nullptr));
return;
}
X509_free(cert);
}
void SSL::UsePrivateKey(const Byte* data, const UInt_64 size)
{
EVP_PKEY *key = d2i_PrivateKey(EVP_PKEY_RSA, nullptr, &data, (long)size);
if (!key)
{
EHS_LOG_INT(LogType::ERR, 0, "Invalid private key.");
return;
}
if (SSL_CTX_use_PrivateKey(ctx, key) != 1)
{
EHS_LOG_INT(LogType::ERR, 1, "Failed to use private key.");
return;
}
EVP_PKEY_free(key);
BIO_free(keyBio);
}
bool SSL::IsValid()

View File

@@ -38,7 +38,7 @@ namespace ehc
}
Socket::Socket()
: hdl(EHS_INVALID_SOCKET), type(AddrType::IPV4), port(0), bound(false), appVer(0, 0, 0),
: hdl(EHS_INVALID_SOCKET), type(IP::V4), port(0), bound(false), appVer(0, 0, 0),
disposition(Disposition::UNKNOWN), dropPackets(false), hashId(0), buffer(nullptr), bufferSize(0),
maxEndpoints(0), lastTSC(0), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectedCb(nullptr),
activeCb(nullptr), disconnectedCb(nullptr)
@@ -47,7 +47,7 @@ namespace ehc
}
Socket::Socket(const Version& ver, const Disposition disposition, const Str_8& id, const UInt_64 maxEndpoints)
: hdl(EHS_INVALID_SOCKET), type(AddrType::IPV4), port(0), bound(false), appVer(ver), disposition(disposition),
: hdl(EHS_INVALID_SOCKET), type(IP::V4), port(0), bound(false), appVer(ver), disposition(disposition),
dropPackets(false), id(id), hashId(id.Hash_32()), buffer(nullptr), bufferSize(0),
maxEndpoints(maxEndpoints), lastTSC(CPU::GetTSC()), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f),
connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr)
@@ -113,9 +113,9 @@ namespace ehc
}
#endif
if (type == AddrType::IPV6)
if (type == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
else if (type == AddrType::IPV4)
else if (type == IP::V4)
hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else
return;
@@ -140,12 +140,12 @@ namespace ehc
return;
}
if (type == AddrType::IPV4)
if (type == IP::V4)
{
buffer = new Byte[EHS_IPV4_UDP_PAYLOAD];
bufferSize = EHS_IPV4_UDP_PAYLOAD;
}
else if (type == AddrType::IPV6)
else if (type == IP::V6)
{
buffer = new Byte[EHS_IPV6_UDP_PAYLOAD];
bufferSize = EHS_IPV6_UDP_PAYLOAD;
@@ -204,9 +204,9 @@ namespace ehc
if (hdl == EHS_INVALID_SOCKET || bound)
return;
if (type == AddrType::IPV6)
if (type == IP::V6)
Bind_v6(newAddress, newPort);
else if (type == AddrType::IPV4)
else if (type == IP::V4)
Bind_v4(newAddress, newPort);
address = newAddress;
@@ -580,7 +580,7 @@ namespace ehc
return hdl != EHS_INVALID_SOCKET;
}
void Socket::SetAddressType(const AddrType newType)
void Socket::SetAddressType(const IP newType)
{
if (hdl != EHS_INVALID_SOCKET)
return;
@@ -588,7 +588,7 @@ namespace ehc
type = newType;
}
AddrType Socket::GetAddressType() const
IP Socket::GetAddressType() const
{
return type;
}
@@ -1219,14 +1219,14 @@ namespace ehc
return 0;
}
if (type == AddrType::IPV4 && size > EHS_IPV4_UDP_PAYLOAD)
if (type == IP::V4 && size > EHS_IPV4_UDP_PAYLOAD)
{
EHS_LOG_INT(LogType::ERR, 1, "Attempted to receive with a buffer size of, \"" + Str_8::FromNum(size)
+ "\", that exceeds, \"" + Str_8::FromNum(EHS_IPV4_UDP_PAYLOAD) + ".");
}
sockaddr_in6 remote = {};
UInt_32 addrLen = type == AddrType::IPV6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
UInt_32 addrLen = type == IP::V6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
SInt_64 received = 0;
#if defined(EHS_OS_WINDOWS)

View File

@@ -30,8 +30,8 @@ namespace ehs
{
}
TCP::TCP(const AddrType addrType)
: BaseTCP(addrType), hdl(EHS_INVALID_SOCKET)
TCP::TCP(const IP IP)
: BaseTCP(IP), hdl(EHS_INVALID_SOCKET)
{
TCP::Initialize();
}
@@ -78,9 +78,9 @@ namespace ehs
if (IsValid())
return;
if (addrType == AddrType::IPV6)
if (ip == IP::V6)
hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
else if (addrType == AddrType::IPV4)
else if (ip == IP::V4)
hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
else
return;
@@ -114,17 +114,17 @@ namespace ehs
hdl = EHS_INVALID_SOCKET;
}
void TCP::Bind(const Str_8& address, UInt_16 port)
void TCP::Bind(Str_8 address, const UInt_16 &port)
{
if (!IsValid() || bound || connection)
return;
if (addrType == AddrType::IPV6)
if (ip == IP::V6)
Bind_v6(address, port);
else if (addrType == AddrType::IPV4)
else if (ip == IP::V4)
Bind_v4(address, port);
this->localAddr = address;
this->localAddr = (Str_8 &&)address;
this->localPort = port;
bound = true;
@@ -155,7 +155,7 @@ namespace ehs
UInt_32 addrLen = sizeof(sockaddr_in6);
TCP* client = new TCP();
client->addrType = addrType;
client->ip = ip;
client->localAddr = localAddr;
client->localPort = localPort;
client->connection = true;
@@ -207,26 +207,26 @@ namespace ehs
return client;
}
void TCP::Connect(const Str_8& address, const UInt_16 port)
void TCP::Connect(Str_8 address, const UInt_16 &port)
{
if (connection || !IsValid() || listening)
return;
remoteHostName = address;
remoteHostName = (Str_8 &&)address;
remotePort = port;
if (addrType == AddrType::IPV6)
if (ip == IP::V6)
{
if (IsIPv6Only())
remoteAddr = DNS::Resolve(AddrType::IPV6, address);
remoteAddr = DNS::Resolve(IP::V6, remoteHostName);
else
remoteAddr = DNS::Resolve(address);
remoteAddr = DNS::Resolve(remoteHostName);
Connect_v6(remoteAddr, port);
}
else if (addrType == AddrType::IPV4)
else if (ip == IP::V4)
{
remoteAddr = DNS::Resolve(AddrType::IPV4, address);
remoteAddr = DNS::Resolve(IP::V4, remoteHostName);
Connect_v4(remoteAddr, port);
}
@@ -338,7 +338,7 @@ namespace ehs
void TCP::SetIPv6Only(const bool value)
{
if (addrType != AddrType::IPV6)
if (ip != IP::V6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
@@ -362,7 +362,7 @@ namespace ehs
bool TCP::IsIPv6Only() const
{
if (addrType != AddrType::IPV6)
if (ip != IP::V6)
return false;
if (!IsValid())
@@ -385,12 +385,30 @@ namespace ehs
return result;
}
void TCP::SetReuse(const bool &value)
{
if (!IsValid())
{
EHS_LOG_INT(LogType::WARN, 1, "Attempted to set address and port reuse while socket is not initialized.");
return;
}
const int result = (int)value;
if (setsockopt(hdl, SOL_SOCKET, SO_REUSEPORT, &result, sizeof(int)) == -1)
{
EHS_LOG_INT(LogType::ERR, 2, "Failed to set address and port reuse with error #" + Str_8::FromNum(errno) + ".");
return;
}
EHS_LOG_SUCCESS();
}
bool TCP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;
}
void TCP::Bind_v6(const Str_8& address, UInt_16 port)
void TCP::Bind_v6(const Str_8& address, const UInt_16 &port) const
{
sockaddr_in6 result = {};
result.sin6_family = AF_INET6;
@@ -426,7 +444,7 @@ namespace ehs
}
}
void TCP::Bind_v4(const Str_8& address, UInt_16 port)
void TCP::Bind_v4(const Str_8& address, const UInt_16 &port) const
{
sockaddr_in result = {};
result.sin_family = AF_INET;
@@ -461,7 +479,7 @@ namespace ehs
}
}
void TCP::Connect_v6(const Str_8& address, UInt_16 port)
void TCP::Connect_v6(const Str_8 &address, const UInt_16 &port)
{
sockaddr_in6 result = {};
result.sin6_family = AF_INET6;
@@ -498,7 +516,7 @@ namespace ehs
}
}
void TCP::Connect_v4(const Str_8& address, UInt_16 port)
void TCP::Connect_v4(const Str_8 &address, const UInt_16 &port)
{
sockaddr_in result = {};
result.sin_family = AF_INET;

View File

@@ -33,8 +33,8 @@ namespace ehs
{
}
TCP::TCP(const AddrType addrType)
: BaseTCP(addrType), hdl(EHS_INVALID_SOCKET)
TCP::TCP(const IP IP)
: BaseTCP(IP), hdl(EHS_INVALID_SOCKET)
{
TCP::Initialize();
}
@@ -90,9 +90,9 @@ namespace ehs
return;
}
if (addrType == AddrType::IPV6)
if (ip == IP::V6)
hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
else if (addrType == AddrType::IPV4)
else if (ip == IP::V4)
hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
else
return;
@@ -137,17 +137,17 @@ namespace ehs
connected = false;
}
void TCP::Bind(const Str_8& address, UInt_16 port)
void TCP::Bind(Str_8 address, const UInt_16 &port)
{
if (!IsValid() || bound || connection)
return;
if (addrType == AddrType::IPV6)
if (ip == IP::V6)
Bind_v6(address, port);
else if (addrType == AddrType::IPV4)
else if (ip == IP::V4)
Bind_v4(address, port);
this->localAddr = address;
this->localAddr = (Str_8 &&)address;
this->localPort = port;
bound = true;
@@ -178,7 +178,7 @@ namespace ehs
UInt_32 addrLen = sizeof(sockaddr_in6);
TCP* client = new TCP();
client->addrType = addrType;
client->ip = ip;
client->localAddr = localAddr;
client->localPort = localPort;
client->connection = true;
@@ -236,26 +236,26 @@ namespace ehs
return client;
}
void TCP::Connect(const Str_8& address, const UInt_16 port)
void TCP::Connect(Str_8 address, const UInt_16 &port)
{
if (connection || !IsValid() || listening)
return;
remoteHostName = address;
remoteHostName = (Str_8 &&)address;
remotePort = port;
if (addrType == AddrType::IPV6)
if (ip == IP::V6)
{
if (IsIPv6Only())
remoteAddr = DNS::Resolve(AddrType::IPV6, address);
remoteAddr = DNS::Resolve(IP::V6, remoteHostName);
else
remoteAddr = DNS::Resolve(address);
remoteAddr = DNS::Resolve(remoteHostName);
Connect_v6(remoteAddr, port);
}
else if (addrType == AddrType::IPV4)
else if (ip == IP::V4)
{
remoteAddr = DNS::Resolve(AddrType::IPV4, address);
remoteAddr = DNS::Resolve(IP::V4, remoteHostName);
Connect_v4(remoteAddr, port);
}
@@ -359,7 +359,7 @@ namespace ehs
void TCP::SetIPv6Only(const bool value)
{
if (addrType != AddrType::IPV6)
if (ip != IP::V6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
@@ -383,7 +383,7 @@ namespace ehs
bool TCP::IsIPv6Only() const
{
if (addrType != AddrType::IPV6)
if (ip != IP::V6)
return false;
if (!IsValid())
@@ -406,6 +406,10 @@ namespace ehs
return result;
}
void TCP::SetReuse(const bool &value)
{
}
bool TCP::IsValid() const
{
return hdl != EHS_INVALID_SOCKET;

View File

@@ -25,12 +25,12 @@ namespace ehs
{
}
UDP::UDP(const AddrType addrType)
: BaseUDP(addrType), hdl(EHS_INVALID_SOCKET)
UDP::UDP(const IP version)
: BaseUDP(version), hdl(EHS_INVALID_SOCKET)
{
if (addrType == AddrType::IPV6)
if (version == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
else if (addrType == AddrType::IPV4)
else if (version == IP::V4)
hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else
return;
@@ -96,33 +96,32 @@ namespace ehs
bound = false;
}
void UDP::Bind(const AddrType type, const Str_8& address, const UInt_16 port)
void UDP::Bind(const Endpoint &endpoint)
{
if (!IsValid() || bound)
return;
if (type == AddrType::IPV6)
Bind_v6(address, port);
else if (type == AddrType::IPV4)
Bind_v4(address, port);
if (endpoint.version == IP::V6)
Bind_v6(endpoint.address, endpoint.port);
else if (endpoint.version == IP::V4)
Bind_v4(endpoint.address, endpoint.port);
this->address = address;
this->port = port;
localEndpoint = endpoint;
bound = true;
}
UInt_64 UDP::Send(const AddrType type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size)
UInt_64 UDP::Send(const Endpoint &endpoint, const Byte *const data, const UInt_64 size)
{
if (type == AddrType::IPV6)
return Send_v6(address, port, data, size);
else if (type == AddrType::IPV4)
return Send_v4(address, port, data, size);
if (endpoint.version == IP::V6)
return Send_v6(endpoint.address, endpoint.port, data, size);
else if (endpoint.version == IP::V4)
return Send_v4(endpoint.address, endpoint.port, data, size);
return 0;
}
UInt_64 UDP::Receive(AddrType* const type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size)
UInt_64 UDP::Receive(Endpoint *endpoint, Byte* const data, const UInt_64 size)
{
if (!IsValid())
{
@@ -161,9 +160,7 @@ namespace ehs
return received;
}
*type = AddrType::IPV6;
*address = tmpAddr;
*port = ntohs(remote.sin6_port);
*endpoint = {IP::V6, tmpAddr, remote.sin6_port};
}
else if (addrLen == sizeof(sockaddr_in))
{
@@ -178,9 +175,7 @@ namespace ehs
return received;
}
*type = AddrType::IPV4;
*address = tmpAddr;
*port = ntohs(((sockaddr_in*)&remote)->sin_port);
*endpoint = {IP::V4, tmpAddr, ntohs(((sockaddr_in*)&remote)->sin_port)};
}
return received;
@@ -205,7 +200,7 @@ namespace ehs
void UDP::SetIPv6Only(const bool value)
{
if (type != AddrType::IPV6)
if (localEndpoint.version != IP::V6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
@@ -229,7 +224,7 @@ namespace ehs
bool UDP::IsIPv6Only() const
{
if (type != AddrType::IPV6)
if (localEndpoint.version != IP::V6)
return false;
if (!IsValid())

View File

@@ -24,8 +24,8 @@ namespace ehs
{
}
UDP::UDP(const AddrType addrType)
: BaseUDP(addrType), hdl(EHS_INVALID_SOCKET)
UDP::UDP(const IP IP)
: BaseUDP(IP), hdl(EHS_INVALID_SOCKET)
{
WSADATA data = {};
@@ -36,9 +36,9 @@ namespace ehs
return;
}
if (addrType == AddrType::IPV6)
if (IP == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
else if (addrType == AddrType::IPV4)
else if (IP == IP::V4)
hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else
return;
@@ -110,33 +110,32 @@ namespace ehs
bound = false;
}
void UDP::Bind(const AddrType type, const Str_8& address, const UInt_16 port)
void UDP::Bind(const Endpoint &endpoint)
{
if (!IsValid() || bound)
return;
if (type == AddrType::IPV6)
Bind_v6(address, port);
else if (type == AddrType::IPV4)
Bind_v4(address, port);
if (endpoint.version == IP::V6)
Bind_v6(endpoint.address, endpoint.port);
else if (endpoint.version == IP::V4)
Bind_v4(endpoint.address, endpoint.port);
this->address = address;
this->port = port;
localEndpoint = endpoint;
bound = true;
}
UInt_64 UDP::Send(const AddrType type, const Str_8& address, const UInt_16 port, const Byte *const data, const UInt_64 size)
UInt_64 UDP::Send(const Endpoint &endpoint, const Byte *const data, const UInt_64 size)
{
if (type == AddrType::IPV6)
return Send_v6(address, port, data, size);
else if (type == AddrType::IPV4)
return Send_v4(address, port, data, size);
if (endpoint.version == IP::V6)
return Send_v6(endpoint.address, endpoint.port, data, size);
else if (endpoint.version == IP::V4)
return Send_v4(endpoint.address, endpoint.port, data, size);
return 0;
}
UInt_64 UDP::Receive(AddrType* type, Str_8* const address, UInt_16* const port, Byte* const data, const UInt_64 size)
UInt_64 UDP::Receive(Endpoint *endpoint, Byte* const data, const UInt_64 size)
{
if (!IsValid())
{
@@ -174,9 +173,11 @@ namespace ehs
return received;
}
*type = AddrType::IPV6;
*address = tmpAddr;
*port = ntohs(remote.sin6_port);
*endpoint = {
IP::V6,
tmpAddr,
ntohs(remote.sin6_port)
};
}
else if (addrLen == sizeof(sockaddr_in))
{
@@ -191,9 +192,11 @@ namespace ehs
return received;
}
*type = AddrType::IPV4;
*address = tmpAddr;
*port = ntohs(((sockaddr_in*)&remote)->sin_port);
*endpoint = {
IP::V4,
tmpAddr,
ntohs(((sockaddr_in*)&remote)->sin_port)
};
}
return received;
@@ -225,7 +228,7 @@ namespace ehs
void UDP::SetIPv6Only(const bool value)
{
if (type != AddrType::IPV6)
if (localEndpoint.version != IP::V6)
{
EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return;
@@ -249,7 +252,7 @@ namespace ehs
bool UDP::IsIPv6Only() const
{
if (type != AddrType::IPV6)
if (localEndpoint.version != IP::V6)
return false;
if (!IsValid())
@@ -362,7 +365,7 @@ namespace ehs
Int_32 code = inet_pton(AF_INET6, addr, &result.sin6_addr);
if (!code)
{
EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + address + "\" is not valid.");
EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + addr + "\" is not valid.");
return 0;
}
else if (code == -1)
@@ -403,7 +406,7 @@ namespace ehs
int code = inet_pton(AF_INET, addr, &result.sin_addr);
if (!code)
{
EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + address + "\" is not valid.");
EHS_LOG_INT(LogType::ERR, 1, "The given address, \"" + addr + "\" is not valid.");
return 0;
}
else if (code == -1)

View File

@@ -0,0 +1,193 @@
#include "ehs/io/socket/ehc/NetChannel.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetSys.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/PRNG.h"
namespace ehs
{
const UInt_64 NetChannel::internalSys = Str_8::Hash_64("Internal");
const UInt_64 NetChannel::connectOp = Str_8::Hash_64("Connect");
const UInt_64 NetChannel::connectedOp = Str_8::Hash_64("Connected");
const UInt_64 NetChannel::rejectedOp = Str_8::Hash_64("Rejected");
const UInt_64 NetChannel::disconnectOp = Str_8::Hash_64("Disconnect");
const UInt_64 NetChannel::disconnectedOp = Str_8::Hash_64("Disconnected");
const UInt_64 NetChannel::statusUpdateOp = Str_8::Hash_64("StatusUpdate");
const UInt_64 NetChannel::pingOp = Str_8::Hash_64("Ping");
const UInt_64 NetChannel::pongOp = Str_8::Hash_64("Pong");
const UInt_64 NetChannel::latencyOp = Str_8::Hash_64("Latency");
const UInt_64 NetChannel::receivedOp = Str_8::Hash_64("Received");
NetChannel::~NetChannel()
{
}
NetChannel::NetChannel()
: owner(nullptr), id(0), maxTimeout(5.0f), resendRate(0.5f)
{
}
NetChannel::NetChannel(Str_8 name, const Version &version)
: owner(nullptr), id(name.Hash_64()), name((Str_8 &&)name), version(version), maxTimeout(5.0f),
resendRate(0.5f)
{
}
NetChannel::NetChannel(NetChannel &&channel) noexcept
: owner(channel.owner), id(channel.id), name((Str_8 &&)channel.name), version(channel.version),
maxTimeout(channel.maxTimeout), resendRate(channel.resendRate)
{
channel.owner = nullptr;
channel.id = 0;
channel.version = {};
channel.maxTimeout = 5.0f;
channel.resendRate = 0.5f;
}
NetChannel::NetChannel(const NetChannel &channel)
: owner(nullptr), id(channel.id), name(channel.name), version(channel.version),
maxTimeout(channel.maxTimeout), resendRate(channel.resendRate)
{
}
NetChannel &NetChannel::operator=(NetChannel &&channel) noexcept
{
if (this == &channel)
return *this;
owner = channel.owner;
id = channel.id;
name = (Str_8 &&)channel.name;
version = channel.version;
maxTimeout = channel.maxTimeout;
resendRate = channel.resendRate;
channel.owner = nullptr;
channel.id = 0;
channel.version = {};
channel.maxTimeout = 5.0f;
channel.resendRate = 0.5f;
return *this;
}
NetChannel &NetChannel::operator=(const NetChannel &channel)
{
if (this == &channel)
return *this;
owner = nullptr;
id = channel.id;
name = channel.name;
version = channel.version;
maxTimeout = channel.maxTimeout;
resendRate = channel.resendRate;
return *this;
}
EHC *NetChannel::GetOwner() const
{
return owner;
}
UInt_64 NetChannel::GetId() const
{
return id;
}
Str_8 NetChannel::GetName() const
{
return name;
}
Version NetChannel::GetVersion() const
{
return version;
}
void NetChannel::SetMaxTimeout(const float seconds)
{
maxTimeout = seconds;
}
float NetChannel::GetMaxTimeout() const
{
return maxTimeout;
}
void NetChannel::SetResendRate(const float seconds)
{
resendRate = seconds;
}
float NetChannel::GetResendRate() const
{
return resendRate;
}
void NetChannel::EnableDropPackets(const bool enable)
{
dropPackets = enable;
}
bool NetChannel::IsDropPacketsEnabled() const
{
return dropPackets;
}
bool NetChannel::AddSystem(NetSys *sys)
{
if (sys->GetId() == internalSys)
return false;
if (HasSystem(sys->GetId()))
return false;
systems.Push(sys);
return true;
}
bool NetChannel::IsValid() const
{
return owner && id;
}
void NetChannel::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload)
{
}
void NetChannel::Poll(const float &delta)
{
}
bool NetChannel::HasSystem(const UInt_64 sysId) const
{
for (UInt_64 i = 0; i < systems.Size(); ++i)
if (systems[i]->GetId() == sysId)
return true;
return false;
}
bool NetChannel::HasSystem(const Str_8& sysName) const
{
return HasSystem(sysName.Hash_64());
}
NetSys* NetChannel::GetSystem(const UInt_64 sysId) const
{
for (UInt_64 i = 0; i < systems.Size(); ++i)
if (systems[i]->GetId() == sysId)
return systems[i];
return nullptr;
}
NetSys* NetChannel::GetSystem(const Str_8& sysName) const
{
return GetSystem(sysName.Hash_64());
}
}

View File

@@ -0,0 +1,385 @@
#include "ehs/io/socket/ehc/NetClientCh.h"
#include "ehs/io/socket/EHC.h"
namespace ehs
{
NetClientCh::~NetClientCh()
{
}
NetClientCh::NetClientCh()
: token{}, status(NetStatus::DISCONNECTED), queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f),
latency(0.0f), timeout(5.0f), nextSendId(0), nextRecvId(0)
{
}
NetClientCh::NetClientCh(Str_8 name, const Version &version, Endpoint remoteEndpoint)
: NetChannel((Str_8 &&)name, version), remoteEndpoint((Endpoint &&)remoteEndpoint), token{},
status(NetStatus::DISCONNECTED), queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f),
latency(0.0f), timeout(0.0f), nextSendId(0), nextRecvId(0)
{
}
NetClientCh::NetClientCh(NetClientCh &&client) noexcept
: NetChannel((NetChannel &&)client), remoteEndpoint((Endpoint &&)client.remoteEndpoint), token{},
status(client.status), queueSlot(client.queueSlot), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f),
latency(0.0f), timeout(0.0f), nextSendId(0), sent((Vector<Insurance> &&)client.sent), nextRecvId(0),
received((Vector<NetFrag> &&)client.received)
{
Util::Copy(token, client.token, 64);
Util::Zero(client.token, 64);
client.status = NetStatus::DISCONNECTED;
client.queueSlot = 0;
client.deltaDuration = 0.0f;
client.deltaRate = 0.0f;
client.lastPing = 0.0f;
client.latency = 0.0f;
client.timeout = 0.0f;
client.nextSendId = 0;
client.nextRecvId = 0;
}
NetClientCh::NetClientCh(const NetClientCh &client)
: NetChannel(client), remoteEndpoint(client.remoteEndpoint), token{}, status(NetStatus::DISCONNECTED),
queueSlot(0), deltaDuration(0.0f), deltaRate(0.0f), lastPing(0.0f), latency(0.0f), timeout(0.0f), nextSendId(0),
nextRecvId(0)
{
}
NetClientCh & NetClientCh::operator=(NetClientCh &&client) noexcept
{
if (this == &client)
return *this;
NetChannel::operator=((NetChannel &&)client);
remoteEndpoint = (Endpoint &&)client.remoteEndpoint;
Util::Copy(token, client.token, 64);
status = client.status;
queueSlot = client.queueSlot;
deltaDuration = client.deltaDuration;
deltaRate = client.deltaRate;
lastPing = client.lastPing;
latency = client.latency;
timeout = client.timeout;
nextSendId = client.nextSendId;
sent = (Vector<Insurance> &&)client.sent;
nextRecvId = client.nextRecvId;
received = (Vector<NetFrag> &&)client.received;
Util::Zero(client.token, 64);
client.status = NetStatus::DISCONNECTED;
client.queueSlot = 0;
client.deltaDuration = 0.0f;
client.deltaRate = 0.0f;
client.lastPing = 0.0f;
client.latency = 0.0f;
client.timeout = 0.0f;
client.nextSendId = 0;
client.nextRecvId = 0;
return *this;
}
NetClientCh & NetClientCh::operator=(const NetClientCh &client)
{
if (this == &client)
return *this;
remoteEndpoint = client.remoteEndpoint;
Util::Zero(token, 64);
status = NetStatus::DISCONNECTED;
queueSlot = 0;
deltaDuration = 0.0f;
deltaRate = 0.0f;
lastPing = 0.0f;
latency = 0.0f;
timeout = 0.0f;
nextSendId = 0;
sent = {};
nextRecvId = 0;
received = {};
return *this;
}
void NetClientCh::OnConnected(Serializer<UInt_64> data)
{
}
void NetClientCh::OnActive(Serializer<UInt_64> data)
{
}
void NetClientCh::OnQueueUpdate(Serializer<UInt_64> data)
{
}
void NetClientCh::OnDisconnected(Serializer<UInt_64> data)
{
}
void NetClientCh::OnRejected(Serializer<UInt_64> data)
{
}
void NetClientCh::OnTimeout(Serializer<UInt_64> data)
{
}
void NetClientCh::Connect(const Endpoint &endpoint, const Serializer<UInt_64> &payload)
{
if (!GetOwner()->udp.IsValid())
return;
Send(false, true, false, internalSys, connectOp, payload);
status = NetStatus::PENDING;
}
bool NetClientCh::Disconnect(const Serializer<UInt_64> &payload)
{
if (!GetOwner()->udp.IsValid())
return false;
Send(false, true, false, internalSys, disconnectOp, payload);
return true;
}
void NetClientCh::Send(const bool deltaLocked, UInt_64 encId, const bool ensure, UInt_64 sysId, UInt_64 opId,
const Serializer<UInt_64> &payload)
{
if (!IsValid() || (deltaLocked && deltaDuration < deltaRate))
return;
const EHC *owner = GetOwner();
NetEnc *enc = owner->GetEncryption(encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "Encryption with the Id, \"" + Str_8::FromNum(encId) + "\", does not exist.");
return;
}
Header header = {
EHC::GetVersion(),
encId,
enc->GetVersion(),
GetId(),
NetChannelType::SERVER,
GetVersion(),
nextSendId++,
1,
0,
ensure,
"",
sysId,
opId
};
Util::Copy(header.token, token, 64);
const Endpoint localEndpoint = owner->GetLocalEndpoint();
if ((localEndpoint.version == IP::V6 && payload.Size() > EHC_IPV6_PAYLOAD) || (localEndpoint.version == IP::V4 && payload.Size() > EHC_IPV4_PAYLOAD))
{
NetFrag frags = FragmentData(localEndpoint.version, header, payload);
for (UInt_64 i = 0; i < frags.Size(); ++i)
{
Header newHeader = frags.GetHeader();
newHeader.fragment = i;
Send(enc, newHeader, frags[i]);
}
}
else
{
Send(enc, header, payload);
}
}
void NetClientCh::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8 &sysName,
const Str_8 &opName, const Serializer<UInt_64> &payload)
{
Send(deltaLocked, encName.Hash_64(), ensure, sysName.Hash_64(), opName.Hash_64(), payload);
}
NetStatus NetClientCh::GetStatus() const
{
return status;
}
void NetClientCh::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload)
{
if (!Util::Compare(token, header.token, 64))
return;
if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == connectedOp)
{
if (status != NetStatus::PENDING)
return;
Util::Copy(token, header.token, 64);
status = payload.Read<NetStatus>();
queueSlot = payload.Read<UInt_64>();
OnConnected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == disconnectedOp)
{
OnDisconnected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == rejectedOp)
{
OnRejected({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == statusUpdateOp)
{
const NetStatus newStatus = payload.Read<NetStatus>();
queueSlot = payload.Read<UInt_64>();
if (status == NetStatus::ACTIVE)
OnActive({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
else if (status == NetStatus::QUEUED && newStatus == NetStatus::QUEUED)
OnQueueUpdate({Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
status = newStatus;
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == receivedOp)
{
const UInt_64 msgId = payload.Read<UInt_64>();
const UInt_64 fragment = payload.Read<UInt_64>();
RemoveInsurance(msgId, fragment);
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == pingOp)
{
deltaRate = payload.Read<float>();
Pong(delta);
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == latencyOp)
{
latency = payload.Read<float>();
}
}
void NetClientCh::Poll(const float &delta)
{
}
NetFrag NetClientCh::FragmentData(const IP version, const Header& header, const Serializer<>& data)
{
NetFrag result;
if (version == IP::V6)
{
UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD;
if (data.Size() % EHC_IPV6_PAYLOAD)
++frags;
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV6_PAYLOAD;
for (UInt_64 i = 0; i < result.Size(); ++i)
{
size = EHC_IPV6_PAYLOAD;
if (i == result.Size() - 1)
size = data.Size() % EHC_IPV6_PAYLOAD;
result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size};
}
}
else if (version == IP::V4)
{
UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD;
if (data.Size() % EHC_IPV4_PAYLOAD)
++frags;
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV4_PAYLOAD;
for (UInt_64 i = 0; i < result.Size(); ++i)
{
size = EHC_IPV4_PAYLOAD;
if (i == result.Size() - 1)
size = data.Size() % EHC_IPV4_PAYLOAD;
result[i] = {data.GetEndianness(), &data[i * EHC_IPV4_PAYLOAD], size};
}
}
return result;
}
void NetClientCh::Send(NetEnc *enc, const Header& header, const Serializer<UInt_64>& payload)
{
Serializer result(Endianness::LE);
result.Write(header);
result.WriteSer(payload);
enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool));
if (header.ensure)
sent.Push({header, payload});
GetOwner()->udp.Send(remoteEndpoint, result, result.Size());
}
void NetClientCh::Pong(const float delta)
{
Serializer payload(Endianness::LE);
payload.Write(delta);
Send(false, true, false, internalSys, pongOp, payload);
timeout = 0.0f;
}
void NetClientCh::RemoveInsurance(const UInt_64 msgId, const UInt_64 fragment)
{
for (UInt_64 i = 0; i < sent.Size(); ++i)
{
if (sent[i].header.id == msgId && sent[i].header.fragment == fragment)
{
sent.Remove(i);
break;
}
}
timeout = 0.0f;
}
void NetClientCh::AddReceived(const Header& header, const Serializer<>& payload)
{
NetFrag* frags = nullptr;
for (UInt_64 i = 0; i < received.Size(); ++i)
{
if (received[i].GetHeader().id == header.id)
{
if (received[i][header.fragment].Size())
return;
frags = &received[i];
break;
}
}
if (header.id > nextRecvId)
nextRecvId = header.id + 1;
if (frags)
(*frags)[header.fragment] = payload;
else
received.Push({header, payload});
timeout = 0.0f;
}
}

View File

@@ -3,24 +3,24 @@
namespace ehs
{
NetEnc::NetEnc()
: owner(nullptr), hashId(0)
: id(0)
{
}
NetEnc::NetEnc(Str_8 id)
: owner(nullptr), hashId(id.Hash_64()), id((Str_8 &&)id)
NetEnc::NetEnc(Str_8 name, const Version &version)
: id(name.Hash_64()), name((Str_8 &&)name), version(version)
{
}
NetEnc::NetEnc(NetEnc&& enc) noexcept
: owner(enc.owner), hashId(enc.hashId), id((Str_8 &&)enc.id)
: id(enc.id), name((Str_8 &&)enc.name), version(enc.version)
{
enc.owner = nullptr;
enc.hashId = 0;
enc.id = 0;
enc.version = {};
}
NetEnc::NetEnc(const NetEnc& enc)
: owner(nullptr), hashId(enc.hashId), id(enc.id)
: id(enc.id), name(enc.name), version(enc.version)
{
}
@@ -29,12 +29,12 @@ namespace ehs
if (this == &enc)
return *this;
owner = enc.owner;
hashId = enc.hashId;
id = (Str_8 &&)enc.id;
id = enc.id;
name = (Str_8 &&)enc.name;
version = enc.version;
enc.owner = nullptr;
enc.hashId = 0;
enc.id = 0;
enc.version = {};
return *this;
}
@@ -44,28 +44,28 @@ namespace ehs
if (this == &enc)
return *this;
owner = nullptr;
hashId = enc.hashId;
id = enc.id;
name = enc.name;
version = enc.version;
return *this;
}
EHC* NetEnc::GetOwner() const
{
return owner;
}
UInt_64 NetEnc::GetHashId() const
{
return hashId;
}
Str_8 NetEnc::GetId() const
UInt_64 NetEnc::GetId() const
{
return id;
}
Str_8 NetEnc::GetName() const
{
return name;
}
Version NetEnc::GetVersion() const
{
return version;
}
void NetEnc::Encrypt(Byte *data, UInt_64 size) const
{
}

View File

@@ -1,53 +1,46 @@
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/io/socket/ehc/NetServerCh.h"
#include "ehs/system/CPU.h"
namespace ehs
{
NetEnd::NetEnd()
: owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(0), status(Status::PENDING),
arch(Architecture::UNKNOWN), token{}, nextSendId(0), nextRecvId(0), type(AddrType::IPV6), port(0),
deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f),
queueSlot(0)
{
}
NetEnd::NetEnd(const EndDisp disposition, Str_8 id, const Architecture arch, const AddrType type,
Str_8 address, const UInt_16 port)
: owner(nullptr), disposition(disposition), hashName(id.Hash_64()), name((Str_8&&)id), status(Status::ACTIVE),
arch(arch), token{}, nextSendId(0), nextRecvId(0), type(type), address((Str_8&&)address), port(port),
deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f),
queueSlot(0)
{
}
NetEnd::NetEnd(const AddrType type, Str_8 address, const UInt_16 port)
: owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(0), status(Status::PENDING),
arch(Architecture::UNKNOWN), token{}, nextSendId(0), nextRecvId(0), type(type), address((Str_8&&)address),
port(port), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f),
: owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0),
deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f),
latency(0.0f), queueSlot(0)
{
}
NetEnd::NetEnd(Str_8 id, Endpoint endpoint)
: owner(nullptr), id(id.Hash_64()), name((Str_8&&)id), status(NetStatus::ACTIVE), token{}, nextSendId(0),
nextRecvId(0), endpoint((Endpoint &&)endpoint), deltaDuration(0.0f), deltaRate(1.0f / 60.0f),
timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0)
{
}
NetEnd::NetEnd(Endpoint endpoint)
: owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0),
endpoint((Endpoint &&)endpoint), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f),
oldLatency(0.0f), latency(0.0f), queueSlot(0)
{
}
NetEnd::NetEnd(NetEnd &&end) noexcept
: owner(end.owner), disposition(end.disposition), hashName(end.hashName), name((Str_8&&)end.name), status(end.status), arch(end.arch), token{},
: owner(end.owner), id(end.id), name((Str_8&&)end.name), status(end.status), token{},
nextSendId(end.nextSendId), sent((Vector<Insurance>&&)end.sent), nextRecvId(end.nextRecvId),
received((Vector<NetFrags>&&)end.received), type(end.type), address((Str_8&&)end.address), port(end.port),
received((Vector<NetFrag>&&)end.received), endpoint((Endpoint &&)end.endpoint),
deltaDuration(end.deltaDuration), deltaRate(end.deltaRate), timeout(end.timeout), lastPing(end.lastPing),
oldLatency(end.oldLatency), latency(end.latency), queueSlot(end.queueSlot)
{
end.owner = nullptr;
end.disposition = EndDisp::ENDPOINT;
end.hashName = 0;
end.status = Status::PENDING;
end.arch = Architecture::UNKNOWN;
end.id = 0;
end.status = NetStatus::PENDING;
Util::Copy(token, end.token, 64);
Util::Zero(end.token, 64);
end.nextSendId = 0;
end.nextRecvId = 0;
end.type = AddrType::IPV6;
end.port = 0;
end.deltaDuration = 0.0f;
end.deltaRate = 1.0f / 60.0f;
end.timeout = 0.0f;
@@ -58,9 +51,9 @@ namespace ehs
}
NetEnd::NetEnd(const NetEnd& end)
: owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(end.hashName), name(end.name), status(Status::PENDING), arch(Architecture::UNKNOWN),
token{}, nextSendId(0), nextRecvId(0), type(end.type), port(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f),
timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0)
: owner(nullptr), id(end.id), name(end.name), status(NetStatus::PENDING), token{}, nextSendId(0),
nextRecvId(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f),
latency(0.0f), queueSlot(0)
{
}
@@ -70,19 +63,15 @@ namespace ehs
return *this;
owner = end.owner;
disposition = end.disposition;
hashName = end.hashName;
id = end.id;
name = (Str_8&&)end.name;
status = end.status;
arch = end.arch;
Util::Copy(token, end.token, 64);
nextSendId = end.nextSendId;
sent = (Vector<Insurance>&&)end.sent;
nextRecvId = end.nextRecvId;
received = (Vector<NetFrags>&&)end.received;
type = end.type;
address = (Str_8&&)end.address;
port = end.port;
received = (Vector<NetFrag>&&)end.received;
endpoint = (Endpoint &&)end.endpoint;
deltaDuration = end.deltaDuration;
deltaRate = end.deltaRate;
timeout = end.timeout;
@@ -92,15 +81,11 @@ namespace ehs
queueSlot = end.queueSlot;
end.owner = nullptr;
end.disposition = EndDisp::ENDPOINT;
end.hashName = 0;
end.status = Status::PENDING;
end.arch = Architecture::UNKNOWN;
end.id = 0;
end.status = NetStatus::PENDING;
Util::Zero(end.token, 64);
end.nextSendId = 0;
end.nextRecvId = 0;
end.type = AddrType::IPV6;
end.port = 0;
end.deltaDuration = 0.0f;
end.deltaRate = 1.0f / 60.0f;
end.timeout = 0.0f;
@@ -118,19 +103,15 @@ namespace ehs
return *this;
owner = nullptr;
disposition = EndDisp::ENDPOINT;
hashName = end.hashName;
id = end.id;
name = end.name;
status = Status::PENDING;
arch = Architecture::UNKNOWN;
status = NetStatus::PENDING;
Util::Zero(token, 64);
nextSendId = 0;
sent = {};
nextRecvId = 0;
received = {};
type = AddrType::IPV6;
address = {};
port = 0;
endpoint = {};
deltaDuration = 0.0f;
deltaRate = 1.0f / 60.0f;
timeout = 0.0f;
@@ -142,14 +123,9 @@ namespace ehs
return *this;
}
EndDisp NetEnd::GetDisposition() const
UInt_64 NetEnd::GetId() const
{
return disposition;
}
UInt_64 NetEnd::GetHashName() const
{
return hashName;
return id;
}
Str_8 NetEnd::GetName() const
@@ -157,44 +133,54 @@ namespace ehs
return name;
}
Status NetEnd::GetStatus() const
NetStatus NetEnd::GetStatus() const
{
return status;
}
Architecture NetEnd::GetArchitecture() const
{
return arch;
}
UInt_64 NetEnd::GetNextSendId() const
{
return nextSendId;
}
void NetEnd::Send(const bool deltaLocked, const UInt_64 encHashId, const bool ensure, const UInt_64 sys,
const UInt_64 op, const Serializer<UInt_64> &payload)
void NetEnd::Send(const bool deltaLocked, const UInt_64 encId, const bool ensure, const UInt_64 sysId,
const UInt_64 opId, const Serializer<UInt_64> &payload)
{
if (deltaLocked && deltaDuration < deltaRate)
if (!owner || !owner->GetOwner() || (deltaLocked && deltaDuration < deltaRate))
return;
EHC *ehc = owner->GetOwner();
NetEnc *enc = ehc->GetEncryption(encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "Encryption with the Id, \"" + Str_8::FromNum(encId) + "\", does not exist.");
return;
}
Header header = {
encHashId,
EHC::GetVersion(),
encId,
enc->GetVersion(),
GetId(),
NetChannelType::SERVER,
GetVersion(),
nextSendId++,
1,
0,
ensure,
owner->GetDisposition(),
"",
sys,
op
sysId,
opId
};
Util::Copy(header.token, token, 64);
if ((owner->GetLocalAddressType() == AddrType::IPV6 && payload.Size() > EHC_IPV6_PAYLOAD) || (owner->GetLocalAddressType() == AddrType::IPV4 && payload.Size() > EHC_IPV4_PAYLOAD))
if ((ehc->GetLocalEndpoint().version == IP::V6 && payload.Size() > EHC_IPV6_PAYLOAD) ||
(ehc->GetLocalEndpoint().version == IP::V4 && payload.Size() > EHC_IPV4_PAYLOAD))
{
NetFrags frags = FragmentData(header, payload);
NetFrag frags = FragmentData(header, payload);
for (UInt_64 i = 0; i < frags.Size(); ++i)
{
Header newHeader = frags.GetHeader();
@@ -209,10 +195,10 @@ namespace ehs
}
}
void NetEnd::Send(const bool deltaLocked, const Str_8 &encId, const bool ensure, const Str_8& sys,
const Str_8& op, const Serializer<>& payload)
void NetEnd::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8& sysName,
const Str_8& opName, const Serializer<>& payload)
{
Send(deltaLocked, encId.Hash_64(), ensure, sys.Hash_64(), op.Hash_64(), payload);
Send(deltaLocked, encName.Hash_64(), ensure, sysName.Hash_64(), opName.Hash_64(), payload);
}
UInt_64 NetEnd::GetNextRecvId() const
@@ -220,14 +206,9 @@ namespace ehs
return nextRecvId;
}
Str_8 NetEnd::GetAddress() const
Endpoint NetEnd::GetEndpoint() const
{
return address;
}
UInt_16 NetEnd::GetPort() const
{
return port;
return endpoint;
}
float NetEnd::GetDeltaRate() const
@@ -273,17 +254,21 @@ namespace ehs
sent[i].lastResend += delta;
if (sent[i].lastResend >= owner->GetResendRate())
{
EHC *ehc = owner->GetOwner();
Serializer result(Endianness::LE);
result.Write(sent[i].header);
result.WriteSer(sent[i].payload);
if (sent[i].header.encHashId)
if (sent[i].header.encId)
{
NetEnc *enc = owner->GetEncryption(sent[i].header.encHashId);
NetEnc *enc = ehc->GetEncryption(sent[i].header.encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " +
Str_8::FromNum(sent[i].header.encHashId) + ", does not exist.");
Str_8::FromNum(sent[i].header.encId) + ", does not exist.");
continue;
}
@@ -291,24 +276,21 @@ namespace ehs
enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool));
}
owner->udp.Send(type, address, port, result, result.Size());
ehc->udp.Send(endpoint, result, result.Size());
sent[i].lastResend = Math::Mod(sent[i].lastResend, owner->GetResendRate());
}
}
}
if (owner->GetDisposition() == EndDisp::SERVICE)
{
lastPing += delta;
if (lastPing >= 1.0f)
Ping(delta);
}
EHS_LOG_SUCCESS();
}
void NetEnd::SetStatus(const Status newStatus)
void NetEnd::SetStatus(const NetStatus newStatus)
{
status = newStatus;
}
@@ -329,7 +311,7 @@ namespace ehs
void NetEnd::AddReceived(const Header& header, const Serializer<>& payload)
{
NetFrags* frags = nullptr;
NetFrag* frags = nullptr;
for (UInt_64 i = 0; i < received.Size(); ++i)
{
@@ -354,7 +336,7 @@ namespace ehs
timeout = 0.0f;
}
Vector<NetFrags>* NetEnd::GetReceived()
Vector<NetFrag>* NetEnd::GetReceived()
{
return &received;
}
@@ -374,16 +356,6 @@ namespace ehs
latency = 0.0f;
}
void NetEnd::Pong(const float delta)
{
Serializer payload(Endianness::LE);
payload.Write(delta);
Send(false, true, false, "Internal", "Pong", payload);
timeout = 0.0f;
}
void NetEnd::SendLatency()
{
oldLatency = latency * 1000;
@@ -407,17 +379,19 @@ namespace ehs
queueSlot = slot;
}
NetFrags NetEnd::FragmentData(const Header& header, const Serializer<>& data)
NetFrag NetEnd::FragmentData(const Header& header, const Serializer<>& data)
{
NetFrags result;
NetFrag result;
if (owner->GetLocalAddressType() == AddrType::IPV6)
EHC *ehc = owner->GetOwner();
if (ehc->GetLocalEndpoint().version == IP::V6)
{
UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD;
if (data.Size() % EHC_IPV6_PAYLOAD)
++frags;
result = NetFrags(header, frags);
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV6_PAYLOAD;
@@ -430,13 +404,13 @@ namespace ehs
result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size};
}
}
else if (owner->GetLocalAddressType() == AddrType::IPV4)
else if (ehc->GetLocalEndpoint().version == IP::V4)
{
UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD;
if (data.Size() % EHC_IPV4_PAYLOAD)
++frags;
result = NetFrags(header, frags);
result = NetFrag(header, frags);
UInt_64 size = EHC_IPV4_PAYLOAD;
@@ -455,17 +429,19 @@ namespace ehs
void NetEnd::Send(const Header& header, const Serializer<UInt_64>& payload)
{
EHC *ehc = owner->GetOwner();
Serializer result(Endianness::LE);
result.Write(header);
result.WriteSer(payload);
if (header.encHashId)
if (header.encId)
{
NetEnc *enc = owner->GetEncryption(header.encHashId);
NetEnc *enc = ehc->GetEncryption(header.encId);
if (!enc)
{
EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " +
Str_8::FromNum(header.encHashId) + ", does not exist.");
Str_8::FromNum(header.encId) + ", does not exist.");
return;
}
@@ -476,7 +452,7 @@ namespace ehs
if (header.ensure)
sent.Push({header, payload});
owner->udp.Send(type, address, port, result, result.Size());
ehc->udp.Send(endpoint, result, result.Size());
}
bool NetEnd::SortingNeeded() const
@@ -499,7 +475,7 @@ namespace ehs
if (!SortingNeeded())
return;
Vector<NetFrags> sorted(0, received.Stride());
Vector<NetFrag> sorted(0, received.Stride());
for (UInt_64 a = 0; a < received.Size(); ++a)
{

View File

@@ -1,32 +1,32 @@
#include "ehs/io/socket/ehc/NetFrags.h"
#include "ehs/io/socket/ehc/NetFrag.h"
namespace ehs
{
NetFrags::~NetFrags()
NetFrag::~NetFrag()
{
delete[] data;
}
NetFrags::NetFrags()
NetFrag::NetFrag()
: data(nullptr), size(0)
{
}
NetFrags::NetFrags(const Header &header, const Serializer<UInt_64> &payload)
: header(header), data(new Serializer<UInt_64>[header.fragments]), size(header.fragments)
NetFrag::NetFrag(const Header &header, const Serializer<UInt_64> &payload)
: header(header), data(new Serializer<UInt_64>[header.fragmentCount]), size(header.fragmentCount)
{
this->header.fragment = 0;
data[header.fragment] = payload;
}
NetFrags::NetFrags(const Header &header, const UInt_64 size)
NetFrag::NetFrag(const Header &header, const UInt_64 size)
: header(header), data(new Serializer<UInt_64>[size]), size(size)
{
this->header.fragments = size;
this->header.fragmentCount = size;
this->header.fragment = 0;
}
NetFrags::NetFrags(NetFrags &&frags) noexcept
NetFrag::NetFrag(NetFrag &&frags) noexcept
: header(frags.header), data(frags.data), size(frags.size)
{
frags.header = {};
@@ -34,14 +34,14 @@ namespace ehs
frags.size = 0;
}
NetFrags::NetFrags(const NetFrags &frags)
NetFrag::NetFrag(const NetFrag &frags)
: header(frags.header), data(new Serializer<UInt_64>[frags.size]), size(frags.size)
{
for (UInt_64 i = 0; i < size; ++i)
data[i] = frags.data[i];
}
NetFrags &NetFrags::operator=(NetFrags &&frags) noexcept
NetFrag &NetFrag::operator=(NetFrag &&frags) noexcept
{
if (this == &frags)
return *this;
@@ -60,7 +60,7 @@ namespace ehs
return *this;
}
NetFrags &NetFrags::operator=(const NetFrags &frags)
NetFrag &NetFrag::operator=(const NetFrag &frags)
{
if (this == &frags)
return *this;
@@ -75,22 +75,22 @@ namespace ehs
return *this;
}
NetFrags::operator Serializer<UInt_64> *() const
NetFrag::operator Serializer<UInt_64> *() const
{
return data;
}
Header NetFrags::GetHeader() const
Header NetFrag::GetHeader() const
{
return header;
}
UInt_64 NetFrags::Size() const
UInt_64 NetFrag::Size() const
{
return size;
}
bool NetFrags::IsComplete() const
bool NetFrag::IsComplete() const
{
for (UInt_64 i = 0; i < size; ++i)
if (!data[i].Size())
@@ -99,7 +99,7 @@ namespace ehs
return true;
}
Packet NetFrags::Combine() const
Packet NetFrag::Combine() const
{
UInt_64 rSize = 0;
for (UInt_64 i = 0; i < size; ++i)
@@ -110,7 +110,7 @@ namespace ehs
header,
{Endianness::LE, rSize}
};
result.header.fragments = 0;
result.header.fragmentCount = 0;
for (UInt_64 i = 0; i < size; ++i)
result.payload.WriteSer(data[i]);

View File

@@ -1,28 +1,27 @@
#include "ehs/io/socket/ehc/NetOp.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetSys.h"
namespace ehs
{
NetOp::NetOp()
: hashId(0)
: id(0)
{
}
NetOp::NetOp(Str_8 id)
: hashId(id.Hash_64()), id((Str_8 &&)id)
NetOp::NetOp(Str_8 name)
: id(name.Hash_64()), name((Str_8 &&)name)
{
}
NetOp::NetOp(NetOp&& op) noexcept
: hashId(op.hashId), id((Str_8 &&)op.id)
: id(op.id), name((Str_8 &&)op.name)
{
op.hashId = 0;
op.id = 0;
}
NetOp::NetOp(const NetOp &op)
: hashId(op.hashId), id(op.id)
: id(op.id), name(op.name)
{
}
@@ -31,10 +30,10 @@ namespace ehs
if (this == &op)
return *this;
hashId = op.hashId;
id = (Str_8 &&)op.id;
id = op.id;
name = (Str_8 &&)op.name;
op.hashId = 0;
op.id = 0;
return *this;
}
@@ -44,23 +43,23 @@ namespace ehs
if (this == &op)
return *this;
hashId = op.hashId;
id = op.id;
name = op.name;
return *this;
}
Str_8 NetOp::GetId() const
UInt_64 NetOp::GetId() const
{
return id;
}
UInt_64 NetOp::GetHashId() const
Str_8 NetOp::GetName() const
{
return hashId;
return name;
}
void NetOp::Process(EHC *ehc, NetEnd *endpoint, NetSys *sys, Serializer<UInt_64> &payload)
void NetOp::Execute(NetChannel *channel, NetEnd *endpoint, NetSys *sys, Serializer<UInt_64> &payload)
{
}
}

View File

@@ -0,0 +1,602 @@
#include "ehs/io/socket/ehc/NetServerCh.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetSys.h"
#include "ehs/io/socket/EHC.h"
#include "ehs/PRNG.h"
namespace ehs
{
NetServerCh::~NetServerCh()
{
Shutdown();
}
NetServerCh::NetServerCh()
: maxEndpoints(0)
{
}
NetServerCh::NetServerCh(Str_8 name, const Version &version, const UInt_64 maxEndpoints)
: NetChannel((Str_8 &&)name, version), maxEndpoints(maxEndpoints)
{
}
NetServerCh::NetServerCh(NetServerCh &&server) noexcept
: NetChannel((NetChannel &&)server), endpoints((Vector<NetEnd *> &&)server.endpoints), maxEndpoints(server.maxEndpoints)
{
for (UInt_64 i = 0; i < endpoints.Size(); i++)
endpoints[i]->owner = this;
}
NetServerCh::NetServerCh(const NetServerCh &server)
: NetChannel(server), maxEndpoints(server.maxEndpoints)
{
}
NetServerCh &NetServerCh::operator=(NetServerCh &&server) noexcept
{
if (this == &server)
return *this;
NetChannel::operator=((NetChannel &&)server);
Shutdown();
endpoints = (Vector<NetEnd *> &&)server.endpoints;
for (UInt_64 i = 0; i < endpoints.Size(); i++)
endpoints[i]->owner = this;
maxEndpoints = server.maxEndpoints;
server.maxEndpoints = 0;
return *this;
}
NetServerCh &NetServerCh::operator=(const NetServerCh &server)
{
if (this == &server)
return *this;
NetChannel::operator=(server);
Shutdown();
endpoints = {};
maxEndpoints = server.maxEndpoints;
return *this;
}
bool NetServerCh::OnEndpointConnect(NetEnd *endpoint, Serializer<UInt_64> payload)
{
return true;
}
Serializer<UInt_64> NetServerCh::OnEndpointAccepted(NetEnd *endpoint)
{
return {};
}
void NetServerCh::OnEndpointDisconnect(NetEnd *endpoint, Serializer<UInt_64> payload)
{
}
void NetServerCh::OnEndpointTimeout(NetEnd *endpoint)
{
}
void NetServerCh::OnEndpointActive(NetEnd *endpoint)
{
}
Serializer<UInt_64> NetServerCh::OnShutdown()
{
return {};
}
Serializer<UInt_64> OnShutdown()
{
return {};
}
void NetServerCh::Broadcast(const NetStatus endStatus, const bool deltaLocked, const UInt_64 encHashId,
const bool ensure, const UInt_64 sysHashId, const UInt_64 opHashId, const Serializer<UInt_64> &payload)
{
if (!GetOwner()->udp.IsValid())
return;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetStatus() == endStatus)
endpoints[i]->Send(deltaLocked, encHashId, ensure, sysHashId, opHashId, payload);
}
void NetServerCh::Broadcast(const NetStatus endStatus, const bool deltaLocked, const Str_8 &encId, const bool ensure,
const Str_8 &sysId, const Str_8 &opId,
const Serializer<UInt_64> &payload)
{
Broadcast(endStatus, deltaLocked, encId.Hash_64(), ensure, sysId.Hash_64(), opId.Hash_64(), payload);
}
bool NetServerCh::HasEndpoint(const NetStatus endStatus, const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (Util::Compare(endpoints[i]->token, token, 64))
return true;
}
return false;
}
bool NetServerCh::HasEndpoint(const NetStatus endStatus, const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (endpoints[i]->GetId() == hashName)
return true;
}
return false;
}
bool NetServerCh::HasEndpoint(const NetStatus endStatus, const Str_8 &id) const
{
return HasEndpoint(endStatus, id.Hash_64());
}
bool NetServerCh::HasEndpoint(const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (Util::Compare(endpoints[i]->token, token, 64))
return true;
return false;
}
bool NetServerCh::HasEndpoint(const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetId() == hashName)
return true;
return false;
}
bool NetServerCh::HasEndpoint(const Str_8 &id) const
{
return HasEndpoint(id.Hash_64());
}
bool NetServerCh::HasEndpoint(const Endpoint &endpoint) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port)
return true;
return false;
}
NetEnd* NetServerCh::GetEndpoint(const NetStatus endStatus, const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (Util::Compare(endpoints[i]->token, token, 64))
return endpoints[i];
}
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const NetStatus endStatus, const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() != endStatus)
continue;
if (endpoints[i]->GetId() == hashName)
return endpoints[i];
}
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const NetStatus endStatus, const Str_8 &id) const
{
return GetEndpoint(endStatus, id.Hash_64());
}
NetEnd *NetServerCh::GetEndpoint(const Char_8 token[64]) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (Util::Compare(endpoints[i]->token, token, 64))
return endpoints[i];
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const UInt_64 hashName) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetId() == hashName)
return endpoints[i];
return nullptr;
}
NetEnd *NetServerCh::GetEndpoint(const Str_8 &id) const
{
return GetEndpoint(id.Hash_64());
}
NetEnd *NetServerCh::GetEndpoint(const Endpoint &endpoint) const
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port)
return endpoints[i];
return nullptr;
}
Array<NetEnd *> NetServerCh::GetEndpoints(const NetStatus endStatus)
{
Array<NetEnd*> result(endpoints.Size());
UInt_64 count = 0;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetStatus() == endStatus)
result[count++] = endpoints[i];
result.Resize(count);
return result;
}
UInt_64 NetServerCh::GetEndpointsCount(const NetStatus endStatus)
{
UInt_64 count = 0;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
if (endpoints[i]->GetStatus() == endStatus)
++count;
return count;
}
UInt_64 NetServerCh::GetMaxEndpoints() const
{
return maxEndpoints;
}
void NetServerCh::Process(const float &delta, const Endpoint &endpoint, const Header &header, Serializer<UInt_64> &payload)
{
if (header.channelVer != GetVersion())
return;
if (!header.ensure && !header.token[0] && header.systemId == internalSys && header.opId == connectOp)
{
NetEnd* end = new NetEnd(payload.ReadStr(), endpoint);
end->owner = this;
GenerateToken(end->token);
end->SetStatus(NetStatus::PENDING);
Serializer sPayload(Endianness::LE);
if (!OnEndpointConnect(end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()}))
{
sPayload.WriteStr<Char_8, UInt_64>("Connection rejected.");
end->Send(false, true, false, internalSys, rejectedOp, sPayload);
return;
}
endpoints.Push(end);
UInt_64 active = GetEndpointsCount(NetStatus::ACTIVE);
if (maxEndpoints && active >= maxEndpoints)
{
end->SetStatus(NetStatus::QUEUED);
UpdateQueue(active);
sPayload.Write(NetStatus::QUEUED);
sPayload.Write(end->GetQueueSlot());
}
else
{
end->SetStatus(NetStatus::ACTIVE);
OnEndpointActive(end);
sPayload.Write(NetStatus::ACTIVE);
sPayload.Write(0);
}
sPayload.WriteSer(OnEndpointAccepted(end));
end->Send(false, 0, false, internalSys, connectedOp, sPayload);
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == disconnectOp)
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
end->Send(false, 0, false, internalSys, disconnectedOp, {});
OnEndpointDisconnect(end, {Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset()});
RemoveEndpoint(end->token);
UpdateQueue();
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == pongOp)
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
end->SetDeltaRate(payload.Read<float>());
end->SendLatency();
}
else if (!header.ensure && header.token[0] && header.systemId == internalSys && header.opId == receivedOp)
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
const UInt_64 msgId = payload.Read<UInt_64>();
const UInt_64 fragment = payload.Read<UInt_64>();
end->RemoveInsurance(msgId, fragment);
}
else if (header.token[0])
{
NetEnd* end = GetEndpoint(header.token);
if (!end)
return;
if (IsDropPacketsEnabled() && !header.ensure && header.id < end->GetNextRecvId())
{
EHS_LOG_INT(LogType::INFO, 6, "Old packet intentionally dropped.");
return;
}
if (header.ensure)
{
Serializer sPayload(Endianness::LE);
sPayload.Write(header.id);
sPayload.Write(header.fragment);
end->Send(false, 0, false, internalSys, receivedOp, sPayload);
}
end->AddReceived(
header,
Serializer<>(Endianness::LE, &payload[payload.GetOffset()], payload.Size() - payload.GetOffset())
);
}
else
{
EHS_LOG_INT(LogType::INFO, 7, "Corrupted packet.");
}
}
void NetServerCh::GenerateToken(Char_8 in[64])
{
PRNG_u64 rng(CPU::GetTSC());
for (UInt_64 i = 0; i < 8; ++i)
{
do
((UInt_64*)in)[i] = rng.Generate();
while (!i && ((UInt_64*)in)[i] == 0);
}
if (HasEndpoint(in))
GenerateToken(in);
}
void NetServerCh::UpdateQueue(UInt_64 active)
{
UInt_64 slot = 0;
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetStatus() == NetStatus::QUEUED)
{
if (active < maxEndpoints)
{
endpoints[i]->SetStatus(NetStatus::ACTIVE);
endpoints[i]->SetQueueSlot(0);
Serializer payload(Endianness::LE);
payload.Write(NetStatus::ACTIVE);
payload.Write(0);
endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload);
OnEndpointActive(endpoints[i]);
++active;
}
else
{
if (endpoints[i]->GetQueueSlot() != slot)
{
Serializer payload(Endianness::LE);
payload.Write(NetStatus::QUEUED);
payload.Write(slot);
endpoints[i]->Send(false, true, false, internalSys, statusUpdateOp, payload);
endpoints[i]->SetQueueSlot(slot++);
}
else
{
++slot;
}
}
}
}
}
void NetServerCh::UpdateQueue()
{
UpdateQueue(GetEndpointsCount(NetStatus::ACTIVE));
}
bool NetServerCh::RemoveEndpoint(const Char_8 token[64])
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (Util::Compare(endpoints[i]->token, token, 64))
{
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
return true;
}
}
return false;
}
bool NetServerCh::RemoveEndpoint(const Endpoint &endpoint)
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i]->GetEndpoint().address == endpoint.address && endpoints[i]->GetEndpoint().port == endpoint.port)
{
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
return true;
}
}
return false;
}
bool NetServerCh::RemoveEndpoint(const NetEnd* const end)
{
for (UInt_64 i = 0; i < endpoints.Size(); ++i)
{
if (endpoints[i] == end)
{
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
return true;
}
}
return false;
}
void NetServerCh::Poll(const float &delta)
{
UInt_64 i = 0;
while (i < endpoints.Size())
{
endpoints[i]->Poll(delta);
if (endpoints[i]->GetStatus() == NetStatus::PENDING)
{
if (endpoints[i]->GetTimeout() >= GetMaxTimeout())
{
OnEndpointTimeout(endpoints[i]);
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
continue;
}
}
else
{
if (endpoints[i]->GetTimeout() >= GetMaxTimeout())
{
OnEndpointTimeout(endpoints[i]);
delete endpoints[i];
if (i != endpoints.Size() - 1)
endpoints.Swap(i, endpoints.End());
endpoints.Pop();
UpdateQueue();
continue;
}
Vector<NetFrag>* frags = endpoints[i]->GetReceived();
UInt_64 f = 0;
while (f < frags->Size())
{
if (!(*frags)[f].IsComplete())
{
++f;
continue;
}
Packet packet = (*frags)[f].Combine();
NetSys* sys = GetSystem(packet.header.systemId);
if (!sys)
{
++f;
continue;
}
sys->Execute(this, endpoints[i], packet.header.opId, packet.payload);
frags->Swap(f, frags->End());
frags->Pop();
}
}
++i;
}
}
void NetServerCh::Shutdown()
{
Serializer<UInt_64> payload = OnShutdown();
for (UInt_64 i = 0; i < endpoints.Size(); i++)
{
endpoints[i]->Send(false, 0, false, internalSys, disconnectOp, payload);
delete endpoints[i];
}
}
}

View File

@@ -2,6 +2,7 @@
#include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetOp.h"
#include "ehs/io/socket/ehc/NetChannel.h"
namespace ehs
{
@@ -14,23 +15,23 @@ namespace ehs
}
NetSys::NetSys()
: hashId(0)
: id(0)
{
}
NetSys::NetSys(Str_8 id)
: hashId(id.Hash_64()), id((Str_8&&)id)
NetSys::NetSys(Str_8 name)
: id(name.Hash_64()), name((Str_8&&)name)
{
}
NetSys::NetSys(NetSys&& sys) noexcept
: hashId(sys.hashId), id((Str_8&&)sys.id), ops((Array<NetOp*>&&)sys.ops)
: id(sys.id), name((Str_8&&)sys.name), ops((Array<NetOp*>&&)sys.ops)
{
sys.hashId = 0;
sys.id = 0;
}
NetSys::NetSys(const NetSys& sys)
: hashId(sys.hashId), id(sys.id)
: id(sys.id), name(sys.name)
{
}
@@ -39,11 +40,11 @@ namespace ehs
if (this == &sys)
return *this;
hashId = sys.hashId;
id = (Str_8&&)sys.id;
id = sys.id;
name = (Str_8&&)sys.name;
ops = (Array<NetOp*>&&)sys.ops;
sys.hashId = 0;
sys.id = 0;
return *this;
}
@@ -53,27 +54,27 @@ namespace ehs
if (this == &sys)
return *this;
hashId = sys.hashId;
id = sys.id;
name = sys.name;
ops = Array<NetOp*>();
return *this;
}
Str_8 NetSys::GetId() const
UInt_64 NetSys::GetId() const
{
return id;
}
UInt_64 NetSys::GetHashId() const
Str_8 NetSys::GetName() const
{
return hashId;
return name;
}
bool NetSys::HasOperation(const UInt_64 hashId) const
bool NetSys::HasOperation(const UInt_64 id) const
{
for (UInt_64 i = 0; i < ops.Size(); ++i)
if (ops[i]->GetHashId() == hashId)
if (ops[i]->GetId() == id)
return true;
return false;
@@ -81,7 +82,7 @@ namespace ehs
bool NetSys::AddOperation(NetOp* op)
{
if (HasOperation(op->GetHashId()))
if (HasOperation(op->GetId()))
return false;
ops.Push(op);
@@ -89,13 +90,13 @@ namespace ehs
return true;
}
void NetSys::Execute(EHC *ehc, NetEnd *endpoint, const UInt_64 hashId, Serializer<UInt_64> &payload)
void NetSys::Execute(NetChannel *channel, NetEnd *endpoint, const UInt_64 hashId, Serializer<UInt_64> &payload)
{
for (UInt_64 i = 0; i < ops.Size(); ++i)
{
if (ops[i]->GetHashId() == hashId)
if (ops[i]->GetId() == hashId)
{
ops[i]->Process(ehc, endpoint, this, payload);
ops[i]->Execute(channel, endpoint, this, payload);
return;
}
}

View File

@@ -0,0 +1,44 @@
#include "ehs/io/socket/ehc/NetUtils.h"
namespace ehs
{
void WriteHeader(const Header &header, Serializer<UInt_64> &data)
{
data.WriteVersion(header.version);
data.Write(header.encId);
data.WriteVersion(header.encVer);
data.Write(header.channelId);
data.Write(header.channelType);
data.WriteVersion(header.channelVer);
data.Write(header.id);
data.Write(header.fragmentCount);
data.Write(header.fragment);
data.Write(header.ensure);
data.WriteArray(header.token, 64);
data.Write(header.systemId);
data.Write(header.opId);
}
Header ReadHeader(Serializer<UInt_64> &data)
{
Header header = {};
header.version = data.ReadVersion();
header.encId = data.Read<UInt_64>();
header.encVer = data.ReadVersion();
header.channelId = data.Read<UInt_64>();
header.channelType = data.Read<NetChannelType>();
header.channelVer = data.ReadVersion();
header.id = data.Read<UInt_64>();
header.fragmentCount = data.Read<UInt_64>();
header.fragment = data.Read<UInt_64>();
header.ensure = data.Read<bool>();
UInt_64 tokenSize = sizeof(header.token) / sizeof(Char_8);
data.ReadArray<Char_8, UInt_64>(header.token, &tokenSize);
header.systemId = data.Read<UInt_64>();
header.opId = data.Read<UInt_64>();
return header;
}
}

View File

@@ -18,7 +18,7 @@ namespace ehs
}
Spotify::Spotify(Str_8 clientId, Str_8 secret, Str_8 redURI, Array<Str_8> scopes, const bool forceVerify)
: client(AddrType::IPV4), clientId((Str_8 &&)clientId), secret((Str_8 &&)secret), redURI((Str_8 &&)redURI),
: client(IP::V4), clientId((Str_8 &&)clientId), secret((Str_8 &&)secret), redURI((Str_8 &&)redURI),
scopes((Array<Str_8> &&)scopes), forceVerify(forceVerify)
{
}
@@ -41,7 +41,7 @@ namespace ehs
"&response_type=code&show_dialog=" + (forceVerify ? "true" : "false") + "&scope=" +
scopesFinal;
TCP server(AddrType::IPV4);
TCP server(IP::V4);
server.Initialize();
server.Bind("", 65534);
server.Listen();
@@ -73,7 +73,7 @@ namespace ehs
server.Release();
SSL accounts(AddrType::IPV4);
SSL accounts(IP::V4);
accounts.Initialize();
accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port);
@@ -81,7 +81,7 @@ namespace ehs
authReq.SetContentType(ContentType::APP_FORMURLENCODED);
authReq.BasicAuth(clientId, secret);
authReq.AddToBody("grant_type", "authorization_code");
authReq.AddToBody("code", cbReq.GetQuery("code"));
authReq.AddToBody("code", cbReq.GetQueryValue("code"));
authReq.AddToBody("redirect_uri", rURI);
accounts.SendReq(authReq);
@@ -134,7 +134,7 @@ namespace ehs
StartConnection();
Request req(Verb::PUT, "/v1/me/player/volume");
req.AddQuery("volume_percent", Str_8::FromNum(level));
req.AddQueryVar({"volume_percent", Str_8::FromNum(level)});
req.BearerAuth(token);
client.SendReq(req);
@@ -206,7 +206,7 @@ namespace ehs
}
Request req(Verb::PUT, "/v1/me/player/repeat");
req.AddQuery("state", result);
req.AddQueryVar({"state", result});
req.BearerAuth(token);
client.SendReq(req);
@@ -226,7 +226,7 @@ namespace ehs
StartConnection();
Request req(Verb::PUT, "/v1/me/player/repeat");
req.AddQuery("state", state ? "true" : "false");
req.AddQueryVar({"state", state ? "true" : "false"});
req.BearerAuth(token);
client.SendReq(req);
@@ -258,10 +258,10 @@ namespace ehs
q += "+track%3A" + name.ReplaceAll(" ", "+");
req.AddQuery("q", q);
req.AddQuery("type", "track");
req.AddQuery("limit", "1");
req.AddQuery("offset", "0");
req.AddQueryVar({"q", q});
req.AddQueryVar({"type", "track"});
req.AddQueryVar({"limit", "1"});
req.AddQueryVar({"offset", "0"});
req.BearerAuth(token);
client.SendReq(req);
@@ -454,7 +454,7 @@ namespace ehs
StartConnection();
Request req(Verb::POST, "/v1/me/player/queue");
req.AddQuery("uri", "spotify:track:" + id);
req.AddQueryVar({"uri", "spotify:track:" + id});
req.BearerAuth(token);
client.SendReq(req);
@@ -505,8 +505,8 @@ namespace ehs
StartConnection();
Request req(Verb::POST, "/v1/playlists/" + playlistId + "/tracks");
req.AddQuery("position", Str_8::FromNum(pos));
req.AddQuery("uris", "spotify:track:" + trackId);
req.AddQueryVar({"position", Str_8::FromNum(pos)});
req.AddQueryVar({"uris", "spotify:track:" + trackId});
req.BearerAuth(token);
client.SendReq(req);
@@ -564,7 +564,7 @@ namespace ehs
StartConnection();
Request req(Verb::PUT, "/v1/me/player/seek");
req.AddQuery("position_ms", Str_8::FromNum(pos));
req.AddQueryVar({"position_ms", Str_8::FromNum(pos)});
req.BearerAuth(token);
client.SendReq(req);
@@ -588,7 +588,7 @@ namespace ehs
bool Spotify::ReAuthorize()
{
SSL accounts(AddrType::IPV4);
SSL accounts(IP::V4);
accounts.Initialize();
accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port);

View File

@@ -16,7 +16,7 @@ namespace ehs
}
Twitch::Twitch(const Str_8& clientId, const Str_8& secret, const Str_8& redURI, const Array<Str_8>& scopes, const bool forceVerify)
: client(AddrType::IPV4), clientId(clientId), secret(secret), redURI(redURI), scopes(scopes), forceVerify(forceVerify)
: client(IP::V4), clientId(clientId), secret(secret), redURI(redURI), scopes(scopes), forceVerify(forceVerify)
{
}
@@ -38,7 +38,7 @@ namespace ehs
"&response_type=code&force_verify=" + (forceVerify ? "true" : "false") + "&scope=" +
scopesFinal;
TCP server(AddrType::IPV4);
TCP server(IP::V4);
server.Bind("", 65535);
server.Listen();
@@ -78,7 +78,7 @@ namespace ehs
authReq.SetContentType(ContentType::APP_FORMURLENCODED);
authReq.AddToBody("client_id", clientId);
authReq.AddToBody("client_secret", secret);
authReq.AddToBody("code", cbReq.GetQuery("code"));
authReq.AddToBody("code", cbReq.GetQueryValue("code"));
authReq.AddToBody("grant_type", "authorization_code");
authReq.AddToBody("redirect_uri", redURI);

View File

@@ -53,7 +53,7 @@ namespace ehs
if (initialized)
return;
client = TCP(ehs::AddrType::IPV4);
client = TCP(ehs::IP::V4);
client.Connect(DNS::Resolve("irc.chat.twitch.tv"), 6667);
client.SetBlocking(false);

View File

@@ -0,0 +1,24 @@
#include "ehs/system/AVX2.h"
namespace ehs
{
bool AVX2::CompareUnaligned(const UInt_64* a, const UInt_64* b)
{
return false;
}
bool AVX2::CompareUnaligned(const SInt_64* a, const SInt_64* b)
{
return false;
}
bool AVX2::CompareAligned(const UInt_64* a, const UInt_64* b)
{
return false;
}
bool AVX2::CompareAligned(const SInt_64* a, const SInt_64* b)
{
return false;
}
}

View File

@@ -0,0 +1,49 @@
global _ZN3ehs4AVX216CompareUnalignedEPKmS2_
global _ZN3ehs4AVX216CompareUnalignedEPKlS2_
global _ZN3ehs4AVX214CompareAlignedEPKmS2_
global _ZN3ehs4AVX214CompareAlignedEPKlS2_
section .text
_ZN3ehs4AVX216CompareUnalignedEPKmS2_:
VMOVDQU YMM0, [RDI]
VMOVDQU YMM1, [RSI]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET
_ZN3ehs4AVX216CompareUnalignedEPKlS2_:
VMOVDQU YMM0, [RDI]
VMOVDQU YMM1, [RSI]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET
_ZN3ehs4AVX214CompareAlignedEPKmS2_:
VMOVDQA YMM0, [RDI]
VMOVDQA YMM1, [RSI]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET
_ZN3ehs4AVX214CompareAlignedEPKlS2_:
VMOVDQA YMM0, [RDI]
VMOVDQA YMM1, [RSI]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET

View File

@@ -0,0 +1,49 @@
global ?CompareUnaligned@AVX2@ehs@@SA_NPEBK0@Z
global ?CompareUnaligned@AVX2@ehs@@SA_NPEBJ0@Z
global ?CompareAligned@AVX2@ehs@@SA_NPEBK0@Z
global ?CompareAligned@AVX2@ehs@@SA_NPEBJ0@Z
section .text
?CompareUnaligned@AVX2@ehs@@SA_NPEBK0@Z:
VMOVDQU YMM0, [RCX]
VMOVDQU YMM1, [RDX]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET
?CompareUnaligned@AVX2@ehs@@SA_NPEBJ0@Z:
VMOVDQU YMM0, [RCX]
VMOVDQU YMM1, [RDX]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET
?CompareAligned@AVX2@ehs@@SA_NPEBK0@Z:
VMOVDQA YMM0, [RCX]
VMOVDQA YMM1, [RDX]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET
?CompareAligned@AVX2@ehs@@SA_NPEBJ0@Z:
VMOVDQA YMM0, [RCX]
VMOVDQA YMM1, [RDX]
VPCMPEQQ YMM2, YMM0, YMM1
VPMOVMSKB EAX, YMM2
CMP EAX, 0xFFFFFFFF
SETE AL
RET

View File

@@ -0,0 +1,24 @@
#include "ehs/system/AVX512.h"
namespace ehs
{
bool AVX512::CompareUnaligned(const UInt_64* a, const UInt_64* b)
{
return false;
}
bool AVX512::CompareUnaligned(const SInt_64* a, const SInt_64* b)
{
return false;
}
bool AVX512::CompareAligned(const UInt_64* a, const UInt_64* b)
{
return false;
}
bool AVX512::CompareAligned(const SInt_64* a, const SInt_64* b)
{
return false;
}
}

View File

@@ -0,0 +1,49 @@
global _ZN3ehs6AVX51216CompareUnalignedEPKmS2_
global _ZN3ehs6AVX51216CompareUnalignedEPKlS2_
global _ZN3ehs6AVX51214CompareAlignedEPKmS2_
global _ZN3ehs6AVX51214CompareAlignedEPKlS2_
section .text
_ZN3ehs6AVX51216CompareUnalignedEPKmS2_:
VMOVDQU64 ZMM0, [RDI]
VMOVDQU64 ZMM1, [RSI]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET
_ZN3ehs6AVX51216CompareUnalignedEPKlS2_:
VMOVDQU64 ZMM0, [RDI]
VMOVDQU64 ZMM1, [RSI]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET
_ZN3ehs6AVX51214CompareAlignedEPKmS2_:
VMOVDQA64 ZMM0, [RDI]
VMOVDQA64 ZMM1, [RSI]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET
_ZN3ehs6AVX51214CompareAlignedEPKlS2_:
VMOVDQA64 ZMM0, [RDI]
VMOVDQA64 ZMM1, [RSI]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET

View File

@@ -0,0 +1,49 @@
global ?CompareUnaligned@AVX512@ehs@@SA_NPEBK0@Z
global ?CompareUnaligned@AVX512@ehs@@SA_NPEBJ0@Z
global ?CompareAligned@AVX512@ehs@@SA_NPEBK0@Z
global ?CompareAligned@AVX512@ehs@@SA_NPEBJ0@Z
section .text
?CompareUnaligned@AVX512@ehs@@SA_NPEBK0@Z:
VMOVDQU64 ZMM0, [RCX]
VMOVDQU64 ZMM1, [RDX]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET
?CompareUnaligned@AVX512@ehs@@SA_NPEBJ0@Z:
VMOVDQU64 ZMM0, [RCX]
VMOVDQU64 ZMM1, [RDX]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET
?CompareAligned@AVX512@ehs@@SA_NPEBK0@Z:
VMOVDQA64 ZMM0, [RCX]
VMOVDQA64 ZMM1, [RDX]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET
?CompareAligned@AVX512@ehs@@SA_NPEBJ0@Z:
VMOVDQA64 ZMM0, [RCX]
VMOVDQA64 ZMM1, [RDX]
VPCMPEQQ K1, ZMM0, ZMM1
KORTESTQ K1, K1
SETC AL
RET

View File

@@ -2,7 +2,7 @@
namespace ehs
{
void BaseSystem::OpenURI(const Str_8& uri)
void BaseSystem::OpenURI(Str_8 uri)
{
}

View File

@@ -10,11 +10,75 @@ namespace ehs
UInt_64 CPU::TSC_Freq = 0;
#endif
const bool CPU::hasFPU = RetrieveFPU();
const bool CPU::hasVME = RetrieveVME();
const bool CPU::hasDE = RetrieveDE();
const bool CPU::hasPSE = RetrievePSE();
const bool CPU::hasTSC = RetrieveTSC();
const bool CPU::hasMSR = RetrieveMSR();
const bool CPU::hasPAE = RetrievePAE();
const bool CPU::hasMCE = RetrieveMCE();
const bool CPU::hasCX8 = RetrieveCX8();
const bool CPU::hasAPIC = RetrieveAPIC();
const bool CPU::hasSEP = RetrieveSEP();
const bool CPU::hasMTRR = RetrieveMTRR();
const bool CPU::hasPGE = RetrievePGE();
const bool CPU::hasMCA = RetrieveMCA();
const bool CPU::hasCMOV = RetrieveCMOV();
const bool CPU::hasPSE_36 = RetrievePSE_36();
const bool CPU::hasPSN = RetrievePSN();
const bool CPU::hasCLFSH = RetrieveCLFSH();
const bool CPU::hasDS = RetrieveDS();
const bool CPU::hasACPI = RetrieveACPI();
const bool CPU::hasMMX = RetrieveMMX();
const bool CPU::hasFXSR = RetrieveFXSR();
const bool CPU::hasSSE = RetrieveSSE();
const bool CPU::hasSSE2 = RetrieveSSE2();
const bool CPU::hasSS = RetrieveSS();
const bool CPU::hasHTT = RetrieveHTT();
const bool CPU::hasTM = RetrieveTM();
const bool CPU::hasIA64 = RetrieveIA64();
const bool CPU::hasPBE = RetrievePBE();
const bool CPU::hasSSE3 = RetrieveSSE3();
const bool CPU::hasPCLMULQDQ = RetrievePCLMULQDQ();
const bool CPU::hasDTES64 = RetrieveDTES64();
const bool CPU::hasMONITOR = RetrieveMONITOR();
const bool CPU::hasVMX = RetrieveVMX();
const bool CPU::hasSMX = RetrieveSMX();
const bool CPU::hasEST = RetrieveEST();
const bool CPU::hasTM2 = RetrieveTM2();
const bool CPU::hasSSSE3 = RetrieveSSSE3();
const bool CPU::hasCNXT_ID = RetrieveCNXT_ID();
const bool CPU::hasSDBG = RetrieveSDBG();
const bool CPU::hasFMA = RetrieveFMA();
const bool CPU::hasCX16 = RetrieveCX16();
const bool CPU::hasXTPR = RetrieveXTPR();
const bool CPU::hasPDCM = RetrievePDCM();
const bool CPU::hasPCID = RetrievePCID();
const bool CPU::hasDCA = RetrieveDCA();
const bool CPU::hasSSE4_1 = RetrieveSSE4_1();
const bool CPU::hasSSE4_2 = RetrieveSSE4_2();
const bool CPU::hasX2APIC = RetrieveX2APIC();
const bool CPU::hasMOVBE = RetrieveMOVBE();
const bool CPU::hasPOPCNT = RetrievePOPCNT();
const bool CPU::hasTSC_DEADLINE = RetrieveTSC_DEADLINE();
const bool CPU::hasAES = RetrieveAES();
const bool CPU::hasXSAVE = RetrieveXSAVE();
const bool CPU::hasOSXSAVE = RetrieveOSXSAVE();
const bool CPU::hasAVX = RetrieveAVX();
const bool CPU::hasF16C = RetrieveF16C();
const bool CPU::hasRDRND = RetrieveRDRND();
const bool CPU::hasHYPERVISOR = RetrieveHYPERVISOR();
const bool CPU::hasAVX2 = RetrieveAVX2();
const bool CPU::hasAVX512F = RetrieveAVX512F();
const bool CPU::hasRDSEED = RetrieveRDSEED();
const bool CPU::hasADX = RetrieveADX();
Architecture CPU::GetArchitecture()
{
#if defined(EHS_ARCH_X64)
return Architecture::X64;
#elif defined(EHS_ARCH_ARM64)
#elif defined(EHS_ARCH_AARCH64)
return Architecture::ARM64;
#else
return Architecture::UNKNOWN;
@@ -49,13 +113,19 @@ namespace ehs
return frequency.QuadPart;
#elif defined(EHS_OS_LINUX)
#if defined(EHS_ARCH_X64)
if (!TSC_Freq)
TSC_Freq = RetrieveTSC_Freq();
return TSC_Freq;
#endif
#elif defined(EHS_ARCH_AARCH64)
return RetrieveFreq_AARCH64();
#else
return 0;
#endif
#else
return 0;
#endif
}
UInt_64 CPU::GetTSC()
@@ -69,7 +139,7 @@ namespace ehs
TSC tsc;
RDTSCP(&tsc);
#if defined(EHS_ARCH_X64)
#if defined(EHS_ARCH_X64) || defined(EHS_ARCH_AARCH64)
UInt_64 result = 0;
#if defined(EHS_LITTLE_ENDIAN)
@@ -119,324 +189,589 @@ namespace ehs
return (UInt_8)(GetInfoBits() >> 20);
}
bool CPU::HasFPU()
bool CPU::RetrieveFPU()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000000001;
#else
return false;
#endif
}
bool CPU::HasVME()
bool CPU::RetrieveVME()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000000010;
#else
return false;
#endif
}
bool CPU::HasDE()
bool CPU::RetrieveDE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000000100;
#else
return false;
#endif
}
bool CPU::HasPSE()
bool CPU::RetrievePSE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000001000;
#else
return false;
#endif
}
bool CPU::HasTSC()
bool CPU::RetrieveTSC()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000010000;
#else
return false;
#endif
}
bool CPU::HasMSR()
bool CPU::RetrieveMSR()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000100000;
#else
return false;
#endif
}
bool CPU::HasPAE()
bool CPU::RetrievePAE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000001000000;
#else
return false;
#endif
}
bool CPU::HasMCE()
bool CPU::RetrieveMCE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000010000000;
#else
return false;
#endif
}
bool CPU::HasCX8()
bool CPU::RetrieveCX8()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000100000000;
#else
return false;
#endif
}
bool CPU::HasAPIC()
bool CPU::RetrieveAPIC()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000001000000000;
#else
return false;
#endif
}
bool CPU::HasSEP()
bool CPU::RetrieveSEP()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000100000000000;
#else
return false;
#endif
}
bool CPU::HasMTRR()
bool CPU::RetrieveMTRR()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000001000000000000;
#else
return false;
#endif
}
bool CPU::HasPGE()
bool CPU::RetrievePGE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000010000000000000;
#else
return false;
#endif
}
bool CPU::HasMCA()
bool CPU::RetrieveMCA()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000100000000000000;
#else
return false;
#endif
}
bool CPU::HasCMOV()
bool CPU::RetrieveCMOV()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000001000000000000000;
#else
return false;
#endif
}
bool CPU::HasPAT()
bool CPU::RetrievePAT()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000010000000000000000;
#else
return false;
#endif
}
bool CPU::HasPSE_36()
bool CPU::RetrievePSE_36()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000100000000000000000;
#else
return false;
#endif
}
bool CPU::HasPSN()
bool CPU::RetrievePSN()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000001000000000000000000;
#else
return false;
#endif
}
bool CPU::HasCLFSH()
bool CPU::RetrieveCLFSH()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000010000000000000000000;
#else
return false;
#endif
}
bool CPU::HasDS()
bool CPU::RetrieveDS()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000001000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasACPI()
bool CPU::RetrieveACPI()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000010000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasMMX()
bool CPU::RetrieveMMX()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000100000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasFXSR()
bool CPU::RetrieveFXSR()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000001000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasSSE()
bool CPU::RetrieveSSE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000010000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasSSE2()
bool CPU::RetrieveSSE2()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000100000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasSS()
bool CPU::RetrieveSS()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00001000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasHTT()
bool CPU::RetrieveHTT()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00010000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasTM()
bool CPU::RetrieveTM()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00100000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasIA64()
bool CPU::RetrieveIA64()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b01000000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasPBE()
bool CPU::RetrievePBE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b10000000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasSSE3()
bool CPU::RetrieveSSE3()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000000001;
#else
return false;
#endif
}
bool CPU::HasPCLMULQDQ()
bool CPU::RetrievePCLMULQDQ()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000000010;
#else
return false;
#endif
}
bool CPU::HasDTES64()
bool CPU::RetrieveDTES64()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000000100;
#else
return false;
#endif
}
bool CPU::HasMONITOR()
bool CPU::RetrieveMONITOR()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000001000;
#else
return false;
#endif
}
bool CPU::HasDS_CPL()
bool CPU::RetrieveDS_CPL()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000010000;
#else
return false;
#endif
}
bool CPU::HasVMX()
bool CPU::RetrieveVMX()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000100000;
#else
return false;
#endif
}
bool CPU::HasSMX()
bool CPU::RetrieveSMX()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000001000000;
#else
return false;
#endif
}
bool CPU::HasEST()
bool CPU::RetrieveEST()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000010000000;
#else
return false;
#endif
}
bool CPU::HasTM2()
bool CPU::RetrieveTM2()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000100000000;
#else
return false;
#endif
}
bool CPU::HasSSSE3()
bool CPU::RetrieveSSSE3()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000001000000000;
#else
return false;
#endif
}
bool CPU::HasCNXT_ID()
bool CPU::RetrieveCNXT_ID()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000010000000000;
#else
return false;
#endif
}
bool CPU::HasSDBG()
bool CPU::RetrieveSDBG()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000100000000000;
#else
return false;
#endif
}
bool CPU::HasFMA()
bool CPU::RetrieveFMA()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000001000000000000;
#else
return false;
#endif
}
bool CPU::HasCX16()
bool CPU::RetrieveCX16()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000010000000000000;
#else
return false;
#endif
}
bool CPU::HasXTPR()
bool CPU::RetrieveXTPR()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000100000000000000;
#else
return false;
#endif
}
bool CPU::HasPDCM()
bool CPU::RetrievePDCM()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000001000000000000000;
#else
return false;
#endif
}
bool CPU::HasPCID()
bool CPU::RetrievePCID()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000100000000000000000;
#else
return false;
#endif
}
bool CPU::HasDCA()
bool CPU::RetrieveDCA()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000001000000000000000000;
#else
return false;
#endif
}
bool CPU::HasSSE4_1()
bool CPU::RetrieveSSE4_1()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000010000000000000000000;
#else
return false;
#endif
}
bool CPU::HasSSE4_2()
bool CPU::RetrieveSSE4_2()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000100000000000000000000;
#else
return false;
#endif
}
bool CPU::HasX2APIC()
bool CPU::RetrieveX2APIC()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000001000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasMOVBE()
bool CPU::RetrieveMOVBE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000010000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasPOPCNT()
bool CPU::RetrievePOPCNT()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000100000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasTSC_DEADLINE()
bool CPU::RetrieveTSC_DEADLINE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000001000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasAES()
bool CPU::RetrieveAES()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000010000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasXSAVE()
bool CPU::RetrieveXSAVE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000100000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasOSXSAVE()
bool CPU::RetrieveOSXSAVE()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00001000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasAVX()
bool CPU::RetrieveAVX()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00010000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasF16C()
bool CPU::RetrieveF16C()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00100000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasRDRND()
bool CPU::RetrieveRDRND()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b01000000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasHYPERVISOR()
bool CPU::RetrieveHYPERVISOR()
{
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b10000000000000000000000000000000;
#else
return false;
#endif
}
bool CPU::HasAVX2()
bool CPU::RetrieveAVX2()
{
#ifdef EHS_ARCH_X64
return GetExtFeatureBits_1() & 0b00000000000000000000000000100000;
#else
return false;
#endif
}
bool CPU::HasRDSEED()
bool CPU::RetrieveAVX512F()
{
#ifdef EHS_ARCH_X64
return GetExtFeatureBits_1() & 0b00000000000000010000000000000000;
#else
return false;
#endif
}
bool CPU::RetrieveRDSEED()
{
#ifdef EHS_ARCH_X64
return GetExtFeatureBits_1() & 0b00000000000001000000000000000000;
#else
return false;
#endif
}
bool CPU::HasADX()
bool CPU::RetrieveADX()
{
#ifdef EHS_ARCH_X64
return GetExtFeatureBits_1() & 0b00000000000010000000000000000000;
#else
return false;
#endif
}
/*

View File

@@ -2,10 +2,6 @@
namespace ehs
{
void CPU::RDTSCP(TSC* tsc)
{
}
void CPU::GetManufacturer(Char_8* input)
{
}
@@ -43,4 +39,9 @@ namespace ehs
void CPU::GetBrand(Char_8* input)
{
}
UInt_8 CPU::GetCacheLineSize()
{
return 0;
}
}

View File

@@ -0,0 +1,14 @@
.global _ZN3ehs3CPU6RDTSCPEPNS_3TSCE
.global _ZN3ehs3CPU20RetrieveFreq_AARCH64Ev
.section .text
_ZN3ehs3CPU6RDTSCPEPNS_3TSCE:
MRS X2, CNTVCT_EL0
EOR W1, W1, W1
STR W1, [X0]
STR X2, [X0, #4]
RET
_ZN3ehs3CPU20RetrieveFreq_AARCH64Ev:
MRS X0, CNTFRQ_EL0
RET

View File

@@ -7,6 +7,7 @@ global _ZN3ehs3CPU19GetExtFeatureBits_1Ev
global _ZN3ehs3CPU19GetExtFeatureBits_2Ev
global _ZN3ehs3CPU19GetExtFeatureBits_3Ev
global _ZN3ehs3CPU8GetBrandEPc
global _ZN3ehs3CPU16GetCacheLineSizeEv
section .text
_ZN3ehs3CPU6RDTSCPEPNS_3TSCE:
@@ -130,3 +131,16 @@ section .text
POP RBX
RET
_ZN3ehs3CPU16GetCacheLineSizeEv:
PUSH RBX
MOV EAX, 0x80000006
CPUID
XOR EAX, EAX
MOV AL, CL
POP RBX
RET

View File

@@ -6,6 +6,7 @@ global ?GetExtFeatureBits_1@CPU@ehs@@SAIXZ
global ?GetExtFeatureBits_2@CPU@ehs@@SAKXZ
global ?GetExtFeatureBits_3@CPU@ehs@@SAKXZ
global ?GetBrand@CPU@ehs@@SAXPEAD@Z
global ?GetCacheLineSize@CPU@ehs@@SAEXZ
section .text
?GetManufacturer@CPU@ehs@@SAXPEAD@Z:
@@ -125,3 +126,16 @@ section .text
POP RBX
RET
?GetCacheLineSize@CPU@ehs@@SAEXZ:
PUSH RBX
MOV EAX, 0x80000006
CPUID
XOR EAX, EAX
MOV AL, CL
POP RBX
RET

Some files were not shown because too many files have changed in this diff Show More