Compare commits

..

30 Commits

Author SHA1 Message Date
WolverinDEV
931e1c270b Merge branch '1.4.10-openssl' of https://git.did.science/TeaSpeak/server/root into 1.4.10-openssl 2021-04-15 19:42:00 +02:00
WolverinDEV
bc54660006 Updated revs 2021-04-15 19:41:49 +02:00
WolverinDEV
0ccee27e6a Updated openssl-prebuild rev 2021-01-26 13:34:08 +00:00
WolverinDEV
bc24c6d91f Updated some refs 2021-01-26 13:33:44 +00:00
WolverinDEV
facddce695 Updated build helpers rev 2020-07-31 17:40:20 +02:00
WolverinDEV
bcff60d91f Update to 1.4.18 2020-07-31 17:37:51 +02:00
WolverinDEV
1ce0f85b46 Fixed tommath rev 2020-05-10 16:41:21 +02:00
WolverinDEV
6bd5c60186 Fixed tommath branch 2020-05-10 16:39:33 +02:00
WolverinDEV
d3ade9a2ab Fixed broken reference 2020-05-10 16:31:14 +02:00
WolverinDEV
be4c69e956 Updated TeaSpeak rev 2020-05-10 16:28:06 +02:00
WolverinDEV
fd1d4d6e24 Fixed broken links and updated revs 2020-05-10 16:27:23 +02:00
WolverinDEV
6a52b6a6e4 Added some revs 2020-05-10 16:03:04 +02:00
WolverinDEV
b3dcde3210 Updating revs 2020-05-10 16:02:40 +02:00
WolverinDEV
de274c5547 Replaced TeaDNS module 2020-05-07 21:48:35 +02:00
WolverinDEV
58756781f3 Deleted old TeaDNS folder 2020-05-07 21:47:46 +02:00
WolverinDEV
a90c95295e Updated revs 2020-04-20 21:27:39 +02:00
WolverinDEV
507fe5f236 Updated revs 2020-04-19 23:25:08 +02:00
WolverinDEV
2f270ae6bc Updated DP rev 2020-04-19 17:22:46 +02:00
WolverinDEV
e6010f9a15 Updated refs 2020-04-19 12:54:11 +02:00
WolverinDEV
ef51e10e52 Fixed revs 2020-03-25 21:00:26 +01:00
WolverinDEV
8d18f54503 Updating revs 2020-03-25 20:38:29 +01:00
WolverinDEV
50f9c0ad52 Fixed the web rtc stuff 2020-03-20 17:00:48 +01:00
WolverinDEV
66c981da2e Some updates 2020-03-02 20:01:02 +01:00
WolverinDEV
6b7dbc57ee Updated some revs 2020-03-02 20:00:38 +01:00
WolverinDEV
0b502b3d65 Added static build for datapipes 2020-03-02 19:50:19 +01:00
WolverinDEV
0e567fb640 Updated rev 2020-03-02 19:22:49 +01:00
WolverinDEV
9e36c9a718 Updated DP rev 2020-03-02 19:10:33 +01:00
WolverinDEV
a4eca54d4f Updated build helper rev 2020-03-02 18:56:22 +01:00
WolverinDEV
9d9812b9b1 Updated main revs 2020-03-02 18:48:44 +01:00
WolverinDEV
e9ab8a565e Updated library refs 2020-03-02 18:43:38 +01:00
40 changed files with 127 additions and 1710 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ WebClient.zip
Web-Client-I18N Web-Client-I18N
.idea .idea
symbols symbols
downloads

27
.gitmodules vendored
View File

@ -4,14 +4,15 @@
branch = master branch = master
[submodule "libraries/Thread-Pool"] [submodule "libraries/Thread-Pool"]
path = libraries/Thread-Pool path = libraries/Thread-Pool
url = http://git.mcgalaxy.de:8090/WolverinDEV/Thread-Pool.git url = https://git.did.science/WolverinDEV/ThreadPool.git
branch = master branch = master
[submodule "libraries/tomcrypt"] [submodule "libraries/tomcrypt"]
path = libraries/tomcrypt path = libraries/tomcrypt
url = http://git.mcgalaxy.de:8090/WolverinDEV/tomcrypt.git url = https://git.did.science/TeaSpeak/libraries/tomcrypt.git
[submodule "libraries/tommath"] [submodule "libraries/tommath"]
branch = develop
path = libraries/tommath path = libraries/tommath
url = http://git.mcgalaxy.de:8090/WolverinDEV/tommath.git url = https://git.did.science/TeaSpeak/libraries/tommath.git
[submodule "libraries/CXXTerminal"] [submodule "libraries/CXXTerminal"]
path = libraries/CXXTerminal path = libraries/CXXTerminal
url = https://github.com/WolverinDEV/CXXTerminal.git url = https://github.com/WolverinDEV/CXXTerminal.git
@ -30,10 +31,10 @@
url = https://github.com/libevent/libevent.git url = https://github.com/libevent/libevent.git
[submodule "TeaSpeak"] [submodule "TeaSpeak"]
path = TeaSpeak path = TeaSpeak
url = https://git.did.science/WolverinDEV/TeaSpeak.git url = https://git.did.science/TeaSpeak/Server/Server
[submodule "libraries/spdlog"] [submodule "libraries/spdlog"]
path = libraries/spdlog path = libraries/spdlog
url = http://git.mcgalaxy.de:8090/WolverinDEV/spdlog.git url = https://git.did.science/TeaSpeak/libraries/spdlog.git
[submodule "libraries/StringVariable"] [submodule "libraries/StringVariable"]
path = libraries/StringVariable path = libraries/StringVariable
url = https://github.com/WolverinDEV/StringVariable.git url = https://github.com/WolverinDEV/StringVariable.git
@ -57,15 +58,21 @@
path = libraries/jemalloc path = libraries/jemalloc
url = https://github.com/jemalloc/jemalloc.git url = https://github.com/jemalloc/jemalloc.git
branch = dev branch = dev
[submodule "Web-Client"]
path = Web-Client
url = https://github.com/TeaSpeak/TeaWeb.git
[submodule "build-helpers"] [submodule "build-helpers"]
path = build-helpers path = build-helpers
url = https://github.com/WolverinDEV/build-helpers.git url = https://github.com/WolverinDEV/build-helpers.git
[submodule "libraries/libnice"] [submodule "libraries/libnice"]
path = libraries/libnice path = libraries/libnice
url = https://git.did.science/WolverinDEV/libnice-prebuild.git url = https://git.did.science/TeaSpeak/libraries/libnice-prebuild.git
[submodule "libraries/glibc"] [submodule "libraries/glibc"]
path = libraries/glibc path = libraries/glibc
url = https://git.did.science/WolverinDEV/glibc-prebuild.git url = https://git.did.science/TeaSpeak/libraries/glib2.0.git
[submodule "libraries/openssl-prebuild"]
path = libraries/openssl-prebuild
url = https://git.did.science/TeaSpeak/libraries/openssl-prebuild.git
[submodule "TeaDNS"]
path = TeaDNS
url = https://git.did.science/TeaSpeak/WebDNS.git
[submodule "libraries/zstd"]
path = libraries/zstd
url = https://github.com/facebook/zstd.git

1
TeaDNS Submodule

@ -0,0 +1 @@
Subproject commit 58c1ce1185e32617870606e9926ab415418f984b

View File

