blob: a13ebdd71004133affb4dbf6a81181a0f97fe3f6 [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 */
Adrien Béraud612b55b2023-05-29 10:42:04 -040017#pragma once
18
19#include "ice_options.h"
Adrien Béraud612b55b2023-05-29 10:42:04 -040020#include "ip_utils.h"
21
Adrien Béraud67ff0772023-07-12 11:22:29 -040022#include <msgpack.hpp>
23
Adrien Béraud612b55b2023-05-29 10:42:04 -040024#include <functional>
25#include <memory>
Adrien Béraud612b55b2023-05-29 10:42:04 -040026#include <vector>
Adrien Béraud67ff0772023-07-12 11:22:29 -040027#include <chrono>
Adrien Béraud612b55b2023-05-29 10:42:04 -040028
Andreas Traczyk24cc01e2023-08-23 18:55:15 -040029#if defined(_MSC_VER)
30#include <BaseTsd.h>
31using ssize_t = SSIZE_T;
32#endif
33
Adrien Béraud6de3f882023-07-06 12:56:29 -040034extern "C" {
35struct pj_ice_sess_cand;
36}
37
Adrien Béraud612b55b2023-05-29 10:42:04 -040038namespace dht {
39namespace log {
Adrien Béraud9132a812023-07-21 11:20:40 -040040struct Logger;
Adrien Béraud612b55b2023-05-29 10:42:04 -040041}
42}
43
Adrien Béraud1ae60aa2023-07-07 09:55:09 -040044namespace dhtnet {
Adrien Béraud612b55b2023-05-29 10:42:04 -040045
46using Logger = dht::log::Logger;
47
48namespace upnp {
49class Controller;
50}
51
52class IceTransport;
Amna81221ad2023-09-14 17:33:26 -040053class IceTransportFactory;
Adrien Béraud612b55b2023-05-29 10:42:04 -040054
55using IceRecvCb = std::function<ssize_t(unsigned char* buf, size_t len)>;
56using IceCandidate = pj_ice_sess_cand;
57using onShutdownCb = std::function<void(void)>;
58
59struct ICESDP
60{
61 std::vector<IceCandidate> rem_candidates;
62 std::string rem_ufrag;
63 std::string rem_pwd;
64};
65
66struct SDP
67{
68 std::string ufrag;
69 std::string pwd;
70
71 std::vector<std::string> candidates;
72 MSGPACK_DEFINE(ufrag, pwd, candidates)
73};
74
75class IceTransport
76{
77public:
78 using Attribute = struct
79 {
80 std::string ufrag;
81 std::string pwd;
82 };
83
84 /**
85 * Constructor
86 */
Adrien Béraud89933c12023-07-26 14:53:30 -040087 IceTransport(std::string_view name, const std::shared_ptr<Logger>& logger = {});
Adrien Béraud612b55b2023-05-29 10:42:04 -040088 ~IceTransport();
89
90 const std::shared_ptr<Logger>& logger() const;
91
92 void initIceInstance(const IceTransportOptions& options);
93
94 /**
95 * Get current state
96 */
97 bool isInitiator() const;
98
99 /**
100 * Start transport negotiation between local candidates and given remote
101 * to find the right candidate pair.
102 * This function doesn't block, the callback on_negodone_cb will be called
103 * with the negotiation result when operation is really done.
104 * Return false if negotiation cannot be started else true.
105 */
106 bool startIce(const Attribute& rem_attrs, std::vector<IceCandidate>&& rem_candidates);
107 bool startIce(const SDP& sdp);
108
109 /**
110 * Cancel operations
111 */
112 void cancelOperations();
113
114 /**
115 * Returns true if ICE transport has been initialized
116 * [mutex protected]
117 */
118 bool isInitialized() const;
119
120 /**
121 * Returns true if ICE negotiation has been started
122 * [mutex protected]
123 */
124 bool isStarted() const;
125
126 /**
127 * Returns true if ICE negotiation has completed with success
128 * [mutex protected]
129 */
130 bool isRunning() const;
131
132 /**
133 * Returns true if ICE transport is in failure state
134 * [mutex protected]
135 */
136 bool isFailed() const;
137
138 IpAddr getLocalAddress(unsigned comp_id) const;
139
140 IpAddr getRemoteAddress(unsigned comp_id) const;
141
142 IpAddr getDefaultLocalAddress() const { return getLocalAddress(1); }
143
144 /**
145 * Return ICE session attributes
146 */
147 const Attribute getLocalAttributes() const;
148
149 /**
150 * Return ICE session attributes
151 */
152 std::vector<std::string> getLocalCandidates(unsigned comp_id) const;
153
154 /**
155 * Return ICE session attributes
156 */
157 std::vector<std::string> getLocalCandidates(unsigned streamIdx, unsigned compId) const;
158
159 bool parseIceAttributeLine(unsigned streamIdx,
160 const std::string& line,
161 IceCandidate& cand) const;
162
163 bool getCandidateFromSDP(const std::string& line, IceCandidate& cand) const;
164
165 // I/O methods
166
167 void setOnRecv(unsigned comp_id, IceRecvCb cb);
168 void setOnShutdown(onShutdownCb&& cb);
169
170 ssize_t recv(unsigned comp_id, unsigned char* buf, size_t len, std::error_code& ec);
171 ssize_t recvfrom(unsigned comp_id, char* buf, size_t len, std::error_code& ec);
172
173 ssize_t send(unsigned comp_id, const unsigned char* buf, size_t len);
174
175 bool waitForInitialization(std::chrono::milliseconds timeout);
176
177 int waitForNegotiation(std::chrono::milliseconds timeout);
178
179 ssize_t waitForData(unsigned comp_id, std::chrono::milliseconds timeout, std::error_code& ec);
180
181 unsigned getComponentCount() const;
182
183 // Set session state
184 bool setSlaveSession();
185 bool setInitiatorSession();
186
Adrien Béraud02d6dad2023-11-06 09:26:51 -0500187 bool isTCPEnabled() const;
Adrien Béraud612b55b2023-05-29 10:42:04 -0400188
189 ICESDP parseIceCandidates(std::string_view sdp_msg);
190
191 void setDefaultRemoteAddress(unsigned comp_id, const IpAddr& addr);
192
193 std::string link() const;
194
195private:
196 class Impl;
197 std::unique_ptr<Impl> pimpl_;
198};
199
Adrien Béraud612b55b2023-05-29 10:42:04 -0400200}; // namespace jami