blob: 2c7f07afda8a7a64ebdda6ebf38b1c2111fe38df [file] [log] [blame]
Adrien Béraud612b55b2023-05-29 10:42:04 -04001/*
2 * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
3 *
4 * Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
5 * Author: Eden Abitbol <eden.abitbol@savoirfairelinux.com>
6 * Author: Mohamed Chibani <mohamed.chibani@savoirfairelinux.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
Morteza Namvar5f639522023-07-04 17:08:58 -040023#include "upnp/upnp_control.h"
24#include "upnp/upnp_context.h"
Adrien Béraud612b55b2023-05-29 10:42:04 -040025
Adrien Béraud1ae60aa2023-07-07 09:55:09 -040026namespace dhtnet {
Adrien Béraud612b55b2023-05-29 10:42:04 -040027namespace upnp {
28
Adrien Béraud25c30c42023-07-05 13:46:54 -040029Controller::Controller(const std::shared_ptr<UPnPContext>& ctx)
30 : upnpContext_(ctx)
Adrien Béraud612b55b2023-05-29 10:42:04 -040031{
Adrien Béraud612b55b2023-05-29 10:42:04 -040032 upnpContext_->registerController(this);
Morteza Namvar5f639522023-07-04 17:08:58 -040033 // JAMI_DBG("Controller@%p: Created UPnP Controller session", this);
Adrien Béraud612b55b2023-05-29 10:42:04 -040034}
35
36Controller::~Controller()
37{
Morteza Namvar5f639522023-07-04 17:08:58 -040038 // JAMI_DBG("Controller@%p: Destroying UPnP Controller session", this);
Adrien Béraud612b55b2023-05-29 10:42:04 -040039
40 releaseAllMappings();
41 upnpContext_->unregisterController(this);
42}
43
44void
45Controller::setPublicAddress(const IpAddr& addr)
46{
47 assert(upnpContext_);
48
49 if (addr and addr.getFamily() == AF_INET) {
50 upnpContext_->setPublicAddress(addr);
51 }
52}
53
54bool
55Controller::isReady() const
56{
57 assert(upnpContext_);
58 return upnpContext_->isReady();
59}
60
61IpAddr
62Controller::getExternalIP() const
63{
64 assert(upnpContext_);
65 if (upnpContext_->isReady()) {
66 return upnpContext_->getExternalIP();
67 }
68 return {};
69}
70
71Mapping::sharedPtr_t
72Controller::reserveMapping(uint16_t port, PortType type)
73{
74 Mapping map(type, port, port);
75 return reserveMapping(map);
76}
77
78Mapping::sharedPtr_t
79Controller::reserveMapping(Mapping& requestedMap)
80{
81 assert(upnpContext_);
82
83 // Try to get a provisioned port
84 auto mapRes = upnpContext_->reserveMapping(requestedMap);
85 if (mapRes)
86 addLocalMap(*mapRes);
87 return mapRes;
88}
89
90void
91Controller::releaseMapping(const Mapping& map)
92{
93 assert(upnpContext_);
94
95 removeLocalMap(map);
96 return upnpContext_->releaseMapping(map);
97}
98
99void
100Controller::releaseAllMappings()
101{
102 assert(upnpContext_);
103
104 std::lock_guard<std::mutex> lk(mapListMutex_);
105 for (auto const& [_, map] : mappingList_) {
106 upnpContext_->releaseMapping(map);
107 }
108 mappingList_.clear();
109}
110
111void
112Controller::addLocalMap(const Mapping& map)
113{
114 if (map.getMapKey()) {
115 std::lock_guard<std::mutex> lock(mapListMutex_);
116 auto ret = mappingList_.emplace(map.getMapKey(), map);
117 if (not ret.second) {
Morteza Namvar5f639522023-07-04 17:08:58 -0400118 // JAMI_WARN("Mapping request for %s already in the list!", map.toString().c_str());
Adrien Béraud612b55b2023-05-29 10:42:04 -0400119 }
120 }
121}
122
123bool
124Controller::removeLocalMap(const Mapping& map)
125{
126 assert(upnpContext_);
127
128 std::lock_guard<std::mutex> lk(mapListMutex_);
129 if (mappingList_.erase(map.getMapKey()) != 1) {
Morteza Namvar5f639522023-07-04 17:08:58 -0400130 // JAMI_ERR("Failed to remove mapping %s from local list", map.getTypeStr());
Adrien Béraud612b55b2023-05-29 10:42:04 -0400131 return false;
132 }
133
134 return true;
135}
136
137uint16_t
138Controller::generateRandomPort(PortType type)
139{
140 return UPnPContext::generateRandomPort(type);
141}
142
143} // namespace upnp
144} // namespace jami