Add server sent events, change vfs structure, dark mode error pages and dark mode anonydrop
This commit is contained in:
@@ -6,7 +6,8 @@ on:
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
|
PACKAGE_AND_BREW: ${{ secrets.PACKAGE_AND_BREW }}
|
||||||
|
VERSION: ${{ gitea.ref_name }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-arch:
|
build-arch:
|
||||||
runs-on: arch-builder
|
runs-on: arch-builder
|
||||||
@@ -20,3 +21,22 @@ jobs:
|
|||||||
- run: chown build:build /home/build/PKGBUILD
|
- run: chown build:build /home/build/PKGBUILD
|
||||||
- run: chown build:build /home/build/build-arch.sh
|
- run: chown build:build /home/build/build-arch.sh
|
||||||
- run: su build -c /home/build/build-arch.sh
|
- run: su build -c /home/build/build-arch.sh
|
||||||
|
|
||||||
|
update-tap:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: "master"
|
||||||
|
path: "tapdir"
|
||||||
|
repository: "tesses50/tesses-tap.git"
|
||||||
|
token: ${{ env.PACKAGE_AND_BREW }}
|
||||||
|
- run: |
|
||||||
|
cd tapdir
|
||||||
|
bash ../Packaging/edit-formula.sh
|
||||||
|
git config user.name "Tesses Gitea Bot"
|
||||||
|
git config user.email "noreply@tesses.net"
|
||||||
|
git add .
|
||||||
|
git commit -m "Push tesses-framework=${{ env.VERSION }}"
|
||||||
|
git push
|
||||||
|
|||||||
19
Packaging/edit-formula.sh
Normal file
19
Packaging/edit-formula.sh
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export HASH=`curl https://git.tesses.org/tesses50/tessesframework/archive/$VERSION.tar.gz 2> /dev/null | shasum -a 256 | awk '{print $1}'`
|
||||||
|
|
||||||
|
echo "class Tessesframework < Formula" > "Formula/tessesframework.rb"
|
||||||
|
echo " desc \"\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " homepage \"\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " url \"https://git.tesses.org/tesses50/tessesframework/archive/$VERSION.tar.gz\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " sha256 \"$HASH\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " license \"MIT\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " depends_on \"cmake\" => :build" >> "Formula/tessesframework.rb"
|
||||||
|
echo " depends_on \"mbedtls@3\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " def install" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"cmake\", \"-S\", \".\", \"-B\", \"build\", \"-DTESSESFRAMEWORK_FETCHCONTENT=OFF\", *std_cmake_args" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"cmake\", \"--build\", \"build\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"cmake\", \"--install\", \"build\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " end" >> "Formula/tessesframework.rb"
|
||||||
|
echo " test do" >> "Formula/tessesframework.rb"
|
||||||
|
echo " system \"true\"" >> "Formula/tessesframework.rb"
|
||||||
|
echo " end" >> "Formula/tessesframework.rb"
|
||||||
|
echo "end" >> "Formula/tessesframework.rb"
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.0.3
|
||||||
|
Add server sent events, change vfs structure, dark mode error pages and dark mode anonydrop
|
||||||
|
|
||||||
## 0.0.2
|
## 0.0.2
|
||||||
Add UUIDs
|
Add UUIDs
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ using namespace Tesses::Framework::Http;
|
|||||||
using namespace Tesses::Framework::Streams;
|
using namespace Tesses::Framework::Streams;
|
||||||
using namespace Tesses::Framework::TextStreams;
|
using namespace Tesses::Framework::TextStreams;
|
||||||
using namespace Tesses::Framework::Threading;
|
using namespace Tesses::Framework::Threading;
|
||||||
|
|
||||||
|
std::shared_ptr<ServerSentEvents> sse = std::make_shared<ServerSentEvents>();
|
||||||
|
|
||||||
class Johnny : public ServerContextData
|
class Johnny : public ServerContextData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -65,7 +68,7 @@ class MyWebServer : public IHttpServer {
|
|||||||
for(size_t i=0;i<10000; i++)
|
for(size_t i=0;i<10000; i++)
|
||||||
{
|
{
|
||||||
writer.WriteLine("<li>" + std::to_string(i) + "</li>");
|
writer.WriteLine("<li>" + std::to_string(i) + "</li>");
|
||||||
|
TF_Sleep(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine("</ul>");
|
writer.WriteLine("</ul>");
|
||||||
@@ -74,6 +77,15 @@ class MyWebServer : public IHttpServer {
|
|||||||
writer.WriteLine("</html>");
|
writer.WriteLine("</html>");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if(ctx.path == "/ssetest.html")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if(ctx.path == "/sse")
|
||||||
|
{
|
||||||
|
ctx.SendServerSentEvents(sse);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if(ctx.path == "/main.js")
|
else if(ctx.path == "/main.js")
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -162,6 +174,13 @@ class MyOtherWebServer : public IHttpServer
|
|||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
TF_InitWithConsole();
|
TF_InitWithConsole();
|
||||||
|
int64_t timer = 0;
|
||||||
|
auto timerHDL= TF_Timer([&timer]()->void{
|
||||||
|
timer++;
|
||||||
|
|
||||||
|
sse->SendData("Timer has ticked " + std::to_string(timer) + " times now");
|
||||||
|
});
|
||||||
|
|
||||||
std::shared_ptr<RouteServer> routeSvr = std::make_shared<RouteServer>();
|
std::shared_ptr<RouteServer> routeSvr = std::make_shared<RouteServer>();
|
||||||
routeSvr->Get("/name/{name}/greeting",[](ServerContext& ctx)->bool{
|
routeSvr->Get("/name/{name}/greeting",[](ServerContext& ctx)->bool{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace Tesses::Framework
|
|||||||
std::shared_ptr<TF_Timer_Handle> TF_Timer();
|
std::shared_ptr<TF_Timer_Handle> TF_Timer();
|
||||||
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, int64_t interval=1000, bool enabled=true);
|
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, int64_t interval=1000, bool enabled=true);
|
||||||
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, std::chrono::milliseconds interval, bool enabled=true);
|
std::shared_ptr<TF_Timer_Handle> TF_Timer(std::function<void()> cb, std::chrono::milliseconds interval, bool enabled=true);
|
||||||
|
|
||||||
void TF_Init();
|
void TF_Init();
|
||||||
void TF_InitWithConsole();
|
void TF_InitWithConsole();
|
||||||
void TF_AllowPortable(std::string argv0);
|
void TF_AllowPortable(std::string argv0);
|
||||||
@@ -76,6 +76,7 @@ namespace Tesses::Framework
|
|||||||
void TF_RunEventLoop();
|
void TF_RunEventLoop();
|
||||||
void TF_RunEventLoopItteration();
|
void TF_RunEventLoopItteration();
|
||||||
bool TF_IsRunning();
|
bool TF_IsRunning();
|
||||||
|
void TF_Sleep(uint32_t sleepMS);
|
||||||
void TF_SetIsRunning(bool _isRunning);
|
void TF_SetIsRunning(bool _isRunning);
|
||||||
void TF_Quit();
|
void TF_Quit();
|
||||||
bool TF_GetConsoleEventsEnabled();
|
bool TF_GetConsoleEventsEnabled();
|
||||||
|
|||||||
@@ -13,12 +13,30 @@ namespace Tesses::Framework::Http
|
|||||||
public:
|
public:
|
||||||
virtual ~ServerContextData();
|
virtual ~ServerContextData();
|
||||||
};
|
};
|
||||||
|
class ServerContext;
|
||||||
|
class ServerSentEvents {
|
||||||
|
std::vector<std::shared_ptr<Tesses::Framework::Streams::Stream>> strms;
|
||||||
|
Tesses::Framework::Threading::Mutex mtx;
|
||||||
|
private:
|
||||||
|
void SendEventRaw(const std::string& evt);
|
||||||
|
public:
|
||||||
|
void SendRetry(uint32_t ms);
|
||||||
|
void SendRetry(std::chrono::milliseconds ms);
|
||||||
|
void SendRetry(Tesses::Framework::Date::TimeSpan ts);
|
||||||
|
void SendData(const std::string& message);
|
||||||
|
void SendData(const std::string& message, const std::string& dataType);
|
||||||
|
void SendId(const std::string& idVal);
|
||||||
|
void SendCustomEvent(const std::string& type, const std::string& value);
|
||||||
|
void SendComment(const std::string& comment);
|
||||||
|
friend class ServerContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class ServerContext {
|
class ServerContext {
|
||||||
|
|
||||||
bool sent;
|
bool sent;
|
||||||
bool debug;
|
bool debug;
|
||||||
|
std::vector<std::shared_ptr<ServerSentEvents>> sse;
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
std::shared_ptr<Tesses::Framework::Streams::Stream> strm;
|
||||||
std::map<std::string,ServerContextData*> data;
|
std::map<std::string,ServerContextData*> data;
|
||||||
std::queue<std::function<bool(ServerContext& ctx)>> headerhandlers;
|
std::queue<std::function<bool(ServerContext& ctx)>> headerhandlers;
|
||||||
@@ -54,6 +72,7 @@ namespace Tesses::Framework::Http
|
|||||||
void SendNotFound();
|
void SendNotFound();
|
||||||
void SendBadRequest();
|
void SendBadRequest();
|
||||||
void SendException(std::exception& ex);
|
void SendException(std::exception& ex);
|
||||||
|
void SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse);
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
|
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenResponseStream();
|
||||||
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
|
std::shared_ptr<Tesses::Framework::Streams::Stream> OpenRequestStream();
|
||||||
ServerContext& WithStatusCode(StatusCode code);
|
ServerContext& WithStatusCode(StatusCode code);
|
||||||
@@ -87,6 +106,9 @@ namespace Tesses::Framework::Http
|
|||||||
data[name] = item;
|
data[name] = item;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
friend class ServerSentEvents;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class IHttpServer {
|
class IHttpServer {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
namespace Tesses::Framework::Streams
|
namespace Tesses::Framework::Streams
|
||||||
{
|
{
|
||||||
class NetworkStream;
|
class NetworkStream;
|
||||||
|
|
||||||
class TcpServer {
|
class TcpServer {
|
||||||
int32_t sock;
|
int32_t sock;
|
||||||
bool owns;
|
bool owns;
|
||||||
@@ -20,7 +20,7 @@ namespace Tesses::Framework::Streams
|
|||||||
~TcpServer();
|
~TcpServer();
|
||||||
bool IsValid();
|
bool IsValid();
|
||||||
void Close();
|
void Close();
|
||||||
};
|
};
|
||||||
enum class SocketType {
|
enum class SocketType {
|
||||||
ST_IPv4_TCP,
|
ST_IPv4_TCP,
|
||||||
ST_IPv4_UDP,
|
ST_IPv4_UDP,
|
||||||
@@ -46,14 +46,19 @@ namespace Tesses::Framework::Streams
|
|||||||
void Listen(int32_t backlog);
|
void Listen(int32_t backlog);
|
||||||
void Bind(std::string ip, uint16_t port);
|
void Bind(std::string ip, uint16_t port);
|
||||||
void SetBroadcast(bool bC);
|
void SetBroadcast(bool bC);
|
||||||
|
void SetReuseAddress(bool reuse);
|
||||||
|
void SetReusePort(bool reuse);
|
||||||
|
void SetMulticastTTL(uint8_t ttl);
|
||||||
|
void SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0");
|
||||||
std::shared_ptr<NetworkStream> Accept(std::string& ip, uint16_t& port);
|
std::shared_ptr<NetworkStream> Accept(std::string& ip, uint16_t& port);
|
||||||
size_t Read(uint8_t* buff, size_t sz);
|
size_t Read(uint8_t* buff, size_t sz);
|
||||||
size_t Write(const uint8_t* buff, size_t sz);
|
size_t Write(const uint8_t* buff, size_t sz);
|
||||||
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
|
size_t ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port);
|
||||||
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
|
size_t WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port);
|
||||||
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
|
static std::vector<std::pair<std::string,std::string>> GetIPs(bool ipV6=false);
|
||||||
|
|
||||||
~NetworkStream();
|
~NetworkStream();
|
||||||
void SetNoDelay(bool noDelay);
|
void SetNoDelay(bool noDelay);
|
||||||
void Close();
|
void Close();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,79 @@ using namespace Tesses::Framework::TextStreams;
|
|||||||
|
|
||||||
namespace Tesses::Framework::Http
|
namespace Tesses::Framework::Http
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void ServerSentEvents::SendEventRaw(const std::string& evt)
|
||||||
|
{
|
||||||
|
this->mtx.Lock();
|
||||||
|
for(auto& item : this->strms)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
StreamWriter writer(item);
|
||||||
|
writer.newline = "\r\n";
|
||||||
|
writer.WriteLine(evt);
|
||||||
|
|
||||||
|
|
||||||
|
}catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->mtx.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSentEvents::SendId(const std::string& id)
|
||||||
|
{
|
||||||
|
SendCustomEvent("id",id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSentEvents::SendData(const std::string& message)
|
||||||
|
{
|
||||||
|
SendCustomEvent("data", message);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendComment(const std::string& comment)
|
||||||
|
{
|
||||||
|
SendCustomEvent("", comment);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendCustomEvent(const std::string& etype, const std::string& message)
|
||||||
|
{
|
||||||
|
std::string text = etype + ": ";
|
||||||
|
for(auto item : message)
|
||||||
|
{
|
||||||
|
if(item == '\r') continue;
|
||||||
|
if(item == '\n') {
|
||||||
|
text += "\r\n" + etype + ": ";
|
||||||
|
}
|
||||||
|
else text += item;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendEventRaw(text);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendData(const std::string& message, const std::string& mtype)
|
||||||
|
{
|
||||||
|
std::string text = "event: " + mtype + "\r\ndata: ";
|
||||||
|
for(auto item : message)
|
||||||
|
{
|
||||||
|
if(item == '\r') continue;
|
||||||
|
if(item == '\n') {
|
||||||
|
text += "\r\ndata: ";
|
||||||
|
}
|
||||||
|
else text += item;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendEventRaw(text);
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendRetry(uint32_t ms)
|
||||||
|
{
|
||||||
|
SendCustomEvent("retry", std::to_string(ms));
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendRetry(std::chrono::milliseconds ms)
|
||||||
|
{
|
||||||
|
SendCustomEvent("retry", std::to_string(ms.count()));
|
||||||
|
}
|
||||||
|
void ServerSentEvents::SendRetry(Tesses::Framework::Date::TimeSpan ts)
|
||||||
|
{
|
||||||
|
SendRetry((uint32_t)ts.TotalSeconds() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
class WSServer
|
class WSServer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -282,6 +355,7 @@ namespace Tesses::Framework::Http
|
|||||||
this->conn->OnClose(false);
|
this->conn->OnClose(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int _header_field(multipart_parser* p, const char *at, size_t length)
|
static int _header_field(multipart_parser* p, const char *at, size_t length)
|
||||||
{
|
{
|
||||||
@@ -344,6 +418,7 @@ namespace Tesses::Framework::Http
|
|||||||
data->currentHeaders.Clear();
|
data->currentHeaders.Clear();
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
std::string ServerContext::GetUrlWithQuery()
|
std::string ServerContext::GetUrlWithQuery()
|
||||||
{
|
{
|
||||||
if(this->queryParams.kvp.empty()) return this->path;
|
if(this->queryParams.kvp.empty()) return this->path;
|
||||||
@@ -364,6 +439,34 @@ namespace Tesses::Framework::Http
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ServerContext::SendServerSentEvents(std::shared_ptr<ServerSentEvents> sse)
|
||||||
|
{
|
||||||
|
this->responseHeaders.SetValue("X-Accel-Buffering","no");
|
||||||
|
this->responseHeaders.SetValue("Content-Type","text/event-stream");
|
||||||
|
this->responseHeaders.SetValue("Cache-Control","no-cache");
|
||||||
|
auto strm = this->OpenResponseStream();
|
||||||
|
if(strm == nullptr || this->method == "HEAD") return;
|
||||||
|
sse->mtx.Lock();
|
||||||
|
sse->strms.push_back(strm);
|
||||||
|
sse->mtx.Unlock();
|
||||||
|
while(!this->strm->EndOfStream())
|
||||||
|
{
|
||||||
|
TF_Sleep(10);
|
||||||
|
}
|
||||||
|
sse->mtx.Lock();
|
||||||
|
for(auto index = sse->strms.begin(); index != sse->strms.end(); index++)
|
||||||
|
{
|
||||||
|
if(*index == strm)
|
||||||
|
{
|
||||||
|
sse->strms.erase(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sse->mtx.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
std::string ServerContext::ReadString()
|
std::string ServerContext::ReadString()
|
||||||
{
|
{
|
||||||
if(strm == nullptr) return {};
|
if(strm == nullptr) return {};
|
||||||
|
|||||||
@@ -160,20 +160,30 @@ namespace Tesses::Framework::Http
|
|||||||
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
||||||
{
|
{
|
||||||
this->done=true;
|
this->done=true;
|
||||||
StreamWriter writer(this->strm);
|
try {
|
||||||
writer.newline = "\r\n";
|
|
||||||
writer.WriteLine("0");
|
StreamWriter writer(this->strm);
|
||||||
writer.WriteLine();
|
writer.newline = "\r\n";
|
||||||
|
writer.WriteLine("0");
|
||||||
|
writer.WriteLine();
|
||||||
|
}catch(...){
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HttpStream::~HttpStream()
|
HttpStream::~HttpStream()
|
||||||
{
|
{
|
||||||
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
if(this->length == -1 && this->http1_1 && !done && !this->recv)
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
StreamWriter writer(this->strm);
|
StreamWriter writer(this->strm);
|
||||||
writer.newline = "\r\n";
|
writer.newline = "\r\n";
|
||||||
writer.WriteLine("0");
|
writer.WriteLine("0");
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
|
}catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
#include "TessesFramework/Streams/NetworkStream.hpp"
|
#include "TessesFramework/Streams/NetworkStream.hpp"
|
||||||
#include "TessesFramework/Http/HttpUtils.hpp"
|
#include "TessesFramework/Http/HttpUtils.hpp"
|
||||||
|
#include <TessesFramework/Streams/NetworkStream.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||||
|
|
||||||
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
|
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
|
||||||
|
|
||||||
|
|
||||||
@@ -11,7 +13,7 @@ using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
|||||||
|
|
||||||
#define ss_family sin_family
|
#define ss_family sin_family
|
||||||
#endif
|
#endif
|
||||||
#if defined(GEKKO) && !(defined(TESSESFRAMEWORK_USE_WII_SOCKET) && defined(HW_RVL))
|
#if defined(GEKKO) && !(defined(TESSESFRAMEWORK_USE_WII_SOCKET) && defined(HW_RVL))
|
||||||
#include <network.h>
|
#include <network.h>
|
||||||
#define NETWORK_GETSOCKNAME net_getsockname
|
#define NETWORK_GETSOCKNAME net_getsockname
|
||||||
#define NETWORK_RECV net_recv
|
#define NETWORK_RECV net_recv
|
||||||
@@ -34,6 +36,8 @@ using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
|||||||
#endif
|
#endif
|
||||||
#undef min
|
#undef min
|
||||||
#pragma comment(lib, "ws2_32.lib")
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -47,6 +51,7 @@ extern "C" {
|
|||||||
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__SWITCH__) && !defined(__PS2__)
|
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__SWITCH__) && !defined(__PS2__)
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -88,7 +93,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
std::vector<std::pair<std::string,std::string>> NetworkStream::GetIPs(bool ipV6)
|
std::vector<std::pair<std::string,std::string>> NetworkStream::GetIPs(bool ipV6)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<std::string, std::string>> ipConfig;
|
std::vector<std::pair<std::string, std::string>> ipConfig;
|
||||||
|
|
||||||
#if defined(GEKKO)
|
#if defined(GEKKO)
|
||||||
//if_config( char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries);
|
//if_config( char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries);
|
||||||
char localIp[16];
|
char localIp[16];
|
||||||
@@ -103,7 +108,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
ULONG size = 15000;
|
ULONG size = 15000;
|
||||||
PIP_ADAPTER_ADDRESSES addresses = NULL;
|
PIP_ADAPTER_ADDRESSES addresses = NULL;
|
||||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);
|
addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);
|
||||||
|
|
||||||
int retval = GetAdaptersAddresses(family, flags, 0, addresses, &size);
|
int retval = GetAdaptersAddresses(family, flags, 0, addresses, &size);
|
||||||
if(retval != 0) {
|
if(retval != 0) {
|
||||||
free(addresses);
|
free(addresses);
|
||||||
@@ -145,15 +150,15 @@ namespace Tesses::Framework::Streams {
|
|||||||
if (ifa->ifa_addr == NULL)
|
if (ifa->ifa_addr == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET) { // IPv4
|
if (ifa->ifa_addr->sa_family == AF_INET) { // IPv4
|
||||||
|
|
||||||
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
||||||
|
|
||||||
}
|
}
|
||||||
#if defined(AF_INET6)
|
#if defined(AF_INET6)
|
||||||
if (ifa->ifa_addr->sa_family == AF_INET6 && ipV6) { // IPv6
|
if (ifa->ifa_addr->sa_family == AF_INET6 && ipV6) { // IPv6
|
||||||
|
|
||||||
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
ipConfig.push_back(std::pair<std::string,std::string>(ifa->ifa_name, StringifyIP(ifa->ifa_addr)));
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -161,7 +166,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
freeifaddrs(ifAddrStruct);
|
freeifaddrs(ifAddrStruct);
|
||||||
#endif
|
#endif
|
||||||
return ipConfig;
|
return ipConfig;
|
||||||
|
|
||||||
}
|
}
|
||||||
void SetPort(struct sockaddr* addr, uint16_t port)
|
void SetPort(struct sockaddr* addr, uint16_t port)
|
||||||
{
|
{
|
||||||
@@ -175,10 +180,10 @@ namespace Tesses::Framework::Streams {
|
|||||||
{
|
{
|
||||||
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
||||||
a->sin6_port = htons(port);
|
a->sin6_port = htons(port);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
static uint16_t getPort(struct sockaddr* addr)
|
static uint16_t getPort(struct sockaddr* addr)
|
||||||
{
|
{
|
||||||
@@ -192,13 +197,13 @@ namespace Tesses::Framework::Streams {
|
|||||||
{
|
{
|
||||||
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
struct sockaddr_in6* a = (struct sockaddr_in6*)addr;\
|
||||||
return ntohs(a->sin6_port);
|
return ntohs(a->sin6_port);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
bool IPParse(std::string str,struct sockaddr_storage* addr)
|
bool IPParse(std::string str,struct sockaddr_storage* addr)
|
||||||
{
|
{
|
||||||
memset(addr,0,sizeof(struct sockaddr_storage));
|
memset(addr,0,sizeof(struct sockaddr_storage));
|
||||||
uint8_t ip[16];
|
uint8_t ip[16];
|
||||||
|
|
||||||
@@ -218,7 +223,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
{
|
{
|
||||||
|
|
||||||
struct sockaddr_in6* inAddr = (struct sockaddr_in6*)addr;
|
struct sockaddr_in6* inAddr = (struct sockaddr_in6*)addr;
|
||||||
|
|
||||||
inAddr->sin6_family = AF_INET6;
|
inAddr->sin6_family = AF_INET6;
|
||||||
memcpy(&inAddr->sin6_addr,ip,16);
|
memcpy(&inAddr->sin6_addr,ip,16);
|
||||||
return 6;
|
return 6;
|
||||||
@@ -281,9 +286,9 @@ namespace Tesses::Framework::Streams {
|
|||||||
HttpUtils::NibbleToHex(ip[15] & 0x0F),
|
HttpUtils::NibbleToHex(ip[15] & 0x0F),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return "";
|
return "";
|
||||||
@@ -293,7 +298,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
uint8_t addr_parts[4];
|
uint8_t addr_parts[4];
|
||||||
} my_addr_t;
|
} my_addr_t;
|
||||||
|
|
||||||
bool NetworkStream::DataAvailable(int timeout)
|
bool NetworkStream::DataAvailable(int timeout)
|
||||||
{
|
{
|
||||||
pollfd fd;
|
pollfd fd;
|
||||||
@@ -314,7 +319,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkStream::NetworkStream(std::string unixPath,bool isServer)
|
NetworkStream::NetworkStream(std::string unixPath,bool isServer)
|
||||||
{
|
{
|
||||||
this->endOfStream=false;
|
this->endOfStream=false;
|
||||||
@@ -328,12 +333,12 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sockaddr_un unx;
|
struct sockaddr_un unx;
|
||||||
|
|
||||||
memset(&unx, 0, sizeof(unx));
|
memset(&unx, 0, sizeof(unx));
|
||||||
unx.sun_family = AF_UNIX;
|
unx.sun_family = AF_UNIX;
|
||||||
|
|
||||||
strncpy(unx.sun_path, unixPath.c_str(),sizeof(unx.sun_path)-1);
|
strncpy(unx.sun_path, unixPath.c_str(),sizeof(unx.sun_path)-1);
|
||||||
|
|
||||||
if(isServer)
|
if(isServer)
|
||||||
{
|
{
|
||||||
unlink(unixPath.c_str());
|
unlink(unixPath.c_str());
|
||||||
@@ -344,7 +349,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(NETWORK_CONNECT(this->sock,(const sockaddr*)&unx, (socklen_t)sizeof(unx)) != 0)
|
if(NETWORK_CONNECT(this->sock,(const sockaddr*)&unx, (socklen_t)sizeof(unx)) != 0)
|
||||||
{
|
{
|
||||||
@@ -360,7 +365,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
this->owns=true;
|
this->owns=true;
|
||||||
this->valid=false;
|
this->valid=false;
|
||||||
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__PS2__) && !defined(__SWITCH__) && ((defined(_WIN32) && defined(HAS_AFUNIX) ) || !defined(_WIN32))
|
#if defined(AF_UNIX) && !defined(GEKKO) && !defined(__PS2__) && !defined(__SWITCH__) && ((defined(_WIN32) && defined(HAS_AFUNIX) ) || !defined(_WIN32))
|
||||||
@@ -372,7 +377,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sockaddr_un unx;
|
struct sockaddr_un unx;
|
||||||
|
|
||||||
memset(&unx, 0, sizeof(unx));
|
memset(&unx, 0, sizeof(unx));
|
||||||
unx.sun_family = AF_UNIX;
|
unx.sun_family = AF_UNIX;
|
||||||
unlink(unixPath.c_str());
|
unlink(unixPath.c_str());
|
||||||
@@ -384,7 +389,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||||
{
|
{
|
||||||
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
||||||
this->valid = false;
|
this->valid = false;
|
||||||
@@ -397,14 +402,14 @@ namespace Tesses::Framework::Streams {
|
|||||||
TcpServer::TcpServer(uint16_t port, int32_t backlog)
|
TcpServer::TcpServer(uint16_t port, int32_t backlog)
|
||||||
{
|
{
|
||||||
this->owns=true;
|
this->owns=true;
|
||||||
this->sock = NETWORK_SOCKET(AF_INET, SOCK_STREAM, 0);
|
this->sock = NETWORK_SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||||
|
|
||||||
if(this->sock < 0)
|
if(this->sock < 0)
|
||||||
{
|
{
|
||||||
std::cout << "FAILED TO CREATE SOCKET FOR SOME REASON" << std::endl;
|
std::cout << "FAILED TO CREATE SOCKET FOR SOME REASON" << std::endl;
|
||||||
this->valid=false;
|
this->valid=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
@@ -436,7 +441,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||||
{
|
{
|
||||||
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
||||||
this->valid = false;
|
this->valid = false;
|
||||||
@@ -496,24 +501,24 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
uint8_t ipBytes[16];
|
uint8_t ipBytes[16];
|
||||||
bool success = IPParse(ip, &addr);
|
bool success = IPParse(ip, &addr);
|
||||||
if(!success)
|
if(!success)
|
||||||
{
|
{
|
||||||
this->valid=false;
|
this->valid=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPort((struct sockaddr*)&addr, port);
|
SetPort((struct sockaddr*)&addr, port);
|
||||||
|
|
||||||
this->sock = NETWORK_SOCKET((int)addr.ss_family, SOCK_STREAM, 0);
|
this->sock = NETWORK_SOCKET((int)addr.ss_family, SOCK_STREAM, 0);
|
||||||
if(this->sock < 0)
|
if(this->sock < 0)
|
||||||
{
|
{
|
||||||
this->valid=false;
|
this->valid=false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -522,7 +527,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||||
{
|
{
|
||||||
this->valid = false;
|
this->valid = false;
|
||||||
return;
|
return;
|
||||||
@@ -554,7 +559,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
struct sockaddr_storage storage;
|
struct sockaddr_storage storage;
|
||||||
memset(&storage,0, sizeof(storage));
|
memset(&storage,0, sizeof(storage));
|
||||||
socklen_t addrlen=(socklen_t)sizeof(storage);
|
socklen_t addrlen=(socklen_t)sizeof(storage);
|
||||||
|
|
||||||
int s = NETWORK_ACCEPT(this->sock, (struct sockaddr*)&storage, &addrlen);
|
int s = NETWORK_ACCEPT(this->sock, (struct sockaddr*)&storage, &addrlen);
|
||||||
if(s < 0)
|
if(s < 0)
|
||||||
{
|
{
|
||||||
@@ -563,7 +568,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
ip = StringifyIP((struct sockaddr*)&storage);
|
ip = StringifyIP((struct sockaddr*)&storage);
|
||||||
port = getPort((struct sockaddr*)&storage);
|
port = getPort((struct sockaddr*)&storage);
|
||||||
|
|
||||||
return std::make_shared<NetworkStream>(s,true);
|
return std::make_shared<NetworkStream>(s,true);
|
||||||
}
|
}
|
||||||
bool NetworkStream::CanRead()
|
bool NetworkStream::CanRead()
|
||||||
@@ -584,32 +589,32 @@ namespace Tesses::Framework::Streams {
|
|||||||
case SocketType::ST_IPv4_TCP:
|
case SocketType::ST_IPv4_TCP:
|
||||||
#if defined(AF_INET)
|
#if defined(AF_INET)
|
||||||
this->sock = NETWORK_SOCKET(AF_INET,SOCK_STREAM, 0);
|
this->sock = NETWORK_SOCKET(AF_INET,SOCK_STREAM, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case SocketType::ST_IPv4_UDP:
|
case SocketType::ST_IPv4_UDP:
|
||||||
#if defined(AF_INET)
|
#if defined(AF_INET)
|
||||||
this->sock = NETWORK_SOCKET(AF_INET,SOCK_DGRAM, 0);
|
this->sock = NETWORK_SOCKET(AF_INET,SOCK_DGRAM, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SocketType::ST_IPv6_TCP:
|
case SocketType::ST_IPv6_TCP:
|
||||||
#if defined(AF_INET6)
|
#if defined(AF_INET6)
|
||||||
this->sock = NETWORK_SOCKET(AF_INET6,SOCK_STREAM, 0);
|
this->sock = NETWORK_SOCKET(AF_INET6,SOCK_STREAM, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case SocketType::ST_IPv6_UDP:
|
case SocketType::ST_IPv6_UDP:
|
||||||
#if defined(AF_INET6)
|
#if defined(AF_INET6)
|
||||||
this->sock = NETWORK_SOCKET(AF_INET6,SOCK_DGRAM, 0);
|
this->sock = NETWORK_SOCKET(AF_INET6,SOCK_DGRAM, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case SocketType::ST_UNIX:
|
case SocketType::ST_UNIX:
|
||||||
#if defined(AF_UNIX) && ((defined(_WIN32) && defined(HAS_AFUNIX) ) || !defined(_WIN32))
|
#if defined(AF_UNIX) && ((defined(_WIN32) && defined(HAS_AFUNIX) ) || !defined(_WIN32))
|
||||||
this->sock = NETWORK_SOCKET(AF_UNIX,SOCK_DGRAM, 0);
|
this->sock = NETWORK_SOCKET(AF_UNIX,SOCK_DGRAM, 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -621,7 +626,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
this->owns=true;
|
this->owns=true;
|
||||||
this->success=false;
|
this->success=false;
|
||||||
std::string portStr = std::to_string((uint32_t)port);
|
std::string portStr = std::to_string((uint32_t)port);
|
||||||
|
|
||||||
struct addrinfo hint;
|
struct addrinfo hint;
|
||||||
memset(&hint, 0, sizeof(hint));
|
memset(&hint, 0, sizeof(hint));
|
||||||
#if defined(AF_INET6)
|
#if defined(AF_INET6)
|
||||||
@@ -631,7 +636,7 @@ namespace Tesses::Framework::Streams {
|
|||||||
#endif
|
#endif
|
||||||
hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM;
|
hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM;
|
||||||
|
|
||||||
struct addrinfo* result;
|
struct addrinfo* result;
|
||||||
|
|
||||||
|
|
||||||
int status = NETWORK_GETADDRINFO(ipOrFqdn.c_str(),portStr.c_str(), &hint, &result);
|
int status = NETWORK_GETADDRINFO(ipOrFqdn.c_str(),portStr.c_str(), &hint, &result);
|
||||||
@@ -680,11 +685,11 @@ namespace Tesses::Framework::Streams {
|
|||||||
return this->endOfStream;
|
return this->endOfStream;
|
||||||
}
|
}
|
||||||
void NetworkStream::Listen(int32_t backlog)
|
void NetworkStream::Listen(int32_t backlog)
|
||||||
{
|
{
|
||||||
if(this->success)
|
if(this->success)
|
||||||
NETWORK_LISTEN(this->sock, backlog);
|
NETWORK_LISTEN(this->sock, backlog);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkStream::Bind(std::string ip, uint16_t port)
|
void NetworkStream::Bind(std::string ip, uint16_t port)
|
||||||
{
|
{
|
||||||
if(!this->success) return;
|
if(!this->success) return;
|
||||||
@@ -693,14 +698,14 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
uint8_t ipBytes[16];
|
uint8_t ipBytes[16];
|
||||||
bool success = IPParse(ip, &addr);
|
bool success = IPParse(ip, &addr);
|
||||||
if(!success)
|
if(!success)
|
||||||
{
|
{
|
||||||
this->success=false;
|
this->success=false;
|
||||||
if(this->owns)
|
if(this->owns)
|
||||||
NETWORK_CLOSE(this->sock);
|
NETWORK_CLOSE(this->sock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPort((struct sockaddr*)&addr, port);
|
SetPort((struct sockaddr*)&addr, port);
|
||||||
int on=1;
|
int on=1;
|
||||||
#if defined(SO_REUSEPORT)
|
#if defined(SO_REUSEPORT)
|
||||||
@@ -720,16 +725,81 @@ namespace Tesses::Framework::Streams {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void NetworkStream::SetBroadcast(bool bC)
|
void NetworkStream::SetReuseAddress(bool reuse)
|
||||||
{
|
{
|
||||||
if(!this->success) return;
|
if(!this->success) return;
|
||||||
int broadcast = 1;
|
int no = reuse ? 1 : 0;
|
||||||
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)) != 0)
|
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&no, sizeof(no)) != 0)
|
||||||
{
|
{
|
||||||
this->success=false;
|
this->success=false;
|
||||||
if(this->owns)
|
if(this->owns)
|
||||||
NETWORK_CLOSE(this->sock);
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NetworkStream::SetReusePort(bool reuse)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
int no = reuse ? 1 : 0;
|
||||||
|
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_REUSEPORT, (const char*)&no, sizeof(no)) != 0)
|
||||||
|
{
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastTTL(uint8_t ttl)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
|
||||||
|
if (NETWORK_SETSOCKOPT(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl)) != 0)
|
||||||
|
{
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastMembership(std::string multicastAddress, std::string ifaceIP)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
|
||||||
|
struct sockaddr_storage maddr;
|
||||||
|
struct sockaddr_storage iaddr;
|
||||||
|
|
||||||
|
bool success = IPParse(multicastAddress, &maddr) && IPParse(ifaceIP, &iaddr);
|
||||||
|
if(success && maddr.ss_family == AF_INET && iaddr.ss_family == AF_INET)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ip_mreq req;
|
||||||
|
req.imr_multiaddr = ((struct sockaddr_in*)&maddr)->sin_addr;
|
||||||
|
req.imr_interface = ((struct sockaddr_in*)&iaddr)->sin_addr;
|
||||||
|
|
||||||
|
if(NETWORK_SETSOCKOPT(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&req, sizeof(req)) != 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkStream::SetBroadcast(bool bC)
|
||||||
|
{
|
||||||
|
if(!this->success) return;
|
||||||
|
int broadcast = bC ? 1 : 0;
|
||||||
|
if (NETWORK_SETSOCKOPT(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast)) != 0)
|
||||||
|
{
|
||||||
|
this->success=false;
|
||||||
|
if(this->owns)
|
||||||
|
NETWORK_CLOSE(this->sock);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
||||||
@@ -745,12 +815,12 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
ip = StringifyIP((struct sockaddr*)&storage);
|
ip = StringifyIP((struct sockaddr*)&storage);
|
||||||
port = getPort((struct sockaddr*)&storage);
|
port = getPort((struct sockaddr*)&storage);
|
||||||
|
|
||||||
return std::make_shared<NetworkStream>((int32_t)s,(bool)true);
|
return std::make_shared<NetworkStream>((int32_t)s,(bool)true);
|
||||||
}
|
}
|
||||||
size_t NetworkStream::Read(uint8_t* buff, size_t sz)
|
size_t NetworkStream::Read(uint8_t* buff, size_t sz)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!this->success) return 0;
|
if(!this->success) return 0;
|
||||||
auto r = NETWORK_RECV(this->sock,(char*)buff,sz,0);
|
auto r = NETWORK_RECV(this->sock,(char*)buff,sz,0);
|
||||||
|
|
||||||
@@ -759,20 +829,20 @@ namespace Tesses::Framework::Streams {
|
|||||||
this->endOfStream=true;
|
this->endOfStream=true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (size_t)r;
|
return (size_t)r;
|
||||||
}
|
}
|
||||||
size_t NetworkStream::Write(const uint8_t* buff, size_t sz)
|
size_t NetworkStream::Write(const uint8_t* buff, size_t sz)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!this->success) return 0;
|
if(!this->success) return 0;
|
||||||
|
|
||||||
auto sz2 = NETWORK_SEND(this->sock,(const char*)buff,sz, 0);
|
auto sz2 = NETWORK_SEND(this->sock,(const char*)buff,sz, 0);
|
||||||
if(sz2 <= 0) {
|
if(sz2 <= 0) {
|
||||||
this->endOfStream=true;
|
this->endOfStream=true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (size_t)sz;
|
return (size_t)sz;
|
||||||
}
|
}
|
||||||
size_t NetworkStream::ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port)
|
size_t NetworkStream::ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port)
|
||||||
@@ -786,10 +856,10 @@ namespace Tesses::Framework::Streams {
|
|||||||
if(r < 0) return 0;
|
if(r < 0) return 0;
|
||||||
return (size_t)r;
|
return (size_t)r;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
size_t NetworkStream::WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port)
|
size_t NetworkStream::WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port)
|
||||||
{
|
{
|
||||||
@@ -800,14 +870,14 @@ namespace Tesses::Framework::Streams {
|
|||||||
|
|
||||||
uint8_t ipBytes[16];
|
uint8_t ipBytes[16];
|
||||||
bool success = IPParse(ip, &addr);
|
bool success = IPParse(ip, &addr);
|
||||||
if(!success)
|
if(!success)
|
||||||
{
|
{
|
||||||
this->success=false;
|
this->success=false;
|
||||||
if(this->owns)
|
if(this->owns)
|
||||||
NETWORK_CLOSE(this->sock);
|
NETWORK_CLOSE(this->sock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPort((struct sockaddr*)&addr, port);
|
SetPort((struct sockaddr*)&addr, port);
|
||||||
auto sz2 = NETWORK_SENDTO(this->sock,(const char*)buff,sz, 0, (const sockaddr*)&addr, (socklen_t)sizeof(addr));
|
auto sz2 = NETWORK_SENDTO(this->sock,(const char*)buff,sz, 0, (const sockaddr*)&addr, (socklen_t)sizeof(addr));
|
||||||
if(sz2 < 0) return 0;
|
if(sz2 < 0) return 0;
|
||||||
@@ -827,11 +897,11 @@ namespace Tesses::Framework::Streams {
|
|||||||
}
|
}
|
||||||
void NetworkStream::SetNoDelay(bool noDelay)
|
void NetworkStream::SetNoDelay(bool noDelay)
|
||||||
{
|
{
|
||||||
|
|
||||||
int noDelay2 = noDelay;
|
int noDelay2 = noDelay;
|
||||||
NETWORK_SETSOCKOPT(this->sock, SOL_SOCKET, TCP_NODELAY, (const char*)&noDelay2,(socklen_t)sizeof(noDelay2));
|
NETWORK_SETSOCKOPT(this->sock, SOL_SOCKET, TCP_NODELAY, (const char*)&noDelay2,(socklen_t)sizeof(noDelay2));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
namespace Tesses::Framework::Streams {
|
namespace Tesses::Framework::Streams {
|
||||||
@@ -850,7 +920,7 @@ TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog)
|
|||||||
}
|
}
|
||||||
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
std::shared_ptr<NetworkStream> TcpServer::GetStream(std::string& ip, uint16_t& port)
|
std::shared_ptr<NetworkStream> TcpServer::GetStream(std::string& ip, uint16_t& port)
|
||||||
{
|
{
|
||||||
@@ -866,7 +936,7 @@ bool TcpServer::IsValid()
|
|||||||
}
|
}
|
||||||
void TcpServer::Close()
|
void TcpServer::Close()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
bool NetworkStream::EndOfStream() {
|
bool NetworkStream::EndOfStream() {
|
||||||
return true;
|
return true;
|
||||||
@@ -877,7 +947,7 @@ bool NetworkStream::CanRead() {
|
|||||||
bool NetworkStream::CanWrite() {
|
bool NetworkStream::CanWrite() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkStream::NetworkStream(SocketType type)
|
NetworkStream::NetworkStream(SocketType type)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -888,7 +958,7 @@ NetworkStream::NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,
|
|||||||
}
|
}
|
||||||
NetworkStream::NetworkStream(std::string unixPath, bool isServer)
|
NetworkStream::NetworkStream(std::string unixPath, bool isServer)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
NetworkStream::NetworkStream(int32_t sock, bool owns)
|
NetworkStream::NetworkStream(int32_t sock, bool owns)
|
||||||
{
|
{
|
||||||
@@ -906,6 +976,23 @@ void NetworkStream::SetBroadcast(bool bC)
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
void NetworkStream::SetReuseAddress(bool reuse)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void NetworkStream::SetReusePort(bool reuse)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastTTL(uint8_t ttl)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void NetworkStream::SetMulticastMembership(std::string multicastAddress, std::string ifaceIP="0.0.0.0")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
std::shared_ptr<NetworkStream> NetworkStream::Accept(std::string& ip, uint16_t& port)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -936,7 +1023,7 @@ NetworkStream::~NetworkStream()
|
|||||||
}
|
}
|
||||||
void NetworkStream::SetNoDelay(bool noDelay)
|
void NetworkStream::SetNoDelay(bool noDelay)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
void NetworkStream::Close()
|
void NetworkStream::Close()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ namespace Tesses::Framework::Streams {
|
|||||||
read = len;
|
read = len;
|
||||||
if(read > 0)
|
if(read > 0)
|
||||||
{
|
{
|
||||||
|
size_t r0=read;
|
||||||
read=this->Write(buffer,read);
|
read=this->Write(buffer,read);
|
||||||
|
|
||||||
if(read == 0)
|
if(read == 0)
|
||||||
{
|
{
|
||||||
throw std::out_of_range("Failed to write!");
|
throw std::out_of_range("Failed to write!");
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ static GXRModeObj *rmode = NULL;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace Tesses::Framework
|
namespace Tesses::Framework
|
||||||
{
|
{
|
||||||
@@ -85,7 +89,19 @@ namespace Tesses::Framework
|
|||||||
cb();
|
cb();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
void TF_Sleep(uint32_t sleepMS)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
Sleep((DWORD)sleepMS);
|
||||||
|
#else
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
ts.tv_sec = (time_t)(sleepMS / 1000);
|
||||||
|
ts.tv_nsec = (sleepMS % 1000) * 1000000;
|
||||||
|
|
||||||
|
nanosleep(&ts,NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
void TF_ConnectToSelf(uint16_t port)
|
void TF_ConnectToSelf(uint16_t port)
|
||||||
{
|
{
|
||||||
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false);
|
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false);
|
||||||
|
|||||||
Reference in New Issue
Block a user