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 - name: Building/Compiling/Installing Project
run: | run: |
cd ${{ gitea.workspace }} cd ${{ gitea.workspace }}
vcpkg install
mkdir build mkdir build
cd 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 --build . --config Release
cmake --install . cmake --install .
@@ -36,6 +35,8 @@ jobs:
mv build/Release/EHS_Dyn.dll bin mv build/Release/EHS_Dyn.dll bin
mv build/Release/StrToHash.exe bin mv build/Release/StrToHash.exe bin
mv build/Release/zlib1.dll 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 mkdir lib
mv build/Release/EHS_Stc.lib lib mv build/Release/EHS_Stc.lib lib
mv build/Release/EHS_Dyn.lib lib mv build/Release/EHS_Dyn.lib lib
@@ -56,6 +57,7 @@ jobs:
files: |- files: |-
ehs-windows-amd64.zip ehs-windows-amd64.zip
api_key: '${{secrets.RELEASE_TOKEN}}' api_key: '${{secrets.RELEASE_TOKEN}}'
pre_release: false
Linux-AMD64-Build: Linux-AMD64-Build:
runs-on: linux-x86_64 runs-on: linux-x86_64
@@ -65,7 +67,7 @@ jobs:
- name: Installing Dependencies - name: Installing Dependencies
run: | 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 - name: Generating Documentation
run: | run: |
@@ -74,7 +76,7 @@ jobs:
- name: Building/Compiling/Installing Project - name: Building/Compiling/Installing Project
run: | run: |
cd ${{ gitea.workspace }} 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 --build . --config Release
cmake --install . cmake --install .
@@ -101,6 +103,7 @@ jobs:
files: |- files: |-
ehs-linux-amd64.zip ehs-linux-amd64.zip
api_key: '${{secrets.RELEASE_TOKEN}}' api_key: '${{secrets.RELEASE_TOKEN}}'
pre_release: false
Linux-AARCH64-Build: Linux-AARCH64-Build:
runs-on: linux-aarch64 runs-on: linux-aarch64
@@ -109,7 +112,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Installing Dependencies - 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 - name: Generating Documentation
run: | run: |
@@ -118,7 +121,7 @@ jobs:
- name: Building/Compiling/Installing Project - name: Building/Compiling/Installing Project
run: | run: |
cd ${{ gitea.workspace }} 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 --build . --config Release
cmake --install . cmake --install .
@@ -145,3 +148,4 @@ jobs:
files: |- files: |-
ehs-linux-aarch64.zip ehs-linux-aarch64.zip
api_key: '${{secrets.RELEASE_TOKEN}}' 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_WINDOWS FALSE)
set(IS_OS_LINUX FALSE) set(IS_OS_LINUX FALSE)
@@ -11,6 +11,8 @@ set(IS_ARCH_ARM FALSE)
project(EHS CXX C) project(EHS CXX C)
set(CMAKE_VERBOSE_MAKEFILE ON)
if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
set(IS_OS_WINDOWS TRUE) set(IS_OS_WINDOWS TRUE)
set(USER_HOME_DIRECTORY "$ENV{USERPROFILE}") set(USER_HOME_DIRECTORY "$ENV{USERPROFILE}")
@@ -51,6 +53,7 @@ set(EHS_SOURCES
src/Color3.cpp include/ehs/Color3.h src/Color3.cpp include/ehs/Color3.h
src/Version.cpp include/ehs/Version.h src/Version.cpp include/ehs/Version.h
src/Base64.cpp include/ehs/Base64.h src/Base64.cpp include/ehs/Base64.h
src/SHA256.cpp include/ehs/SHA256.h
src/Data.cpp include/ehs/Data.h src/Data.cpp include/ehs/Data.h
src/Range.cpp include/ehs/Range.h src/Range.cpp include/ehs/Range.h
src/Util.cpp include/ehs/Util.h src/Util.cpp include/ehs/Util.h
@@ -97,6 +100,8 @@ set(EHS_SOURCES
include/ehs/system/OS.h include/ehs/system/OS.h
include/ehs/system/Semaphore.h include/ehs/system/Semaphore.h
include/ehs/system/System.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/Json.cpp include/ehs/json/Json.h
src/json/JsonBase.cpp include/ehs/json/JsonBase.h src/json/JsonBase.cpp include/ehs/json/JsonBase.h
@@ -134,7 +139,7 @@ set(EHS_SOURCES
include/ehs/io/socket/ehc/NetUtils.h include/ehs/io/socket/ehc/NetUtils.h
src/io/socket/EHC.cpp include/ehs/io/socket/EHC.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/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/NetSys.cpp include/ehs/io/socket/ehc/NetSys.h
src/io/socket/ehc/NetOp.cpp include/ehs/io/socket/ehc/NetOp.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/Directory.h
include/ehs/io/socket/ehc/NetEnc.h include/ehs/io/socket/ehc/NetEnc.h
src/io/socket/ehc/NetEnc.cpp 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) if (IS_OS_WINDOWS)
@@ -205,7 +221,10 @@ if (IS_OS_WINDOWS)
src/io/COM.cpp include/ehs/io/COM.h 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/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 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) elseif (IS_OS_LINUX)
list(APPEND EHS_SOURCES list(APPEND EHS_SOURCES
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h 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/system/User.cpp include/ehs/system/User.h
src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h src/io/Directory_LNX.cpp include/ehs/io/Directory_LNX.h
src/io/Usb_LNX.cpp include/ehs/io/Usb_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") if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland")
add_compile_definitions(EHS_WS_WAYLAND) add_compile_definitions(EHS_WS_WAYLAND)
@@ -240,17 +260,14 @@ elseif (IS_OS_LINUX)
endif () endif ()
if (IS_ARCH_AMD64) 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) 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 ()
endif() endif()
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
#message("${CMAKE_CXX_FLAGS}")
add_library(EHS_Stc STATIC ${EHS_SOURCES}) 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) add_executable(StrToHash src/StrToHash.cpp)
target_compile_definitions(EHS_Dyn PRIVATE EHS_LIB_EXPORT) 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) target_link_libraries(StrToHash OpenSSL::SSL OpenSSL::Crypto ZLIB::ZLIB)
if (IS_OS_WINDOWS) 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) target_link_libraries(StrToHash ws2_32 avrt EHS_Stc)
elseif (IS_OS_LINUX) elseif (IS_OS_LINUX)
if (LINUX_WINDOW_SYSTEM STREQUAL "Wayland") 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) target_link_libraries(StrToHash xcb xcb-cursor xcb-xfixes xcb-xinput)
endif () endif ()
target_link_libraries(EHS_Dyn z asound pipewire-0.3) target_link_libraries(EHS_Dyn z pipewire-0.3)
target_link_libraries(StrToHash z asound EHS_Stc) target_link_libraries(StrToHash z EHS_Stc)
endif () endif ()

View File

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

View File

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

View File

@@ -8,17 +8,26 @@ namespace ehs
class EHS_LIB_IO Base64 class EHS_LIB_IO Base64
{ {
private: private:
static const char ascii[]; static constexpr UInt_8 asciiUrl[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
static constexpr UInt_8 ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
public: public:
static Str_8 EncodeURL(const Str_8 &input);
static Str_8 Encode(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); static Str_8 Decode(const Str_8 &input);
private: 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 namespace ehs
{ {
class EHS_LIB_IO HRNG class HRNG
{ {
public: public:
static UInt_64 GenerateSeed_u64(); 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] tags The tags to associate this log with.
/// @param [in] code The unique code to use. /// @param [in] code The unique code to use.
/// @param [in] msg Detailed information about what happened. /// @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. /// Initializes members with the given information.
/// @param [in] tags The tags to associate this log with. /// @param [in] tags The tags to associate this log with.
@@ -134,17 +134,17 @@ namespace ehs
#ifndef EHS_LOG_INT #ifndef EHS_LOG_INT
#ifdef EHS_DEBUG #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 #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
#endif #endif
#ifndef EHS_LOG #ifndef EHS_LOG
#ifdef EHS_DEBUG #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 #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
#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 namespace ehs
{ {
template<typename N = UInt_64> template<typename N = UInt_64>
class Serializer : public BaseObj class Serializer
{ {
private: private:
Endianness endianness; Endianness endianness;
@@ -30,7 +30,7 @@ namespace ehs
N offset; N offset;
public: public:
~Serializer() override ~Serializer()
{ {
delete[] data; delete[] data;
} }
@@ -38,32 +38,27 @@ namespace ehs
Serializer() Serializer()
: endianness(Endianness::BE), data(nullptr), size(0), offset(0) : endianness(Endianness::BE), data(nullptr), size(0), offset(0)
{ {
AddType("Serializer");
} }
Serializer(const Endianness endianness) Serializer(const Endianness endianness)
: endianness(endianness), data(nullptr), size(0), offset(0) : endianness(endianness), data(nullptr), size(0), offset(0)
{ {
AddType("Serializer");
} }
Serializer(const Endianness endianness, const N size) Serializer(const Endianness endianness, const N size)
: endianness(endianness), data(new Byte[size]), size(size), offset(0) : 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) 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) : endianness(endianness), data(new Byte[size]), size(size), offset(offset)
{ {
AddType("Serializer");
for (N i = 0; i < size; ++i) for (N i = 0; i < size; ++i)
this->data[i] = data[i]; this->data[i] = data[i];
} }
Serializer(Serializer&& serializer) noexcept 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) size(serializer.size), offset(serializer.offset)
{ {
serializer.data = nullptr; serializer.data = nullptr;
@@ -72,7 +67,7 @@ namespace ehs
} }
Serializer(const Serializer& serializer) 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) size(serializer.size), offset(serializer.offset)
{ {
for (N i = 0; i < serializer.size; ++i) for (N i = 0; i < serializer.size; ++i)
@@ -84,8 +79,6 @@ namespace ehs
if (this == &serializer) if (this == &serializer)
return *this; return *this;
BaseObj::operator=((Serializer&&)serializer);
endianness = serializer.endianness; endianness = serializer.endianness;
delete[] data; delete[] data;
data = serializer.data; data = serializer.data;
@@ -104,8 +97,6 @@ namespace ehs
if (this == &serializer) if (this == &serializer)
return *this; return *this;
BaseObj::operator=(serializer);
endianness = serializer.endianness; endianness = serializer.endianness;
delete[] data; delete[] data;
@@ -1228,7 +1219,7 @@ namespace ehs
void Resize(const N newSize) void Resize(const N newSize)
{ {
Byte* result = new Byte[newSize]; Byte* result = new Byte[newSize];
Util::Copy(result, data, size); Util::Copy(result, data, newSize >= size ? size : newSize);
delete[] data; delete[] data;
data = result; data = result;
size = newSize; size = newSize;

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,7 @@ namespace ehs
class EHS_LIB_IO DNS final : public BaseDNS class EHS_LIB_IO DNS final : public BaseDNS
{ {
public: 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); static Str_8 Resolve(const Str_8 &hostname);
}; };

View File

@@ -7,7 +7,7 @@ namespace ehs
class EHS_LIB_IO DNS final : public BaseDNS class EHS_LIB_IO DNS final : public BaseDNS
{ {
public: 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); static Str_8 Resolve(const Str_8 &hostname);
}; };

View File

@@ -1,78 +1,41 @@
#pragma once #pragma once
#include "ehs/io/socket/ehc/NetUtils.h"
#include "ehs/io/socket/ehc/NetEnc.h" #include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/Serializer.h"
#include "ehs/Vector.h"
#include "ehs/Array.h" #include "ehs/Array.h"
#include "Socket.h" #include "Socket.h"
#include "UDP.h" #include "UDP.h"
namespace ehs namespace ehs
{ {
class NetSys; class NetServerCh;
class NetClientCh;
class NetEnd; class NetEnd;
class EHC; 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 class EHC
{ {
private: private:
friend class NetEnc; friend class NetEnc;
friend class NetChannel;
friend class NetServerCh;
friend class NetClientCh;
friend class NetEnd; friend class NetEnd;
static const Version version; 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; UDP udp;
Version appVer;
EndDisp disposition;
UInt_64 hashName;
Str_8 name;
bool dropPackets;
Byte* buffer; Byte* buffer;
UInt_32 bufferSize; UInt_32 bufferSize;
Array<NetEnc *> encryptions;
Array<NetSys *> systems;
UInt_32 maxEndpoints;
UInt_64 lastTSC; UInt_64 lastTSC;
float delta; float delta;
float maxTimeout; Array<NetEnc *> encryptions;
float resendRate; Array<NetServerCh *> servers;
ConnectCb connectCb; Array<NetClientCh *> clients;
ConnectedCb connectedCb;
ActiveCb activeCb;
DisconnectCb disconnectCb;
DisconnectedCb disconnectedCb;
TimeoutCb timeoutCb;
protected:
Vector<NetEnd*> endpoints;
public: public:
~EHC(); ~EHC();
EHC(); EHC(IP version = IP::V6);
EHC(const Version &ver, Str_8 name, UInt_64 maxEndpoints);
EHC(const Version &ver, Str_8 name);
EHC(EHC &&sock) noexcept; EHC(EHC &&sock) noexcept;
@@ -86,143 +49,47 @@ namespace ehs
void Release(); void Release();
void Bind(AddrType newType, const Str_8& newAddress, UInt_16 newPort); void Bind(const Endpoint &endpoint);
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 Poll(); void Poll();
bool IsInitialized() const; bool IsInitialized() const;
AddrType GetLocalAddressType() const; Endpoint GetLocalEndpoint() const;
Str_8 GetLocalAddress() const;
UInt_16 GetLocalPort() const;
bool IsBound() const; bool IsBound() const;
static Version GetVersion(); 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); 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; NetClientCh *GetClient(const Str_8& clientName) 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);
private: 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]); NetEnc* GetEncryption(const Str_8& encName) const;
bool RemoveEndpoint(const Str_8& address, UInt_16 port);
bool RemoveEndpoint(const NetEnd* end);
void PollEndpoints();
}; };
} }

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

View File

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

View File

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

View File

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

View File

@@ -22,7 +22,7 @@ namespace ehs
/// Default members initialization. /// Default members initialization.
TCP(); TCP();
TCP(AddrType addrType); TCP(IP IP);
TCP(TCP&& tcp) noexcept; 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] 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. /// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called. /// @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. /// Listens for incoming connections. Used for servers or PtP.
void Listen() override; void Listen() override;
@@ -58,7 +58,7 @@ namespace ehs
/// Connects to a TCP Socket that listens for incoming connections. Used for clients or PtP. /// 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 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. /// @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. /// 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. /// @param [in] buffer The C-style array to send.
@@ -84,15 +84,17 @@ namespace ehs
bool IsIPv6Only() const override; bool IsIPv6Only() const override;
void SetReuse(const bool &value) override;
bool IsValid() const override; bool IsValid() const override;
private: 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. /// Default members initialization.
TCP(); TCP();
TCP(AddrType addrType); TCP(IP IP);
TCP(TCP&& tcp) noexcept; 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] 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. /// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called. /// @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. /// Listens for incoming connections. Used for servers or PtP.
void Listen() override; void Listen() override;
@@ -58,7 +58,7 @@ namespace ehs
/// Connects to a TCP Socket that listens for incoming connections. Used for clients or PtP. /// 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 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. /// @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. /// 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. /// @param [in] buffer The C-style array to send.
@@ -84,12 +84,14 @@ namespace ehs
bool IsIPv6Only() const override; bool IsIPv6Only() const override;
void SetReuse(const bool &value) override;
bool IsValid() const override; bool IsValid() const override;
private: 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); void Connect_v6(const Str_8& address, UInt_16 port);

View File

@@ -19,7 +19,7 @@ namespace ehs
UDP(); UDP();
/// Default members initialization. /// Default members initialization.
UDP(AddrType type); UDP(IP version);
UDP(UDP&& udp) noexcept; 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] 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. /// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called. /// @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. /// 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. /// @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] data The C-style byte array to send.
/// @param [in] size The size of the C-style byte array. /// @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". /// @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. /// Receives data using the packet helper class.
/// @param [out] addr The Ipv4 or Ipv6 address of the sender. /// @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. /// @param [in] size The size of the pre-allocated C-style byte array.
/// @returns The size of the data received. /// @returns The size of the data received.
/// @warning The provided C-style byte array must be freed when finished using. /// @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. /// Sets whether or not receiving data blocks the next task.
/// @param [in] blocking Whether or not to block. /// @param [in] blocking Whether or not to block.