@ -1,30 +0,0 @@
cmake_minimum_required(VERSION 3.15)
project(TeaWebDNS)
set(CMAKE_CXX_STANDARD 17)
#Setup the compiler (Cant be done within a function!)
if (MSVC)
set(CompilerFlags
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -static-libgcc -static-libstdc++")
endif()
# Require libevent
find_package(Libevent REQUIRED)
include_directories(${LIBEVENT_INCLUDE_DIRS})
add_executable(TeaWebDNS main.cpp src/server.cpp)
target_link_libraries(TeaWebDNS ${LIBEVENT_STATIC_LIBRARIES} pthread)

View File

@ -1,32 +0,0 @@
cmake_minimum_required(VERSION 3.15)
project(TeaWebDNS)
set(CMAKE_CXX_STANDARD 17)
#Setup the compiler (Cant be done within a function!)
if (MSVC)
set(CompilerFlags
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
)
foreach(CompilerFlag ${CompilerFlags})
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -static-libgcc -static-libstdc++")
endif()
# Require libevent
find_package(Libevent REQUIRED)
include_directories(${LIBEVENT_INCLUDE_DIRS})
add_subdirectory(util)
add_executable(TeaWebDNS main.cpp server/src/server.cpp server/src/handler.cpp)
target_link_libraries(TeaWebDNS ${LIBEVENT_STATIC_LIBRARIES} pthread teadns__parser)

View File

@ -1,38 +0,0 @@
#include <iostream>
#include <cstring>
#include "server/src/server.h"
#include "server/src/handler.h"
using namespace ts::dns;
std::vector<sockaddr_storage> bindings() {
std::vector<sockaddr_storage> result{};
{
sockaddr_in& any_v4{reinterpret_cast<sockaddr_in&>(result.emplace_back())};
memset(&any_v4, 0, sizeof(sockaddr_in));
any_v4.sin_family = AF_INET;
any_v4.sin_port = htons(1222); //htons(53);
any_v4.sin_addr.s_addr = (1UL << 24U) | 127U;
}
return result;
}
int main() {
std::string error{};
auto handler = std::make_shared<DNSHandler>();
WebDNSServer server{handler};
if(!server.start(bindings(), error)) {
for(auto& binding : server.bindings())
std::cout << " - " << binding->error << "\n";
std::cerr << "Failed to start server: " << error << "\n";
return 1;
}
std::this_thread::sleep_for(std::chrono::seconds{100});
return 0;
}

View File

@ -1,8 +0,0 @@
#include <iostream>
#include "handler.h"
#include "net.h"
void ts::dns::WebDNSHandler::handle_message(const sockaddr_storage &address, void *buffer, size_t size) {
std::cout << "Received " << size << " bytes from " << net::to_string(address, true) << "\n";
}

View File

@ -1,17 +0,0 @@
#pragma once
#include <sys/socket.h>
namespace ts::dns {
class DNSHandler {
public:
virtual void handle_message(const sockaddr_storage& /* address */, void* /* buffer */, size_t /* buffer size */) = 0;
};
class WebDNSHandler : public DNSHandler {
public:
void handle_message(const sockaddr_storage &storage, void *pVoid, size_t size) override;
private:
};
}

View File

@ -1,261 +0,0 @@
#pragma once
#include <string>
#include <cstring>
#include <deque>
#include <vector>
#include <tuple>
#ifdef WIN32
#include <WS2tcpip.h>
#include <WinSock2.h>
#include <Windows.h>
#include <in6addr.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#endif
namespace net {
inline std::string to_string(const in6_addr& address) {
char buffer[INET6_ADDRSTRLEN];
if(!inet_ntop(AF_INET6, (void*) &address, buffer, INET6_ADDRSTRLEN)) return "";
return std::string(buffer);
}
inline std::string to_string(const in_addr& address) {
char buffer[INET_ADDRSTRLEN];
if(!inet_ntop(AF_INET, (void*) &address, buffer, INET_ADDRSTRLEN)) return "";
return std::string(buffer);
}
inline uint16_t port(const sockaddr_storage& address) {
switch(address.ss_family) {
case AF_INET:
return htons(((sockaddr_in*) &address)->sin_port);
case AF_INET6:
return htons(((sockaddr_in6*) &address)->sin6_port);
default:
return 0;
}
}
inline std::string to_string(const sockaddr_storage& address, bool port = true) {
switch(address.ss_family) {
case AF_INET:
return to_string(((sockaddr_in*) &address)->sin_addr) + (port ? ":" + std::to_string(htons(((sockaddr_in*) &address)->sin_port)) : "");
case AF_INET6:
return to_string(((sockaddr_in6*) &address)->sin6_addr) + (port ? ":" + std::to_string(htons(((sockaddr_in6*) &address)->sin6_port)) : "");
default:
return "unknown_type";
}
}
inline socklen_t address_size(const sockaddr_storage& address) {
switch (address.ss_family) {
case AF_INET: return sizeof(sockaddr_in);
case AF_INET6: return sizeof(sockaddr_in6);
default: return 0;
}
}
inline bool address_equal(const sockaddr_storage& a, const sockaddr_storage& b) {
if(a.ss_family != b.ss_family) return false;
if(a.ss_family == AF_INET) return ((sockaddr_in*) &a)->sin_addr.s_addr == ((sockaddr_in*) &b)->sin_addr.s_addr;
else if(a.ss_family == AF_INET6) {
#ifdef WIN32
return memcmp(((sockaddr_in6*) &a)->sin6_addr.u.Byte, ((sockaddr_in6*) &b)->sin6_addr.u.Byte, 16) == 0;
#else
return memcmp(((sockaddr_in6*) &a)->sin6_addr.__in6_u.__u6_addr8, ((sockaddr_in6*) &b)->sin6_addr.__in6_u.__u6_addr8, 16) == 0;
#endif
}
return false;
}
inline bool address_equal_ranged(const sockaddr_storage& a, const sockaddr_storage& b, uint8_t range) {
if(a.ss_family != b.ss_family) return false;
if(a.ss_family == AF_INET) {
auto address_a = ((sockaddr_in*) &a)->sin_addr.s_addr;
auto address_b = ((sockaddr_in*) &b)->sin_addr.s_addr;
if(range > 32)
range = 32;
range = (uint8_t) (32 - range);
address_a <<= range;
address_b <<= range;
return address_a == address_b;
} else if(a.ss_family == AF_INET6) {
#ifdef WIN32
throw std::runtime_error("not implemented");
//FIXME: Implement me!
#elif defined(__x86_64__) && false
static_assert(sizeof(__int128) == 16);
auto address_a = (__int128) ((sockaddr_in6*) &a)->sin6_addr.__in6_u.__u6_addr32;
auto address_b = (__int128) ((sockaddr_in6*) &b)->sin6_addr.__in6_u.__u6_addr32;
if(range > 128)
range = 128;
range = (uint8_t) (128 - range);
address_a <<= range;
address_b <<= range;
return address_a == address_b;
#else
static_assert(sizeof(uint64_t) == 8);
if(range > 128)
range = 128;
range = (uint8_t) (128 - range);
auto address_ah = (uint64_t) (((sockaddr_in6*) &a)->sin6_addr.__in6_u.__u6_addr8 + 0);
auto address_al = (uint64_t) (((sockaddr_in6*) &a)->sin6_addr.__in6_u.__u6_addr8 + 8);
auto address_bh = (uint64_t) (((sockaddr_in6*) &b)->sin6_addr.__in6_u.__u6_addr8 + 0);
auto address_bl = (uint64_t) (((sockaddr_in6*) &b)->sin6_addr.__in6_u.__u6_addr8 + 8);
if(range > 64) {
/* only lower counts */
return (address_al << (range - 64)) == (address_bl << (range - 64));
} else {
return address_al == address_bl &&(address_bh << (range - 64)) == (address_ah << (range - 64));
}
#endif
}
return false;
}
inline bool is_ipv6(const std::string& str) {
sockaddr_in6 sa{};
return inet_pton(AF_INET6, str.c_str(), &(sa.sin6_addr)) != 0;
}
inline bool is_ipv4(const std::string& str) {
sockaddr_in sa{};
return inet_pton(AF_INET, str.c_str(), &(sa.sin_addr)) != 0;
}
inline bool is_anybind(sockaddr_storage& storage) {
if(storage.ss_family == AF_INET) {
auto data = (sockaddr_in*) &storage;
return data->sin_addr.s_addr == 0;
} else if(storage.ss_family == AF_INET6) {
auto data = (sockaddr_in6*) &storage;
#ifdef WIN32
auto& blocks = data->sin6_addr.u.Word;
return
blocks[0] == 0 &&
blocks[1] == 0 &&
blocks[2] == 0 &&
blocks[3] == 0 &&
blocks[4] == 0 &&
blocks[5] == 0 &&
blocks[6] == 0 &&
blocks[7] == 0;
#else
auto& blocks = data->sin6_addr.__in6_u.__u6_addr32;
return blocks[0] == 0 && blocks[1] == 0 && blocks[2] == 0 && blocks[3] == 0;
#endif
}
return false;
}
inline bool resolve_address(const std::string& address, sockaddr_storage& result) {
if(is_ipv4(address)) {
sockaddr_in s{};
s.sin_port = 0;
s.sin_family = AF_INET;
auto record = gethostbyname(address.c_str());
if(!record)
return false;
s.sin_addr.s_addr = ((in_addr*) record->h_addr)->s_addr;
memcpy(&result, &s, sizeof(s));
return true;
} else if(is_ipv6(address)) {
sockaddr_in6 s{};
s.sin6_family = AF_INET6;
s.sin6_port = 0;
s.sin6_flowinfo = 0;
s.sin6_scope_id = 0;
#ifdef WIN32
auto record = gethostbyname(address.c_str());
#else
auto record = gethostbyname2(address.c_str(), AF_INET6);
#endif
if(!record) return false;
s.sin6_addr = *(in6_addr*) record->h_addr;
memcpy(&result, &s, sizeof(s));
return true;
} else if(address == "[::]" || address == "::") {
sockaddr_in6 s{};
s.sin6_family = AF_INET6;
s.sin6_port = 0;
s.sin6_flowinfo = 0;
s.sin6_scope_id = 0;
memcpy(&s.sin6_addr, &in6addr_any, sizeof(in6_addr));
memcpy(&result, &s, sizeof(s));
return true;
}
return false;
}
namespace helpers {
inline void strip(std::string& message) {
while(!message.empty()) {
if(message[0] == ' ')
message = message.substr(1);
else if(message[message.length() - 1] == ' ')
message = message.substr(0, message.length() - 1);
else break;
}
}
inline std::deque<std::string> split(const std::string& message, char delimiter) {
std::deque<std::string> result{};
size_t found, index = 0;
do {
found = message.find(delimiter, index);
result.push_back(message.substr(index, found - index));
index = found + 1;
} while(index != 0);
return result;
}
}
inline std::vector<std::tuple<std::string, sockaddr_storage, std::string>> resolve_bindings(const std::string& bindings, uint16_t port) {
auto binding_list = helpers::split(bindings, ',');
std::vector<std::tuple<std::string, sockaddr_storage, std::string>> result;
result.reserve(binding_list.size());
for(auto& address : binding_list) {
helpers::strip(address);
sockaddr_storage element{};
memset(&element, 0, sizeof(element));
if(!resolve_address(address, element)) {
result.emplace_back(address, element, "address resolve failed");
continue;
}
if(element.ss_family == AF_INET) {
((sockaddr_in*) &element)->sin_port = htons(port);
} else if(element.ss_family == AF_INET6) {
((sockaddr_in6*) &element)->sin6_port = htons(port);
}
result.emplace_back(address, element, "");
}
return result;
}
}

View File

@ -1,254 +0,0 @@
#include "./server.h"
#include "./handler.h"
#include "./net.h"
#include <event.h>
#include <functional>
#include <cstring>
#include <iostream>
#include <cassert>
#include <zconf.h>
#include <fcntl.h>
using namespace ts::dns;
WebDNSServer::~WebDNSServer() {
this->stop();
}
bool WebDNSServer::start(const std::vector<sockaddr_storage> &bindings, std::string &error) {
size_t successful_binds{0};
std::lock_guard lock{this->bind_lock};
if(this->started) {
error = "server already bound";
return false;
}
this->event_base = event_base_new();
if(!this->event_base) {
error = "failed to spawn event base";
goto error_exit;
}
this->event_base_ticker = evtimer_new(this->event_base, [](auto, auto, void* server){
reinterpret_cast<WebDNSServer*>(server)->event_cb_timer();
}, this);
if(!this->event_base_ticker) {
error = "failed to spawn heartbeat event";
goto error_exit;
}
this->_bindings.resize(bindings.size());
for(size_t index = 0; index < bindings.size(); index++) {
auto& binding = *(this->_bindings[index] = std::make_unique<Binding>());
binding.server = this;
memcpy(&binding.address, &bindings[index], sizeof(sockaddr_storage));
if(!this->bind(binding, error))
binding.error = error;
else
successful_binds++;
}
if(!successful_binds) {
error = "failed to bind to any address";
goto error_exit;
}
{
timeval timeout{10, 0};
event_add(this->event_base_ticker, &timeout);
}
this->event_base_executor = std::thread(std::bind(&WebDNSServer::event_executor, this));
this->started = true;
return true;
error_exit:
if(this->event_base_ticker) {
event_del_block(this->event_base_ticker);
event_free(this->event_base_ticker);
this->event_base_ticker = nullptr;
}
if(this->event_base) {
event_base_free(this->event_base);
this->event_base = nullptr;
}
return false;
}
void WebDNSServer::stop() {
std::unique_lock lock{this->bind_lock};
if(!this->started)
return;
this->started = false;
assert(this->event_base); //Must be set else the started flag was invalid
assert(this->event_base_ticker); //Must be set else the started flag was invalid
event_base_loopexit(this->event_base, nullptr);
timeval timeout{0, 0};
event_add(this->event_base_ticker, &timeout);
//TODO: timeout?
lock.unlock();
this->event_base_executor.join();
lock.lock();
for(auto& binding : this->bindings())
this->unbind(*binding);
event_free(this->event_base_ticker);
this->event_base_ticker = nullptr;
}
bool WebDNSServer::bind(Binding &binding, std::string &error) {
binding.socket = socket(binding.address.ss_family, SOCK_DGRAM, 0);
if(binding.socket < 2) {
error = "failed to create socket";
return false;
}
int enable{1};
if(binding.address.ss_family == AF_INET6) {
if(setsockopt(binding.socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &enable, sizeof(enable)) < 0) {
error = "failed to enable packet info (v6) (" + std::to_string(errno) + "/" + strerror(errno) + ")";
goto cleanup_exit;
}
if(setsockopt(binding.socket, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)) < 0) {
error = "failed to enable ip v6 only (" + std::to_string(errno) + "/" + strerror(errno) + ")";
goto cleanup_exit;
}
} else {
if(setsockopt(binding.socket, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable)) < 0) {
error = "failed to enable packet info (" + std::to_string(errno) + "/" + strerror(errno) + ")";
goto cleanup_exit;
}
}
if(::bind(binding.socket, (const sockaddr*) &binding.address, sizeof(binding.address)) < 0) {
error = "failed to bind: " + std::to_string(errno) + "/" + strerror(errno);
goto cleanup_exit;
}
if(fcntl(binding.socket, F_SETFL, fcntl(binding.socket, F_GETFL, 0) | O_NONBLOCK) < 0) {
error = "failed to enable noblock";
goto cleanup_exit;
}
#ifdef WIN32
u_long enabled = 0;
auto non_block_rs = ioctlsocket(binding.socket, FIONBIO, &enabled);
if (non_block_rs != NO_ERROR) {
error = "failed to enable nonblock";
goto cleanup_exit;
}
#endif
binding.read_event = event_new(this->event_base, binding.socket, EV_READ | EV_PERSIST, &WebDNSServer::event_cb_read, &binding);
if(!binding.read_event) {
error = "failed to create read event";
goto cleanup_exit;
}
binding.write_event = event_new(this->event_base, binding.socket, EV_WRITE, &WebDNSServer::event_cb_write, &binding);
if(!binding.read_event) {
error = "failed to create write event";
goto cleanup_exit;
}
event_add(binding.read_event, nullptr);
return true;
cleanup_exit:
if(binding.read_event) {
event_del_noblock(binding.read_event);
event_free(binding.read_event);
binding.read_event = nullptr;
}
if(binding.write_event) {
event_del_noblock(binding.write_event);
event_free(binding.write_event);
binding.write_event = nullptr;
}
return false;
}
void WebDNSServer::unbind(Binding &binding) {
if(binding.read_event) {
event_del_block(binding.read_event);
event_free(binding.read_event);
binding.read_event = nullptr;
}
if(binding.write_event) {
event_del_block(binding.write_event);
event_free(binding.write_event);
binding.write_event = nullptr;
}
if(binding.socket) {
::shutdown(binding.socket, SHUT_RDWR);
::close(binding.socket);
binding.socket = 0;
}
}
void WebDNSServer::event_executor() {
do {
event_base_dispatch(this->event_base);
} while(event_base_got_exit(this->event_base));
}
void WebDNSServer::event_cb_timer() {
std::lock_guard lock{this->bind_lock};
if(this->started) {
timeval timeout{10, 0};
event_add(this->event_base_ticker, &timeout);
}
}
void WebDNSServer::event_cb_read(evutil_socket_t fd, short, void *ptr_binding) {
auto binding = reinterpret_cast<Binding*>(ptr_binding);
auto server = binding->server;
sockaddr_storage source_address{};
socklen_t source_address_length{0};
ssize_t read_length{-1};
size_t buffer_length = 1600; /* IPv6 MTU is ~1.5k */
char buffer[1600];
size_t read_count = 0;
while(true) { //TODO: Some kind of timeout
source_address_length = sizeof(sockaddr_storage);
read_length = recvfrom(fd, (char*) buffer, buffer_length, MSG_DONTWAIT, (struct sockaddr*) &source_address, &source_address_length);
if(read_length <= 0) {
if(errno == EAGAIN)
break;
std::cerr << "Failed to receive data: " << errno << "/" << strerror(errno) << "\n";
break; /* this should never happen! */
}
read_count++;
//buffer, (size_t) read_length
auto handler = server->handler;
if(handler)
handler->handle_message(source_address, buffer, read_length);
else
std::cerr << "Dropping " << read_length << " bytes from " << net::to_string(source_address, true) << " because we've no handler\n";
}
}
void WebDNSServer::event_cb_write(evutil_socket_t fd, short, void *ptr_binding) {
auto binding = reinterpret_cast<Binding*>(ptr_binding);
auto server = binding->server;
}

