Skip to content

Commit

Permalink
Expose DTLS connection info to PeerConnection
Browse files Browse the repository at this point in the history
  • Loading branch information
gasperov committed Nov 15, 2023
1 parent 3681569 commit fac0753
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 3 deletions.
7 changes: 7 additions & 0 deletions examples/copy-paste-capi/answerer.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static void RTC_API dataChannelCallback(int pc, int dc, void *ptr);
static void RTC_API descriptionCallback(int pc, const char *sdp, const char *type, void *ptr);
static void RTC_API candidateCallback(int pc, const char *cand, const char *mid, void *ptr);
static void RTC_API stateChangeCallback(int pc, rtcState state, void *ptr);
static void RTC_API DtlsHandshakeDoneCallback(int pc, const char *dtlsVersion, const char* cipher, void *ptr);
static void RTC_API gatheringStateCallback(int pc, rtcGatheringState state, void *ptr);
static void RTC_API closedCallback(int id, void *ptr);
static void RTC_API messageCallback(int id, const char *message, int size, void *ptr);
Expand Down Expand Up @@ -69,6 +70,7 @@ int main(int argc, char **argv) {
rtcSetLocalCandidateCallback(peer->pc, candidateCallback);
rtcSetStateChangeCallback(peer->pc, stateChangeCallback);
rtcSetGatheringStateChangeCallback(peer->pc, gatheringStateCallback);
rtcSetDtlsHandshakeDoneCallback(peer->pc, DtlsHandshakeDoneCallback);

rtcSetDataChannelCallback(peer->pc, dataChannelCallback);

Expand Down Expand Up @@ -196,6 +198,11 @@ static void RTC_API stateChangeCallback(int pc, rtcState state, void *ptr) {
printf("State %s: %s\n", "answerer", state_print(state));
}

static void RTC_API DtlsHandshakeDoneCallback(int pc, const char *dtlsVersion, const char* cipher, void *ptr) {
Peer *peer = (Peer *)ptr;
printf("Dtls info version: %s cipher: %s\n", dtlsVersion, cipher);
}

static void RTC_API gatheringStateCallback(int pc, rtcGatheringState state, void *ptr) {
Peer *peer = (Peer *)ptr;
peer->gatheringState = state;
Expand Down
7 changes: 7 additions & 0 deletions examples/copy-paste-capi/offerer.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ typedef struct {
static void RTC_API descriptionCallback(int pc, const char *sdp, const char *type, void *ptr);
static void RTC_API candidateCallback(int pc, const char *cand, const char *mid, void *ptr);
static void RTC_API stateChangeCallback(int pc, rtcState state, void *ptr);
static void RTC_API DtlsHandshakeDoneCallback(int pc, const char *dtlsVersion, const char* cipher, void *ptr);
static void RTC_API gatheringStateCallback(int pc, rtcGatheringState state, void *ptr);
static void RTC_API openCallback(int id, void *ptr);
static void RTC_API closedCallback(int id, void *ptr);
Expand Down Expand Up @@ -68,6 +69,7 @@ int main(int argc, char **argv) {
rtcSetLocalCandidateCallback(peer->pc, candidateCallback);
rtcSetStateChangeCallback(peer->pc, stateChangeCallback);
rtcSetGatheringStateChangeCallback(peer->pc, gatheringStateCallback);
rtcSetDtlsHandshakeDoneCallback(peer->pc, DtlsHandshakeDoneCallback);

// Since we are the offerer, we will create a datachannel
peer->dc = rtcCreateDataChannel(peer->pc, "test");
Expand Down Expand Up @@ -200,6 +202,11 @@ static void RTC_API stateChangeCallback(int pc, rtcState state, void *ptr) {
printf("State %s: %s\n", "offerer", state_print(state));
}

static void RTC_API DtlsHandshakeDoneCallback(int pc, const char *dtlsVersion, const char* cipher, void *ptr) {
Peer *peer = (Peer *)ptr;
printf("Dtls info version: %s cipher: %s\n", dtlsVersion, cipher);
}

static void RTC_API gatheringStateCallback(int pc, rtcGatheringState state, void *ptr) {
Peer *peer = (Peer *)ptr;
peer->gatheringState = state;
Expand Down
1 change: 1 addition & 0 deletions include/rtc/peerconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
void onIceStateChange(std::function<void(IceState state)> callback);
void onGatheringStateChange(std::function<void(GatheringState state)> callback);
void onSignalingStateChange(std::function<void(SignalingState state)> callback);
void onDtlsHandshakeDone(std::function<void(const std::string&, const std::string&)> callback);

void resetCallbacks();

Expand Down
3 changes: 3 additions & 0 deletions include/rtc/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ typedef void(RTC_API *rtcDescriptionCallbackFunc)(int pc, const char *sdp, const
typedef void(RTC_API *rtcCandidateCallbackFunc)(int pc, const char *cand, const char *mid,
void *ptr);
typedef void(RTC_API *rtcStateChangeCallbackFunc)(int pc, rtcState state, void *ptr);
typedef void(RTC_API *rtcDTLSHandshakeDoneCallbackFunc)(int pc, const char *dtlsVersion, const char* cipher, void *ptr);
typedef void(RTC_API *rtcIceStateChangeCallbackFunc)(int pc, rtcIceState state, void *ptr);
typedef void(RTC_API *rtcGatheringStateCallbackFunc)(int pc, rtcGatheringState state, void *ptr);
typedef void(RTC_API *rtcSignalingStateCallbackFunc)(int pc, rtcSignalingState state, void *ptr);
Expand Down Expand Up @@ -202,6 +203,8 @@ RTC_C_EXPORT int rtcSetLocalDescription(int pc, const char *type);
RTC_C_EXPORT int rtcSetRemoteDescription(int pc, const char *sdp, const char *type);
RTC_C_EXPORT int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid);

RTC_C_EXPORT int rtcSetDtlsHandshakeDoneCallback(int pc, rtcDTLSHandshakeDoneCallbackFunc cb);

RTC_C_EXPORT int rtcGetLocalDescription(int pc, char *buffer, int size);
RTC_C_EXPORT int rtcGetRemoteDescription(int pc, char *buffer, int size);

Expand Down
14 changes: 14 additions & 0 deletions src/capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,20 @@ int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb) {
});
}

int rtcSetDtlsHandshakeDoneCallback(int pc, rtcDTLSHandshakeDoneCallbackFunc cb) {
return wrap([&] {
auto peerConnection = getPeerConnection(pc);
if (cb)
peerConnection->onDtlsHandshakeDone([pc, cb](const std::string& version, const std::string& cipher) {
if (auto ptr = getUserPointer(pc))
cb(pc, version.c_str(), cipher.c_str(), *ptr);
});
else
peerConnection->onDtlsHandshakeDone(nullptr);
return RTC_ERR_SUCCESS;
});
}

int rtcSetIceStateChangeCallback(int pc, rtcIceStateChangeCallbackFunc cb) {
return wrap([&] {
auto peerConnection = getPeerConnection(pc);
Expand Down
42 changes: 42 additions & 0 deletions src/impl/dtlstransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,20 @@ void DtlsTransport::postHandshake() {
// Dummy
}

DtlsTransport::DtlsInfo DtlsTransport::getDtlsInfo() {
DtlsInfo info;
{
std::lock_guard lock(mSslMutex);
auto desc = gnutls_session_get_desc(mSession);
if (desc) {
info.version = "gnu";
info.suite = desc;
gnutls_free(desc);
}
}
return info;
}

void DtlsTransport::doRecv() {
std::lock_guard lock(mRecvMutex);
--mPendingRecvCount;
Expand Down Expand Up @@ -519,6 +533,20 @@ void DtlsTransport::postHandshake() {
// Dummy
}

DtlsTransport::DtlsInfo DtlsTransport::getDtlsInfo() {
DtlsInfo info;
{
std::lock_guard lock(mSslMutex);
auto version = mbedtls_ssl_get_version(&mSsl);
auto suite = mbedtls_ssl_get_ciphersuite(&mSsl);
if (version && suite) {
info.version = version;
info.suite = suite;
}
}
return info;
}

void DtlsTransport::doRecv() {
std::lock_guard lock(mRecvMutex);
--mPendingRecvCount;
Expand Down Expand Up @@ -912,6 +940,20 @@ void DtlsTransport::postHandshake() {
// Dummy
}

DtlsTransport::DtlsInfo DtlsTransport::getDtlsInfo() {
DtlsInfo info;
{
std::lock_guard lock(mSslMutex);
auto version = SSL_get_version(mSsl);
auto suite = SSL_get_cipher(mSsl);
if (version && suite) {
info.version = version;
info.suite = suite;
}
}
return info;
}

void DtlsTransport::doRecv() {
std::lock_guard lock(mRecvMutex);
--mPendingRecvCount;
Expand Down
10 changes: 7 additions & 3 deletions src/impl/dtlstransport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class DtlsTransport : public Transport, public std::enable_shared_from_this<Dtls

bool isClient() const { return mIsClient; }

struct DtlsInfo {
std::string version;
std::string suite;
};
DtlsInfo getDtlsInfo();

protected:
virtual void incoming(message_ptr message) override;
virtual bool outgoing(message_ptr message) override;
Expand All @@ -58,6 +64,7 @@ class DtlsTransport : public Transport, public std::enable_shared_from_this<Dtls
Queue<message_ptr> mIncomingQueue;
std::atomic<int> mPendingRecvCount = 0;
std::mutex mRecvMutex;
std::mutex mSslMutex;
std::atomic<unsigned int> mCurrentDscp = 0;
std::atomic<bool> mOutgoingResult = true;

Expand All @@ -76,8 +83,6 @@ class DtlsTransport : public Transport, public std::enable_shared_from_this<Dtls
mbedtls_ssl_config mConf;
mbedtls_ssl_context mSsl;

std::mutex mSslMutex;

uint32_t mFinMs = 0, mIntMs = 0;
std::chrono::time_point<std::chrono::steady_clock> mTimerSetAt;

Expand All @@ -100,7 +105,6 @@ class DtlsTransport : public Transport, public std::enable_shared_from_this<Dtls
SSL_CTX *mCtx = NULL;
SSL *mSsl = NULL;
BIO *mInBio, *mOutBio;
std::mutex mSslMutex;

void handleTimeout();

Expand Down
14 changes: 14 additions & 0 deletions src/impl/peerconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,18 @@ shared_ptr<IceTransport> PeerConnection::initIceTransport() {
}
}

void PeerConnection::printDtlsInfo() {
auto lower = std::atomic_load(&mDtlsTransport);
if (lower) {
auto info = lower->getDtlsInfo();
PLOG_INFO << "Connected with DTLS version " << info.version
<< ", cipher suite " << info.suite;
if (dtlsHandshakeDoneCallback) {
dtlsHandshakeDoneCallback(info.version, info.suite);
}
}
}

shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
try {
if (auto transport = std::atomic_load(&mDtlsTransport))
Expand All @@ -225,6 +237,7 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {

switch (transportState) {
case DtlsTransport::State::Connected:
printDtlsInfo();
if (auto remote = remoteDescription(); remote && remote->hasApplication())
initSctpTransport();
else
Expand Down Expand Up @@ -1266,6 +1279,7 @@ void PeerConnection::resetCallbacks() {
iceStateChangeCallback = nullptr;
gatheringStateChangeCallback = nullptr;
signalingStateChangeCallback = nullptr;
dtlsHandshakeDoneCallback = nullptr;
trackCallback = nullptr;
}

Expand Down
2 changes: 2 additions & 0 deletions src/impl/peerconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
synchronized_callback<IceState> iceStateChangeCallback;
synchronized_callback<GatheringState> gatheringStateChangeCallback;
synchronized_callback<SignalingState> signalingStateChangeCallback;
synchronized_callback<const std::string&, const std::string&> dtlsHandshakeDoneCallback;
synchronized_callback<shared_ptr<rtc::Track>> trackCallback;

private:
void printDtlsInfo();
void dispatchMedia(message_ptr message);
void updateTrackSsrcCache(const Description &description);

Expand Down
4 changes: 4 additions & 0 deletions src/peerconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
impl()->signalingStateChangeCallback = callback;
}

void PeerConnection::onDtlsHandshakeDone(std::function<void(const std::string&, const std::string&)> callback) {
impl()->dtlsHandshakeDoneCallback = callback;
}

void PeerConnection::resetCallbacks() { impl()->resetCallbacks(); }

bool PeerConnection::getSelectedCandidatePair(Candidate *local, Candidate *remote) {
Expand Down
6 changes: 6 additions & 0 deletions test/capi_connectivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ static void RTC_API signalingStateCallback(int pc, rtcSignalingState state, void
printf("Signaling state %d: %d\n", peer == peer1 ? 1 : 2, (int)state);
}

static void RTC_API DtlsHandshakeDoneCallback(int pc, const char *dtlsVersion, const char* cipher, void *ptr) {
Peer *peer = (Peer *)ptr;
printf("Dtls info version: %s cipher: %s\n", dtlsVersion, cipher);
}

static void RTC_API openCallback(int id, void *ptr) {
Peer *peer = (Peer *)ptr;
peer->connected = true;
Expand Down Expand Up @@ -168,6 +173,7 @@ static Peer *createPeer(const rtcConfiguration *config) {
rtcSetIceStateChangeCallback(peer->pc, iceStateChangeCallback);
rtcSetGatheringStateChangeCallback(peer->pc, gatheringStateCallback);
rtcSetSignalingStateChangeCallback(peer->pc, signalingStateCallback);
rtcSetDtlsHandshakeDoneCallback(peer->pc, DtlsHandshakeDoneCallback);

return peer;
}
Expand Down
6 changes: 6 additions & 0 deletions test/capi_track.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ static void RTC_API stateChangeCallback(int pc, rtcState state, void *ptr) {
printf("State %d: %d\n", peer == peer1 ? 1 : 2, (int)state);
}

static void RTC_API DtlsHandshakeDoneCallback(int pc, const char *dtlsVersion, const char* cipher, void *ptr) {
Peer *peer = (Peer *)ptr;
printf("Dtls info version: %s cipher: %s\n", dtlsVersion, cipher);
}

static void RTC_API gatheringStateCallback(int pc, rtcGatheringState state, void *ptr) {
Peer *peer = (Peer *)ptr;
peer->gatheringState = state;
Expand Down Expand Up @@ -122,6 +127,7 @@ static Peer *createPeer(const rtcConfiguration *config) {
rtcSetLocalCandidateCallback(peer->pc, candidateCallback);
rtcSetStateChangeCallback(peer->pc, stateChangeCallback);
rtcSetGatheringStateChangeCallback(peer->pc, gatheringStateCallback);
rtcSetDtlsHandshakeDoneCallback(peer->pc, DtlsHandshakeDoneCallback);

peer->tr = -1;
return peer;
Expand Down

0 comments on commit fac0753

Please sign in to comment.