View File

@@ -19,7 +19,7 @@ namespace ehs
UDP(); UDP();
/// Default members initialization. /// Default members initialization.
UDP(const AddrType addrType); UDP(const IP IP);
UDP(UDP&& udp) noexcept; 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] 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. /// @param [in] port The port to bind to.
/// @note Requires the port given to be forwarded if this is called. /// @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. /// 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. /// @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] data The C-style byte array to send.
/// @param [in] size The size of the C-style byte array. /// @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". /// @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. /// Receives data using the packet helper class.
/// @param [out] addr The Ipv4 or Ipv6 address of the sender. /// @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. /// @param [in] size The size of the pre-allocated C-style byte array.
/// @returns The size of the data received. /// @returns The size of the data received.
/// @warning The provided C-style byte array must be freed when finished using. /// @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. /// Sets whether or not receiving data blocks the next task.
/// @param [in] blocking Whether or not to block. /// @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 #pragma once
#include "ehs/Str.h" #include "ehs/Str.h"
#include "ehs/Version.h"
namespace ehs namespace ehs
{ {
@@ -11,16 +12,16 @@ namespace ehs
private: private:
friend class EHC; friend class EHC;
EHC *owner; UInt_64 id;
UInt_64 hashId; Str_8 name;
Str_8 id; Version version;
public: public:
virtual ~NetEnc() = default; virtual ~NetEnc() = default;
NetEnc(); NetEnc();
NetEnc(Str_8 id); NetEnc(Str_8 name, const Version &version);
NetEnc(NetEnc &&enc) noexcept; NetEnc(NetEnc &&enc) noexcept;
@@ -30,11 +31,11 @@ namespace ehs
NetEnc &operator=(const NetEnc &enc); 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; virtual void Encrypt(Byte *data, UInt_64 size) const;

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include "NetUtils.h" #include "NetUtils.h"
#include "NetFrags.h" #include "NetFrag.h"
#include "ehs/Str.h" #include "ehs/Str.h"
#include "ehs/Vector.h" #include "ehs/Vector.h"
@@ -10,27 +10,23 @@
namespace ehs namespace ehs
{ {
class EHC; class NetServerCh;
class NetEnd class NetEnd
{ {
private: private:
friend class EHC; friend class NetServerCh;
EHC* owner; NetServerCh* owner;
EndDisp disposition; UInt_64 id;
UInt_64 hashName;
Str_8 name; Str_8 name;
Status status; NetStatus status;
Architecture arch;
Char_8 token[64]; Char_8 token[64];
UInt_64 nextSendId; UInt_64 nextSendId;
Vector<Insurance> sent; Vector<Insurance> sent;
UInt_64 nextRecvId; UInt_64 nextRecvId;
Vector<NetFrags> received; Vector<NetFrag> received;
AddrType type; Endpoint endpoint;
Str_8 address;
UInt_16 port;
float deltaDuration; float deltaDuration;
float deltaRate; float deltaRate;
float timeout; float timeout;
@@ -42,9 +38,9 @@ namespace ehs
public: public:
NetEnd(); 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; NetEnd(NetEnd &&end) noexcept;
@@ -54,15 +50,11 @@ namespace ehs
NetEnd &operator=(const NetEnd &end); NetEnd &operator=(const NetEnd &end);
EndDisp GetDisposition() const; UInt_64 GetId() const;
UInt_64 GetHashName() const;
Str_8 GetName() const; Str_8 GetName() const;
Status GetStatus() const; NetStatus GetStatus() const;
Architecture GetArchitecture() const;
UInt_64 GetNextSendId() 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] sys The system hash id to execute an operation from.
/// @param [in] op The operation hash id in the system to execute. /// @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. /// @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. /// 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. /// @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] sys The system string id to execute an operation from.
/// @param [in] op The operation string id in the system to execute. /// @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. /// @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; UInt_64 GetNextRecvId() const;
Str_8 GetAddress() const; Endpoint GetEndpoint() const;
UInt_16 GetPort() const;
void SetDeltaRate(float newDeltaRate); void SetDeltaRate(float newDeltaRate);
@@ -107,23 +97,21 @@ namespace ehs
private: private:
void Poll(float delta); void Poll(float delta);
void SetStatus(Status newStatus); void SetStatus(NetStatus newStatus);
void RemoveInsurance(UInt_64 msgId, UInt_64 fragment); void RemoveInsurance(UInt_64 msgId, UInt_64 fragment);
void AddReceived(const Header& header, const Serializer<>& payload); void AddReceived(const Header& header, const Serializer<>& payload);
Vector<NetFrags>* GetReceived(); Vector<NetFrag>* GetReceived();
void Ping(float delta); void Ping(float delta);
void Pong(float delta);
void SetLatency(float newLatency); void SetLatency(float newLatency);
void SetQueueSlot(UInt_64 slot); 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); 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 namespace ehs
{ {
class EHC; class NetChannel;
class NetSys; class NetSys;
class NetEnd; class NetEnd;
@@ -14,15 +14,15 @@ namespace ehs
private: private:
friend class NetSys; friend class NetSys;
UInt_64 hashId; UInt_64 id;
Str_8 id; Str_8 name;
public: public:
virtual ~NetOp() = default; virtual ~NetOp() = default;
NetOp(); NetOp();
NetOp(Str_8 id); NetOp(Str_8 name);
NetOp(NetOp &&op) noexcept; NetOp(NetOp &&op) noexcept;
@@ -32,11 +32,11 @@ namespace ehs
NetOp &operator=(const NetOp &op); NetOp &operator=(const NetOp &op);
Str_8 GetId() const; UInt_64 GetId() const;
UInt_64 GetHashId() const; Str_8 GetName() const;
private: 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 namespace ehs
{ {
class EHC; class NetChannel;
class NetEnd; class NetEnd;
class NetOp; class NetOp;
class NetSys class NetSys
{ {
private: private:
friend class EHC; friend class NetChannel;
friend class NetServerCh;
friend class NetClientCh;
UInt_64 hashId; UInt_64 id;
Str_8 id; Str_8 name;
Array<NetOp*> ops; Array<NetOp*> ops;
public: public:
@@ -24,7 +26,7 @@ namespace ehs
NetSys(); NetSys();
NetSys(Str_8 id); NetSys(Str_8 name);
NetSys(NetSys &&sys) noexcept; NetSys(NetSys &&sys) noexcept;
@@ -34,15 +36,15 @@ namespace ehs
NetSys &operator=(const NetSys &sys); 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); bool AddOperation(NetOp *op);
private: 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 namespace ehs
{ {
enum class EndDisp : UInt_8 enum class NetStatus : UInt_8
{
ENDPOINT,
SERVICE
};
enum class Status : UInt_8
{ {
DISCONNECTED,
ACTIVE, ACTIVE,
PENDING, PENDING,
IN_LOCAL_QUEUE, QUEUED
IN_REMOTE_QUEUE, };
enum class NetChannelType : UInt_8
{
SERVER,
CLIENT
}; };
struct Header 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 id = 0;
UInt_64 fragments = 0; UInt_64 fragmentCount = 0;
UInt_64 fragment = 0; UInt_64 fragment = 0;
bool ensure = false; bool ensure = false;
EndDisp disposition = EndDisp::ENDPOINT;
Char_8 token[64] = {}; Char_8 token[64] = {};
UInt_64 system = 0; UInt_64 systemId = 0;
UInt_64 op = 0; UInt_64 opId = 0;
}; };
void WriteHeader(const Header &header, Serializer<UInt_64> &data);
Header ReadHeader(Serializer<UInt_64> &data);
struct Packet struct Packet
{ {
Header header; 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 #define EHS_64_BIT
#elif defined(_M_ARM64) || defined(__aarch64__) #elif defined(_M_ARM64) || defined(__aarch64__)
#define EHS_LITTLE_ENDIAN #define EHS_LITTLE_ENDIAN
#define EHS_ARCH_ARM64 #define EHS_ARCH_AARCH64
#define EHS_64_BIT #define EHS_64_BIT
#else #else
#error Unsupported architecture. #error Unsupported architecture.

View File

@@ -8,7 +8,7 @@ namespace ehs
class EHS_LIB_IO BaseSystem class EHS_LIB_IO BaseSystem
{ {
public: 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); static Str_8 OpenFileDialog(const Str_8 &dir, const Str_8 &filters);

View File

@@ -38,6 +38,70 @@ namespace ehs
#endif #endif
public: 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 Architecture GetArchitecture();
static UInt_8 PointerSize(); static UInt_8 PointerSize();
@@ -68,151 +132,157 @@ namespace ehs
static UInt_8 GetExtFamilyId(); 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 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 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 UInt_32 GetExtFeatureBits_1();
static bool HasAVX2();
static bool HasRDSEED();
static bool HasADX();
static UInt_32 GetExtFeatureBits_2(); static UInt_32 GetExtFeatureBits_2();
static UInt_32 GetExtFeatureBits_3(); static UInt_32 GetExtFeatureBits_3();
/// Retrieves the CPU brand as a null-terminated ASCII string. private:
/// @param[out] input A 48 byte character array representing the brand. static bool RetrieveFPU();
static void GetBrand(Char_8* input);
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(); //static Str_8 ToStr();
private: static UInt_64 RetrieveFreq_AARCH64();
static UInt_64 RetrieveTSC_Freq(); static UInt_64 RetrieveTSC_Freq();
static UInt_64 CalculateTSC_Freq(); static UInt_64 CalculateTSC_Freq();

View File

@@ -8,7 +8,7 @@ namespace ehs
class EHS_LIB_IO System : public BaseSystem class EHS_LIB_IO System : public BaseSystem
{ {
public: 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); 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 class EHS_LIB_IO System : public BaseSystem
{ {
public: public:
static void OpenURI(const Str_8& uri); static void OpenURI(Str_8 uri);
}; };
} }

View File

@@ -2,7 +2,35 @@
namespace ehs 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) Str_8 Base64::Encode(const Str_8 &input)
{ {
@@ -18,9 +46,9 @@ namespace ehs
for (int i = 0, j = 0; i < input_length;) { for (int i = 0, j = 0; i < input_length;) {
// Take first byte and shift right by 2 bits // Take first byte and shift right by 2 bits
UInt_32 octet_a = 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 ? input[i++] : 0; UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_c = i < input_length ? 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; UInt_32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
@@ -42,63 +70,151 @@ namespace ehs
return result; 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) Str_8 Base64::Decode(const Str_8 &input)
{ {
UInt_64 in_len = input.Size(); Str_8 result(input.Size() * 3 / 4);
int i = 0;
int j = 0;
int in_ = 0;
char char_array_4[4], char_array_3[3];
Str_8 ret;
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 (remaining >= 4)
if (i ==4)
{ {
for (i = 0; i <4; i++) for (UInt_8 i = 0; i < 4; ++i)
char_array_4[i] = Find(char_array_4[i]); {
if (!IsBase64(input[offsetIn + i]))
return {};
char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4); quartet[i] = Find(input[offsetIn + i]);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); if (quartet[i] == EHS_UINT_8_MAX)
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; return {};
}
for (i = 0; (i < 3); i++) result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4));
ret += char_array_3[i]; 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) return result;
{
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 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) UInt_8 Base64::Find(const UInt_8 &c)
{
for (char i = 0; i < (char)sizeof(ascii); ++i)
{ {
for (UInt_8 i = 0; i < (UInt_8)sizeof(ascii) - 1; ++i)
if (ascii[i] == c) if (ascii[i] == c)
return i; return i;
}
return EHS_SINT_8_MAX; 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) Log::Log(LogType type, const Str_8 &tags, const UInt_64 code, Str_8 msg)
: type(type), tags(tags.size()), code(code), msg((Str_8&&)msg) : type(type), code(code), msg((Str_8&&)msg)
{ {
UInt_64 i = 0; const Vector<Str_8> tmpTags = tags.Split(", ");
for (auto v = tags.begin(); v != tags.end(); ++v)
this->tags[i++] = *v; this->tags = Array<Str_8>(&tmpTags[0], tmpTags.Size());
} }
Log::Log(LogType type, Array<Str_8> tags, const UInt_64 code, Str_8 msg) 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) double Math::Sqrt(const double from)
{ {
#if defined(EHS_ARCH_X64) #if defined(EHS_ARCH_X64)
if (CPU::HasAVX()) if (CPU::hasAVX)
return Sqrt_AVX(from); return Sqrt_AVX(from);
else if (CPU::HasSSE()) else if (CPU::hasSSE)
return Sqrt_SSE2(from); return Sqrt_SSE2(from);
double temp = 0.0; double temp = 0.0;
@@ -51,7 +51,7 @@ namespace ehs
} }
return result; return result;
#elif defined(EHS_ARCH_ARM64) #elif defined(EHS_ARCH_AARCH64)
return Sqrt_VFP4(from); return Sqrt_VFP4(from);
#endif #endif
} }
@@ -59,9 +59,9 @@ namespace ehs
float Math::Sqrt(const float from) float Math::Sqrt(const float from)
{ {
#if defined(EHS_ARCH_X64) #if defined(EHS_ARCH_X64)
if (CPU::HasAVX()) if (CPU::hasAVX)
return Sqrt_AVX(from); return Sqrt_AVX(from);
else if (CPU::HasSSE()) else if (CPU::hasSSE)
return Sqrt_SSE(from); return Sqrt_SSE(from);
float temp = 0.0f; float temp = 0.0f;
@@ -74,7 +74,7 @@ namespace ehs
} }
return result; return result;
#elif defined(EHS_ARCH_ARM64) #elif defined(EHS_ARCH_AARCH64)
return Sqrt_VFP4(from); return Sqrt_VFP4(from);
#endif #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/Util.h"
#include "ehs/system/CPU.h"
#include "ehs/system/AVX2.h"
#include "ehs/system/AVX512.h"
namespace ehs namespace ehs
{ {
bool Util::Compare(const void* const a, const void* const b, const UInt_64 size) 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) Vector<Str_32> Console::GetArgs_32(const UInt_64 bufferSize)
{ {
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)
return UTF::To_32(GetCommandLineW()).Split(U" "); return UTF::To_32(GetCommandLineW()).ParseArgs();
#elif defined(EHS_OS_LINUX) #elif defined(EHS_OS_LINUX)
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN); File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
Array<Byte> data = cmdFile.ReadArray(bufferSize); Array<Byte> data = cmdFile.ReadArray(bufferSize);
@@ -725,7 +725,7 @@ namespace ehs
Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize) Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize)
{ {
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)
return Str_16(GetCommandLineW()).Split(L" "); return Str_16(GetCommandLineW()).ParseArgs();
#elif defined(EHS_OS_LINUX) #elif defined(EHS_OS_LINUX)
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN); File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
Array<Byte> data = cmdFile.ReadArray(bufferSize); Array<Byte> data = cmdFile.ReadArray(bufferSize);
@@ -755,7 +755,7 @@ namespace ehs
Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize) Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize)
{ {
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)
return UTF::To_8(GetCommandLineW()).Split(" "); return UTF::To_8(GetCommandLineW()).ParseArgs();
#elif defined(EHS_OS_LINUX) #elif defined(EHS_OS_LINUX)
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN); File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
Array<Byte> data = cmdFile.ReadArray(bufferSize); Array<Byte> data = cmdFile.ReadArray(bufferSize);

View File

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

View File

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

View File

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

View File

@@ -7,14 +7,14 @@
namespace ehs 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* result = nullptr;
addrinfo req = {}; addrinfo req = {};
if (type == AddrType::IPV6) if (type == IP::V6)
req.ai_family = AF_INET6; req.ai_family = AF_INET6;
else if (type == AddrType::IPV4) else if (type == IP::V4)
req.ai_family = AF_INET; req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result); Int_32 code = getaddrinfo(hostname, nullptr, &req, &result);

View File

@@ -6,7 +6,7 @@
namespace ehs 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 = {}; WSADATA data = {};
@@ -20,9 +20,9 @@ namespace ehs
addrinfo* result = nullptr; addrinfo* result = nullptr;
addrinfo req = {}; addrinfo req = {};
if (type == AddrType::IPV6) if (type == IP::V6)
req.ai_family = AF_INET6; req.ai_family = AF_INET6;
else if (type == AddrType::IPV4) else if (type == IP::V4)
req.ai_family = AF_INET; req.ai_family = AF_INET;
Int_32 code = getaddrinfo(hostname, nullptr, &req, &result); 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 namespace ehs
{ {
Request::Request() Request::Request()
: verb(Verb::GET), cType(ContentType::NONE) : verb(Verb::POST), cType(ContentType::NONE)
{ {
} }
Request::Request(const Verb verb, const Str_8& rsrc) Request::Request(const Verb &verb, Str_8 rsrc)
: verb(verb), rsrc(rsrc), cType(ContentType::NONE) : 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) : verb(Verb::POST), cType(ContentType::NONE)
{ {
ReadData(Str_8(data, size)); ReadData(Str_8(data, size));
@@ -25,17 +25,49 @@ namespace ehs
ReadData(data); 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; return *this;
verb = req.verb; verb = other.verb;
rsrc = req.rsrc; rsrc = (Str_8 &&)other.rsrc;
queries = req.queries; queries = (Vector<QueryVar> &&)other.queries;
header = req.header; header = (Vector<HeaderVar> &&)other.header;
cType = req.cType; cType = other.cType;
body = req.body; 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; return* this;
} }
@@ -45,7 +77,7 @@ namespace ehs
return verb; return verb;
} }
void Request::SetContentType(const ContentType cType) void Request::SetContentType(const ContentType &cType)
{ {
if (body.Size()) if (body.Size())
body.Resize(0); body.Resize(0);
@@ -58,9 +90,9 @@ namespace ehs
return cType; 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 Str_8 Request::GetResource() const
@@ -68,69 +100,179 @@ namespace ehs
return rsrc; 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) 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) queries.Swap(i, queries.End());
return data[1]; 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; return queries;
} }
void Request::BasicAuth(const Str_8& id, const Str_8& secret) 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) 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) void Request::BearerAuth(const Str_8& token, const Str_8& clientId)
{ {
AddToHeader("Authorization", "Bearer " + token); AddHeaderVar({"Authorization", "Bearer " + token});
AddToHeader("Client-Id", clientId); AddHeaderVar({"Client-Id", clientId});
} }
void Request::BotAuth(const Str_8& token) 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) 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) header.Swap(i, header.End());
return data[1]; 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; return header;
} }
@@ -200,16 +342,20 @@ namespace ehs
Str_8 result = VerbToStr(verb) + " " + rsrc; Str_8 result = VerbToStr(verb) + " " + rsrc;
if (queries.Size()) if (queries.Size())
result += "?" + queries[0]; result += "?" + queries[0].ToStr();
for (UInt_64 i = 1; i < queries.Size(); ++i) for (UInt_64 i = 1; i < queries.Size(); ++i)
result += "&" + queries[i]; result += "&" + queries[i].ToStr();
result += " HTTP/1.1\r\n"; result += " HTTP/1.1\r\n";
for (UInt_64 i = 0; i < header.Size(); ++i) 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"; result += "Content-Type: " + ContentTypeToStr(cType) + "\r\n";
@@ -227,7 +373,7 @@ namespace ehs
return rsrc.Size() || queries.Size() || header.Size() || body.Size(); 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) switch (verb)
{ {
@@ -244,7 +390,7 @@ namespace ehs
} }
} }
Str_8 Request::ContentTypeToStr(const ContentType cType) Str_8 Request::ContentTypeToStr(const ContentType &cType)
{ {
switch (cType) switch (cType)
{ {
@@ -262,8 +408,12 @@ namespace ehs
return "text/plain"; return "text/plain";
case ContentType::TEXT_HTML: case ContentType::TEXT_HTML:
return "text/html"; return "text/html";
case ContentType::TEXT_CSS:
return "text/css";
case ContentType::TEXT_XML: case ContentType::TEXT_XML:
return "text/xml"; return "text/xml";
case ContentType::IMG_X_ICON:
return "image/x-icon";
default: default:
return ""; return "";
} }
@@ -285,8 +435,12 @@ namespace ehs
return ContentType::TEXT_PLAIN; return ContentType::TEXT_PLAIN;
else if (value == "text/html") else if (value == "text/html")
return ContentType::TEXT_HTML; return ContentType::TEXT_HTML;
else if (value == "text/css")
return ContentType::TEXT_CSS;
else if (value == "text/xml") else if (value == "text/xml")
return ContentType::TEXT_XML; return ContentType::TEXT_XML;
else if (value == "image/x-icon")
return ContentType::IMG_X_ICON;
else else
return ContentType::NONE; return ContentType::NONE;
} }
@@ -308,7 +462,14 @@ namespace ehs
{ {
rsrc = meta[1].Sub(0, queryIndex); rsrc = meta[1].Sub(0, queryIndex);
cType = ContentType::APP_FORMURLENCODED; 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 else
{ {
@@ -331,7 +492,9 @@ namespace ehs
if (var[0] == "Content-Length") if (var[0] == "Content-Length")
continue; 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 namespace ehs
{ {
Response::Response(const UInt_32 code, const Str_8& server) Response::Response()
: code(code), server(server), cType(ContentType::NONE) : 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) : code(0), cType(ContentType::NONE)
{ {
ReadData(Str_8(data, size)); ReadData(Str_8(data, size));
@@ -19,26 +24,51 @@ namespace ehs
ReadData(data); ReadData(data);
} }
Response::Response() Response::Response(Response&& other) noexcept
: code(0), cType(ContentType::NONE) : 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; return *this;
code = res.code; code = other.code;
server = res.server; server = (Str_8 &&)other.server;
cType = res.cType; cType = other.cType;
header = res.header; header = (Vector<HeaderVar> &&)other.header;
body = res.body; body = (Str_8 &&)other.body;
other.code = 0;
other.cType = ContentType::NONE;
return *this; 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; this->code = code;
} }
@@ -48,9 +78,9 @@ namespace ehs
return code; 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 Str_8 Response::GetServer() const
@@ -58,7 +88,7 @@ namespace ehs
return server; return server;
} }
void Response::SetContentType(const ContentType cType) void Response::SetContentType(const ContentType &cType)
{ {
this->cType = cType; this->cType = cType;
} }
@@ -68,27 +98,80 @@ namespace ehs
return cType; 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) 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) header.Swap(i, header.End());
return data[1]; 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; return header;
} }
@@ -159,14 +242,11 @@ namespace ehs
for (UInt_64 i = 0; i < header.Size(); ++i) for (UInt_64 i = 0; i < header.Size(); ++i)
{ {
if (header[i].Find("Content-Length", nullptr, SearchPattern::LEFT_RIGHT, IndexResult::ENDING)) if (header[i] == 11245195881701120957ull || header[i] == 6556302699635904946ull ||
continue; header[i] == 13347276190653935221ull) // Content-Length, Server, and Content-Type in order from left to right.
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))
continue; 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; 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(); 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) if (code == 100)
return "Continue"; return "Continue";
@@ -323,7 +403,7 @@ namespace ehs
return "Unused Status Code"; return "Unused Status Code";
} }
Str_8 Response::ContentTypeToStr(const ContentType cType) Str_8 Response::ContentTypeToStr(const ContentType &cType)
{ {
switch (cType) switch (cType)
{ {
@@ -341,8 +421,12 @@ namespace ehs
return "text/plain"; return "text/plain";
case ContentType::TEXT_HTML: case ContentType::TEXT_HTML:
return "text/html"; return "text/html";
case ContentType::TEXT_CSS:
return "text/css";
case ContentType::TEXT_XML: case ContentType::TEXT_XML:
return "text/xml"; return "text/xml";
case ContentType::IMG_X_ICON:
return "image/x-icon";
default: default:
return ""; return "";
} }
@@ -364,8 +448,12 @@ namespace ehs
return ContentType::TEXT_PLAIN; return ContentType::TEXT_PLAIN;
else if (value == "text/html") else if (value == "text/html")
return ContentType::TEXT_HTML; return ContentType::TEXT_HTML;
else if (value == "text/css")
return ContentType::TEXT_CSS;
else if (value == "text/xml") else if (value == "text/xml")
return ContentType::TEXT_XML; return ContentType::TEXT_XML;
else if (value == "image/x-icon")
return ContentType::IMG_X_ICON;
else else
return ContentType::NONE; return ContentType::NONE;
} }
@@ -384,12 +472,12 @@ namespace ehs
Vector<Str_8> var = lines[i].Split(": "); Vector<Str_8> var = lines[i].Split(": ");
if (var[0].GetLower() == "server") if (var[0] == "Server")
{ {
server = var[1]; server = var[1];
continue; continue;
} }
else if (var[0].GetLower() == "content-type") else if (var[0] == "Content-Type")
{ {
Vector<Str_8> ctData = var[1].Split(";"); Vector<Str_8> ctData = var[1].Split(";");
@@ -397,7 +485,9 @@ namespace ehs
continue; 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/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/opensslv.h>
#include <openssl/provider.h>
namespace ehs namespace ehs
{ {
@@ -12,6 +14,11 @@ namespace ehs
if (!IsValid()) if (!IsValid())
return; return;
EVP_PKEY_free(pkey);
X509_free(cert);
if (sslHdl) if (sslHdl)
{ {
if (connection) if (connection)
@@ -25,28 +32,28 @@ namespace ehs
} }
SSL::SSL() SSL::SSL()
: ctx(nullptr), sslHdl(nullptr) : server(false), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{ {
} }
SSL::SSL(const AddrType type) SSL::SSL(const IP &type, const bool &server)
: TCP(type), ctx(nullptr), sslHdl(nullptr) : TCP(type), server(server), ctx(nullptr), sslHdl(nullptr), cert(nullptr), pkey(nullptr)
{ {
SSL::Initialize(); SSL::Initialize();
} }
SSL::SSL(TCP&& tcp) noexcept 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) 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) 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); TCP::operator=(ssl);
server = ssl.server;
ctx = nullptr; ctx = nullptr;
sslHdl = nullptr; sslHdl = nullptr;
cert = nullptr;
pkey = nullptr;
return *this; return *this;
} }
@@ -71,6 +81,40 @@ namespace ehs
return; return;
SSL_library_init(); 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() void SSL::Release()
@@ -80,6 +124,12 @@ namespace ehs
if (!IsValid()) if (!IsValid())
return; return;
EVP_PKEY_free(pkey);
pkey = nullptr;
X509_free(cert);
cert = nullptr;
if (sslHdl) if (sslHdl)
{ {
if (connection) 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); sslHdl = SSL_new(ctx);
SSL_set_fd(sslHdl, hdl); SSL_set_fd(sslHdl, hdl);
TCP::Bind(address, port); TCP::Listen();
EHS_LOG_SUCCESS();
} }
SSL* SSL::Accept() SSL* SSL::Accept()
@@ -118,13 +163,21 @@ namespace ehs
return nullptr; return nullptr;
TCP* tcp = TCP::Accept(); TCP* tcp = TCP::Accept();
if (!tcp)
return nullptr;
SSL* client = new SSL(std::move(*tcp)); SSL* client = new SSL(std::move(*tcp));
delete tcp; delete tcp;
client->ctx = nullptr; client->sslHdl = SSL_new(this->ctx);
client->sslHdl = SSL_new(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); SSL_set_fd(client->sslHdl, client->hdl);
int err = SSL_accept(client->sslHdl); int err = SSL_accept(client->sslHdl);
@@ -134,21 +187,29 @@ namespace ehs
return {}; return {};
} }
EHS_LOG_SUCCESS();
return client; 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); TCP::Connect(address, port);
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ctx = SSL_CTX_new(SSLv23_client_method());
sslHdl = SSL_new(ctx); sslHdl = SSL_new(ctx);
SSL_set_fd(sslHdl, hdl); 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) UInt_64 SSL::Send(const Byte* const buffer, const UInt_32 size)
@@ -157,8 +218,12 @@ namespace ehs
if (written <= 0) if (written <= 0)
{ {
int code = SSL_get_error(sslHdl, written); int code = SSL_get_error(sslHdl, written);
if (code != SSL_ERROR_WANT_WRITE)
{
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
EHS_LOG_INT(LogType::ERR, 0, "Failed to send data with error #" + Str_8::FromNum(code) + "."); EHS_LOG_INT(LogType::ERR, 0, "Failed to send data with error #" + Str_8::FromNum(code) + ".");
}
return 0; return 0;
} }
@@ -171,48 +236,46 @@ namespace ehs
if (received <= 0) if (received <= 0)
{ {
int code = SSL_get_error(sslHdl, received); int code = SSL_get_error(sslHdl, received);
if (code != SSL_ERROR_WANT_READ)
{
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data with error #" + Str_8::FromNum(code) + "."); EHS_LOG_INT(LogType::ERR, 0, "Failed to receive data with error #" + Str_8::FromNum(code) + ".");
}
return 0; return 0;
} }
return received; 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); BIO* certBio = BIO_new_mem_buf(data, (int)size);
if (!cert) 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; 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; return;
} }
X509_free(cert); BIO_free(keyBio);
}
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);
} }
bool SSL::IsValid() bool SSL::IsValid()