View File

@ -1,54 +0,0 @@
#pragma once
#include <sys/socket.h>
#include <vector>
#include <string>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <event.h>
namespace ts::dns {
class DNSHandler;
class WebDNSServer {
public:
struct Binding {
WebDNSServer* server{nullptr};
sockaddr_storage address{};
int socket{0};
std::string error{};
inline bool active() const { return this->socket != 0; }
event* read_event{nullptr};
event* write_event{nullptr};
};
WebDNSServer(const std::shared_ptr<DNSHandler>& handler) : handler{handler} {};
virtual ~WebDNSServer();
bool start(const std::vector<sockaddr_storage>& /* bindings */, std::string& /* error */);
void stop();
const std::vector<std::unique_ptr<Binding>>& bindings() const { return this->_bindings; }
private:
std::shared_ptr<DNSHandler> handler;
std::mutex bind_lock{};
std::vector<std::unique_ptr<Binding>> _bindings;
bool started{false};
std::thread event_base_executor{};
struct event* event_base_ticker{nullptr};
struct event_base* event_base{nullptr};
bool bind(Binding& /* binding */, std::string& /* error */);
void unbind(Binding& /* binding */);
void event_cb_timer();
static void event_cb_read(evutil_socket_t fd, short, void *binding);
static void event_cb_write(evutil_socket_t fd, short, void *binding);
void event_executor();
};
}

View File

@ -1,5 +0,0 @@
project(TeaDNS-Parser)
add_library(teadns__parser INTERFACE)
target_sources(teadns__parser INTERFACE src/response.cpp src/types.cpp)
target_include_directories(teadns__parser INTERFACE include)

View File

@ -1,8 +0,0 @@
//
// Created by wolverindev on 21.11.19.
//
#ifndef TEAWEBDNS_BUILDER_H
#define TEAWEBDNS_BUILDER_H
#endif //TEAWEBDNS_BUILDER_H

View File

@ -1,254 +0,0 @@
#pragma once
#include <memory>
#include <string>
#include <cstdint>
#include <vector>
#ifdef WIN32
#include <WinSock2.h>
#include <Windows.h>
#include <WinDNS.h>
#else
#include <netinet/in.h>
#endif
#include "./types.h"
struct in6_addr;
namespace tc::dns {
namespace response {
class DNSHeader;
class DNSQuery;
class DNSResourceRecords;
}
class DNSResponse;
struct DNSResponseData;
struct DNSResponseData {
#ifdef WIN32
bool wide_string{false};
DNS_QUERY_RESULT data{};
#else
uint8_t* buffer{nullptr};
size_t length{0};
std::string parse_dns_dn(std::string& /* error */, size_t& /* index */, bool /* compression allowed */);
#endif
~DNSResponseData();
};
class DNSResponse {
friend class Resolver;
public:
typedef std::vector<std::shared_ptr<response::DNSResourceRecords>> rr_list_t;
typedef std::vector<std::shared_ptr<response::DNSQuery>> q_list_t;
DNSResponse(const DNSResponse&) = delete;
DNSResponse(DNSResponse&&) = delete;
bool parse(std::string& /* error */);
#ifndef WIN32
[[nodiscard]] inline const std::string why_bogus() const { return this->bogus; }
[[nodiscard]] inline const uint8_t* packet_data() const { return this->data->buffer; }
[[nodiscard]] inline size_t packet_length() const { return this->data->length; }
[[nodiscard]] inline bool is_secure() const { return this->secure_state > 0; }
[[nodiscard]] inline bool is_secure_dnssec() const { return this->secure_state == 2; }
[[nodiscard]] response::DNSHeader header() const;
#endif
[[nodiscard]] q_list_t queries() const { return this->parsed_queries; }
[[nodiscard]] rr_list_t answers() const { return this->parsed_answers; }
[[nodiscard]] rr_list_t authorities() const { return this->parsed_authorities; }
[[nodiscard]] rr_list_t additionals() const { return this->parsed_additionals; }
private:
#ifndef WIN32
DNSResponse(uint8_t /* secure state */, const char* /* bogus */, void* /* packet */, size_t /* length */);
std::shared_ptr<response::DNSResourceRecords> parse_rr(std::string& /* error */, size_t& index, bool /* compression allowed dn */);
std::string bogus;
uint8_t secure_state{0};
#else
DNSResponse(std::shared_ptr<DNSResponseData>);
#endif
std::shared_ptr<DNSResponseData> data{nullptr};
bool is_parsed{false};
std::string parse_error{};
q_list_t parsed_queries;
rr_list_t parsed_answers;
rr_list_t parsed_authorities;
rr_list_t parsed_additionals;
};
namespace response {
#ifndef WIN32
class DNSHeader {
friend class tc::dns::DNSResponse;
public:
[[nodiscard]] inline size_t id() const { return this->field(0); }
[[nodiscard]] inline bool is_answer() const { return this->field(1) & 0x1UL; }
[[nodiscard]] inline bool is_authoritative_answer() const { return (uint8_t) ((this->field(1) >> 5UL) & 0x01UL); }
[[nodiscard]] inline bool is_truncation() const { return (uint8_t) ((this->field(1) >> 6UL) & 0x01UL); }
[[nodiscard]] inline bool is_recursion_desired() const { return (uint8_t) ((this->field(1) >> 7UL) & 0x01UL); }
[[nodiscard]] inline bool is_recursion_available() const { return (uint8_t) ((this->field(1) >> 8UL) & 0x01UL); }
[[nodiscard]] inline uint8_t query_type() const { return (uint8_t) ((this->field(1) >> 1UL) & 0x07UL); }
[[nodiscard]] inline uint8_t response_code() const { return (uint8_t) ((this->field(1) >> 12UL) & 0x07UL); }
[[nodiscard]] inline uint16_t query_count() const { return ntohs(this->field(2)); }
[[nodiscard]] inline uint16_t answer_count() const { return ntohs(this->field(3)); }
[[nodiscard]] inline uint16_t authority_count() const { return ntohs(this->field(4)); }
[[nodiscard]] inline uint16_t additional_count() const { return htons(this->field(5)); }
private:
[[nodiscard]] uint16_t field(int index) const;
explicit DNSHeader(const DNSResponse* response) : response{response} {}
const DNSResponse* response{nullptr};
};
#endif
class DNSQuery {
friend class tc::dns::DNSResponse;
public:
[[nodiscard]] inline std::string qname() const { return this->name; }
[[nodiscard]] inline rrtype::value qtype() const { return this->type; }
[[nodiscard]] inline rrclass::value qclass() const { return this->klass; }
private:
DNSQuery(std::string name, rrtype::value type, rrclass::value klass) : name{std::move(name)}, type{type}, klass{klass} {}
std::string name;
rrtype::value type;
rrclass::value klass;
};
class DNSResourceRecords {
friend class tc::dns::DNSResponse;
public:
[[nodiscard]] inline std::string qname() const {
#ifdef WIN32
return std::string{this->nrecord->pName};
#else
return this->name;
#endif
}
[[nodiscard]] inline rrtype::value atype() const {
#ifdef WIN32
return static_cast<rrtype::value>(this->nrecord->wType);
#else
return this->type;
#endif
}
[[nodiscard]] inline rrclass::value aclass() const {
#ifdef WIN32
return static_cast<rrclass::value>(1);
#else
return this->klass;
#endif
}
[[nodiscard]] inline uint16_t attl() const {
#ifdef WIN32
return (uint16_t) this->nrecord->dwTtl;
#else
return this->ttl;
#endif
}
#ifndef WIN32
[[nodiscard]] const uint8_t* payload_data() const;
[[nodiscard]] inline size_t payload_length() const { return this->length; }
[[nodiscard]] inline size_t payload_offset() const { return this->offset; }
#else
[[nodiscard]] inline PDNS_RECORDA native_record() const { return this->nrecord; }
[[nodiscard]] bool is_wide_string() const;
#endif
[[nodiscard]] inline std::shared_ptr<DNSResponseData> dns_data() const {
return this->data;
}
template <typename T>
[[nodiscard]] inline T parse() const {
if(T::type != this->atype())
throw std::logic_error{"parser type mismatch"};
return T{this};
}
private:
std::shared_ptr<DNSResponseData> data{nullptr};
#ifdef WIN32
DNSResourceRecords(std::shared_ptr<DNSResponseData>, PDNS_RECORDA);
PDNS_RECORDA nrecord{nullptr};
#else
DNSResourceRecords(std::shared_ptr<DNSResponseData>, size_t, size_t, uint32_t, std::string , rrtype::value, rrclass::value);
size_t offset{0};
size_t length{0};
uint32_t ttl;
std::string name;
rrtype::value type;
rrclass::value klass;
#endif
};
namespace rrparser {
struct base {
protected:
explicit base(const DNSResourceRecords* handle) : handle{handle} {}
const DNSResourceRecords* handle{nullptr};
};
struct named_base : public base {
public:
[[nodiscard]] bool is_valid();
[[nodiscard]] std::string name();
protected:
explicit named_base(const DNSResourceRecords* handle) : base{handle} {}
};
#define define_parser(name, base, ...) \
struct name : public base { \
friend class response::DNSResourceRecords; \
public: \
static constexpr auto type = rrtype::name; \
__VA_ARGS__ \
private: \
explicit name(const DNSResourceRecords* handle) : base{handle} {} \
}
define_parser(A, base,
[[nodiscard]] bool is_valid();
[[nodiscard]] std::string address_string();
[[nodiscard]] in_addr address();
);
define_parser(AAAA, base,
[[nodiscard]] bool is_valid();
[[nodiscard]] std::string address_string();
[[nodiscard]] in6_addr address();
);
define_parser(SRV, base,
[[nodiscard]] bool is_valid();
[[nodiscard]] uint16_t priority();
[[nodiscard]] uint16_t weight();
[[nodiscard]] uint16_t target_port();
[[nodiscard]] std::string target_hostname();
);
define_parser(CNAME, named_base);
};
}
}

