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