blob: 8dacd7476998ef88bf406c1d9123eeb40d2ce385 [file] [log] [blame]
Adrien Béraud612b55b2023-05-29 10:42:04 -04001/*
2 * Copyright (C) 2004-2023 Savoir-faire Linux Inc.
3 *
Adrien Béraudcb753622023-07-17 22:32:49 -04004 * This program is free software: you can redistribute it and/or modify
Adrien Béraud612b55b2023-05-29 10:42:04 -04005 * it under the terms of the GNU General Public License as published by
Adrien Béraudcb753622023-07-17 22:32:49 -04006 * the Free Software Foundation, either version 3 of the License, or
Adrien Béraud612b55b2023-05-29 10:42:04 -04007 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Adrien Béraudcb753622023-07-17 22:32:49 -040011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Adrien Béraud612b55b2023-05-29 10:42:04 -040012 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
Adrien Béraudcb753622023-07-17 22:32:49 -040015 * along with this program. If not, see <https://www.gnu.org/licenses/>.
Adrien Béraud612b55b2023-05-29 10:42:04 -040016 */
Morteza Namvar5f639522023-07-04 17:08:58 -040017#include "upnp/upnp_control.h"
18#include "upnp/upnp_context.h"
Adrien Béraud612b55b2023-05-29 10:42:04 -040019
Adrien Béraud1ae60aa2023-07-07 09:55:09 -040020namespace dhtnet {
Adrien Béraud612b55b2023-05-29 10:42:04 -040021namespace upnp {
22
Adrien Béraud25c30c42023-07-05 13:46:54 -040023Controller::Controller(const std::shared_ptr<UPnPContext>& ctx)
24 : upnpContext_(ctx)
Adrien Béraud612b55b2023-05-29 10:42:04 -040025{
Adrien Berauda8731ac2023-08-17 12:19:39 -040026 upnpContext_->dispatch([c=upnpContext_, this]{
27 c->registerController(this);
28 });
Adrien Béraud612b55b2023-05-29 10:42:04 -040029}
30
31Controller::~Controller()
32{
Adrien Béraud612b55b2023-05-29 10:42:04 -040033 releaseAllMappings();
Adrien Berauda8731ac2023-08-17 12:19:39 -040034 upnpContext_->dispatch([c=upnpContext_, this]{
35 c->unregisterController(this);
36 });
Adrien Béraud612b55b2023-05-29 10:42:04 -040037}
38
39void
40Controller::setPublicAddress(const IpAddr& addr)
41{
42 assert(upnpContext_);
43
44 if (addr and addr.getFamily() == AF_INET) {
45 upnpContext_->setPublicAddress(addr);
46 }
47}
48
49bool
50Controller::isReady() const
51{
52 assert(upnpContext_);
53 return upnpContext_->isReady();
54}
55
56IpAddr
57Controller::getExternalIP() const
58{
59 assert(upnpContext_);
60 if (upnpContext_->isReady()) {
61 return upnpContext_->getExternalIP();
62 }
63 return {};
64}
65
66Mapping::sharedPtr_t
67Controller::reserveMapping(uint16_t port, PortType type)
68{
69 Mapping map(type, port, port);
70 return reserveMapping(map);
71}
72
73Mapping::sharedPtr_t
74Controller::reserveMapping(Mapping& requestedMap)
75{
76 assert(upnpContext_);
77
78 // Try to get a provisioned port
79 auto mapRes = upnpContext_->reserveMapping(requestedMap);
80 if (mapRes)
81 addLocalMap(*mapRes);
82 return mapRes;
83}
84
85void
86Controller::releaseMapping(const Mapping& map)
87{
88 assert(upnpContext_);
89
90 removeLocalMap(map);
91 return upnpContext_->releaseMapping(map);
92}
93
94void
95Controller::releaseAllMappings()
96{
97 assert(upnpContext_);
98
99 std::lock_guard<std::mutex> lk(mapListMutex_);
100 for (auto const& [_, map] : mappingList_) {
101 upnpContext_->releaseMapping(map);
102 }
103 mappingList_.clear();
104}
105
106void
107Controller::addLocalMap(const Mapping& map)
108{
109 if (map.getMapKey()) {
110 std::lock_guard<std::mutex> lock(mapListMutex_);
111 auto ret = mappingList_.emplace(map.getMapKey(), map);
Adrien Béraud612b55b2023-05-29 10:42:04 -0400112 }
113}
114
115bool
116Controller::removeLocalMap(const Mapping& map)
117{
118 assert(upnpContext_);
119
120 std::lock_guard<std::mutex> lk(mapListMutex_);
Sébastien Blin91cda3c2024-01-10 16:21:18 -0500121 return mappingList_.erase(map.getMapKey()) == 1;
Adrien Béraud612b55b2023-05-29 10:42:04 -0400122}
123
124uint16_t
125Controller::generateRandomPort(PortType type)
126{
127 return UPnPContext::generateRandomPort(type);
128}
129
130} // namespace upnp
Sébastien Blin464bdff2023-07-19 08:02:53 -0400131} // namespace dhtnet