blob: 3ce16aca59b2ce87b3f9a951589d833d9eec6b79 [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
24#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>
31
32namespace jami {
33namespace upnp {
34
35using sys_clock = std::chrono::system_clock;
36
37enum class PortType { TCP, UDP };
38enum class MappingState { PENDING, IN_PROGRESS, FAILED, OPEN };
39
40enum class NatProtocolType;
41class IGD;
42
43class Mapping
44{
45 friend class UPnPContext;
46 friend class NatPmp;
47 friend class PUPnP;
48
49public:
50 using key_t = uint64_t;
51 using sharedPtr_t = std::shared_ptr<Mapping>;
52 using NotifyCallback = std::function<void(sharedPtr_t)>;
53
54 static constexpr char const* MAPPING_STATE_STR[4] {"PENDING", "IN_PROGRESS", "FAILED", "OPEN"};
55 static constexpr char const* UPNP_MAPPING_DESCRIPTION_PREFIX {"JAMI"};
56
57 Mapping(PortType type,
58 uint16_t portExternal = 0,
59 uint16_t portInternal = 0,
60 bool available = true);
61 Mapping(const Mapping& other);
62 Mapping(Mapping&& other) = delete;
63 ~Mapping() = default;
64
65 // Delete operators with confusing semantic.
66 Mapping& operator=(Mapping&& other) = delete;
67 bool operator==(const 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
74 inline explicit operator bool() const { return isValid(); }
75
76 void updateFrom(const Mapping& other);
77 void updateFrom(const Mapping::sharedPtr_t& other);
78 std::string getExternalAddress() const;
79 uint16_t getExternalPort() const;
80 std::string getExternalPortStr() const;
81 std::string getInternalAddress() const;
82 uint16_t getInternalPort() const;
83 std::string getInternalPortStr() const;
84 PortType getType() const;
85 const char* getTypeStr() const;
86 static const char* getTypeStr(PortType type) { return type == PortType::UDP ? "UDP" : "TCP"; }
87 std::shared_ptr<IGD> getIgd() const;
88 NatProtocolType getProtocol() const;
89 const char* getProtocolName() const;
90 bool isAvailable() const;
91 MappingState getState() const;
92 const char* getStateStr() const;
93 static const char* getStateStr(MappingState state)
94 {
95 return MAPPING_STATE_STR[static_cast<int>(state)];
96 }
97 std::string toString(bool extraInfo = false) const;
98 bool isValid() const;
99 bool hasValidHostAddress() const;
100 bool hasPublicAddress() const;
101 void setNotifyCallback(NotifyCallback cb);
102 void enableAutoUpdate(bool enable);
103 bool getAutoUpdate() const;
104 key_t getMapKey() const;
105 static PortType getTypeFromMapKey(key_t key);
106#if HAVE_LIBNATPMP
107 sys_clock::time_point getRenewalTime() const;
108#endif
109
110private:
111 NotifyCallback getNotifyCallback() const;
112 void setInternalAddress(const std::string& addr);
113 void setExternalPort(uint16_t port);
114 void setInternalPort(uint16_t port);
115
116 void setIgd(const std::shared_ptr<IGD>& igd);
117 void setAvailable(bool val);
118 void setState(const MappingState& state);
119 void updateDescription();
120#if HAVE_LIBNATPMP
121 void setRenewalTime(sys_clock::time_point time);
122#endif
123
124 mutable std::mutex mutex_;
125 PortType type_ {PortType::UDP};
126 uint16_t externalPort_ {0};
127 uint16_t internalPort_ {0};
128 std::string internalAddr_;
129 // Protocol and
130 std::shared_ptr<IGD> igd_;
131 // Track if the mapping is available to use.
132 bool available_;
133 // Track the state of the mapping
134 MappingState state_;
135 NotifyCallback notifyCb_;
136 // If true, a new mapping will be requested on behave of the mapping
137 // owner when the mapping state changes from "OPEN" to "FAILED".
138 bool autoUpdate_;
139#if HAVE_LIBNATPMP
140 sys_clock::time_point renewalTime_;
141#endif
142};
143
144} // namespace upnp
145} // namespace jami