Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add callback for unhandled STUN requests #1211

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ set(LIBDATACHANNEL_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/configuration.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/datachannel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/description.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/iceudpmuxlistener.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/mediahandler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/global.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/message.cpp
Expand Down Expand Up @@ -99,6 +100,7 @@ set(LIBDATACHANNEL_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/configuration.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/datachannel.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/description.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/iceudpmuxlistener.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/mediahandler.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/rtcpreceivingsession.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/rtc/common.hpp
Expand Down Expand Up @@ -139,6 +141,7 @@ set(LIBDATACHANNEL_IMPL_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlssrtptransport.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlstransport.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/icetransport.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/iceudpmuxlistener.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/init.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/peerconnection.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/logcounter.cpp
Expand Down Expand Up @@ -171,6 +174,7 @@ set(LIBDATACHANNEL_IMPL_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlssrtptransport.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/dtlstransport.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/icetransport.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/iceudpmuxlistener.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/init.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/internals.hpp
${CMAKE_CURRENT_SOURCE_DIR}/src/impl/peerconnection.hpp
Expand Down
2 changes: 1 addition & 1 deletion deps/libjuice
47 changes: 47 additions & 0 deletions include/rtc/iceudpmuxlistener.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2025 Alex Potsides
* Copyright (c) 2025 Paul-Louis Ageneau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#ifndef RTC_ICE_UDP_MUX_LISTENER_H
#define RTC_ICE_UDP_MUX_LISTENER_H

#include "common.hpp"

namespace rtc {

namespace impl {

struct IceUdpMuxListener;

} // namespace impl

struct IceUdpMuxRequest { // TODO change name
string localUfrag;
string remoteUfrag;
string remoteAddress;
uint16_t remotePort;
};

class RTC_CPP_EXPORT IceUdpMuxListener final : private CheshireCat<impl::IceUdpMuxListener> {
public:
IceUdpMuxListener(uint16_t port, optional<string> bindAddress = nullopt);
~IceUdpMuxListener();

void stop();

uint16_t port() const;

void OnUnhandledStunRequest(std::function<void(IceUdpMuxRequest)> callback);

private:
using CheshireCat<impl::IceUdpMuxListener>::impl;
};

} // namespace rtc

#endif
1 change: 1 addition & 0 deletions include/rtc/rtc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "datachannel.hpp"
#include "peerconnection.hpp"
#include "track.hpp"
#include "iceudpmuxlistener.hpp"

#if RTC_ENABLE_WEBSOCKET

Expand Down
2 changes: 1 addition & 1 deletion src/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ std::shared_future<void> Cleanup() { return impl::Init::Instance().cleanup(); }

void SetSctpSettings(SctpSettings s) { impl::Init::Instance().setSctpSettings(std::move(s)); }

RTC_CPP_EXPORT std::ostream &operator<<(std::ostream &out, LogLevel level) {
std::ostream &operator<<(std::ostream &out, LogLevel level) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RTC_CPP_EXPORT has been removed here, not sure if that was intentional.

switch (level) {
case LogLevel::Fatal:
out << "fatal";
Expand Down
29 changes: 29 additions & 0 deletions src/iceudpmuxlistener.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) 2025 Alex Potsides
* Copyright (c) 2025 Paul-Louis Ageneau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include "iceudpmuxlistener.hpp"

#include "impl/iceudpmuxlistener.hpp"

namespace rtc {

IceUdpMuxListener::IceUdpMuxListener(uint16_t port, optional<string> bindAddress)
: CheshireCat<impl::IceUdpMuxListener>(port, std::move(bindAddress)) {}

IceUdpMuxListener::~IceUdpMuxListener() {}

void IceUdpMuxListener::stop() { impl()->stop(); }

uint16_t IceUdpMuxListener::port() const { return impl()->port; }

void IceUdpMuxListener::OnUnhandledStunRequest(std::function<void(IceUdpMuxRequest)> callback) {
impl()->unhandledStunRequestCallback = callback;
}

} // namespace rtc
62 changes: 62 additions & 0 deletions src/impl/iceudpmuxlistener.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2025 Alex Potsides
* Copyright (c) 2025 Paul-Louis Ageneau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#include "iceudpmuxlistener.hpp"
#include "internals.hpp"

namespace rtc::impl {

#if !USE_NICE
void IceUdpMuxListener::UnhandledStunRequestCallback(const juice_mux_binding_request *info,
void *user_ptr) {
auto listener = static_cast<IceUdpMuxListener *>(user_ptr);
if (!listener)
return;

IceUdpMuxRequest request;
request.localUfrag = info->local_ufrag;
request.remoteUfrag = info->remote_ufrag;
request.remoteAddress = info->address;
request.remotePort = info->port;
listener->unhandledStunRequestCallback(std::move(request));
}
#endif

IceUdpMuxListener::IceUdpMuxListener(uint16_t port, [[maybe_unused]] optional<string> bindAddress) : port(port) {
PLOG_VERBOSE << "Creating IceUdpMuxListener";

#if !USE_NICE
PLOG_DEBUG << "Registering ICE UDP mux listener for port " << port;
if (juice_mux_listen(bindAddress ? bindAddress->c_str() : NULL, port,
IceUdpMuxListener::UnhandledStunRequestCallback, this) < 0) {
throw std::runtime_error("Failed to register ICE UDP mux listener");
}
#else
PLOG_WARNING << "ICE UDP mux is not available with libnice";
#endif
}

IceUdpMuxListener::~IceUdpMuxListener() {
PLOG_VERBOSE << "Destroying IceUdpMuxListener";
stop();
}

void IceUdpMuxListener::stop() {
if (mStopped.exchange(true))
return;

#if !USE_NICE
PLOG_DEBUG << "Unregistering ICE UDP mux listener for port " << port;
if (juice_mux_listen(NULL, port, NULL, NULL) < 0) {
PLOG_ERROR << "Failed to unregister ICE UDP mux listener";
}
#endif
}

} // namespace rtc::impl
45 changes: 45 additions & 0 deletions src/impl/iceudpmuxlistener.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2025 Alex Potsides
* Copyright (c) 2025 Paul-Louis Ageneau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

#ifndef RTC_IMPL_ICE_UDP_MUX_LISTENER_H
#define RTC_IMPL_ICE_UDP_MUX_LISTENER_H

#include "common.hpp"

#include "rtc/iceudpmuxlistener.hpp"

#if !USE_NICE
#include <juice/juice.h>
#endif

#include <atomic>

namespace rtc::impl {

struct IceUdpMuxListener final {
IceUdpMuxListener(uint16_t port, optional<string> bindAddress = nullopt);
~IceUdpMuxListener();

void stop();

const uint16_t port;
synchronized_callback<IceUdpMuxRequest> unhandledStunRequestCallback;

private:
#if !USE_NICE
static void UnhandledStunRequestCallback(const juice_mux_binding_request *info, void *user_ptr);
#endif

std::atomic<bool> mStopped;
};

}

#endif

Loading