#include "include/socket.h" Socket::Socket(std::string url, std::function toLog) : url(url), toLog(std::move(toLog)) { #ifdef IBM // WSA INIT int a = 0; #endif #ifdef APL int a = 0; #endif #ifdef LIN int s; s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { toLog("Error creating socket."); return; } struct sockaddr_in sa; memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = resolveHost("german-airlines.de"); // address of german-airlines.de sa.sin_port = htons(443); socklen_t socklen = sizeof(sa); if (connect(s, (struct sockaddr *)&sa, socklen)) { toLog("Error connecting to server."); return; } SSL_library_init(); SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); const SSL_METHOD *meth = TLSv1_2_client_method(); SSL_CTX *ctx = SSL_CTX_new(meth); ssl = SSL_new(ctx); if (!ssl) { toLog("Error creating SSL."); logSSL(); return; } sock = SSL_get_fd(ssl); SSL_set_fd(ssl, s); int err = SSL_connect(ssl); if (err <= 0) { std::ostringstream msg; msg << "Error creating SSL connection. err=" << err; toLog(msg.str()); logSSL(); return; } std::ostringstream msg; msg << "SSL connection using " << SSL_get_cipher(ssl); toLog(msg.str()); #endif // PLATFORM AGNOSTIC } Socket::~Socket() { #ifdef IBM // WSA DEINIT int a = 0; #endif #ifdef LIN close(sock); SSL_shutdown(ssl); SSL_free(ssl); #endif } void Socket::sendData(data d) { if (strcmp(d.path, lastPath) != 0) { strcpy(lastPath, d.path); if (util::generateMD5(d.path, lastHash, toLog)) { strcpy(lastHash, "NOT SET"); } } nlohmann::json json = { {"altitude", d.alt}, {"vs", d.vs}, {"ias", d.ias}, {"magHdg", d.magHeading}, {"truHdg", d.truHdg}, {"totFuel", d.totFuelKg}, {"fuelFlow", d.ff}, {"hash", lastHash}, }; { std::lock_guard lock(wsLock); // SEND } } #ifdef LIN void Socket::logSSL() { int err; while ((err = ERR_get_error())) { char *str = ERR_error_string(err, 0); if (!str) return; toLog(str); } } void *Socket::getSinAddr(addrinfo *addr) { switch (addr->ai_family) { case AF_INET: return &(reinterpret_cast(addr->ai_addr)->sin_addr); case AF_INET6: return &(reinterpret_cast(addr->ai_addr)->sin6_addr); } return NULL; } in_addr_t Socket::resolveHost(const char *host) { addrinfo hints = {}; hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; addrinfo *res; int ret = getaddrinfo(host, NULL, &hints, &res); if (ret != 0) { std::ostringstream msg; msg << "getaddrinfo() failed: " << gai_strerror(ret); toLog(msg.str()); return 0; } else { std::ostringstream msg; msg << res->ai_canonname; toLog(msg.str()); in_addr_t retVal = 0; for (addrinfo *addr = res; addr != NULL; addr = addr->ai_next) { if (addr->ai_family == AF_INET) { retVal = (reinterpret_cast(addr->ai_addr))->sin_addr.s_addr; break; } } freeaddrinfo(res); return retVal; } } #endif