aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/DirectConnection.hpp49
-rw-r--r--include/types.hpp22
-rwxr-xr-xinclude/utils.hpp6
-rw-r--r--src/DirectConnection.cpp112
-rw-r--r--src/main.cpp6
-rw-r--r--tests/main.cpp6
6 files changed, 195 insertions, 6 deletions
diff --git a/include/DirectConnection.hpp b/include/DirectConnection.hpp
new file mode 100644
index 0000000..c11871f
--- /dev/null
+++ b/include/DirectConnection.hpp
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <stdexcept>
+#include "types.hpp"
+#include "utils.hpp"
+
+struct addrinfo;
+
+namespace sibs
+{
+ class InvalidAddressException : public std::runtime_error
+ {
+ public:
+ InvalidAddressException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class ConnectionException : public std::runtime_error
+ {
+ public:
+ ConnectionException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class Ipv4
+ {
+ DISABLE_COPY(Ipv4)
+ public:
+ // Throws InvalidAddressException on error
+ Ipv4(const char *ip, u16 port);
+ ~Ipv4();
+
+ struct addrinfo *address;
+ };
+
+ class DirectConnections
+ {
+ DISABLE_COPY(DirectConnections)
+ public:
+ DirectConnections();
+ ~DirectConnections();
+
+ void connect(const Ipv4 &address);
+ private:
+ void init();
+ void cleanup();
+ private:
+ int eid;
+ int mySocket;
+ };
+}
diff --git a/include/types.hpp b/include/types.hpp
new file mode 100644
index 0000000..0379100
--- /dev/null
+++ b/include/types.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <cstdint>
+
+namespace sibs
+{
+ typedef int8_t i8;
+ typedef int16_t i16;
+ typedef int32_t i32;
+ typedef int64_t i64;
+
+ typedef uint8_t u8;
+ typedef uint16_t u16;
+ typedef uint32_t u32;
+ typedef uint64_t u64;
+
+ typedef float f32;
+ typedef double f64;
+
+ typedef intptr_t isize;
+ typedef uintptr_t usize;
+}
diff --git a/include/utils.hpp b/include/utils.hpp
new file mode 100755
index 0000000..01e478d
--- /dev/null
+++ b/include/utils.hpp
@@ -0,0 +1,6 @@
+#pragma once
+
+// Disable copying for a class or struct
+#define DISABLE_COPY(ClassName) \
+ ClassName(ClassName&) = delete; \
+ ClassName& operator = (ClassName&) = delete;
diff --git a/src/DirectConnection.cpp b/src/DirectConnection.cpp
new file mode 100644
index 0000000..12ae761
--- /dev/null
+++ b/src/DirectConnection.cpp
@@ -0,0 +1,112 @@
+#include "../include/DirectConnection.hpp"
+#include <cstdio>
+#include <cstring>
+
+#ifndef WIN32
+ #include <arpa/inet.h>
+ #include <netdb.h>
+#else
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+#endif
+#include <udt/udt.h>
+
+namespace sibs
+{
+ Ipv4::Ipv4(const char *ip, u16 port)
+ {
+ struct addrinfo hints = {};
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+
+ char portStr[6];
+ sprintf(portStr, "%d", port);
+ int addrInfoResult = getaddrinfo(ip, portStr, &hints, &address);
+ if(addrInfoResult != 0)
+ {
+ std::string errMsg = "Ip ";
+ errMsg += ip;
+ errMsg += " is not a valid ip";
+ throw InvalidAddressException(errMsg);
+ }
+ }
+
+ Ipv4::~Ipv4()
+ {
+ freeaddrinfo(address);
+ }
+
+ DirectConnections::DirectConnections() :
+ mySocket(0)
+ {
+ try
+ {
+ init();
+ }
+ catch(...)
+ {
+ cleanup();
+ }
+ }
+
+ DirectConnections::~DirectConnections()
+ {
+ cleanup();
+ }
+
+ void DirectConnections::init()
+ {
+ UDT::startup();
+ eid = UDT::epoll_create();
+ mySocket = UDT::socket(AI_PASSIVE, AF_INET, SOCK_STREAM);
+ bool rendezvous = true;
+ UDT::setsockopt(mySocket, 0, UDT_RENDEZVOUS, &rendezvous, sizeof(bool));
+ bool reuseAddr = true;
+ UDT::setsockopt(mySocket, 0, UDT_REUSEADDR, &reuseAddr, sizeof(bool));
+
+ // Windows UDP issue
+ // For better performance, modify HKLM\System\CurrentControlSet\Services\Afd\Parameters\FastSendDatagramThreshold
+ #ifdef WIN32
+ int mss = 1052;
+ UDT::setsockopt(socket, 0, UDT_MSS, &mss, sizeof(mss));
+ #endif
+
+ sockaddr_in myAddr = {};
+ myAddr.sin_family = AF_INET;
+ myAddr.sin_port = htons(9000);
+ myAddr.sin_addr.s_addr = INADDR_ANY;
+ memset(&myAddr.sin_zero, '\0', 8);
+
+ if(UDT::bind(mySocket, (sockaddr*)&myAddr, sizeof(myAddr)) == UDT::ERROR)
+ {
+ // TODO: Add ip and port to error
+ std::string errMsg = "UDT: Failed to bind, error: ";
+ errMsg += UDT::getlasterror().getErrorMessage();
+ throw ConnectionException(errMsg);
+ }
+ }
+
+ void DirectConnections::cleanup()
+ {
+ UDT::epoll_release(eid);
+
+ if(mySocket != 0)
+ UDT::close(mySocket);
+
+ UDT::cleanup();
+ }
+
+ void DirectConnections::connect(const Ipv4 &address)
+ {
+ if(UDT::connect(mySocket, address.address->ai_addr, address.address->ai_addrlen) == UDT::ERROR)
+ {
+ // TODO: Add ip and port to error
+ std::string errMsg = "UDT: Failed to connect, error: ";
+ errMsg += UDT::getlasterror().getErrorMessage();
+ throw ConnectionException(errMsg);
+ }
+
+ //UDT::epoll_add_usock(eid, 2);
+ }
+}
diff --git a/src/main.cpp b/src/main.cpp
deleted file mode 100644
index f3f6f6c..0000000
--- a/src/main.cpp
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <udt/udt.h>
-
-int main()
-{
- return 0;
-}
diff --git a/tests/main.cpp b/tests/main.cpp
new file mode 100644
index 0000000..63e50c3
--- /dev/null
+++ b/tests/main.cpp
@@ -0,0 +1,6 @@
+#include "../include/DirectConnection.hpp"
+
+int main()
+{
+ return 0;
+}