View File

@@ -38,7 +38,7 @@ namespace ehc
} }
Socket::Socket() 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), 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), maxEndpoints(0), lastTSC(0), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f), connectedCb(nullptr),
activeCb(nullptr), disconnectedCb(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) 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), 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), maxEndpoints(maxEndpoints), lastTSC(CPU::GetTSC()), delta(0.0f), maxTimeout(5.0f), resendRate(0.5f),
connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr) connectedCb(nullptr), activeCb(nullptr), disconnectedCb(nullptr)
@@ -113,9 +113,9 @@ namespace ehc
} }
#endif #endif
if (type == AddrType::IPV6) if (type == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 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); hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else else
return; return;
@@ -140,12 +140,12 @@ namespace ehc
return; return;
} }
if (type == AddrType::IPV4) if (type == IP::V4)
{ {
buffer = new Byte[EHS_IPV4_UDP_PAYLOAD]; buffer = new Byte[EHS_IPV4_UDP_PAYLOAD];
bufferSize = 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]; buffer = new Byte[EHS_IPV6_UDP_PAYLOAD];
bufferSize = EHS_IPV6_UDP_PAYLOAD; bufferSize = EHS_IPV6_UDP_PAYLOAD;
@@ -204,9 +204,9 @@ namespace ehc
if (hdl == EHS_INVALID_SOCKET || bound) if (hdl == EHS_INVALID_SOCKET || bound)
return; return;
if (type == AddrType::IPV6) if (type == IP::V6)
Bind_v6(newAddress, newPort); Bind_v6(newAddress, newPort);
else if (type == AddrType::IPV4) else if (type == IP::V4)
Bind_v4(newAddress, newPort); Bind_v4(newAddress, newPort);
address = newAddress; address = newAddress;
@@ -580,7 +580,7 @@ namespace ehc
return hdl != EHS_INVALID_SOCKET; return hdl != EHS_INVALID_SOCKET;
} }
void Socket::SetAddressType(const AddrType newType) void Socket::SetAddressType(const IP newType)
{ {
if (hdl != EHS_INVALID_SOCKET) if (hdl != EHS_INVALID_SOCKET)
return; return;
@@ -588,7 +588,7 @@ namespace ehc
type = newType; type = newType;
} }
AddrType Socket::GetAddressType() const IP Socket::GetAddressType() const
{ {
return type; return type;
} }
@@ -1219,14 +1219,14 @@ namespace ehc
return 0; 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) 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) + "."); + "\", that exceeds, \"" + Str_8::FromNum(EHS_IPV4_UDP_PAYLOAD) + ".");
} }
sockaddr_in6 remote = {}; 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; SInt_64 received = 0;
#if defined(EHS_OS_WINDOWS) #if defined(EHS_OS_WINDOWS)