View File

@ -1,138 +0,0 @@
#pragma once
#include <map>
#include <cstdint>
namespace tc::dns {
//https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
struct rrtype {
enum value : uint32_t {
A = 1, // a host address,[RFC1035],
NS = 2, // an authoritative name server,[RFC1035],
MD = 3, // a mail destination (OBSOLETE - use MX),[RFC1035],
MF = 4, // a mail forwarder (OBSOLETE - use MX),[RFC1035],
CNAME = 5, // the canonical name for an alias,[RFC1035],
SOA = 6, // marks the start of a zone of authority,[RFC1035],
MB = 7, // a mailbox domain name (EXPERIMENTAL),[RFC1035],
MG = 8, // a mail group member (EXPERIMENTAL),[RFC1035],
MR = 9, // a mail rename domain name (EXPERIMENTAL),[RFC1035],
NULL_ = 10, // a null RR (EXPERIMENTAL),[RFC1035],
WKS = 11, // a well known service description,[RFC1035],
PTR = 12, // a domain name pointer,[RFC1035],
HINFO = 13, // host information,[RFC1035],
MINFO = 14, // mailbox or mail list information,[RFC1035],
MX = 15, // mail exchange,[RFC1035],
TXT = 16, // text strings,[RFC1035],
RP = 17, // for Responsible Person,[RFC1183],
AFSDB = 18, // for AFS Data Base location,[RFC1183][RFC5864],
X25 = 19, // for X.25 PSDN address,[RFC1183],
ISDN = 20, // for ISDN address,[RFC1183],
RT = 21, // for Route Through,[RFC1183],
NSAP = 22, // "for NSAP address, NSAP style A record",[RFC1706],
NSAP_PTR = 23, // "for domain name pointer, NSAP style",[RFC1348][RFC1637][RFC1706],
SIG = 24, // for security signature,[RFC4034][RFC3755][RFC2535][RFC2536][RFC2537][RFC2931][RFC3110][RFC3008],
KEY = 25, // for security key,[RFC4034][RFC3755][RFC2535][RFC2536][RFC2537][RFC2539][RFC3008][RFC3110],
PX = 26, // X.400 mail mapping information,[RFC2163],
GPOS = 27, // Geographical Position,[RFC1712],
AAAA = 28, // IP6 Address,[RFC3596],
LOC = 29, // Location Information,[RFC1876],
NXT = 30, // Next Domain (OBSOLETE),[RFC3755][RFC2535],
EID = 31, // Endpoint Identifier,[Michael_Patton][http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt],
NIMLOC = 32, // Nimrod Locator,[1][Michael_Patton][http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt],
SRV = 33, // Server Selection,[1][RFC2782],
ATMA = 34, // ATM Address,"[ ATM Forum Technical Committee, ""ATM Name System, V2.0"", Doc ID: AF-DANS-0152.000, July 2000. Available from and held in escrow by IANA.]",
NAPTR = 35, // Naming Authority Pointer,[RFC2915][RFC2168][RFC3403],
KX = 36, // Key Exchanger,[RFC2230],
CERT = 37, //CERT, // [RFC4398],
A6 = 38, // A6 (OBSOLETE - use AAAA),[RFC3226][RFC2874][RFC6563],
DNAME = 39, //DNAME, // [RFC6672],
SINK = 40, //SINK, // [Donald_E_Eastlake][http://tools.ietf.org/html/draft-eastlake-kitchen-sink],
OPT = 41, //OPT, // [RFC6891][RFC3225],
APL = 42, //APL, // [RFC3123],
DS = 43, // Delegation Signer,[RFC4034][RFC3658],
SSHFP = 44, // SSH Key Fingerprint,[RFC4255],
IPSECKEY = 45, //IPSECKEY, // [RFC4025],
RRSIG = 46, //RRSIG, // [RFC4034][RFC3755],
NSEC = 47, //NSEC, // [RFC4034][RFC3755],
DNSKEY = 48, //DNSKEY, // [RFC4034][RFC3755],
DHCID = 49, //DHCID, // [RFC4701],
NSEC3 = 50, //NSEC3, // [RFC5155],
NSEC3PARAM = 51, //NSEC3PARAM, // [RFC5155],
TLSA = 52, //TLSA, // [RFC6698],
SMIMEA = 53, // S/MIME cert association,[RFC8162],SMIMEA/smimea-completed-template
Unassigned = 54, // ,
HIP = 55, // Host Identity Protocol,[RFC8005],
NINFO = 56, //NINFO [Jim_Reid], // NINFO/ninfo-completed-template
RKEY = 57, //RKEY [Jim_Reid], // RKEY/rkey-completed-template
TALINK = 58, // Trust Anchor LINK,[Wouter_Wijngaards],TALINK/talink-completed-template
CDS = 59, // Child DS,[RFC7344],CDS/cds-completed-template
CDNSKEY = 60, // DNSKEY(s) the Child wants reflected in DS,[RFC7344],
OPENPGPKEY = 61, // OpenPGP Key,[RFC7929],OPENPGPKEY/openpgpkey-completed-template
CSYNC = 62, // Child-To-Parent Synchronization,[RFC7477],
ZONEMD = 63, // message digest for DNS zone,[draft-wessels-dns-zone-digest],ZONEMD/zonemd-completed-template
//Unassigned = 64-98,
SPF = 99, // [RFC7208],
UINFO = 100, // [IANA-Reserved],
UID = 101, // [IANA-Reserved],
GID = 102, // [IANA-Reserved],
UNSPEC = 103, // [IANA-Reserved],
NID = 104, //[RFC6742], // ILNP/nid-completed-template
L32 = 105, //[RFC6742], // ILNP/l32-completed-template
L64 = 106, //[RFC6742], // ILNP/l64-completed-template
LP = 107, //[RFC6742], // ILNP/lp-completed-template
EUI48 = 108, // an EUI-48 address,[RFC7043],EUI48/eui48-completed-template
EUI64 = 109, // an EUI-64 address,[RFC7043],EUI64/eui64-completed-template
//Unassigned = 110-248, // ,
TKEY = 249, // Transaction Key,[RFC2930],
TSIG = 250, // Transaction Signature,[RFC2845],
IXFR = 251, // incremental transfer,[RFC1995],
AXFR = 252, // transfer of an entire zone,[RFC1035][RFC5936],
MAILB = 253, // "mailbox-related RRs (MB, MG or MR)",[RFC1035],
MAILA = 254, // mail agent RRs (OBSOLETE - see MX),[RFC1035],
ANY = 255, // A request for some or all records the server has available,[RFC1035][RFC6895][RFC8482],
URI = 256, //URI [RFC7553], // URI/uri-completed-template
CAA = 257, // Certification Authority Restriction,[RFC-ietf-lamps-rfc6844bis-07],CAA/caa-completed-template
AVC = 258, // Application Visibility and Control,[Wolfgang_Riedel],AVC/avc-completed-template
DOA = 259, // Digital Object Architecture,[draft-durand-doa-over-dns],DOA/doa-completed-template
AMTRELAY = 260, // Automatic Multicast Tunneling Relay,[draft-ietf-mboned-driad-amt-discovery],AMTRELAY/amtrelay-completed-template
//Unassigned = 261-32767,
TA = 32768, // DNSSEC Trust Authorities,"[Sam_Weiler][http://cameo.library.cmu.edu/][ Deploying DNSSEC Without a Signed Root. Technical Report 1999-19,
// Information Networking Institute, Carnegie Mellon University, April 2004.]",
DLV = 32769, // DNSSEC Lookaside Validation,[RFC4431],
//Unassigned = 32770-65279,, // ,
//Private use,65280-65534,,,,
Reserved = 65535,
};
static std::map<value, const char*> names;
static const char* name(const value& value) {
if(names.count(value) > 0)
return names.at(value);
return "unknown";
}
};
struct rrclass {
#ifdef IN
#undef IN
#endif
enum value : uint32_t {
IN = 1, /* Internet */
CH = 3, /* Chaos */
HS = 4, /* Hesiod */
QCLASS_NONE = 254,
QCLASS_ANY = 255,
};
static std::map<value, const char*> names;
static const char* name(const value& value) {
if(names.count(value) > 0)
return names.at(value);
return "unknown";
}
};
}

View File

@ -1,4 +0,0 @@
//
// Created by wolverindev on 21.11.19.
//

View File

