/* * This file is part of the Flowee project * Copyright (C) 2020-2024 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "NetworkEndPoint.h" #include EndPoint EndPoint::fromAddr(const std::vector &addr, int16_t port) { assert(addr.size() == 16); // IPv4 is encoded by having the first 10 bytes as zero, then 2 bytes of 255 bool isIPv4 = addr[10] == static_cast(-1) && addr[11] == static_cast(-1); for (int i = 0; isIPv4 && i < 10; ++i) { isIPv4 = addr[0] == 0; } if (isIPv4) { std::array ipv4; for (int i = 0; i < 4; ++i) ipv4[i] = addr[i + 12]; return EndPoint(boost::asio::ip::address_v4(ipv4), port); } std::array ipv6; for (int i = 0; i < 16; ++i) ipv6[i] = addr[i]; return EndPoint(boost::asio::ip::address_v6(ipv6), port); } bool EndPoint::operator==(const EndPoint &other) const { const bool hasHostname = (!other.ipAddress.is_unspecified() || !other.hostname.empty()) && other.announcePort > 0; if (encrypted != other.encrypted) return false; if (hasHostname) { if (!other.hostname.empty() && hostname != other.hostname) return false; if (!other.ipAddress.is_unspecified() && ipAddress != other.ipAddress) return false; if (!(announcePort == 0 || announcePort == other.announcePort || other.announcePort == 0)) return false; return true; } // both empty, perhaps? return ipAddress.is_unspecified() && hostname.empty() && announcePort == 0; } void EndPoint::toAddr(char *addr) const { for (size_t i = 0; i < 16; ++i) { addr[i] = 0; } if (ipAddress.is_v4()) { addr[10] = addr[11] = -1; size_t index = 12; for (auto byte : ipAddress.to_v4().to_bytes()) { assert(index <= 16); addr[index++] = byte; } } else if (ipAddress.is_v6()) { size_t index = 0; for (auto byte : ipAddress.to_v6().to_bytes()) { assert(index <= 16); addr[index++] = byte; } } } std::string EndPoint::toString() const { std::ostringstream answer; if (ipAddress.is_unspecified()) { answer << hostname; } else { if (ipAddress.is_v6()) answer << "["; answer << ipAddress.to_string().c_str(); if (ipAddress.is_v6()) answer << "]"; } answer << ':' << announcePort; if (announcePort != peerPort && peerPort != 0) answer << '|' << peerPort; if (encrypted) answer << " (ssl)"; return answer.str(); }