blob: 19e6421c005caac9182c907ee5672daaf3892916 [file] [log] [blame]
Adrien Béraud612b55b2023-05-29 10:42:04 -04001/*
2 * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
3 *
4 * Author: Eden Abitbol <eden.abitbol@savoirfairelinux.com>
5 * Author: Mohamed Chibani <mohamed.chibani@savoirfairelinux.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#pragma once
23
Adrien Bérauddbb06862023-07-08 09:18:39 -040024#include "../ip_utils.h"
Adrien Béraud612b55b2023-05-29 10:42:04 -040025
26#include <map>
27#include <string>
28#include <chrono>
29#include <functional>
30#include <mutex>
Morteza Namvar5f639522023-07-04 17:08:58 -040031#include <memory>
Adrien Béraud612b55b2023-05-29 10:42:04 -040032
Adrien Béraud1ae60aa2023-07-07 09:55:09 -040033namespace dhtnet {
Adrien Béraud612b55b2023-05-29 10:42:04 -040034namespace upnp {
35
36using sys_clock = std::chrono::system_clock;
37
38enum class PortType { TCP, UDP };
39enum class MappingState { PENDING, IN_PROGRESS, FAILED, OPEN };
40
41enum class NatProtocolType;
42class IGD;
43
44class Mapping
45{
46 friend class UPnPContext;
47 friend class NatPmp;
48 friend class PUPnP;
49
50public:
51 using key_t = uint64_t;
52 using sharedPtr_t = std::shared_ptr<Mapping>;
53 using NotifyCallback = std::function<void(sharedPtr_t)>;
54
55 static constexpr char const* MAPPING_STATE_STR[4] {"PENDING", "IN_PROGRESS", "FAILED", "OPEN"};
56 static constexpr char const* UPNP_MAPPING_DESCRIPTION_PREFIX {"JAMI"};
57
58 Mapping(PortType type,
59 uint16_t portExternal = 0,
60 uint16_t portInternal = 0,
61 bool available = true);
62 Mapping(const Mapping& other);
63 Mapping(Mapping&& other) = delete;
64 ~Mapping() = default;
65
66 // Delete operators with confusing semantic.
67 Mapping& operator=(Mapping&& other) = delete;
68 bool operator==(const Mapping& other) = delete;
69 bool operator!=(const Mapping& other) = delete;
70 bool operator<(const Mapping& other) = delete;
71 bool operator>(const Mapping& other) = delete;
72 bool operator<=(const Mapping& other) = delete;
73 bool operator>=(const Mapping& other) = delete;
74
75 inline explicit operator bool() const { return isValid(); }
76
77 void updateFrom(const Mapping& other);
78 void updateFrom(const Mapping::sharedPtr_t& other);
79 std::string getExternalAddress() const;
80 uint16_t getExternalPort() const;
81 std::string getExternalPortStr() const;
82 std::string getInternalAddress() const;
83 uint16_t getInternalPort() const;
84 std::string getInternalPortStr() const;
85 PortType getType() const;
86 const char* getTypeStr() const;
87 static const char* getTypeStr(PortType type) { return type == PortType::UDP ? "UDP" : "TCP"; }
88 std::shared_ptr<IGD> getIgd() const;
89 NatProtocolType getProtocol() const;
90 const char* getProtocolName() const;
91 bool isAvailable() const;
92 MappingState getState() const;
93 const char* getStateStr() const;
94 static const char* getStateStr(MappingState state)
95 {
96 return MAPPING_STATE_STR[static_cast<int>(state)];
97 }
98 std::string toString(bool extraInfo = false) const;
99 bool isValid() const;
100 bool hasValidHostAddress() const;
101 bool hasPublicAddress() const;
102 void setNotifyCallback(NotifyCallback cb);
103 void enableAutoUpdate(bool enable);
104 bool getAutoUpdate() const;
105 key_t getMapKey() const;
106 static PortType getTypeFromMapKey(key_t key);
107#if HAVE_LIBNATPMP
108 sys_clock::time_point getRenewalTime() const;
109#endif
110
111private:
112 NotifyCallback getNotifyCallback() const;
113 void setInternalAddress(const std::string& addr);
114 void setExternalPort(uint16_t port);
115 void setInternalPort(uint16_t port);
116
117 void setIgd(const std::shared_ptr<IGD>& igd);
118 void setAvailable(bool val);
119 void setState(const MappingState& state);
120 void updateDescription();
121#if HAVE_LIBNATPMP
122 void setRenewalTime(sys_clock::time_point time);
123#endif
124
125 mutable std::mutex mutex_;
126 PortType type_ {PortType::UDP};
127 uint16_t externalPort_ {0};
128 uint16_t internalPort_ {0};
129 std::string internalAddr_;
130 // Protocol and
131 std::shared_ptr<IGD> igd_;
132 // Track if the mapping is available to use.
133 bool available_;
134 // Track the state of the mapping
135 MappingState state_;
136 NotifyCallback notifyCb_;
137 // If true, a new mapping will be requested on behave of the mapping
138 // owner when the mapping state changes from "OPEN" to "FAILED".
139 bool autoUpdate_;
140#if HAVE_LIBNATPMP
141 sys_clock::time_point renewalTime_;
142#endif
143};
144
145} // namespace upnp
146} // namespace jami