@ -1,403 +0,0 @@
#include "teadns/parser.h"
#include <iostream>
#include <codecvt>
#include <algorithm>
#ifdef WIN32
#include <WS2tcpip.h>
#include <in6addr.h>
#include <ip2string.h>
#include <inaddr.h>
#include <WinDNS.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#endif
using namespace tc::dns;
using namespace tc::dns::response;
using namespace tc::dns::response::rrparser;
thread_local std::vector<size_t> visited_links;
std::string DNSResponseData::parse_dns_dn(std::string &error, size_t &index, bool allow_compression) {
if(allow_compression) {
visited_links.clear();
visited_links.reserve(8);
if(std::find(visited_links.begin(), visited_links.end(), index) != visited_links.end()) {
error = "circular link detected";
return "";
}
visited_links.push_back(index);
}
error.clear();
std::string result;
result.reserve(256); //Max length is 253
while(true) {
if(index + 1 > this->length) {
error = "truncated data (missing code)";
goto exit;
}
auto code = this->buffer[index++];
if(code == 0) break;
if((code >> 6U) == 3) {
if(!allow_compression) {
error = "found link, but links are not allowed";
goto exit;
}
auto lower_addr = this->buffer[index++];
if(index + 1 > this->length) {
error = "truncated data (missing lower link address)";
goto exit;
}
size_t addr = ((code & 0x3FU) << 8U) | lower_addr;
if(addr >= this->length) {
error = "invalid link address";
goto exit;
}
auto tail = this->parse_dns_dn(error, addr, true);
if(!error.empty())
goto exit;
if(!result.empty())
result += "." + tail;
else
result = tail;
break;
} else {
if(code > 63) {
error = "max domain label length is 63 characters";
goto exit;
}
if(!result.empty())
result += ".";
if(index + code >= this->length) {
error = "truncated data (domain label)";
goto exit;
}
result.append((const char*) (this->buffer + index), code);
index += code;
}
}
exit:
if(allow_compression) visited_links.pop_back();
return result;
}
DNSResponseData::~DNSResponseData() {
::free(this->buffer);
}
DNSResponse::DNSResponse(uint8_t secure_state, const char* bogus, void *packet, size_t size) {
this->bogus = bogus ? std::string{bogus} : std::string{"packet is secure"};
this->secure_state = secure_state;
this->data = std::make_shared<DNSResponseData>();
this->data->buffer = (uint8_t*) malloc(size);
this->data->length = size;
memcpy(this->data->buffer, packet, size);
}
response::DNSHeader DNSResponse::header() const {
return response::DNSHeader{this};
}
bool DNSResponse::parse(std::string &error) {
if(this->is_parsed) {
error = this->parse_error;
return error.empty();
}
error.clear();
this->is_parsed = true;
auto header = this->header();
size_t index = 12; /* 12 bits for the header */
{
auto count = header.query_count();
this->parsed_queries.reserve(count);
for(size_t idx = 0; idx < count; idx++) {
auto dn = this->data->parse_dns_dn(error, index, true);
if(!error.empty()) {
error = "failed to parse query " + std::to_string(idx) + " dn: " + error; // NOLINT(performance-inefficient-string-concatenation)
goto error_exit;
}
if(index + 4 > this->packet_length()) {
error = "truncated data for query " + std::to_string(index);
goto error_exit;
}
auto type = (rrtype::value) ntohs(*(uint16_t*) (this->data->buffer + index));
index += 2;
auto klass = (rrclass::value) ntohs(*(uint16_t*) (this->data->buffer + index));
index += 2;
this->parsed_queries.emplace_back(new response::DNSQuery{dn, type, klass});
}
}
{
auto count = header.answer_count();
this->parsed_answers.reserve(count);
for(size_t idx = 0; idx < count; idx++) {
this->parsed_answers.push_back(this->parse_rr(error, index, true));
if(!error.empty()) {
error = "failed to parse answer " + std::to_string(idx) + ": " + error; // NOLINT(performance-inefficient-string-concatenation)
goto error_exit;
}
}
}
{
auto count = header.authority_count();
this->parsed_authorities.reserve(count);
for(size_t idx = 0; idx < count; idx++) {
this->parsed_authorities.push_back(this->parse_rr(error, index, true));
if(!error.empty()) {
error = "failed to parse authority " + std::to_string(idx) + ": " + error; // NOLINT(performance-inefficient-string-concatenation)
goto error_exit;
}
}
}
{
auto count = header.additional_count();
this->parsed_additionals.reserve(count);
for(size_t idx = 0; idx < count; idx++) {
this->parsed_additionals.push_back(this->parse_rr(error, index, true));
if(!error.empty()) {
error = "failed to parse additional " + std::to_string(idx) + ": " + error; // NOLINT(performance-inefficient-string-concatenation)
goto error_exit;
}
}
}
return true;
error_exit:
this->parsed_queries.clear();
this->parsed_answers.clear();
this->parsed_authorities.clear();
this->parsed_additionals.clear();
return false;
}
std::shared_ptr<response::DNSResourceRecords> DNSResponse::parse_rr(std::string &error, size_t &index, bool allow_compressed) {
auto dn = this->data->parse_dns_dn(error, index, allow_compressed);
if(!error.empty()) {
error = "failed to parse rr dn: " + error; // NOLINT(performance-inefficient-string-concatenation)
return nullptr;
}
if(index + 10 > this->packet_length()) {
error = "truncated header";
return nullptr;
}
auto type = (rrtype::value) ntohs(*(uint16_t*) (this->data->buffer + index));
index += 2;
auto klass = (rrclass::value) ntohs(*(uint16_t*) (this->data->buffer + index));
index += 2;
auto ttl = ntohl(*(uint32_t*) (this->data->buffer + index));
index += 4;
auto payload_length = ntohs(*(uint16_t*) (this->data->buffer + index));
index += 2;
if(index + payload_length > this->packet_length()) {
error = "truncated body";
return nullptr;
}
auto response = std::shared_ptr<response::DNSResourceRecords>(new response::DNSResourceRecords{this->data, index, payload_length, ttl, dn, type, klass});
index += payload_length;
return response;
}
#ifndef WIN32
uint16_t DNSHeader::field(int index) const {
return ((uint16_t*) this->response->packet_data())[index];
}
DNSResourceRecords::DNSResourceRecords(std::shared_ptr<DNSResponseData> packet, size_t payload_offset, size_t length, uint32_t ttl, std::string name, rrtype::value type, rrclass::value klass)
: offset{payload_offset}, length{length}, ttl{ttl}, name{std::move(name)}, type{type}, klass{klass} {
this->data = std::move(packet);
}
const uint8_t* DNSResourceRecords::payload_data() const {
return this->data->buffer + this->offset;
}
#else
DNSResourceRecords::DNSResourceRecords(std::shared_ptr<tc::dns::DNSResponseData> data, PDNS_RECORDA rdata) : nrecord{rdata}, data{std::move(data)} { }
bool DNSResourceRecords::is_wide_string() const {
return this->data->wide_string;
}
#endif
bool A::is_valid() {
#ifdef WIN32
return true;
#else
return this->handle->payload_length() == 4;
#endif
}
in_addr A::address() {
#ifdef WIN32
in_addr result{};
result.S_un.S_addr = this->handle->native_record()->Data.A.IpAddress;
return result;
#else
//TODO: Attention: Unaligned access
return {*(uint32_t*) this->handle->payload_data()};
#endif
}
std::string A::address_string() {
#ifdef WIN32
struct in_addr address = this->address();
char buffer[17];
RtlIpv4AddressToStringA(&address, buffer);
return std::string{buffer};
#else
auto _1 = this->handle->payload_data()[0],
_2 = this->handle->payload_data()[1],
_3 = this->handle->payload_data()[2],
_4 = this->handle->payload_data()[3];
return std::to_string(_1) + "." + std::to_string(_2) + "." + std::to_string(_3) + "." + std::to_string(_4);
#endif
}
//---------------- AAAA
#ifdef WIN32
bool AAAA::is_valid() {
return true;
}
std::string AAAA::address_string() {
struct in6_addr address = this->address();
char buffer[47];
RtlIpv6AddressToStringA(&address, buffer); //Supported for Win7 as well and not only above 8.1 like inet_ntop
return std::string{buffer};
}
in6_addr AAAA::address() {
in6_addr result{};
memcpy(result.u.Byte, this->handle->native_record()->Data.AAAA.Ip6Address.IP6Byte, 16);
return result;
}
#else
bool AAAA::is_valid() {
return this->handle->payload_length() == 16;
}
std::string AAAA::address_string() {
auto address = this->address();
char buffer[INET6_ADDRSTRLEN];
if(!inet_ntop(AF_INET6, (void*) &address, buffer, INET6_ADDRSTRLEN)) return "";
return std::string(buffer);
}
in6_addr AAAA::address() {
return {
.__in6_u = {
.__u6_addr32 = {
//TODO: Attention unaligned memory access
((uint32_t*) this->handle->payload_data())[0],
((uint32_t*) this->handle->payload_data())[1],
((uint32_t*) this->handle->payload_data())[2],
((uint32_t*) this->handle->payload_data())[3]
}
}
};
}
#endif
//---------------- SRV
#ifdef WIN32
bool SRV::is_valid() { return true; }
std::string SRV::target_hostname() {
if(this->handle->is_wide_string()) {
auto result = std::wstring{ ((PDNS_RECORDW) this->handle->native_record())->Data.Srv.pNameTarget };
return std::string{result.begin(), result.end()};
} else {
return std::string{ this->handle->native_record()->Data.Srv.pNameTarget };
}
}
uint16_t SRV::priority() { return this->handle->native_record()->Data.SRV.wPriority; }
uint16_t SRV::weight() { return this->handle->native_record()->Data.SRV.wWeight; }
uint16_t SRV::target_port() { return this->handle->native_record()->Data.SRV.wPort; }
#else
bool SRV::is_valid() {
if(this->handle->payload_length() < 7)
return false;
size_t index = this->handle->payload_offset() + 6;
std::string error{};
this->handle->dns_data()->parse_dns_dn(error, index, true);
return error.empty();
}
std::string SRV::target_hostname() {
size_t index = this->handle->payload_offset() + 6;
std::string error{};
return this->handle->dns_data()->parse_dns_dn(error, index, true);
}
uint16_t SRV::priority() { return ntohs(((uint16_t*) this->handle->payload_data())[0]); }
uint16_t SRV::weight() { return ntohs(((uint16_t*) this->handle->payload_data())[1]); }
uint16_t SRV::target_port() { return ntohs(((uint16_t*) this->handle->payload_data())[2]); }
#endif
//---------------- All types with a name
bool named_base::is_valid() {
#ifdef WIN32
return true;
#else
size_t index = this->handle->payload_offset();
std::string error{};
this->handle->dns_data()->parse_dns_dn(error, index, true);
return error.empty();
#endif
}
std::string named_base::name() {
#ifdef WIN32
if(this->handle->is_wide_string()) {
auto result = std::wstring{ ((PDNS_RECORDW) this->handle->native_record())->Data.Cname.pNameHost };
return std::string{result.begin(), result.end()};
} else {
return std::string{ this->handle->native_record()->Data.Cname.pNameHost };
}
#else
size_t index = this->handle->payload_offset();
std::string error{};
return this->handle->dns_data()->parse_dns_dn(error, index, true);
#endif
}

View File

