Browse Source

fix: support multiple callbacks for different ports

achingbrain 7 months ago
parent
commit
9157c0c906
2 changed files with 37 additions and 25 deletions
  1. 11 6
      include/rtc/global.hpp
  2. 26 19
      src/global.cpp

+ 11 - 6
include/rtc/global.hpp

@@ -35,15 +35,20 @@ RTC_CPP_EXPORT void Preload();
 RTC_CPP_EXPORT std::shared_future<void> Cleanup();
 
 struct UnhandledStunRequest {
-	optional<std::string> localUfrag;
-	optional<std::string> remoteUfrag;
-	std::string address;
-	uint16_t port;
+	std::string localUfrag;
+	std::string remoteUfrag;
+	std::string remoteHost;
+	uint16_t remotePort;
 };
 
-RTC_CPP_EXPORT typedef std::function<void(UnhandledStunRequest request)> UnhandledStunRequestCallback;
+RTC_CPP_EXPORT typedef std::function<void(UnhandledStunRequest request, void* userPtr)> UnhandledStunRequestCallback;
 
-RTC_CPP_EXPORT void OnUnhandledStunRequest(std::string host, int port, UnhandledStunRequestCallback callback = nullptr);
+struct UnhandledStunRequestHandler {
+	UnhandledStunRequestCallback callback;
+	void *userPtr;
+};
+
+RTC_CPP_EXPORT void OnUnhandledStunRequest(std::string host, int port, UnhandledStunRequestCallback callback = nullptr, void *userPtr = nullptr);
 
 struct SctpSettings {
 	// For the following settings, not set means optimized default

+ 26 - 19
src/global.cpp

@@ -93,50 +93,57 @@ std::shared_future<void> Cleanup() { return impl::Init::Instance().cleanup(); }
 
 void SetSctpSettings(SctpSettings s) { impl::Init::Instance().setSctpSettings(std::move(s)); }
 
-#if !USE_NICE
+std::map<int, UnhandledStunRequestHandler *> unboundStunCallbacks;
 
-UnhandledStunRequestCallback unboundStunCallback;
+#if !USE_NICE
 
 void InvokeUnhandledStunRequestCallback (const juice_mux_binding_request *info, void *user_ptr) {
-	PLOG_DEBUG << "Invoking Unbind STUN listener";
-	auto callback = static_cast<UnhandledStunRequestCallback *>(user_ptr);
-
-	(*callback)({
-		std::string(info->local_ufrag),
-		std::string(info->remote_ufrag),
-		std::string(info->address),
-		info->port
-	});
+	PLOG_DEBUG << "Invoking unhandled STUN request callback";
+
+	UnhandledStunRequestHandler *handler = (struct UnhandledStunRequestHandler*)user_ptr;
+
+	if (handler->callback) {
+		handler->callback({
+			std::string(info->local_ufrag),
+			std::string(info->remote_ufrag),
+			std::string(info->address),
+			info->port
+		}, handler->userPtr);
+	} else {
+		PLOG_DEBUG << "No unhandled STUN request callback configured for port " << info->port;
+	}
 }
 
 #endif
 
-void OnUnhandledStunRequest ([[maybe_unused]] std::string host, [[maybe_unused]] int port, [[maybe_unused]] UnhandledStunRequestCallback callback) {
+void OnUnhandledStunRequest ([[maybe_unused]] std::string host, [[maybe_unused]] int port, [[maybe_unused]] UnhandledStunRequestCallback callback, [[maybe_unused]] void *userPtr) {
 	#if USE_NICE
 		PLOG_WARNING << "BindStunListener is not supported with libnice, please use libjuice";
 	#else
 	if (callback == NULL) {
 		PLOG_DEBUG << "Removing unhandled STUN request listener";
 
+		free(unboundStunCallbacks.at(port));
+		unboundStunCallbacks.erase(port);
+
 		// call with NULL callback to unbind
 		if (juice_mux_listen(host.c_str(), port, NULL, NULL) < 0) {
 			throw std::runtime_error("Could not unbind STUN listener");
 		}
-		unboundStunCallback = NULL;
 
 		return;
 	}
 
 	PLOG_DEBUG << "Adding listener for unhandled STUN requests";
 
-	if (unboundStunCallback != NULL) {
-		throw std::runtime_error("Unhandled STUN request handler already present");
-	}
+	UnhandledStunRequestHandler *handler = (UnhandledStunRequestHandler*)calloc(1, sizeof(UnhandledStunRequestHandler));
+	handler->callback = std::move(callback);
+	handler->userPtr = userPtr;
 
-	unboundStunCallback = std::move(callback);
+	unboundStunCallbacks[port] = handler;
 
-	if (juice_mux_listen(host.c_str(), port, &InvokeUnhandledStunRequestCallback, &unboundStunCallback) < 0) {
-		throw std::invalid_argument("Could add listener for unhandled STUN requests");
+	if (juice_mux_listen(host.c_str(), port, &InvokeUnhandledStunRequestCallback, handler) < 0) {
+		throw std::invalid_argument("Could not add listener for unhandled STUN requests");
 	}
 	#endif
 }