| /* |
| * Copyright (C) 2004-2023 Savoir-faire Linux Inc. |
| * |
| * 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 <https://www.gnu.org/licenses/>. |
| */ |
| #pragma once |
| |
| #include "../ip_utils.h" |
| |
| #include <map> |
| #include <string> |
| #include <chrono> |
| #include <functional> |
| #include <mutex> |
| #include <memory> |
| |
| namespace dhtnet { |
| namespace upnp { |
| |
| using sys_clock = std::chrono::system_clock; |
| |
| enum class PortType { TCP, UDP }; |
| enum class MappingState { PENDING, IN_PROGRESS, FAILED, OPEN }; |
| |
| enum class NatProtocolType; |
| class IGD; |
| |
| class Mapping |
| { |
| friend class UPnPContext; |
| friend class NatPmp; |
| friend class PUPnP; |
| |
| public: |
| using key_t = uint64_t; |
| using sharedPtr_t = std::shared_ptr<Mapping>; |
| using NotifyCallback = std::function<void(sharedPtr_t)>; |
| |
| static constexpr char const* MAPPING_STATE_STR[4] {"PENDING", "IN_PROGRESS", "FAILED", "OPEN"}; |
| static constexpr char const* UPNP_MAPPING_DESCRIPTION_PREFIX {"JAMI"}; |
| |
| Mapping(PortType type, |
| uint16_t portExternal = 0, |
| uint16_t portInternal = 0, |
| bool available = true); |
| Mapping(const Mapping& other); |
| Mapping(Mapping&& other) = delete; |
| ~Mapping() = default; |
| |
| // Delete operators with confusing semantic. |
| Mapping& operator=(Mapping&& other) = delete; |
| bool operator==(const Mapping& other) = delete; |
| bool operator!=(const Mapping& other) = delete; |
| bool operator<(const Mapping& other) = delete; |
| bool operator>(const Mapping& other) = delete; |
| bool operator<=(const Mapping& other) = delete; |
| bool operator>=(const Mapping& other) = delete; |
| |
| inline explicit operator bool() const { return isValid(); } |
| |
| void updateFrom(const Mapping& other); |
| void updateFrom(const Mapping::sharedPtr_t& other); |
| std::string getExternalAddress() const; |
| uint16_t getExternalPort() const; |
| std::string getExternalPortStr() const; |
| std::string getInternalAddress() const; |
| uint16_t getInternalPort() const; |
| std::string getInternalPortStr() const; |
| PortType getType() const; |
| const char* getTypeStr() const; |
| static const char* getTypeStr(PortType type) { return type == PortType::UDP ? "UDP" : "TCP"; } |
| std::shared_ptr<IGD> getIgd() const; |
| NatProtocolType getProtocol() const; |
| std::string_view getProtocolName() const; |
| bool isAvailable() const; |
| MappingState getState() const; |
| const char* getStateStr() const; |
| static const char* getStateStr(MappingState state) |
| { |
| return MAPPING_STATE_STR[static_cast<int>(state)]; |
| } |
| std::string toString(bool extraInfo = false) const; |
| bool isValid() const; |
| bool hasValidHostAddress() const; |
| bool hasPublicAddress() const; |
| void setNotifyCallback(NotifyCallback cb); |
| void enableAutoUpdate(bool enable); |
| bool getAutoUpdate() const; |
| key_t getMapKey() const; |
| static PortType getTypeFromMapKey(key_t key); |
| sys_clock::time_point getRenewalTime() const; |
| sys_clock::time_point getExpiryTime() const; |
| |
| private: |
| NotifyCallback getNotifyCallback() const; |
| void setInternalAddress(const std::string& addr); |
| void setExternalPort(uint16_t port); |
| void setInternalPort(uint16_t port); |
| |
| void setIgd(const std::shared_ptr<IGD>& igd); |
| void setAvailable(bool val); |
| void setState(const MappingState& state); |
| void setRenewalTime(sys_clock::time_point time); |
| void setExpiryTime(sys_clock::time_point time); |
| |
| mutable std::mutex mutex_; |
| PortType type_ {PortType::UDP}; |
| uint16_t externalPort_ {0}; |
| uint16_t internalPort_ {0}; |
| std::string internalAddr_; |
| // Protocol and |
| std::shared_ptr<IGD> igd_; |
| // Track if the mapping is available to use. |
| bool available_; |
| // Track the state of the mapping |
| MappingState state_; |
| NotifyCallback notifyCb_; |
| // If true, a new mapping will be requested on behalf of the mapping |
| // owner when the mapping state changes from "OPEN" to "FAILED". |
| bool autoUpdate_; |
| sys_clock::time_point renewalTime_; |
| sys_clock::time_point expiryTime_; |
| }; |
| |
| struct MappingInfo |
| { |
| std::string remoteHost; |
| std::string protocol; |
| std::string internalClient; |
| std::string enabled; |
| std::string description; |
| uint16_t externalPort; |
| uint16_t internalPort; |
| uint32_t leaseDuration; |
| }; |
| |
| } // namespace upnp |
| } // namespace dhtnet |