@ -1,102 +0,0 @@
#include "teadns/types.h"
std::map<tc::dns::rrtype::value, const char*> tc::dns::rrtype::names{
{tc::dns::rrtype::A, "A"},
{tc::dns::rrtype::NS, "NS"},
{tc::dns::rrtype::MD, "MD"},
{tc::dns::rrtype::MF, "MF"},
{tc::dns::rrtype::CNAME, "CNAME"},
{tc::dns::rrtype::SOA, "SOA"},
{tc::dns::rrtype::MB, "MB"},
{tc::dns::rrtype::MG, "MG"},
{tc::dns::rrtype::MR, "MR"},
{tc::dns::rrtype::NULL_, "NULL_"},
{tc::dns::rrtype::WKS, "WKS"},
{tc::dns::rrtype::PTR, "PTR"},
{tc::dns::rrtype::HINFO, "HINFO"},
{tc::dns::rrtype::MINFO, "MINFO"},
{tc::dns::rrtype::MX, "MX"},
{tc::dns::rrtype::TXT, "TXT"},
{tc::dns::rrtype::RP, "RP"},
{tc::dns::rrtype::AFSDB, "AFSDB"},
{tc::dns::rrtype::X25, "X25"},
{tc::dns::rrtype::ISDN, "ISDN"},
{tc::dns::rrtype::RT, "RT"},
{tc::dns::rrtype::NSAP, "NSAP"},
{tc::dns::rrtype::NSAP_PTR, "NSAP_PTR"},
{tc::dns::rrtype::SIG, "SIG"},
{tc::dns::rrtype::KEY, "KEY"},
{tc::dns::rrtype::PX, "PX"},
{tc::dns::rrtype::GPOS, "GPOS"},
{tc::dns::rrtype::AAAA, "AAAA"},
{tc::dns::rrtype::LOC, "LOC"},
{tc::dns::rrtype::NXT, "NXT"},
{tc::dns::rrtype::EID, "EID"},
{tc::dns::rrtype::NIMLOC, "NIMLOC"},
{tc::dns::rrtype::SRV, "SRV"},
{tc::dns::rrtype::ATMA, "ATMA"},
{tc::dns::rrtype::NAPTR, "NAPTR"},
{tc::dns::rrtype::KX, "KX"},
{tc::dns::rrtype::CERT, "CERT"},
{tc::dns::rrtype::A6, "A6"},
{tc::dns::rrtype::DNAME, "DNAME"},
{tc::dns::rrtype::SINK, "SINK"},
{tc::dns::rrtype::OPT, "OPT"},
{tc::dns::rrtype::APL, "APL"},
{tc::dns::rrtype::DS, "DS"},
{tc::dns::rrtype::SSHFP, "SSHFP"},
{tc::dns::rrtype::IPSECKEY, "IPSECKEY"},
{tc::dns::rrtype::RRSIG, "RRSIG"},
{tc::dns::rrtype::NSEC, "NSEC"},
{tc::dns::rrtype::DNSKEY, "DNSKEY"},
{tc::dns::rrtype::DHCID, "DHCID"},
{tc::dns::rrtype::NSEC3, "NSEC3"},
{tc::dns::rrtype::NSEC3PARAM, "NSEC3PARAM"},
{tc::dns::rrtype::TLSA, "TLSA"},
{tc::dns::rrtype::SMIMEA, "SMIMEA"},
{tc::dns::rrtype::Unassigned, "Unassigned"},
{tc::dns::rrtype::HIP, "HIP"},
{tc::dns::rrtype::NINFO, "NINFO"},
{tc::dns::rrtype::RKEY, "RKEY"},
{tc::dns::rrtype::TALINK, "TALINK"},
{tc::dns::rrtype::CDS, "CDS"},
{tc::dns::rrtype::CDNSKEY, "CDNSKEY"},
{tc::dns::rrtype::OPENPGPKEY, "OPENPGPKEY"},
{tc::dns::rrtype::CSYNC, "CSYNC"},
{tc::dns::rrtype::ZONEMD, "ZONEMD"},
{tc::dns::rrtype::SPF, "SPF"},
{tc::dns::rrtype::UINFO, "UINFO"},
{tc::dns::rrtype::UID, "UID"},
{tc::dns::rrtype::GID, "GID"},
{tc::dns::rrtype::UNSPEC, "UNSPEC"},
{tc::dns::rrtype::NID, "NID"},
{tc::dns::rrtype::L32, "L32"},
{tc::dns::rrtype::L64, "L64"},
{tc::dns::rrtype::LP, "LP"},
{tc::dns::rrtype::EUI48, "EUI48"},
{tc::dns::rrtype::EUI64, "EUI64"},
{tc::dns::rrtype::TKEY, "TKEY"},
{tc::dns::rrtype::TSIG, "TSIG"},
{tc::dns::rrtype::IXFR, "IXFR"},
{tc::dns::rrtype::AXFR, "AXFR"},
{tc::dns::rrtype::MAILB, "MAILB"},
{tc::dns::rrtype::MAILA, "MAILA"},
{tc::dns::rrtype::ANY, "ANY"},
{tc::dns::rrtype::URI, "URI"},
{tc::dns::rrtype::CAA, "CAA"},
{tc::dns::rrtype::AVC, "AVC"},
{tc::dns::rrtype::DOA, "DOA"},
{tc::dns::rrtype::AMTRELAY, "AMTRELAY"},
{tc::dns::rrtype::TA, "TA"},
{tc::dns::rrtype::DLV, "DLV"},
{tc::dns::rrtype::Reserved, "Reserved"},
};
std::map<tc::dns::rrclass::value, const char*> tc::dns::rrclass::names{
{tc::dns::rrclass::IN, "IN"},
{tc::dns::rrclass::CH, "CH"},
{tc::dns::rrclass::HS, "HS"},
{tc::dns::rrclass::QCLASS_ANY, "QCLASS_ANY"},
{tc::dns::rrclass::QCLASS_NONE, "QCLASS_NONE"},
};

@ -1 +1 @@
Subproject commit 25dda4cb4cca9a569f6eb3c1d86eb45838d2dc7f Subproject commit 1e1227773ab60ec317b1f85d29027af19066a074

@ -1 +1 @@
Subproject commit bf8bec670e181ee98b6ea01af372318dc1649130 Subproject commit 8abb33a1292a9371ef6296f3bb956fb765d4a106

View File

@ -75,7 +75,7 @@ cp -r glib/out/lib/ $prebuild_path
``` ```
# Building libnice # Building libnice
Building boringssl Building boringssl (not needed anymore!)
```shell script ```shell script
git clone https://boringssl.googlesource.com/boringssl && cd boringssl && \ git clone https://boringssl.googlesource.com/boringssl && cd boringssl && \
git checkout 1cc95ac0 # This version does TeaSpeak use git checkout 1cc95ac0 # This version does TeaSpeak use
@ -86,6 +86,30 @@ cmake . -DCMAKE_INSTALL_PREFIX=`pwd`/out -DOPENSSL_NO_ASM=ON -DCMAKE_CXX_FLAGS="
make -j`nproc --all` make -j`nproc --all`
``` ```
Building openssl
```shell script
[[ -z "${build_os_type}" ]] && export build_os_type=linux
[[ -z "${build_os_type}" ]] && export build_os_arch=amd64
git clone git://git.openssl.org/openssl.git && cd openssl && \
git checkout OpenSSL_1_1_1-stable && \
mkdir build && cd build && \
../Configure --prefix=`pwd`/../out linux-x86_64 && \
make -j32 && \
make install && \
cd ..
# Update prebuild biraries
[[ ! -d openssl-prebuild ]] && git clone https://git.did.science/WolverinDEV/openssl-prebuild.git
cd openssl-prebuild && \
if [[ ! -d "${build_os_type}_${build_os_arch}" ]]; then
mkdir "${build_os_type}_${build_os_arch}" || { echo "failed to create directory"; }
fi
cd "${build_os_type}_${build_os_arch}" && \
rm -r * && \
cp -r ../../openssl/out/* .
```
Build libnice Build libnice
```shell script ```shell script
[[ -z "${build_os_type}" ]] && export build_os_type=linux [[ -z "${build_os_type}" ]] && export build_os_type=linux
@ -96,18 +120,20 @@ Build libnice
export glib20_dir="`pwd`/../glibc-prebuild/${build_os_type}_${build_os_arch}/" export glib20_dir="`pwd`/../glibc-prebuild/${build_os_type}_${build_os_arch}/"
export glib20_lib_path=$(realpath "$glib20_dir/lib/"*"/") export glib20_lib_path=$(realpath "$glib20_dir/lib/"*"/")
export boringssl_path="`pwd`/../boringssl/" export boringssl_path="`pwd`/../boringssl/"
export openssl_path="`pwd`/../openssl/out/"
#pkg-config --static --cflags glib-2.0 := -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include #pkg-config --static --cflags glib-2.0 := -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
#pkg-config --static --libs glib-2.0 gio-2.0 gobject-2.0 := -pthread -lgio-2.0 -lz -lresolv -lselinux -lgmodule-2.0 -ldl -lgobject-2.0 -lffi -lglib-2.0 -lpcre #pkg-config --static --libs glib-2.0 gio-2.0 gobject-2.0 := -pthread -lgio-2.0 -lz -lresolv -lselinux -lgmodule-2.0 -ldl -lgobject-2.0 -lffi -lglib-2.0 -lpcre
export GLIB_CFLAGS="-I$glib20_dir/include/glib-2.0 -I`echo "$glib20_dir/lib/"*"/glib-2.0/include"`" export GLIB_CFLAGS="-I$glib20_dir/include/glib-2.0 -I`echo "$glib20_dir/lib/"*"/glib-2.0/include"`"
#export GLIB_LIBS="$glib20_lib_path/libgio-2.0.a -lz -lresolv $glib20_lib_path/libgmodule-2.0.a -ldl $glib20_lib_path/libgobject-2.0.a $glib20_lib_path/libffi.a $glib20_lib_path/libglib-2.0.a -lpcre -pthread" # Static #export GLIB_LIBS="$glib20_lib_path/libgio-2.0.a -lz -lresolv $glib20_lib_path/libgmodule-2.0.a -ldl $glib20_lib_path/libgobject-2.0.a $glib20_lib_path/libffi.a $glib20_lib_path/libglib-2.0.a -lpcre -pthread" # Static
export GLIB_LIBS="-lgio-2.0 -lz -lresolv -lgmodule-2.0 -ldl -lgobject-2.0 -lffi -lglib-2.0 -lpcre -pthread" # Shared export GLIB_LIBS="-lgio-2.0 -lz -lresolv -lgmodule-2.0 -ldl -lgobject-2.0 -lffi -lglib-2.0 -lpcre -pthread" # Shared
export LDFLAGS="-L$boringssl_path/crypto/ -L$boringssl_path/ssl/ -L$glib20_lib_path" # For BoringSSL: export LDFLAGS="-L$boringssl_path/crypto/ -L$boringssl_path/ssl/ -L$glib20_lib_path"
export LDFLAGS="-L$openssl_path/lib -L$glib20_lib_path"
# sed -i 's/gtkdocize/#gtkdocize/g' autogen.sh # Fix for ARM # sed -i 's/gtkdocize/#gtkdocize/g' autogen.sh # Fix for ARM
sed -i 's/aclocal --install/aclocal --install -I`pwd`/g' autogen.sh # Fix for automake 1.11 sed -i 's/aclocal --install/aclocal --install -I`pwd`/g' autogen.sh # Fix for automake 1.11
sed -i 's/AM_INIT_AUTOMAKE(\[1.12/AM_INIT_AUTOMAKE(\[1.11/g' configure.ac # Reduce min AC version for ubuntu12.04 sed -i 's/AM_INIT_AUTOMAKE(\[1.12/AM_INIT_AUTOMAKE(\[1.11/g' configure.ac # Reduce min AC version for ubuntu12.04
CFLAGS="-Wno-error=cast-align" ./autogen.sh --prefix=`pwd`/out --with-pic --with-crypto-library=openssl --without-gstreamer --disable-assert --disable-gtk-doc --enable-static=no --enable-shared=yes && \ CFLAGS="-Wno-error=cast-align -I$openssl_path/include/" ./autogen.sh --prefix=`pwd`/out --with-pic --with-crypto-library=openssl --without-gstreamer --disable-assert --disable-gtk-doc --enable-static=no --enable-shared=yes && \
make && \ make && \
make install make install
@ -117,7 +143,7 @@ cd ..
Publishing libnice Publishing libnice
```shell script ```shell script
[[ -z "${build_os_type}" ]] && export build_os_type=linux [[ -z "${build_os_type}" ]] && export build_os_type=linux
[[ -z "${build_os_type}" ]] && export build_os_arch=amd64 [[ -z "${build_os_arch}" ]] && export build_os_arch=amd64
export prebuild_path="`pwd`/libnice-prebuild/${build_os_type}_${build_os_arch}/" export prebuild_path="`pwd`/libnice-prebuild/${build_os_type}_${build_os_arch}/"
[[ ! -d libnice-prebuild ]] && git clone https://git.did.science/WolverinDEV/libnice-prebuild.git [[ ! -d libnice-prebuild ]] && git clone https://git.did.science/WolverinDEV/libnice-prebuild.git
@ -129,4 +155,4 @@ cp -r libnice/out/lib/ $prebuild_path
# Troubleshooting # Troubleshooting
## GLIB2.0 hangs on meson ## GLIB2.0 hangs on meson
Ninja may be too sold. It should work with 1.9.0. Ninja may be too old. It should work with 1.9.0.