View File

@@ -30,8 +30,8 @@ namespace ehs
{ {
} }
TCP::TCP(const AddrType addrType) TCP::TCP(const IP IP)
: BaseTCP(addrType), hdl(EHS_INVALID_SOCKET) : BaseTCP(IP), hdl(EHS_INVALID_SOCKET)
{ {
TCP::Initialize(); TCP::Initialize();
} }
@@ -78,9 +78,9 @@ namespace ehs
if (IsValid()) if (IsValid())
return; return;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
hdl = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); 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); hdl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
else else
return; return;
@@ -114,17 +114,17 @@ namespace ehs
hdl = EHS_INVALID_SOCKET; 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) if (!IsValid() || bound || connection)
return; return;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
Bind_v6(address, port); Bind_v6(address, port);
else if (addrType == AddrType::IPV4) else if (ip == IP::V4)
Bind_v4(address, port); Bind_v4(address, port);
this->localAddr = address; this->localAddr = (Str_8 &&)address;
this->localPort = port; this->localPort = port;
bound = true; bound = true;
@@ -155,7 +155,7 @@ namespace ehs
UInt_32 addrLen = sizeof(sockaddr_in6); UInt_32 addrLen = sizeof(sockaddr_in6);
TCP* client = new TCP(); TCP* client = new TCP();
client->addrType = addrType; client->ip = ip;
client->localAddr = localAddr; client->localAddr = localAddr;
client->localPort = localPort; client->localPort = localPort;
client->connection = true; client->connection = true;
@@ -207,26 +207,26 @@ namespace ehs
return client; 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) if (connection || !IsValid() || listening)
return; return;
remoteHostName = address; remoteHostName = (Str_8 &&)address;
remotePort = port; remotePort = port;
if (addrType == AddrType::IPV6) if (ip == IP::V6)
{ {
if (IsIPv6Only()) if (IsIPv6Only())
remoteAddr = DNS::Resolve(AddrType::IPV6, address); remoteAddr = DNS::Resolve(IP::V6, remoteHostName);
else else
remoteAddr = DNS::Resolve(address); remoteAddr = DNS::Resolve(remoteHostName);
Connect_v6(remoteAddr, port); 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); Connect_v4(remoteAddr, port);
} }
@@ -338,7 +338,7 @@ namespace ehs
void TCP::SetIPv6Only(const bool value) 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."); EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return; return;
@@ -362,7 +362,7 @@ namespace ehs
bool TCP::IsIPv6Only() const bool TCP::IsIPv6Only() const
{ {
if (addrType != AddrType::IPV6) if (ip != IP::V6)
return false; return false;
if (!IsValid()) if (!IsValid())
@@ -385,12 +385,30 @@ namespace ehs
return result; 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 bool TCP::IsValid() const
{ {
return hdl != EHS_INVALID_SOCKET; 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 = {}; sockaddr_in6 result = {};
result.sin6_family = AF_INET6; 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 = {}; sockaddr_in result = {};
result.sin_family = AF_INET; 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 = {}; sockaddr_in6 result = {};
result.sin6_family = AF_INET6; 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 = {}; sockaddr_in result = {};
result.sin_family = AF_INET; result.sin_family = AF_INET;

View File

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

View File

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

View File

@@ -24,8 +24,8 @@ namespace ehs
{ {
} }
UDP::UDP(const AddrType addrType) UDP::UDP(const IP IP)
: BaseUDP(addrType), hdl(EHS_INVALID_SOCKET) : BaseUDP(IP), hdl(EHS_INVALID_SOCKET)
{ {
WSADATA data = {}; WSADATA data = {};
@@ -36,9 +36,9 @@ namespace ehs
return; return;
} }
if (addrType == AddrType::IPV6) if (IP == IP::V6)
hdl = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 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); hdl = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
else else
return; return;
@@ -110,33 +110,32 @@ namespace ehs
bound = false; 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) if (!IsValid() || bound)
return; return;
if (type == AddrType::IPV6) if (endpoint.version == IP::V6)
Bind_v6(address, port); Bind_v6(endpoint.address, endpoint.port);
else if (type == AddrType::IPV4) else if (endpoint.version == IP::V4)
Bind_v4(address, port); Bind_v4(endpoint.address, endpoint.port);
this->address = address; localEndpoint = endpoint;
this->port = port;
bound = true; 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) if (endpoint.version == IP::V6)
return Send_v6(address, port, data, size); return Send_v6(endpoint.address, endpoint.port, data, size);
else if (type == AddrType::IPV4) else if (endpoint.version == IP::V4)
return Send_v4(address, port, data, size); return Send_v4(endpoint.address, endpoint.port, data, size);
return 0; 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()) if (!IsValid())
{ {
@@ -174,9 +173,11 @@ namespace ehs
return received; return received;
} }
*type = AddrType::IPV6; *endpoint = {
*address = tmpAddr; IP::V6,
*port = ntohs(remote.sin6_port); tmpAddr,
ntohs(remote.sin6_port)
};
} }
else if (addrLen == sizeof(sockaddr_in)) else if (addrLen == sizeof(sockaddr_in))
{ {
@@ -191,9 +192,11 @@ namespace ehs
return received; return received;
} }
*type = AddrType::IPV4; *endpoint = {
*address = tmpAddr; IP::V4,
*port = ntohs(((sockaddr_in*)&remote)->sin_port); tmpAddr,
ntohs(((sockaddr_in*)&remote)->sin_port)
};
} }
return received; return received;
@@ -225,7 +228,7 @@ namespace ehs
void UDP::SetIPv6Only(const bool value) 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."); EHS_LOG_INT(LogType::WARN, 0, "Cannot set IPv6 only mode while socket is not using IPv6.");
return; return;
@@ -249,7 +252,7 @@ namespace ehs
bool UDP::IsIPv6Only() const bool UDP::IsIPv6Only() const
{ {
if (type != AddrType::IPV6) if (localEndpoint.version != IP::V6)
return false; return false;
if (!IsValid()) if (!IsValid())
@@ -362,7 +365,7 @@ namespace ehs
Int_32 code = inet_pton(AF_INET6, addr, &result.sin6_addr); Int_32 code = inet_pton(AF_INET6, addr, &result.sin6_addr);
if (!code) 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; return 0;
} }
else if (code == -1) else if (code == -1)
@@ -403,7 +406,7 @@ namespace ehs
int code = inet_pton(AF_INET, addr, &result.sin_addr); int code = inet_pton(AF_INET, addr, &result.sin_addr);
if (!code) 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; return 0;
} }
else if (code == -1) 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 namespace ehs
{ {
NetEnc::NetEnc() NetEnc::NetEnc()
: owner(nullptr), hashId(0) : id(0)
{ {
} }
NetEnc::NetEnc(Str_8 id) NetEnc::NetEnc(Str_8 name, const Version &version)
: owner(nullptr), hashId(id.Hash_64()), id((Str_8 &&)id) : id(name.Hash_64()), name((Str_8 &&)name), version(version)
{ {
} }
NetEnc::NetEnc(NetEnc&& enc) noexcept 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.id = 0;
enc.hashId = 0; enc.version = {};
} }
NetEnc::NetEnc(const NetEnc& enc) 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) if (this == &enc)
return *this; return *this;
owner = enc.owner; id = enc.id;
hashId = enc.hashId; name = (Str_8 &&)enc.name;
id = (Str_8 &&)enc.id; version = enc.version;
enc.owner = nullptr; enc.id = 0;
enc.hashId = 0; enc.version = {};
return *this; return *this;
} }
@@ -44,28 +44,28 @@ namespace ehs
if (this == &enc) if (this == &enc)
return *this; return *this;
owner = nullptr;
hashId = enc.hashId;
id = enc.id; id = enc.id;
name = enc.name;
version = enc.version;
return *this; return *this;
} }
EHC* NetEnc::GetOwner() const UInt_64 NetEnc::GetId() const
{
return owner;
}
UInt_64 NetEnc::GetHashId() const
{
return hashId;
}
Str_8 NetEnc::GetId() const
{ {
return id; return id;
} }
Str_8 NetEnc::GetName() const
{
return name;
}
Version NetEnc::GetVersion() const
{
return version;
}
void NetEnc::Encrypt(Byte *data, UInt_64 size) const 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/NetEnd.h"
#include "ehs/io/socket/EHC.h" #include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnc.h" #include "ehs/io/socket/ehc/NetEnc.h"
#include "ehs/io/socket/ehc/NetServerCh.h"
#include "ehs/system/CPU.h" #include "ehs/system/CPU.h"
namespace ehs namespace ehs
{ {
NetEnd::NetEnd() NetEnd::NetEnd()
: owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(0), status(Status::PENDING), : owner(nullptr), id(0), status(NetStatus::PENDING), token{}, nextSendId(0), nextRecvId(0),
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),
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),
latency(0.0f), queueSlot(0) 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 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), 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), deltaDuration(end.deltaDuration), deltaRate(end.deltaRate), timeout(end.timeout), lastPing(end.lastPing),
oldLatency(end.oldLatency), latency(end.latency), queueSlot(end.queueSlot) oldLatency(end.oldLatency), latency(end.latency), queueSlot(end.queueSlot)
{ {
end.owner = nullptr; end.owner = nullptr;
end.disposition = EndDisp::ENDPOINT; end.id = 0;
end.hashName = 0; end.status = NetStatus::PENDING;
end.status = Status::PENDING;
end.arch = Architecture::UNKNOWN;
Util::Copy(token, end.token, 64); Util::Copy(token, end.token, 64);
Util::Zero(end.token, 64); Util::Zero(end.token, 64);
end.nextSendId = 0; end.nextSendId = 0;
end.nextRecvId = 0; end.nextRecvId = 0;
end.type = AddrType::IPV6;
end.port = 0;
end.deltaDuration = 0.0f; end.deltaDuration = 0.0f;
end.deltaRate = 1.0f / 60.0f; end.deltaRate = 1.0f / 60.0f;
end.timeout = 0.0f; end.timeout = 0.0f;
@@ -58,9 +51,9 @@ namespace ehs
} }
NetEnd::NetEnd(const NetEnd& end) NetEnd::NetEnd(const NetEnd& end)
: owner(nullptr), disposition(EndDisp::ENDPOINT), hashName(end.hashName), name(end.name), status(Status::PENDING), arch(Architecture::UNKNOWN), : owner(nullptr), id(end.id), name(end.name), status(NetStatus::PENDING), token{}, nextSendId(0),
token{}, nextSendId(0), nextRecvId(0), type(end.type), port(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), nextRecvId(0), deltaDuration(0.0f), deltaRate(1.0f / 60.0f), timeout(0.0f), lastPing(0.0f), oldLatency(0.0f),
timeout(0.0f), lastPing(0.0f), oldLatency(0.0f), latency(0.0f), queueSlot(0) latency(0.0f), queueSlot(0)
{ {
} }
@@ -70,19 +63,15 @@ namespace ehs
return *this; return *this;
owner = end.owner; owner = end.owner;
disposition = end.disposition; id = end.id;
hashName = end.hashName;
name = (Str_8&&)end.name; name = (Str_8&&)end.name;
status = end.status; status = end.status;
arch = end.arch;
Util::Copy(token, end.token, 64); Util::Copy(token, end.token, 64);
nextSendId = end.nextSendId; nextSendId = end.nextSendId;
sent = (Vector<Insurance>&&)end.sent; sent = (Vector<Insurance>&&)end.sent;
nextRecvId = end.nextRecvId; nextRecvId = end.nextRecvId;
received = (Vector<NetFrags>&&)end.received; received = (Vector<NetFrag>&&)end.received;
type = end.type; endpoint = (Endpoint &&)end.endpoint;
address = (Str_8&&)end.address;
port = end.port;
deltaDuration = end.deltaDuration; deltaDuration = end.deltaDuration;
deltaRate = end.deltaRate; deltaRate = end.deltaRate;
timeout = end.timeout; timeout = end.timeout;
@@ -92,15 +81,11 @@ namespace ehs
queueSlot = end.queueSlot; queueSlot = end.queueSlot;
end.owner = nullptr; end.owner = nullptr;
end.disposition = EndDisp::ENDPOINT; end.id = 0;
end.hashName = 0; end.status = NetStatus::PENDING;
end.status = Status::PENDING;
end.arch = Architecture::UNKNOWN;
Util::Zero(end.token, 64); Util::Zero(end.token, 64);
end.nextSendId = 0; end.nextSendId = 0;
end.nextRecvId = 0; end.nextRecvId = 0;
end.type = AddrType::IPV6;
end.port = 0;
end.deltaDuration = 0.0f; end.deltaDuration = 0.0f;
end.deltaRate = 1.0f / 60.0f; end.deltaRate = 1.0f / 60.0f;
end.timeout = 0.0f; end.timeout = 0.0f;
@@ -118,19 +103,15 @@ namespace ehs
return *this; return *this;
owner = nullptr; owner = nullptr;
disposition = EndDisp::ENDPOINT; id = end.id;
hashName = end.hashName;
name = end.name; name = end.name;
status = Status::PENDING; status = NetStatus::PENDING;
arch = Architecture::UNKNOWN;
Util::Zero(token, 64); Util::Zero(token, 64);
nextSendId = 0; nextSendId = 0;
sent = {}; sent = {};
nextRecvId = 0; nextRecvId = 0;
received = {}; received = {};
type = AddrType::IPV6; endpoint = {};
address = {};
port = 0;
deltaDuration = 0.0f; deltaDuration = 0.0f;
deltaRate = 1.0f / 60.0f; deltaRate = 1.0f / 60.0f;
timeout = 0.0f; timeout = 0.0f;
@@ -142,14 +123,9 @@ namespace ehs
return *this; return *this;
} }
EndDisp NetEnd::GetDisposition() const UInt_64 NetEnd::GetId() const
{ {
return disposition; return id;
}
UInt_64 NetEnd::GetHashName() const
{
return hashName;
} }
Str_8 NetEnd::GetName() const Str_8 NetEnd::GetName() const
@@ -157,44 +133,54 @@ namespace ehs
return name; return name;
} }
Status NetEnd::GetStatus() const NetStatus NetEnd::GetStatus() const
{ {
return status; return status;
} }
Architecture NetEnd::GetArchitecture() const
{
return arch;
}
UInt_64 NetEnd::GetNextSendId() const UInt_64 NetEnd::GetNextSendId() const
{ {
return nextSendId; return nextSendId;
} }
void NetEnd::Send(const bool deltaLocked, const UInt_64 encHashId, const bool ensure, const UInt_64 sys, void NetEnd::Send(const bool deltaLocked, const UInt_64 encId, const bool ensure, const UInt_64 sysId,
const UInt_64 op, const Serializer<UInt_64> &payload) const UInt_64 opId, const Serializer<UInt_64> &payload)
{ {
if (deltaLocked && deltaDuration < deltaRate) if (!owner || !owner->GetOwner() || (deltaLocked && deltaDuration < deltaRate))
return; 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 = { Header header = {
encHashId, EHC::GetVersion(),
encId,
enc->GetVersion(),
GetId(),
NetChannelType::SERVER,
GetVersion(),
nextSendId++, nextSendId++,
1, 1,
0, 0,
ensure, ensure,
owner->GetDisposition(),
"", "",
sys, sysId,
op opId
}; };
Util::Copy(header.token, token, 64); 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) for (UInt_64 i = 0; i < frags.Size(); ++i)
{ {
Header newHeader = frags.GetHeader(); 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, void NetEnd::Send(const bool deltaLocked, const Str_8 &encName, const bool ensure, const Str_8& sysName,
const Str_8& op, const Serializer<>& payload) 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 UInt_64 NetEnd::GetNextRecvId() const
@@ -220,14 +206,9 @@ namespace ehs
return nextRecvId; return nextRecvId;
} }
Str_8 NetEnd::GetAddress() const Endpoint NetEnd::GetEndpoint() const
{ {
return address; return endpoint;
}
UInt_16 NetEnd::GetPort() const
{
return port;
} }
float NetEnd::GetDeltaRate() const float NetEnd::GetDeltaRate() const
@@ -273,17 +254,21 @@ namespace ehs
sent[i].lastResend += delta; sent[i].lastResend += delta;
if (sent[i].lastResend >= owner->GetResendRate()) if (sent[i].lastResend >= owner->GetResendRate())
{ {
EHC *ehc = owner->GetOwner();
Serializer result(Endianness::LE); Serializer result(Endianness::LE);
result.Write(sent[i].header); result.Write(sent[i].header);
result.WriteSer(sent[i].payload); 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) if (!enc)
{ {
EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " + 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; continue;
} }
@@ -291,24 +276,21 @@ namespace ehs
enc->Encrypt(&result[sizeof(bool)], result.Size() - sizeof(bool)); 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()); sent[i].lastResend = Math::Mod(sent[i].lastResend, owner->GetResendRate());
} }
} }
} }
if (owner->GetDisposition() == EndDisp::SERVICE)
{
lastPing += delta; lastPing += delta;
if (lastPing >= 1.0f) if (lastPing >= 1.0f)
Ping(delta); Ping(delta);
}
EHS_LOG_SUCCESS(); EHS_LOG_SUCCESS();
} }
void NetEnd::SetStatus(const Status newStatus) void NetEnd::SetStatus(const NetStatus newStatus)
{ {
status = newStatus; status = newStatus;
} }
@@ -329,7 +311,7 @@ namespace ehs
void NetEnd::AddReceived(const Header& header, const Serializer<>& payload) void NetEnd::AddReceived(const Header& header, const Serializer<>& payload)
{ {
NetFrags* frags = nullptr; NetFrag* frags = nullptr;
for (UInt_64 i = 0; i < received.Size(); ++i) for (UInt_64 i = 0; i < received.Size(); ++i)
{ {
@@ -354,7 +336,7 @@ namespace ehs
timeout = 0.0f; timeout = 0.0f;
} }
Vector<NetFrags>* NetEnd::GetReceived() Vector<NetFrag>* NetEnd::GetReceived()
{ {
return &received; return &received;
} }
@@ -374,16 +356,6 @@ namespace ehs
latency = 0.0f; 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() void NetEnd::SendLatency()
{ {
oldLatency = latency * 1000; oldLatency = latency * 1000;
@@ -407,17 +379,19 @@ namespace ehs
queueSlot = slot; 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; UInt_64 frags = data.Size() / EHC_IPV6_PAYLOAD;
if (data.Size() % EHC_IPV6_PAYLOAD) if (data.Size() % EHC_IPV6_PAYLOAD)
++frags; ++frags;
result = NetFrags(header, frags); result = NetFrag(header, frags);
UInt_64 size = EHC_IPV6_PAYLOAD; UInt_64 size = EHC_IPV6_PAYLOAD;
@@ -430,13 +404,13 @@ namespace ehs
result[i] = {data.GetEndianness(), &data[i * EHC_IPV6_PAYLOAD], size}; 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; UInt_64 frags = data.Size() / EHC_IPV4_PAYLOAD;
if (data.Size() % EHC_IPV4_PAYLOAD) if (data.Size() % EHC_IPV4_PAYLOAD)
++frags; ++frags;
result = NetFrags(header, frags); result = NetFrag(header, frags);
UInt_64 size = EHC_IPV4_PAYLOAD; UInt_64 size = EHC_IPV4_PAYLOAD;
@@ -455,17 +429,19 @@ namespace ehs
void NetEnd::Send(const Header& header, const Serializer<UInt_64>& payload) void NetEnd::Send(const Header& header, const Serializer<UInt_64>& payload)
{ {
EHC *ehc = owner->GetOwner();
Serializer result(Endianness::LE); Serializer result(Endianness::LE);
result.Write(header); result.Write(header);
result.WriteSer(payload); result.WriteSer(payload);
if (header.encHashId) if (header.encId)
{ {
NetEnc *enc = owner->GetEncryption(header.encHashId); NetEnc *enc = ehc->GetEncryption(header.encId);
if (!enc) if (!enc)
{ {
EHS_LOG_INT(LogType::WARN, 0, "The network encryption with the hash id " + 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; return;
} }
@@ -476,7 +452,7 @@ namespace ehs
if (header.ensure) if (header.ensure)
sent.Push({header, payload}); sent.Push({header, payload});
owner->udp.Send(type, address, port, result, result.Size()); ehc->udp.Send(endpoint, result, result.Size());
} }
bool NetEnd::SortingNeeded() const bool NetEnd::SortingNeeded() const
@@ -499,7 +475,7 @@ namespace ehs
if (!SortingNeeded()) if (!SortingNeeded())
return; return;
Vector<NetFrags> sorted(0, received.Stride()); Vector<NetFrag> sorted(0, received.Stride());
for (UInt_64 a = 0; a < received.Size(); ++a) 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 namespace ehs
{ {
NetFrags::~NetFrags() NetFrag::~NetFrag()
{ {
delete[] data; delete[] data;
} }
NetFrags::NetFrags() NetFrag::NetFrag()
: data(nullptr), size(0) : data(nullptr), size(0)
{ {
} }
NetFrags::NetFrags(const Header &header, const Serializer<UInt_64> &payload) NetFrag::NetFrag(const Header &header, const Serializer<UInt_64> &payload)
: header(header), data(new Serializer<UInt_64>[header.fragments]), size(header.fragments) : header(header), data(new Serializer<UInt_64>[header.fragmentCount]), size(header.fragmentCount)
{ {
this->header.fragment = 0; this->header.fragment = 0;
data[header.fragment] = payload; 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) : header(header), data(new Serializer<UInt_64>[size]), size(size)
{ {
this->header.fragments = size; this->header.fragmentCount = size;
this->header.fragment = 0; this->header.fragment = 0;
} }
NetFrags::NetFrags(NetFrags &&frags) noexcept NetFrag::NetFrag(NetFrag &&frags) noexcept
: header(frags.header), data(frags.data), size(frags.size) : header(frags.header), data(frags.data), size(frags.size)
{ {
frags.header = {}; frags.header = {};
@@ -34,14 +34,14 @@ namespace ehs
frags.size = 0; 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) : header(frags.header), data(new Serializer<UInt_64>[frags.size]), size(frags.size)
{ {
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
data[i] = frags.data[i]; data[i] = frags.data[i];
} }
NetFrags &NetFrags::operator=(NetFrags &&frags) noexcept NetFrag &NetFrag::operator=(NetFrag &&frags) noexcept
{ {
if (this == &frags) if (this == &frags)
return *this; return *this;
@@ -60,7 +60,7 @@ namespace ehs
return *this; return *this;
} }
NetFrags &NetFrags::operator=(const NetFrags &frags) NetFrag &NetFrag::operator=(const NetFrag &frags)
{ {
if (this == &frags) if (this == &frags)
return *this; return *this;
@@ -75,22 +75,22 @@ namespace ehs
return *this; return *this;
} }
NetFrags::operator Serializer<UInt_64> *() const NetFrag::operator Serializer<UInt_64> *() const
{ {
return data; return data;
} }
Header NetFrags::GetHeader() const Header NetFrag::GetHeader() const
{ {
return header; return header;
} }
UInt_64 NetFrags::Size() const UInt_64 NetFrag::Size() const
{ {
return size; return size;
} }
bool NetFrags::IsComplete() const bool NetFrag::IsComplete() const
{ {
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
if (!data[i].Size()) if (!data[i].Size())
@@ -99,7 +99,7 @@ namespace ehs
return true; return true;
} }
Packet NetFrags::Combine() const Packet NetFrag::Combine() const
{ {
UInt_64 rSize = 0; UInt_64 rSize = 0;
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
@@ -110,7 +110,7 @@ namespace ehs
header, header,
{Endianness::LE, rSize} {Endianness::LE, rSize}
}; };
result.header.fragments = 0; result.header.fragmentCount = 0;
for (UInt_64 i = 0; i < size; ++i) for (UInt_64 i = 0; i < size; ++i)
result.payload.WriteSer(data[i]); result.payload.WriteSer(data[i]);

View File

@@ -1,28 +1,27 @@
#include "ehs/io/socket/ehc/NetOp.h" #include "ehs/io/socket/ehc/NetOp.h"
#include "ehs/io/socket/EHC.h" #include "ehs/io/socket/EHC.h"
#include "ehs/io/socket/ehc/NetEnd.h" #include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetSys.h"
namespace ehs namespace ehs
{ {
NetOp::NetOp() NetOp::NetOp()
: hashId(0) : id(0)
{ {
} }
NetOp::NetOp(Str_8 id) NetOp::NetOp(Str_8 name)
: hashId(id.Hash_64()), id((Str_8 &&)id) : id(name.Hash_64()), name((Str_8 &&)name)
{ {
} }
NetOp::NetOp(NetOp&& op) noexcept 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) 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) if (this == &op)
return *this; return *this;
hashId = op.hashId; id = op.id;
id = (Str_8 &&)op.id; name = (Str_8 &&)op.name;
op.hashId = 0; op.id = 0;
return *this; return *this;
} }
@@ -44,23 +43,23 @@ namespace ehs
if (this == &op) if (this == &op)
return *this; return *this;
hashId = op.hashId;
id = op.id; id = op.id;
name = op.name;
return *this; return *this;
} }
Str_8 NetOp::GetId() const UInt_64 NetOp::GetId() const
{ {
return id; 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.h"
#include "ehs/io/socket/ehc/NetEnd.h" #include "ehs/io/socket/ehc/NetEnd.h"
#include "ehs/io/socket/ehc/NetOp.h" #include "ehs/io/socket/ehc/NetOp.h"
#include "ehs/io/socket/ehc/NetChannel.h"
namespace ehs namespace ehs
{ {
@@ -14,23 +15,23 @@ namespace ehs
} }
NetSys::NetSys() NetSys::NetSys()
: hashId(0) : id(0)
{ {
} }
NetSys::NetSys(Str_8 id) NetSys::NetSys(Str_8 name)
: hashId(id.Hash_64()), id((Str_8&&)id) : id(name.Hash_64()), name((Str_8&&)name)
{ {
} }
NetSys::NetSys(NetSys&& sys) noexcept 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) 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) if (this == &sys)
return *this; return *this;
hashId = sys.hashId; id = sys.id;
id = (Str_8&&)sys.id; name = (Str_8&&)sys.name;
ops = (Array<NetOp*>&&)sys.ops; ops = (Array<NetOp*>&&)sys.ops;
sys.hashId = 0; sys.id = 0;
return *this; return *this;
} }
@@ -53,27 +54,27 @@ namespace ehs
if (this == &sys) if (this == &sys)
return *this; return *this;
hashId = sys.hashId;
id = sys.id; id = sys.id;
name = sys.name;
ops = Array<NetOp*>(); ops = Array<NetOp*>();
return *this; return *this;
} }
Str_8 NetSys::GetId() const UInt_64 NetSys::GetId() const
{ {
return id; 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) for (UInt_64 i = 0; i < ops.Size(); ++i)
if (ops[i]->GetHashId() == hashId) if (ops[i]->GetId() == id)
return true; return true;
return false; return false;
@@ -81,7 +82,7 @@ namespace ehs
bool NetSys::AddOperation(NetOp* op) bool NetSys::AddOperation(NetOp* op)
{ {
if (HasOperation(op->GetHashId())) if (HasOperation(op->GetId()))
return false; return false;
ops.Push(op); ops.Push(op);
@@ -89,13 +90,13 @@ namespace ehs
return true; 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) 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; 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) 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) scopes((Array<Str_8> &&)scopes), forceVerify(forceVerify)
{ {
} }
@@ -41,7 +41,7 @@ namespace ehs
"&response_type=code&show_dialog=" + (forceVerify ? "true" : "false") + "&scope=" + "&response_type=code&show_dialog=" + (forceVerify ? "true" : "false") + "&scope=" +
scopesFinal; scopesFinal;
TCP server(AddrType::IPV4); TCP server(IP::V4);
server.Initialize(); server.Initialize();
server.Bind("", 65534); server.Bind("", 65534);
server.Listen(); server.Listen();
@@ -73,7 +73,7 @@ namespace ehs
server.Release(); server.Release();
SSL accounts(AddrType::IPV4); SSL accounts(IP::V4);
accounts.Initialize(); accounts.Initialize();
accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port); accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port);
@@ -81,7 +81,7 @@ namespace ehs
authReq.SetContentType(ContentType::APP_FORMURLENCODED); authReq.SetContentType(ContentType::APP_FORMURLENCODED);
authReq.BasicAuth(clientId, secret); authReq.BasicAuth(clientId, secret);
authReq.AddToBody("grant_type", "authorization_code"); authReq.AddToBody("grant_type", "authorization_code");
authReq.AddToBody("code", cbReq.GetQuery("code")); authReq.AddToBody("code", cbReq.GetQueryValue("code"));
authReq.AddToBody("redirect_uri", rURI); authReq.AddToBody("redirect_uri", rURI);
accounts.SendReq(authReq); accounts.SendReq(authReq);
@@ -134,7 +134,7 @@ namespace ehs
StartConnection(); StartConnection();
Request req(Verb::PUT, "/v1/me/player/volume"); 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); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -206,7 +206,7 @@ namespace ehs
} }
Request req(Verb::PUT, "/v1/me/player/repeat"); Request req(Verb::PUT, "/v1/me/player/repeat");
req.AddQuery("state", result); req.AddQueryVar({"state", result});
req.BearerAuth(token); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -226,7 +226,7 @@ namespace ehs
StartConnection(); StartConnection();
Request req(Verb::PUT, "/v1/me/player/repeat"); Request req(Verb::PUT, "/v1/me/player/repeat");
req.AddQuery("state", state ? "true" : "false"); req.AddQueryVar({"state", state ? "true" : "false"});
req.BearerAuth(token); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -258,10 +258,10 @@ namespace ehs
q += "+track%3A" + name.ReplaceAll(" ", "+"); q += "+track%3A" + name.ReplaceAll(" ", "+");
req.AddQuery("q", q); req.AddQueryVar({"q", q});
req.AddQuery("type", "track"); req.AddQueryVar({"type", "track"});
req.AddQuery("limit", "1"); req.AddQueryVar({"limit", "1"});
req.AddQuery("offset", "0"); req.AddQueryVar({"offset", "0"});
req.BearerAuth(token); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -454,7 +454,7 @@ namespace ehs
StartConnection(); StartConnection();
Request req(Verb::POST, "/v1/me/player/queue"); Request req(Verb::POST, "/v1/me/player/queue");
req.AddQuery("uri", "spotify:track:" + id); req.AddQueryVar({"uri", "spotify:track:" + id});
req.BearerAuth(token); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -505,8 +505,8 @@ namespace ehs
StartConnection(); StartConnection();
Request req(Verb::POST, "/v1/playlists/" + playlistId + "/tracks"); Request req(Verb::POST, "/v1/playlists/" + playlistId + "/tracks");
req.AddQuery("position", Str_8::FromNum(pos)); req.AddQueryVar({"position", Str_8::FromNum(pos)});
req.AddQuery("uris", "spotify:track:" + trackId); req.AddQueryVar({"uris", "spotify:track:" + trackId});
req.BearerAuth(token); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -564,7 +564,7 @@ namespace ehs
StartConnection(); StartConnection();
Request req(Verb::PUT, "/v1/me/player/seek"); 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); req.BearerAuth(token);
client.SendReq(req); client.SendReq(req);
@@ -588,7 +588,7 @@ namespace ehs
bool Spotify::ReAuthorize() bool Spotify::ReAuthorize()
{ {
SSL accounts(AddrType::IPV4); SSL accounts(IP::V4);
accounts.Initialize(); accounts.Initialize();
accounts.Connect("accounts.spotify.com", SSL::HTTPS_Port); 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) 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=" + "&response_type=code&force_verify=" + (forceVerify ? "true" : "false") + "&scope=" +
scopesFinal; scopesFinal;
TCP server(AddrType::IPV4); TCP server(IP::V4);
server.Bind("", 65535); server.Bind("", 65535);
server.Listen(); server.Listen();
@@ -78,7 +78,7 @@ namespace ehs
authReq.SetContentType(ContentType::APP_FORMURLENCODED); authReq.SetContentType(ContentType::APP_FORMURLENCODED);
authReq.AddToBody("client_id", clientId); authReq.AddToBody("client_id", clientId);
authReq.AddToBody("client_secret", secret); 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("grant_type", "authorization_code");
authReq.AddToBody("redirect_uri", redURI); authReq.AddToBody("redirect_uri", redURI);

View File

@@ -53,7 +53,7 @@ namespace ehs
if (initialized) if (initialized)
return; return;
client = TCP(ehs::AddrType::IPV4); client = TCP(ehs::IP::V4);
client.Connect(DNS::Resolve("irc.chat.twitch.tv"), 6667); client.Connect(DNS::Resolve("irc.chat.twitch.tv"), 6667);
client.SetBlocking(false); 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 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; UInt_64 CPU::TSC_Freq = 0;
#endif #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() Architecture CPU::GetArchitecture()
{ {
#if defined(EHS_ARCH_X64) #if defined(EHS_ARCH_X64)
return Architecture::X64; return Architecture::X64;
#elif defined(EHS_ARCH_ARM64) #elif defined(EHS_ARCH_AARCH64)
return Architecture::ARM64; return Architecture::ARM64;
#else #else
return Architecture::UNKNOWN; return Architecture::UNKNOWN;
@@ -49,13 +113,19 @@ namespace ehs
return frequency.QuadPart; return frequency.QuadPart;
#elif defined(EHS_OS_LINUX) #elif defined(EHS_OS_LINUX)
#if defined(EHS_ARCH_X64)
if (!TSC_Freq) if (!TSC_Freq)
TSC_Freq = RetrieveTSC_Freq(); TSC_Freq = RetrieveTSC_Freq();
return TSC_Freq; return TSC_Freq;
#endif #elif defined(EHS_ARCH_AARCH64)
return RetrieveFreq_AARCH64();
#else
return 0; return 0;
#endif
#else
return 0;
#endif
} }
UInt_64 CPU::GetTSC() UInt_64 CPU::GetTSC()
@@ -69,7 +139,7 @@ namespace ehs
TSC tsc; TSC tsc;
RDTSCP(&tsc); RDTSCP(&tsc);
#if defined(EHS_ARCH_X64) #if defined(EHS_ARCH_X64) || defined(EHS_ARCH_AARCH64)
UInt_64 result = 0; UInt_64 result = 0;
#if defined(EHS_LITTLE_ENDIAN) #if defined(EHS_LITTLE_ENDIAN)
@@ -119,324 +189,589 @@ namespace ehs
return (UInt_8)(GetInfoBits() >> 20); return (UInt_8)(GetInfoBits() >> 20);
} }
bool CPU::HasFPU() bool CPU::RetrieveFPU()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000000001; return GetFeatureBits_1() & 0b00000000000000000000000000000001;
#else
return false;
#endif
} }
bool CPU::HasVME() bool CPU::RetrieveVME()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000000010; return GetFeatureBits_1() & 0b00000000000000000000000000000010;
#else
return false;
#endif
} }
bool CPU::HasDE() bool CPU::RetrieveDE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000000100; return GetFeatureBits_1() & 0b00000000000000000000000000000100;
#else
return false;
#endif
} }
bool CPU::HasPSE() bool CPU::RetrievePSE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000001000; return GetFeatureBits_1() & 0b00000000000000000000000000001000;
#else
return false;
#endif
} }
bool CPU::HasTSC() bool CPU::RetrieveTSC()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000010000; return GetFeatureBits_1() & 0b00000000000000000000000000010000;
#else
return false;
#endif
} }
bool CPU::HasMSR() bool CPU::RetrieveMSR()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000000100000; return GetFeatureBits_1() & 0b00000000000000000000000000100000;
#else
return false;
#endif
} }
bool CPU::HasPAE() bool CPU::RetrievePAE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000001000000; return GetFeatureBits_1() & 0b00000000000000000000000001000000;
#else
return false;
#endif
} }
bool CPU::HasMCE() bool CPU::RetrieveMCE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000010000000; return GetFeatureBits_1() & 0b00000000000000000000000010000000;
#else
return false;
#endif
} }
bool CPU::HasCX8() bool CPU::RetrieveCX8()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000000100000000; return GetFeatureBits_1() & 0b00000000000000000000000100000000;
#else
return false;
#endif
} }
bool CPU::HasAPIC() bool CPU::RetrieveAPIC()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000001000000000; return GetFeatureBits_1() & 0b00000000000000000000001000000000;
#else
return false;
#endif
} }
bool CPU::HasSEP() bool CPU::RetrieveSEP()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000000100000000000; return GetFeatureBits_1() & 0b00000000000000000000100000000000;
#else
return false;
#endif
} }
bool CPU::HasMTRR() bool CPU::RetrieveMTRR()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000001000000000000; return GetFeatureBits_1() & 0b00000000000000000001000000000000;
#else
return false;
#endif
} }
bool CPU::HasPGE() bool CPU::RetrievePGE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000010000000000000; return GetFeatureBits_1() & 0b00000000000000000010000000000000;
#else
return false;
#endif
} }
bool CPU::HasMCA() bool CPU::RetrieveMCA()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000000100000000000000; return GetFeatureBits_1() & 0b00000000000000000100000000000000;
#else
return false;
#endif
} }
bool CPU::HasCMOV() bool CPU::RetrieveCMOV()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000001000000000000000; return GetFeatureBits_1() & 0b00000000000000001000000000000000;
#else
return false;
#endif
} }
bool CPU::HasPAT() bool CPU::RetrievePAT()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000010000000000000000; return GetFeatureBits_1() & 0b00000000000000010000000000000000;
#else
return false;
#endif
} }
bool CPU::HasPSE_36() bool CPU::RetrievePSE_36()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000000100000000000000000; return GetFeatureBits_1() & 0b00000000000000100000000000000000;
#else
return false;
#endif
} }
bool CPU::HasPSN() bool CPU::RetrievePSN()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000001000000000000000000; return GetFeatureBits_1() & 0b00000000000001000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasCLFSH() bool CPU::RetrieveCLFSH()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000000010000000000000000000; return GetFeatureBits_1() & 0b00000000000010000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasDS() bool CPU::RetrieveDS()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000001000000000000000000000; return GetFeatureBits_1() & 0b00000000001000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasACPI() bool CPU::RetrieveACPI()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000010000000000000000000000; return GetFeatureBits_1() & 0b00000000010000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasMMX() bool CPU::RetrieveMMX()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000000100000000000000000000000; return GetFeatureBits_1() & 0b00000000100000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasFXSR() bool CPU::RetrieveFXSR()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000001000000000000000000000000; return GetFeatureBits_1() & 0b00000001000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasSSE() bool CPU::RetrieveSSE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000010000000000000000000000000; return GetFeatureBits_1() & 0b00000010000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasSSE2() bool CPU::RetrieveSSE2()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00000100000000000000000000000000; return GetFeatureBits_1() & 0b00000100000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasSS() bool CPU::RetrieveSS()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00001000000000000000000000000000; return GetFeatureBits_1() & 0b00001000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasHTT() bool CPU::RetrieveHTT()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00010000000000000000000000000000; return GetFeatureBits_1() & 0b00010000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasTM() bool CPU::RetrieveTM()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b00100000000000000000000000000000; return GetFeatureBits_1() & 0b00100000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasIA64() bool CPU::RetrieveIA64()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b01000000000000000000000000000000; return GetFeatureBits_1() & 0b01000000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasPBE() bool CPU::RetrievePBE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_1() & 0b10000000000000000000000000000000; return GetFeatureBits_1() & 0b10000000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasSSE3() bool CPU::RetrieveSSE3()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000000001; return GetFeatureBits_2() & 0b00000000000000000000000000000001;
#else
return false;
#endif
} }
bool CPU::HasPCLMULQDQ() bool CPU::RetrievePCLMULQDQ()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000000010; return GetFeatureBits_2() & 0b00000000000000000000000000000010;
#else
return false;
#endif
} }
bool CPU::HasDTES64() bool CPU::RetrieveDTES64()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000000100; return GetFeatureBits_2() & 0b00000000000000000000000000000100;
#else
return false;
#endif
} }
bool CPU::HasMONITOR() bool CPU::RetrieveMONITOR()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000001000; return GetFeatureBits_2() & 0b00000000000000000000000000001000;
#else
return false;
#endif
} }
bool CPU::HasDS_CPL() bool CPU::RetrieveDS_CPL()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000010000; return GetFeatureBits_2() & 0b00000000000000000000000000010000;
#else
return false;
#endif
} }
bool CPU::HasVMX() bool CPU::RetrieveVMX()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000000100000; return GetFeatureBits_2() & 0b00000000000000000000000000100000;
#else
return false;
#endif
} }
bool CPU::HasSMX() bool CPU::RetrieveSMX()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000001000000; return GetFeatureBits_2() & 0b00000000000000000000000001000000;
#else
return false;
#endif
} }
bool CPU::HasEST() bool CPU::RetrieveEST()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000010000000; return GetFeatureBits_2() & 0b00000000000000000000000010000000;
#else
return false;
#endif
} }
bool CPU::HasTM2() bool CPU::RetrieveTM2()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000000100000000; return GetFeatureBits_2() & 0b00000000000000000000000100000000;
#else
return false;
#endif
} }
bool CPU::HasSSSE3() bool CPU::RetrieveSSSE3()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000001000000000; return GetFeatureBits_2() & 0b00000000000000000000001000000000;
#else
return false;
#endif
} }
bool CPU::HasCNXT_ID() bool CPU::RetrieveCNXT_ID()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000010000000000; return GetFeatureBits_2() & 0b00000000000000000000010000000000;
#else
return false;
#endif
} }
bool CPU::HasSDBG() bool CPU::RetrieveSDBG()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000000100000000000; return GetFeatureBits_2() & 0b00000000000000000000100000000000;
#else
return false;
#endif
} }
bool CPU::HasFMA() bool CPU::RetrieveFMA()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000001000000000000; return GetFeatureBits_2() & 0b00000000000000000001000000000000;
#else
return false;
#endif
} }
bool CPU::HasCX16() bool CPU::RetrieveCX16()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000010000000000000; return GetFeatureBits_2() & 0b00000000000000000010000000000000;
#else
return false;
#endif
} }
bool CPU::HasXTPR() bool CPU::RetrieveXTPR()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000000100000000000000; return GetFeatureBits_2() & 0b00000000000000000100000000000000;
#else
return false;
#endif
} }
bool CPU::HasPDCM() bool CPU::RetrievePDCM()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000001000000000000000; return GetFeatureBits_2() & 0b00000000000000001000000000000000;
#else
return false;
#endif
} }
bool CPU::HasPCID() bool CPU::RetrievePCID()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000000100000000000000000; return GetFeatureBits_2() & 0b00000000000000100000000000000000;
#else
return false;
#endif
} }
bool CPU::HasDCA() bool CPU::RetrieveDCA()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000001000000000000000000; return GetFeatureBits_2() & 0b00000000000001000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasSSE4_1() bool CPU::RetrieveSSE4_1()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000010000000000000000000; return GetFeatureBits_2() & 0b00000000000010000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasSSE4_2() bool CPU::RetrieveSSE4_2()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000000100000000000000000000; return GetFeatureBits_2() & 0b00000000000100000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasX2APIC() bool CPU::RetrieveX2APIC()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000001000000000000000000000; return GetFeatureBits_2() & 0b00000000001000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasMOVBE() bool CPU::RetrieveMOVBE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000010000000000000000000000; return GetFeatureBits_2() & 0b00000000010000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasPOPCNT() bool CPU::RetrievePOPCNT()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000000100000000000000000000000; return GetFeatureBits_2() & 0b00000000100000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasTSC_DEADLINE() bool CPU::RetrieveTSC_DEADLINE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000001000000000000000000000000; return GetFeatureBits_2() & 0b00000001000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasAES() bool CPU::RetrieveAES()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000010000000000000000000000000; return GetFeatureBits_2() & 0b00000010000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasXSAVE() bool CPU::RetrieveXSAVE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00000100000000000000000000000000; return GetFeatureBits_2() & 0b00000100000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasOSXSAVE() bool CPU::RetrieveOSXSAVE()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00001000000000000000000000000000; return GetFeatureBits_2() & 0b00001000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasAVX() bool CPU::RetrieveAVX()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00010000000000000000000000000000; return GetFeatureBits_2() & 0b00010000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasF16C() bool CPU::RetrieveF16C()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b00100000000000000000000000000000; return GetFeatureBits_2() & 0b00100000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasRDRND() bool CPU::RetrieveRDRND()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b01000000000000000000000000000000; return GetFeatureBits_2() & 0b01000000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasHYPERVISOR() bool CPU::RetrieveHYPERVISOR()
{ {
#ifdef EHS_ARCH_X64
return GetFeatureBits_2() & 0b10000000000000000000000000000000; return GetFeatureBits_2() & 0b10000000000000000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasAVX2() bool CPU::RetrieveAVX2()
{ {
#ifdef EHS_ARCH_X64
return GetExtFeatureBits_1() & 0b00000000000000000000000000100000; 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; return GetExtFeatureBits_1() & 0b00000000000001000000000000000000;
#else
return false;
#endif
} }
bool CPU::HasADX() bool CPU::RetrieveADX()
{ {
#ifdef EHS_ARCH_X64
return GetExtFeatureBits_1() & 0b00000000000010000000000000000000; return GetExtFeatureBits_1() & 0b00000000000010000000000000000000;
#else
return false;
#endif
} }
/* /*

View File

@@ -2,10 +2,6 @@
namespace ehs namespace ehs
{ {
void CPU::RDTSCP(TSC* tsc)
{
}
void CPU::GetManufacturer(Char_8* input) void CPU::GetManufacturer(Char_8* input)
{ {
} }
@@ -43,4 +39,9 @@ namespace ehs
void CPU::GetBrand(Char_8* input) 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_2Ev
global _ZN3ehs3CPU19GetExtFeatureBits_3Ev global _ZN3ehs3CPU19GetExtFeatureBits_3Ev
global _ZN3ehs3CPU8GetBrandEPc global _ZN3ehs3CPU8GetBrandEPc
global _ZN3ehs3CPU16GetCacheLineSizeEv
section .text section .text
_ZN3ehs3CPU6RDTSCPEPNS_3TSCE: _ZN3ehs3CPU6RDTSCPEPNS_3TSCE:
@@ -130,3 +131,16 @@ section .text
POP RBX POP RBX
RET 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_2@CPU@ehs@@SAKXZ
global ?GetExtFeatureBits_3@CPU@ehs@@SAKXZ global ?GetExtFeatureBits_3@CPU@ehs@@SAKXZ
global ?GetBrand@CPU@ehs@@SAXPEAD@Z global ?GetBrand@CPU@ehs@@SAXPEAD@Z
global ?GetCacheLineSize@CPU@ehs@@SAEXZ
section .text section .text
?GetManufacturer@CPU@ehs@@SAXPEAD@Z: ?GetManufacturer@CPU@ehs@@SAXPEAD@Z:
@@ -125,3 +126,16 @@ section .text
POP RBX POP RBX
RET 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