Merge pull request #19 from paullouisageneau/fix-late-candidates

Fix late candidates triggering DTLS init twice
This commit is contained in:
Paul-Louis Ageneau
2019-12-17 15:04:14 +00:00
committed by GitHub
5 changed files with 32 additions and 9 deletions

View File

@ -91,6 +91,7 @@ private:
std::shared_ptr<DtlsTransport> initDtlsTransport(); std::shared_ptr<DtlsTransport> initDtlsTransport();
std::shared_ptr<SctpTransport> initSctpTransport(); std::shared_ptr<SctpTransport> initSctpTransport();
void endLocalCandidates();
bool checkFingerprint(const std::string &fingerprint) const; bool checkFingerprint(const std::string &fingerprint) const;
void forwardMessage(message_ptr message); void forwardMessage(message_ptr message);
void forwardBufferedAmount(uint16_t stream, size_t amount); void forwardBufferedAmount(uint16_t stream, size_t amount);
@ -114,6 +115,7 @@ private:
std::shared_ptr<IceTransport> mIceTransport; std::shared_ptr<IceTransport> mIceTransport;
std::shared_ptr<DtlsTransport> mDtlsTransport; std::shared_ptr<DtlsTransport> mDtlsTransport;
std::shared_ptr<SctpTransport> mSctpTransport; std::shared_ptr<SctpTransport> mSctpTransport;
std::recursive_mutex mInitMutex;
std::unordered_map<unsigned int, std::weak_ptr<DataChannel>> mDataChannels; std::unordered_map<unsigned int, std::weak_ptr<DataChannel>> mDataChannels;

View File

@ -87,7 +87,6 @@ DtlsTransport::DtlsTransport(shared_ptr<IceTransport> lower, shared_ptr<Certific
DtlsTransport::~DtlsTransport() { DtlsTransport::~DtlsTransport() {
stop(); stop();
gnutls_bye(mSession, GNUTLS_SHUT_RDWR);
gnutls_deinit(mSession); gnutls_deinit(mSession);
} }
@ -98,6 +97,7 @@ void DtlsTransport::stop() {
if (mRecvThread.joinable()) { if (mRecvThread.joinable()) {
mIncomingQueue.stop(); mIncomingQueue.stop();
gnutls_bye(mSession, GNUTLS_SHUT_RDWR);
mRecvThread.join(); mRecvThread.join();
} }
} }

View File

@ -210,6 +210,10 @@ void PeerConnection::onGatheringStateChange(std::function<void(GatheringState st
} }
shared_ptr<IceTransport> PeerConnection::initIceTransport(Description::Role role) { shared_ptr<IceTransport> PeerConnection::initIceTransport(Description::Role role) {
std::lock_guard lock(mInitMutex);
if (auto transport = std::atomic_load(&mIceTransport))
return transport;
auto transport = std::make_shared<IceTransport>( auto transport = std::make_shared<IceTransport>(
mConfig, role, std::bind(&PeerConnection::processLocalCandidate, this, _1), mConfig, role, std::bind(&PeerConnection::processLocalCandidate, this, _1),
[this](IceTransport::State state) { [this](IceTransport::State state) {
@ -237,8 +241,7 @@ shared_ptr<IceTransport> PeerConnection::initIceTransport(Description::Role role
changeGatheringState(GatheringState::InProgress); changeGatheringState(GatheringState::InProgress);
break; break;
case IceTransport::GatheringState::Complete: case IceTransport::GatheringState::Complete:
if (mLocalDescription) endLocalCandidates();
mLocalDescription->endCandidates();
changeGatheringState(GatheringState::Complete); changeGatheringState(GatheringState::Complete);
break; break;
default: default:
@ -251,6 +254,10 @@ shared_ptr<IceTransport> PeerConnection::initIceTransport(Description::Role role
} }
shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() { shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
std::lock_guard lock(mInitMutex);
if (auto transport = std::atomic_load(&mDtlsTransport))
return transport;
auto lower = std::atomic_load(&mIceTransport); auto lower = std::atomic_load(&mIceTransport);
auto transport = std::make_shared<DtlsTransport>( auto transport = std::make_shared<DtlsTransport>(
lower, mCertificate, std::bind(&PeerConnection::checkFingerprint, this, _1), lower, mCertificate, std::bind(&PeerConnection::checkFingerprint, this, _1),
@ -275,6 +282,10 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
} }
shared_ptr<SctpTransport> PeerConnection::initSctpTransport() { shared_ptr<SctpTransport> PeerConnection::initSctpTransport() {
std::lock_guard lock(mInitMutex);
if (auto transport = std::atomic_load(&mSctpTransport))
return transport;
uint16_t sctpPort = remoteDescription()->sctpPort().value_or(DEFAULT_SCTP_PORT); uint16_t sctpPort = remoteDescription()->sctpPort().value_or(DEFAULT_SCTP_PORT);
auto lower = std::atomic_load(&mDtlsTransport); auto lower = std::atomic_load(&mDtlsTransport);
auto transport = std::make_shared<SctpTransport>( auto transport = std::make_shared<SctpTransport>(
@ -301,6 +312,12 @@ shared_ptr<SctpTransport> PeerConnection::initSctpTransport() {
return transport; return transport;
} }
void PeerConnection::endLocalCandidates() {
std::lock_guard lock(mLocalDescriptionMutex);
if (mLocalDescription)
mLocalDescription->endCandidates();
}
bool PeerConnection::checkFingerprint(const std::string &fingerprint) const { bool PeerConnection::checkFingerprint(const std::string &fingerprint) const {
std::lock_guard lock(mRemoteDescriptionMutex); std::lock_guard lock(mRemoteDescriptionMutex);
if (auto expectedFingerprint = if (auto expectedFingerprint =

View File

@ -145,7 +145,6 @@ SctpTransport::SctpTransport(std::shared_ptr<Transport> lower, uint16_t port,
SctpTransport::~SctpTransport() { SctpTransport::~SctpTransport() {
stop(); stop();
usrsctp_shutdown(mSock, SHUT_RDWR);
usrsctp_close(mSock); usrsctp_close(mSock);
usrsctp_deregister_address(this); usrsctp_deregister_address(this);
@ -158,12 +157,15 @@ void SctpTransport::stop() {
Transport::stop(); Transport::stop();
onRecv(nullptr); onRecv(nullptr);
mSendQueue.stop(); if (!mShutdown.exchange(true)) {
mSendQueue.stop();
usrsctp_shutdown(mSock, SHUT_RDWR);
// Unblock incoming // Unblock incoming
std::unique_lock<std::mutex> lock(mConnectMutex); std::unique_lock<std::mutex> lock(mConnectMutex);
mConnectDataSent = true; mConnectDataSent = true;
mConnectCondition.notify_all(); mConnectCondition.notify_all();
}
} }
void SctpTransport::connect() { void SctpTransport::connect() {

View File

@ -95,6 +95,8 @@ private:
std::condition_variable mConnectCondition; std::condition_variable mConnectCondition;
bool mConnectDataSent = false; bool mConnectDataSent = false;
std::atomic<bool> mShutdown = false;
state_callback mStateChangeCallback; state_callback mStateChangeCallback;
std::atomic<State> mState; std::atomic<State> mState;