View File

@ -10,6 +10,15 @@ if [[ -n "$1" ]]; then
export _build_type="Debug" export _build_type="Debug"
# shellcheck disable=SC2089 # shellcheck disable=SC2089
export TEASPEAK_DEPLOY_TYPE_SPECIFIER="-DBUILD_TYPE=1 -DBUILD_TYPE_NAME=beta" export TEASPEAK_DEPLOY_TYPE_SPECIFIER="-DBUILD_TYPE=1 -DBUILD_TYPE_NAME=beta"
if [[ $i_really_wanna_debug -ne 1 ]]; then
echo "Please set the i_really_wanna_debug environment variable to one if you really want a debug build"
exit 1
fi
elif [[ "$1" == "nightly" ]]; then
echo "Initializing nightly session."
export _build_type="RelWithDebInfo"
# shellcheck disable=SC2089
export TEASPEAK_DEPLOY_TYPE_SPECIFIER="-DBUILD_TYPE=2 -DBUILD_TYPE_NAME=nightly"
elif [[ "$1" == "optimized" ]]; then elif [[ "$1" == "optimized" ]]; then
echo "Initializing optimized session." echo "Initializing optimized session."
export _build_type="RelWithDebInfo" export _build_type="RelWithDebInfo"
@ -36,15 +45,22 @@ else
_web_flag="ON" _web_flag="ON"
fi fi
crypto_library_path="$(pwd)/libraries/openssl-prebuild/${build_os_type}_${build_os_arch}/" \
./TeaSpeak/rtclib/generate_shared_library.sh
if [ $? -ne 0 ]; then
exit 1
fi
cd TeaSpeak || exit 1 cd TeaSpeak || exit 1
if [[ -d build ]]; then if [[ -d build && $teaspeak_clean_build -eq 1 ]]; then
rm -r build rm -r build
fi fi
mkdir build || exit 1 [[ ! -d build ]] && { mkdir build || exit 1; }
cd build || exit 1 cd build || exit 1
echo "Build type: $_build_type" echo "Build type: $_build_type"
_command="cmake .. -DCMAKE_BUILD_TYPE=\"$_build_type\" -DCMAKE_CXX_FLAGS=\"${CXX_FLAGS}\" -DBUILD_INCLUDE_FILE=\"$_build_helper_dir/cmake/config/tearoot-server.cmake\" -DCMAKE_MODULE_PATH=\"$_build_helper_dir/cmake/\" -DDISABLE_QT=1 -DDISABLE_CUSTOM_OUTPUT=ON -DDISABLE_QT=ON -DCOMPILE_WEB_CLIENT=\"$_web_flag\" $TEASPEAK_DEPLOY_TYPE_SPECIFIER" _command="cmake .. -DCMAKE_BUILD_TYPE=\"$_build_type\" -DCMAKE_CXX_FLAGS=\"${CXX_FLAGS}\" -DBUILD_INCLUDE_FILE=\"$_build_helper_dir/cmake/config/tearoot-server.cmake\" -DCMAKE_MODULE_PATH=\"$_build_helper_dir/cmake/\" -DDISABLE_QT=1 -DDISABLE_CUSTOM_OUTPUT=ON -DDISABLE_QT=ON -DCOMPILE_WEB_CLIENT=\"$_web_flag\" $TEASPEAK_DEPLOY_TYPE_SPECIFIER -Dmysql_ROOT_DIR=\"`pwd`/../../../mysql-server/out\""
echo "> $_command" echo "> $_command"
eval $_command eval $_command
_code=$? _code=$?
@ -64,7 +80,7 @@ if [[ $_code -ne 0 ]]; then
exit 1 exit 1
fi fi
cmake --build "$(pwd)" --target TeaSpeakServer -- -j 12; _code=$? cmake --build "$(pwd)" --target TeaSpeakServer -- -j 6; _code=$?
if [[ $_code -ne 0 ]]; then if [[ $_code -ne 0 ]]; then
echo "Failed to build server ($_code)" echo "Failed to build server ($_code)"
exit 1 exit 1

@ -1 +1 @@
Subproject commit 978e688b7b0a3a4eebf17c9f72f9c22f14b605b7 Subproject commit f7e6350665519a835770ac247e3d9ab0bdb99688

@ -1 +1 @@
Subproject commit 702b870fdac108eaeee943e45cb160a0951bfa11 Subproject commit 462359e96fb4ddf06d276a375caf933047ca963f

@ -1 +0,0 @@
Subproject commit 1cc95ac07c17d61bea601832bbdc1f8d13d313db

@ -1 +1 @@
Subproject commit db1cda26539c711c3da7ed4d410dfe8190e89b8f Subproject commit 78f7ae495bc147e97a58e8158072fd35fdd99419

View File

@ -60,7 +60,6 @@ function exec_script_external() {
} }
exec_script_external build_libevent.sh event exec_script_external build_libevent.sh event
exec_script_external build_boringssl.sh boringssl
exec_script_external build_breakpad.sh breakpad exec_script_external build_breakpad.sh breakpad
exec_script_external build_cxxterminal.sh CXXTerminal "libevent_path=event" exec_script_external build_cxxterminal.sh CXXTerminal "libevent_path=event"
exec_script build_datapipes.sh DataPipes exec_script build_datapipes.sh DataPipes
@ -76,6 +75,7 @@ exec_script_external build_tommath.sh tommath
exec_script_external build_tomcrypt.sh tomcrypt "tommath_path=`pwd`/tommath/out/${build_os_type}_${build_os_arch}" exec_script_external build_tomcrypt.sh tomcrypt "tommath_path=`pwd`/tommath/out/${build_os_type}_${build_os_arch}"
exec_script_external build_yamlcpp.sh yaml-cpp exec_script_external build_yamlcpp.sh yaml-cpp
exec_script_external build_jemalloc.sh jemalloc exec_script_external build_jemalloc.sh jemalloc
exec_script_external build_zstd.sh zstd
#Log the result #Log the result
end_task "build_third_party" "Build all libraries successfully" end_task "build_third_party" "Build all libraries successfully"

View File

@ -1,30 +0,0 @@
cd boringssl/
if [ ! -d lib ]; then
mkdir lib && cd lib
ln -s ../build/ssl/libssl.so .
ln -s ../build/crypto/libcrypto.so .
cd ..
fi
cat include/openssl/opensslv.h | grep "OPENSSL_VERSION_TEXT" &> /dev/null
if [ $? -ne 0 ]; then
echo '#if false
# define OPENSSL_VERSION_NUMBER 0x1010008fL
#define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1a 20 Nov 2018"
#endif' > include/openssl/opensslv.h
fi
cd build
dpkg -s golang-go &>/dev/null
if [[ $? -ne 0 ]]; then
echo "Installing golang"
sudo apt-get install golang-go
fi
if [ "x86" == "${BUILD_ARCH_TARGET}" ]; then
echo "Build boring SSL in 32 bit mode!"
T32="-DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake"
fi
cmake .. -D -DOPENSSL_NO_ASM=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_C_FLAGS="${C_FLAGS}" -DCMAKE_BUILD_TYPE=Release ${CMAKE_OPTIONS} -DCMAKE_VERBOSE_MAKEFILE=1 ${T32}
make ${CMAKE_MAKE_OPTIONS}
#sudo make install

View File

@ -11,5 +11,5 @@ fi
cd build cd build
../configure ../configure
make CXXFLAGS="-std=c++11 -I../../boringssl/include/ ${CXX_FLAGS}" CFLAGS="${C_FLAGS}" ${MAKE_OPTIONS} make CXXFLAGS="-std=c++11 ${CXX_FLAGS}" CFLAGS="${C_FLAGS}" ${MAKE_OPTIONS}
sudo make install sudo make install

View File

