28#include <pjsip/sip_types.h>
29#include <pjsip/sip_transport_tls.h>
30#include <pj/ssl_sock.h>
32#include <pjnath/stun_config.h>
34#include <pjlib-util.h>
36#include <dhtnet/multiplexed_socket.h>
37#include <dhtnet/ip_utils.h>
38#include <dhtnet/tls_session.h>
40#include <opendht/crypto.h>
46#define RETURN_IF_FAIL(A, VAL, ...) \
48 JAMI_ERROR(__VA_ARGS__); \
68 : transport_(
nullptr, deleteTransport)
71 throw std::runtime_error(
"Invalid transport");
78 fmt::ptr(transport_.get()),
99 fmt::ptr(transport_.get()),
128 const auto& peers =
tlsInfo->remote_cert_info->raw_chain;
129 std::vector<std::pair<const uint8_t*, const uint8_t*>>
bits;
130 bits.resize(peers.cnt);
131 std::transform(peers.cert_raw,
132 peers.cert_raw + peers.cnt,
135 return std::make_pair((uint8_t*) crt.ptr,
136 (uint8_t*) (crt.ptr + crt.slen));
138 tlsInfos_.
peerCert = std::make_shared<dht::crypto::Certificate>(
bits);
144 std::vector<SipTransportStateCallback>
cbs;
146 std::lock_guard lock(stateListenersMutex_);
147 cbs.reserve(stateListeners_.size());
148 for (
auto&
l : stateListeners_)
149 cbs.push_back(
l.second);
158 std::lock_guard lock(stateListenersMutex_);
159 auto pair = stateListeners_.insert(std::make_pair(
lid,
cb));
167 std::lock_guard lock(stateListenersMutex_);
168 auto it = stateListeners_.find(
lid);
169 if (
it != stateListeners_.end()) {
170 stateListeners_.erase(
it);
195 udpTransports_.clear();
198 JAMI_DEBUG(
"Destroying SipTransportBroker@{}…", fmt::ptr(
this));
212 std::lock_guard lock(transportMapMutex_);
213 auto key = transports_.find(
tp);
214 if (key == transports_.end())
222 transports_.erase(key);
225 const auto type =
tp->key.type;
227 const auto updKey = std::find_if(udpTransports_.cbegin(),
228 udpTransports_.cend(),
229 [
tp](
const std::pair<dhtnet::IpAddr, pjsip_transport*>&
pair) {
230 return pair.second == tp;
232 if (
updKey != udpTransports_.cend())
233 udpTransports_.erase(
updKey);
243std::shared_ptr<SipTransport>
247 std::lock_guard lock(transportMapMutex_);
249 auto key = transports_.find(t);
250 if (key != transports_.end()) {
251 if (
auto sipTr = key->second.lock())
255 auto sipTr = std::make_shared<SipTransport>(t);
256 if (key != transports_.end())
259 transports_.emplace(std::make_pair(t,
sipTr));
269 std::unique_lock lock(transportMapMutex_);
270 isDestroying_ =
true;
271 for (
auto& t : transports_) {
272 if (
auto transport = t.second.lock()) {
278std::shared_ptr<SipTransport>
281 std::lock_guard lock(transportMapMutex_);
283 if (
itp != udpTransports_.end()) {
284 auto it = transports_.find(
itp->second);
285 if (
it != transports_.end()) {
286 if (
auto spt =
it->second.lock()) {
292 auto ret = std::make_shared<SipTransport>(
itp->second);
298 udpTransports_.erase(
itp);
304 transports_[
ret->get()] =
ret;
309std::shared_ptr<SipTransport>
310SipTransportBroker::createUdpTransport(
const dhtnet::IpAddr&
ipAddress)
319 JAMI_ERROR(
"pjsip_udp_transport_start2 failed with error {:d}: {:s}",
321 JAMI_ERROR(
"UDP IPv{} Transport did not start on {}",
328 return std::make_shared<SipTransport>(transport);
331std::shared_ptr<TlsListener>
345 return std::make_shared<TlsListener>(listener);
348std::shared_ptr<SipTransport>
350 const dhtnet::IpAddr& remote,
362 sel.u.listener =
l->get();
381 auto ret = std::make_shared<SipTransport>(transport,
l);
384 std::lock_guard lock(transportMapMutex_);
385 transports_[
ret->get()] =
ret;
390std::shared_ptr<SipTransport>
392 const std::shared_ptr<dhtnet::ChannelSocket>& socket,
397 auto sips_tr = std::make_unique<tls::ChanneledSIPTransport>(endpt_,
401 auto sip_tr = std::make_shared<SipTransport>(
tr, socket->peerCertificate());
402 sip_tr->setDeviceId(socket->deviceId().toString());
406 std::lock_guard lock(transportMapMutex_);
std::shared_ptr< SipTransport > addTransport(pjsip_transport *)
SipTransportBroker(pjsip_endpoint *endpt)
std::shared_ptr< SipTransport > getChanneledTransport(const std::shared_ptr< SIPAccountBase > &account, const std::shared_ptr< dhtnet::ChannelSocket > &socket, onShutdownCb &&cb)
void transportStateChanged(pjsip_transport *, pjsip_transport_state, const pjsip_transport_state_info *)
std::shared_ptr< SipTransport > getTlsTransport(const std::shared_ptr< TlsListener > &, const dhtnet::IpAddr &remote, const std::string &remote_name={})
std::shared_ptr< TlsListener > getTlsListener(const dhtnet::IpAddr &, const pjsip_tls_setting *)
void shutdown()
Start graceful shutdown procedure for all transports.
std::shared_ptr< SipTransport > getUdpTransport(const dhtnet::IpAddr &)
SIP transport wraps pjsip_transport.
bool removeStateListener(uintptr_t lid)
void addStateListener(uintptr_t lid, SipTransportStateCallback cb)
void stateCallback(pjsip_transport_state state, const pjsip_transport_state_info *info)
SipTransport(pjsip_transport *)
static const char * stateToStr(pjsip_transport_state state)
static bool isAlive(pjsip_transport_state state)
#define JAMI_ERROR(formatstr,...)
#define JAMI_DEBUG(formatstr,...)
#define JAMI_WARNING(formatstr,...)
std::string sip_strerror(pj_status_t code)
static constexpr std::string_view toString(AuthDecodingState state)
constexpr const size_t TRANSPORT_STATE_SZ
void emitSignal(Args... args)
constexpr const char * TRANSPORT_STATE_STR[]
static pjsip_endpoint * endpt_
std::function< void(pjsip_transport_state, const pjsip_transport_state_info *)> SipTransportStateCallback
std::function< void(void)> onShutdownCb
#define RETURN_IF_FAIL(A, VAL,...)
Specific VoIPLink for SIP (SIP core for incoming and outgoing events).
pj_ssl_cert_verify_flag_t verifyStatus
std::shared_ptr< dht::crypto::Certificate > peerCert