26#include <pjsip/sip_types.h>
27#include <pjsip/sip_transport_tls.h>
28#include <pj/ssl_sock.h>
30#include <pjnath/stun_config.h>
32#include <pjlib-util.h>
34#include <dhtnet/multiplexed_socket.h>
35#include <dhtnet/ip_utils.h>
36#include <dhtnet/tls_session.h>
38#include <opendht/crypto.h>
43#define RETURN_IF_FAIL(A, VAL, ...) \
45 JAMI_ERROR(__VA_ARGS__); \
51constexpr const char*
TRANSPORT_STATE_STR[] = {
"CONNECTED",
"DISCONNECTED",
"SHUTDOWN",
"DESTROY",
"UNKNOWN STATE"};
64 throw std::runtime_error(
"Invalid transport");
71 fmt::ptr(transport_.get()),
91 fmt::ptr(transport_.get()),
119 const auto& peers =
tlsInfo->remote_cert_info->raw_chain;
120 std::vector<std::pair<const uint8_t*, const uint8_t*>>
bits;
121 bits.resize(peers.cnt);
122 std::transform(peers.cert_raw, peers.cert_raw + peers.cnt, std::begin(
bits), [](
const pj_str_t&
crt) {
123 return std::make_pair((uint8_t*) crt.ptr, (uint8_t*) (crt.ptr + crt.slen));
125 tlsInfos_.
peerCert = std::make_shared<dht::crypto::Certificate>(
bits);
131 std::vector<SipTransportStateCallback>
cbs;
133 std::lock_guard lock(stateListenersMutex_);
134 cbs.reserve(stateListeners_.size());
135 for (
auto&
l : stateListeners_)
136 cbs.push_back(
l.second);
145 std::lock_guard lock(stateListenersMutex_);
146 auto pair = stateListeners_.insert(std::make_pair(
lid,
cb));
154 std::lock_guard lock(stateListenersMutex_);
155 auto it = stateListeners_.find(
lid);
156 if (
it != stateListeners_.end()) {
157 stateListeners_.erase(
it);
182 udpTransports_.clear();
185 JAMI_DEBUG(
"Destroying SipTransportBroker@{}…", fmt::ptr(
this));
199 std::lock_guard lock(transportMapMutex_);
200 auto key = transports_.find(
tp);
201 if (key == transports_.end())
209 transports_.erase(key);
212 const auto type =
tp->key.type;
214 const auto updKey = std::find_if(udpTransports_.cbegin(),
215 udpTransports_.cend(),
216 [
tp](
const std::pair<dhtnet::IpAddr, pjsip_transport*>&
pair) {
217 return pair.second == tp;
219 if (
updKey != udpTransports_.cend())
220 udpTransports_.erase(
updKey);
230std::shared_ptr<SipTransport>
234 std::lock_guard lock(transportMapMutex_);
236 auto key = transports_.find(t);
237 if (key != transports_.end()) {
238 if (
auto sipTr = key->second.lock())
242 auto sipTr = std::make_shared<SipTransport>(t);
243 if (key != transports_.end())
246 transports_.emplace(std::make_pair(t,
sipTr));
256 std::unique_lock lock(transportMapMutex_);
257 isDestroying_ =
true;
258 for (
auto& t : transports_) {
259 if (
auto transport = t.second.lock()) {
265std::shared_ptr<SipTransport>
268 std::lock_guard lock(transportMapMutex_);
270 if (
itp != udpTransports_.end()) {
271 auto it = transports_.find(
itp->second);
272 if (
it != transports_.end()) {
273 if (
auto spt =
it->second.lock()) {
279 auto ret = std::make_shared<SipTransport>(
itp->second);
285 udpTransports_.erase(
itp);
291 transports_[
ret->get()] =
ret;
296std::shared_ptr<SipTransport>
297SipTransportBroker::createUdpTransport(
const dhtnet::IpAddr&
ipAddress)
312 return std::make_shared<SipTransport>(transport);
315std::shared_ptr<TlsListener>
328 return std::make_shared<TlsListener>(listener);
331std::shared_ptr<SipTransport>
333 const dhtnet::IpAddr& remote,
345 sel.u.listener =
l->get();
364 auto ret = std::make_shared<SipTransport>(transport,
l);
367 std::lock_guard lock(transportMapMutex_);
368 transports_[
ret->get()] =
ret;
373std::shared_ptr<SipTransport>
375 const std::shared_ptr<dhtnet::ChannelSocket>& socket,
380 auto sips_tr = std::make_unique<tls::ChanneledSIPTransport>(endpt_, socket, std::move(
cb));
382 auto sip_tr = std::make_shared<SipTransport>(
tr, socket->peerCertificate());
383 sip_tr->setDeviceId(socket->deviceId().toString());
387 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, const 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