@ -16,36 +16,14 @@ requires_rebuild ${library_path}
web_cmake_flags="-DBUILD_WEBRTC=${_datapipes_webrtc}" web_cmake_flags="-DBUILD_WEBRTC=${_datapipes_webrtc}"
if [[ ${build_os_type} != "win32" && "${_datapipes_webrtc}" == "ON" ]]; then if [[ ${build_os_type} != "win32" && "${_datapipes_webrtc}" == "ON" ]]; then
cd ${library_path}
#echo "Testing for libnice"
#dpkg-query -l libnice-dev2 &>/dev/null
#if [[ $? -ne 0 ]]; then
# echo "Installing libnice"
# sudo apt-get update
# sudo apt-get install -yes --force-yes libnice-dev
#else
# echo "libnice already installed"
#fi
echo "Building dependencies"
./build_usrsctp.sh
check_err_exit ${library_path} "Failed to build usrsctp!"
./build_srtp.sh
check_err_exit ${library_path} "Failed to build srtp!"
./build_sdptransform.sh
check_err_exit ${library_path} "Failed to build sdptransform!"
cd ..
# -DLibevent_DIR="/mnt/d/TeaSpeak/server/libraries/event/out/linux_amd64/lib/cmake/libevent"
glib20_dir=$(realpath "$(pwd)/glibc/linux_${build_os_arch}/") glib20_dir=$(realpath "$(pwd)/glibc/linux_${build_os_arch}/")
# shellcheck disable=SC2125 # shellcheck disable=SC2125
glib20_lib_path=$(realpath "$glib20_dir/lib/"*"/") glib20_lib_path=$(realpath "$glib20_dir/lib/"*"/")
# TODO: pcre really required here? # TODO: pcre really required here?
web_cmake_flags="$web_cmake_flags -DGLIB_PREBUILD_FLAGS=\"-I$glib20_dir/include -I$glib20_dir/include/glib-2.0/ -I$glib20_lib_path/glib-2.0/include/\"" web_cmake_flags="$web_cmake_flags -DGLIB_PREBUILD_INCLUDES=\"$glib20_dir/include;$glib20_dir/include/glib-2.0/;$glib20_lib_path/glib-2.0/include/\""
web_cmake_flags="$web_cmake_flags -DGLIB_PREBUILD_LIBRARIES=\"$glib20_lib_path/libgio-2.0.so;z;resolv;$glib20_lib_path/libgmodule-2.0.so;$glib20_lib_path/libgobject-2.0.so;$glib20_lib_path/libffi.so;$glib20_lib_path/libglib-2.0.so;pcre\"" web_cmake_flags="$web_cmake_flags -DGLIB_PREBUILD_LIBRARIES=\"$glib20_lib_path/libgio-2.0.so;z;resolv;$glib20_lib_path/libgmodule-2.0.so;$glib20_lib_path/libgobject-2.0.so;$glib20_lib_path/libffi.so;$glib20_lib_path/libglib-2.0.so;pcre\""
web_cmake_flags="$web_cmake_flags -DLIBNICE_PREBUILD_PATH=\"../libnice/linux_${build_os_arch}\"" web_cmake_flags="$web_cmake_flags -DLIBNICE_PREBUILD_PATH=\"../libnice/linux_${build_os_arch}\""
echo "WebRTC flags: $web_cmake_flags" echo "WebRTC flags: $web_cmake_flags"
@ -56,8 +34,9 @@ _cxx_options=""
[[ ${build_os_type} != "win32" ]] && _cxx_options="-fPIC -static-libgcc -static-libstdc++" [[ ${build_os_type} != "win32" ]] && _cxx_options="-fPIC -static-libgcc -static-libstdc++"
[[ ${build_os_type} == "win32" ]] && _cxx_options="-DWIN32" [[ ${build_os_type} == "win32" ]] && _cxx_options="-DWIN32"
general_options="-DCMAKE_C_FLAGS=\"-fPIC\" -DCMAKE_CXX_FLAGS=\"$_cxx_options\" -DBUILD_TESTS=OFF -DBUILD_STATIC=0 -DBUILD_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" general_options="-DCMAKE_C_FLAGS=\"-fPIC\" -DCMAKE_CXX_FLAGS=\"$_cxx_options\" -DBUILD_EXAMPLES=OFF -DBUILD_STATIC=1 -DBUILD_SHARED=1 -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
crypto_options="-DCrypto_ROOT_DIR=\"$(pwd)/boringssl/lib/\" -DCRYPTO_TYPE=\"boringssl\"" #crypto_options="-DCrypto_ROOT_DIR=\"$(pwd)/boringssl/lib/\" -DCRYPTO_TYPE=\"boringssl\""
crypto_options="-DCRYPTO_TYPE=\"openssl\" -DCrypto_ROOT_DIR=\"$(pwd)/openssl-prebuild/${build_os_type}_${build_os_arch}/\""
command="cmake_build ${library_path} ${general_options} ${crypto_options} ${web_cmake_flags} ${CMAKE_OPTIONS}" command="cmake_build ${library_path} ${general_options} ${crypto_options} ${web_cmake_flags} ${CMAKE_OPTIONS}"
eval "$command" eval "$command"

View File

@ -1,4 +1,5 @@
cd ed25519/build/ cd ed25519/build/
cmake .. -DCMAKE_C_FLAGS="-fPIC -I../../boringssl/include/ -L../../boringssl/build/ssl/ -L../../boringssl/build/crypto/ ${C_FLAGS}" -DCMAKE_CXX_FLAGS="-fPIC ${CXX_FLAGS}" -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_OPTIONS} #cmake .. -DCMAKE_C_FLAGS="-fPIC -I../../boringssl/include/ -L../../boringssl/build/ssl/ -L../../boringssl/build/crypto/ ${C_FLAGS}" -DCMAKE_CXX_FLAGS="-fPIC ${CXX_FLAGS}" -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_OPTIONS}
cmake .. -DCMAKE_C_FLAGS="-fPIC ${C_FLAGS}" -DCMAKE_CXX_FLAGS="-fPIC ${CXX_FLAGS}" -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_OPTIONS}
make ${CMAKE_MAKE_OPTIONS} make ${CMAKE_MAKE_OPTIONS}
sudo make install sudo make install

View File

@ -1,4 +1,5 @@
cd event/build/ cd event/build/
cmake .. -DCMAKE_C_FLAGS="-fPIC -I../../boringssl/include/ ${C_FLAGS}" -DEVENT__DISABLE_TESTS=ON -DEVENT__DISABLE_OPENSSL=ON -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_OPTIONS} #cmake .. -DCMAKE_C_FLAGS="-fPIC -I../../boringssl/include/ ${C_FLAGS}" -DEVENT__DISABLE_TESTS=ON -DEVENT__DISABLE_OPENSSL=ON -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_OPTIONS}
cmake .. -DCMAKE_C_FLAGS="-fPIC ${C_FLAGS}" -DEVENT__DISABLE_TESTS=ON -DEVENT__DISABLE_OPENSSL=ON -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_BUILD_TYPE=RelWithDebInfo ${CMAKE_OPTIONS}
make ${CMAKE_MAKE_OPTIONS} make ${CMAKE_MAKE_OPTIONS}
sudo make install sudo make install

@ -1 +1 @@
Subproject commit 3396416fab69945f420f31dea30850806e199984 Subproject commit b4277aac2ecf8189004984cab91a759d9d85b4dc

@ -1 +1 @@
Subproject commit 6ca5739b634a60f80ba64d5fe4d3e56371494fc9 Subproject commit f33e8148d387c98babb5cdd62615e95e7c25ebe1

@ -0,0 +1 @@
Subproject commit 034ea35d38b11cba6c0e50e8685bbb71f8e030be

@ -1 +1 @@
Subproject commit aa9d3c3590bc7422c8afdafcc906cd2bc60228a4 Subproject commit 0ff2920957a1687dd3804275fd3f29f41bfd7dd1

@ -1 +1 @@
Subproject commit 1ffadc46807efce964bec69f38f94ad7093023af Subproject commit a09c53619e0785adf17a597c9e7fd60bbb6ecb09

1
libraries/zstd Submodule

@ -0,0 +1 @@
Subproject commit f85a0f8bcf580aeebfc5c5d37206db908b5fa370

View File

@ -1,7 +1,6 @@
# Introduction # Introduction
This instruction set works with `ubuntu:14.04`. This instruction set works with `ubuntu:14.04`.
# Setting up build tools # Setting up build tools
## General required tools ## General required tools
```shell script ```shell script
@ -77,6 +76,22 @@ make -j`nproc --all` && \
make install make install
``` ```
## MySQL
```shell script
export openssl_path="$(realpath ~/openssl-prebuild/linux_amd64)" && \
apt-get install -y libncurses5-dev && \
git clone https://github.com/mysql/mysql-server.git && cd mysql-server \
mkdir build_ && cd build_ && \
cmake .. -DBUILD_CONFIG=mysql_release -DWITH_ZLIB=bundled -DDOWNLOAD_BOOST=1 -DWITH_BOOST=`pwd`/boost-library/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-lrt" -DWITH_SSL="$openssl_path" -DCMAKE_INSTALL_PREFIX=`pwd`/../out/ &&
make -j 32 # This will fail, but the client will be builded
cmake --install . # This will fail, but the client should work
```
You may have to do this before (on error `unsupported reloc 42 against global symbol`):
https://bugs.mysql.com/bug.php?id=89391
```shell script
mv /usr/bin/ld.gold /usr/bin/NOT_USED_ld.gold
```
## Setting up github ## Setting up github
```shell script ```shell script
git config --global credential.helper store && \ git config --global credential.helper store && \
@ -105,8 +120,8 @@ git submodule update --init --recursive
```shell script ```shell script
export build_os_type=linux export build_os_type=linux
export build_os_arch=amd64 export build_os_arch=amd64
export CMAKE_BUILD_OPTIONS="-j`nproc --all`" export CMAKE_MAKE_OPTIONS="-j`nproc --all`"
export BUILD_OPTIONS="$CMAKE_BUILD_OPTIONS" export MAKE_OPTIONS="$CMAKE_MAKE_OPTIONS"
``` ```
## Build libraries ## Build libraries

View File

@ -1,15 +1,19 @@
# Docker setup
docker run --rm --privileged multiarch/qemu-user-static:register
docker run -it --name build_arm32v7 arm32v7/ubuntu:14.04 /bin/bash
sudo apt-get update && \ sudo apt-get update && \
sudo apt-get install build-essential software-properties-common -y && \ sudo apt-get install build-essential software-properties-common -y && \
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \ sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
sudo apt-get update && \ sudo apt-get update && \
sudo apt-get install gcc-9 g++-9 -y && \ sudo apt-get install gcc-9 g++-9 -y && \
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9 && \ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9 && \
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-9 60 --slave /usr/bin/c++ c++ /usr/bin/c++-9 # THis fails for some reason sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-9 60 --slave /usr/bin/c++ c++ /usr/bin/c++-9 # This fails for some reason
Sometimes its required to build from source: # Sometimes its required to build from source: (Not required for ubuntu 14.04)
https://raw.githubusercontent.com/darrenjs/howto/master/build_scripts/build_gcc_9.sh https://raw.githubusercontent.com/darrenjs/howto/master/build_scripts/build_gcc_9.sh
apt-get install -y autoconf git wget libssl-dev realpath libsqlite3-dev libmysqlclient-dev apt-get install -y autoconf git wget libssl-dev realpath libsqlite3-dev libmysqlclient-dev libpcre3-dev
wget https://github.com/Kitware/CMake/releases/download/v3.16.3/cmake-3.16.3.tar.gz && tar xvf cmake-3.16.3.tar.gz && \ wget https://github.com/Kitware/CMake/releases/download/v3.16.3/cmake-3.16.3.tar.gz && tar xvf cmake-3.16.3.tar.gz && \
cd cmake-3.16.3 && ./configure --parallel=16 && \ cd cmake-3.16.3 && ./configure --parallel=16 && \
@ -31,11 +35,14 @@ git submodule update --init --recursive
./libraries/build.sh ./libraries/build.sh
# External prebuild libraries
# ------------ OpenSSL -------------
git clone https://github.com/openssl/openssl.git && cd openssl && \
git checkout OpenSSL_1_1_1-stable && \
mkdir build && cd build && \
../config --prefix=`pwd`/../out && \
make -j30 && \
make install
# Build MySQL
# -------- Troubleshooting ---------- cmake ../ -DOPENSSL_ROOT_DIR=../../server/libraries/openssl-prebuild/linux_arm32v7/ -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/tmp/boost/ -DCMAKE_INSTALL_PREFIX=../out
If go raises an error/crashes install a newer version:
$ sudo add-apt-repository ppa:gophers/archive
$ sudo apt-get update
$ sudo apt-get install golang-1.11-go
sudo update-alternatives --install /usr/bin/go go /usr/lib/go-1.11/bin/go 1