Commit 89ba505b authored by Guillaume Roguez's avatar Guillaume Roguez

sip: fix sip call crash

MTU discovery was only implemented into TLS secured ICE transport,
not in other sip transport.
This wasn't taken in account and causes crashes when SIP call (TLS or not)
are made.
We fix the problem by detecting the transport type at various stage
and calling correct API (or use default values as in the case of MTU).

Change-Id: Id256a718ca8265a7295085fab8db9cf8e4c99683
parent f3d677fb
......@@ -148,7 +148,7 @@ udp_set_url(struct sockaddr_storage* addr, const char* hostname, int port)
}
static int
udp_socket_create(sockaddr_storage* addr, socklen_t* addr_len, int local_port)
udp_socket_create(sockaddr_storage* addr, socklen_t* addr_len, int local_port, int& family)
{
int udp_fd = -1;
struct addrinfo* res0 = nullptr;
......@@ -160,12 +160,14 @@ udp_socket_create(sockaddr_storage* addr, socklen_t* addr_len, int local_port)
for (res = res0; res; res=res->ai_next) {
#ifdef __APPLE__
udp_fd = socket(res->ai_family, SOCK_DGRAM, 0);
if (udp_fd != -1 && fcntl(udp_fd, F_SETFL, O_NONBLOCK) != -1)
if (udp_fd != -1 && fcntl(udp_fd, F_SETFL, O_NONBLOCK) != -1) {
#else
udp_fd = socket(res->ai_family, SOCK_DGRAM | SOCK_NONBLOCK, 0);
if (udp_fd != -1)
if (udp_fd != -1) {
#endif
break;
family = res->ai_family;
break;
}
RING_ERR("socket error");
}
......@@ -317,8 +319,8 @@ SocketPair::openSockets(const char* uri, int local_rtp_port)
socklen_t rtp_len, rtcp_len;
// Open sockets and store addresses for sending
if ((rtpHandle_ = udp_socket_create(&rtp_addr, &rtp_len, local_rtp_port)) == -1 or
(rtcpHandle_ = udp_socket_create(&rtcp_addr, &rtcp_len, local_rtcp_port)) == -1 or
if ((rtpHandle_ = udp_socket_create(&rtp_addr, &rtp_len, local_rtp_port, rtpFamily_)) == -1 or
(rtcpHandle_ = udp_socket_create(&rtcp_addr, &rtcp_len, local_rtcp_port, rtcpFamily_)) == -1 or
(rtpDestAddrLen_ = udp_set_url(&rtpDestAddr_, hostname, rtp_port)) == 0 or
(rtcpDestAddrLen_ = udp_set_url(&rtcpDestAddr_, hostname, rtcp_port)) == 0) {
......@@ -334,7 +336,13 @@ SocketPair::openSockets(const char* uri, int local_rtp_port)
MediaIOHandle*
SocketPair::createIOContext(const uint16_t mtu)
{
auto ip_header_size = rtp_sock_->getTransportOverhead();
unsigned ip_header_size;
if (rtp_sock_)
ip_header_size = rtp_sock_->getTransportOverhead();
else if (rtpFamily_ == AF_INET6)
ip_header_size = 40;
else
ip_header_size = 20;
return new MediaIOHandle( mtu - (srtpContext_ ? SRTP_OVERHEAD : 0) - UDP_HEADER_SIZE - ip_header_size,
true,
[](void* sp, uint8_t* buf, int len){ return static_cast<SocketPair*>(sp)->readCallback(buf, len); },
......
......@@ -129,6 +129,8 @@ class SocketPair {
int rtpHandle_ {-1};
int rtcpHandle_ {-1};
int rtpFamily_ {0};
int rtcpFamily_ {0};
sockaddr_storage rtpDestAddr_;
socklen_t rtpDestAddrLen_;
sockaddr_storage rtcpDestAddr_;
......
......@@ -44,8 +44,6 @@ namespace ring { namespace tls {
static constexpr const char* TLS_CERT_PRIORITY_STRING {"SECURE192:-VERS-TLS-ALL:+VERS-DTLS-ALL:-RSA:%SERVER_PRECEDENCE:%SAFE_RENEGOTIATION"};
static constexpr const char* TLS_FULL_PRIORITY_STRING {"SECURE192:-KX-ALL:+ANON-ECDH:+ANON-DH:+SECURE192:-VERS-TLS-ALL:+VERS-DTLS-ALL:-RSA:%SERVER_PRECEDENCE:%SAFE_RENEGOTIATION"};
static constexpr int DTLS_MTU {1232}; // (1280 from IPv6 minimum MTU - 40 IPv6 header - 8 UDP header)
static constexpr uint16_t MIN_MTU {512};
static constexpr uint16_t INPUT_BUFFER_SIZE {16*1024}; // to be coherent with the maximum size advised in path mtu discovery
static constexpr std::size_t INPUT_MAX_SIZE {1000}; // Maximum packet to store before dropping (pkt size = DTLS_MTU)
static constexpr ssize_t FLOOD_THRESHOLD {4*1024};
......
......@@ -55,6 +55,8 @@ struct PrivateKey;
namespace ring { namespace tls {
static constexpr uint8_t MTUS_TO_TEST = 4; //number of mtus to test in path mtu discovery.
static constexpr int DTLS_MTU {1232}; // (1280 from IPv6 minimum MTU - 40 IPv6 header - 8 UDP header)
static constexpr uint16_t MIN_MTU {512};
enum class TlsSessionState {
SETUP,
......
......@@ -23,6 +23,7 @@
#include "sip_utils.h"
#include "ip_utils.h"
#include "ice_transport.h"
#include "security/tls_session.h"
#include "ringdht/sip_transport_ice.h"
#include "ringdht/sips_transport_ice.h"
......@@ -174,9 +175,13 @@ SipTransport::removeStateListener(uintptr_t lid)
}
uint16_t
SipTransport::getTlsMtu(){
auto tls_tr = reinterpret_cast<tls::SipsIceTransport::TransportData*>(transport_.get())->self;
return tls_tr->getTlsSessionMtu();
SipTransport::getTlsMtu()
{
if (isIceTransport_ && isSecure()) {
auto tls_tr = reinterpret_cast<tls::SipsIceTransport::TransportData*>(transport_.get())->self;
return tls_tr->getTlsSessionMtu();
}
return ring::tls::DTLS_MTU;
}
SipTransportBroker::SipTransportBroker(pjsip_endpoint *endpt,
......@@ -431,6 +436,7 @@ SipTransportBroker::getIceTransport(const std::shared_ptr<IceTransport>& ice,
new SipIceTransport(endpt_, pool_, ice_pj_transport_type_, ice, comp_id));
auto tr = sip_ice_tr->getTransportBase();
auto sip_tr = std::make_shared<SipTransport>(tr);
sip_tr->setIsIceTransport();
sip_ice_tr.release(); // managed by PJSIP now
{
......@@ -453,6 +459,7 @@ SipTransportBroker::getTlsIceTransport(const std::shared_ptr<ring::IceTransport>
new tls::SipsIceTransport(endpt_, type, params, ice, comp_id));
auto tr = sip_ice_tr->getTransportBase();
auto sip_tr = std::make_shared<SipTransport>(tr);
sip_tr->setIsIceTransport();
sip_ice_tr.release(); // managed by PJSIP now
{
......
......@@ -138,6 +138,8 @@ class SipTransport
/** Only makes sense for connection-oriented transports */
bool isConnected() const noexcept { return connected_; }
void setIsIceTransport() { isIceTransport_ = true; }
uint16_t getTlsMtu();
private:
......@@ -151,6 +153,7 @@ class SipTransport
std::mutex stateListenersMutex_;
bool connected_ {false};
bool isIceTransport_ {false};
TlsInfos tlsInfos_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment