|
@@ -38,6 +38,19 @@ PeerConnection::PeerConnection(const Configuration &config)
|
|
: mConfig(config), mCertificate(make_certificate("libdatachannel")), mState(State::New) {}
|
|
: mConfig(config), mCertificate(make_certificate("libdatachannel")), mState(State::New) {}
|
|
|
|
|
|
PeerConnection::~PeerConnection() {
|
|
PeerConnection::~PeerConnection() {
|
|
|
|
+ changeState(State::Destroying);
|
|
|
|
+ close();
|
|
|
|
+ mSctpTransport.reset();
|
|
|
|
+ mDtlsTransport.reset();
|
|
|
|
+ mIceTransport.reset();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void PeerConnection::close() {
|
|
|
|
+ // Close DataChannels
|
|
|
|
+ closeDataChannels();
|
|
|
|
+ mDataChannels.clear();
|
|
|
|
+
|
|
|
|
+ // Close Transports
|
|
if (auto transport = std::atomic_load(&mIceTransport))
|
|
if (auto transport = std::atomic_load(&mIceTransport))
|
|
transport->stop();
|
|
transport->stop();
|
|
if (auto transport = std::atomic_load(&mDtlsTransport))
|
|
if (auto transport = std::atomic_load(&mDtlsTransport))
|
|
@@ -45,9 +58,8 @@ PeerConnection::~PeerConnection() {
|
|
if (auto transport = std::atomic_load(&mSctpTransport))
|
|
if (auto transport = std::atomic_load(&mSctpTransport))
|
|
transport->stop();
|
|
transport->stop();
|
|
|
|
|
|
- mSctpTransport.reset();
|
|
|
|
- mDtlsTransport.reset();
|
|
|
|
- mIceTransport.reset();
|
|
|
|
|
|
+ // Change state
|
|
|
|
+ changeState(State::Closed);
|
|
}
|
|
}
|
|
|
|
|
|
const Configuration *PeerConnection::config() const { return &mConfig; }
|
|
const Configuration *PeerConnection::config() const { return &mConfig; }
|
|
@@ -210,6 +222,9 @@ shared_ptr<IceTransport> PeerConnection::initIceTransport(Description::Role role
|
|
case IceTransport::State::Connected:
|
|
case IceTransport::State::Connected:
|
|
initDtlsTransport();
|
|
initDtlsTransport();
|
|
break;
|
|
break;
|
|
|
|
+ case IceTransport::State::Disconnected:
|
|
|
|
+ changeState(State::Disconnected);
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
// Ignore
|
|
// Ignore
|
|
break;
|
|
break;
|
|
@@ -246,6 +261,9 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
|
|
case DtlsTransport::State::Failed:
|
|
case DtlsTransport::State::Failed:
|
|
changeState(State::Failed);
|
|
changeState(State::Failed);
|
|
break;
|
|
break;
|
|
|
|
+ case DtlsTransport::State::Disconnected:
|
|
|
|
+ changeState(State::Disconnected);
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
// Ignore
|
|
// Ignore
|
|
break;
|
|
break;
|
|
@@ -293,7 +311,7 @@ bool PeerConnection::checkFingerprint(const std::string &fingerprint) const {
|
|
|
|
|
|
void PeerConnection::forwardMessage(message_ptr message) {
|
|
void PeerConnection::forwardMessage(message_ptr message) {
|
|
if (!message) {
|
|
if (!message) {
|
|
- closeDataChannels();
|
|
|
|
|
|
+ remoteCloseDataChannels();
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -368,6 +386,10 @@ void PeerConnection::closeDataChannels() {
|
|
iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->close(); });
|
|
iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->close(); });
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void PeerConnection::remoteCloseDataChannels() {
|
|
|
|
+ iterateDataChannels([&](shared_ptr<DataChannel> channel) { channel->remoteClose(); });
|
|
|
|
+}
|
|
|
|
+
|
|
void PeerConnection::processLocalDescription(Description description) {
|
|
void PeerConnection::processLocalDescription(Description description) {
|
|
std::optional<uint16_t> remoteSctpPort;
|
|
std::optional<uint16_t> remoteSctpPort;
|
|
if (auto remote = remoteDescription())
|
|
if (auto remote = remoteDescription())
|
|
@@ -401,7 +423,14 @@ void PeerConnection::triggerDataChannel(weak_ptr<DataChannel> weakDataChannel) {
|
|
}
|
|
}
|
|
|
|
|
|
void PeerConnection::changeState(State state) {
|
|
void PeerConnection::changeState(State state) {
|
|
- if (mState.exchange(state) != state)
|
|
|
|
|
|
+ State current;
|
|
|
|
+ do {
|
|
|
|
+ current = mState.load();
|
|
|
|
+ if (current == state || current == State::Destroying)
|
|
|
|
+ return;
|
|
|
|
+ } while (!mState.compare_exchange_weak(current, state));
|
|
|
|
+
|
|
|
|
+ if (state != State::Destroying)
|
|
mStateChangeCallback(state);
|
|
mStateChangeCallback(state);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -431,6 +460,12 @@ std::ostream &operator<<(std::ostream &out, const rtc::PeerConnection::State &st
|
|
case State::Failed:
|
|
case State::Failed:
|
|
str = "failed";
|
|
str = "failed";
|
|
break;
|
|
break;
|
|
|
|
+ case State::Closed:
|
|
|
|
+ str = "closed";
|
|
|
|
+ break;
|
|
|
|
+ case State::Destroying:
|
|
|
|
+ str = "destroying";
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
str = "unknown";
|
|
str = "unknown";
|
|
break;
|
|
break;
|