forked from premiere/premiere-libtorrent
implemented ip_change_notifier_macos (#1891)
implemented ip_change_notifier_macos
This commit is contained in:
parent
51c42adc3e
commit
e4bdd14ae7
|
@ -300,6 +300,11 @@ if (WIN32)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
# for ip_notifier
|
||||||
|
target_link_libraries(torrent-rasterbar "-framework CoreFoundation" "-framework SystemConfiguration")
|
||||||
|
endif (APPLE)
|
||||||
|
|
||||||
if (encryption)
|
if (encryption)
|
||||||
target_link_libraries(torrent-rasterbar ${OPENSSL_LIBRARIES})
|
target_link_libraries(torrent-rasterbar ${OPENSSL_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
6
Jamfile
6
Jamfile
|
@ -160,6 +160,12 @@ rule linking ( properties * )
|
||||||
result += <library>libsocket <library>libnsl ;
|
result += <library>libsocket <library>libnsl ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if <target-os>darwin in $(properties)
|
||||||
|
{
|
||||||
|
# for ip_notifier
|
||||||
|
result += <framework>CoreFoundation <framework>SystemConfiguration ;
|
||||||
|
}
|
||||||
|
|
||||||
if <iconv>on in $(properties)
|
if <iconv>on in $(properties)
|
||||||
{
|
{
|
||||||
result += <library>libiconv ;
|
result += <library>libiconv ;
|
||||||
|
|
|
@ -166,6 +166,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_USE_EXECINFO 1
|
#define TORRENT_USE_EXECINFO 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TORRENT_USE_SYSTEMCONFIGURATION 1
|
||||||
|
|
||||||
#else // __APPLE__
|
#else // __APPLE__
|
||||||
// FreeBSD has a reasonable iconv signature
|
// FreeBSD has a reasonable iconv signature
|
||||||
// unless we're on glibc
|
// unless we're on glibc
|
||||||
|
@ -436,6 +438,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_USE_COMMONCRYPTO 0
|
#define TORRENT_USE_COMMONCRYPTO 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef TORRENT_USE_SYSTEMCONFIGURATION
|
||||||
|
#define TORRENT_USE_SYSTEMCONFIGURATION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TORRENT_USE_CRYPTOAPI
|
#ifndef TORRENT_USE_CRYPTOAPI
|
||||||
#define TORRENT_USE_CRYPTOAPI 0
|
#define TORRENT_USE_CRYPTOAPI 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,12 +31,15 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libtorrent/aux_/ip_notifier.hpp"
|
#include "libtorrent/aux_/ip_notifier.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
#if defined TORRENT_BUILD_SIMULATOR
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
// TODO: simulator support
|
// TODO: simulator support
|
||||||
#elif TORRENT_USE_NETLINK
|
#elif TORRENT_USE_NETLINK
|
||||||
#include "libtorrent/netlink.hpp"
|
#include "libtorrent/netlink.hpp"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#elif TORRENT_USE_SYSTEMCONFIGURATION
|
||||||
|
#include <SystemConfiguration/SystemConfiguration.h>
|
||||||
#elif defined TORRENT_WINDOWS
|
#elif defined TORRENT_WINDOWS
|
||||||
#include "libtorrent/aux_/throw.hpp"
|
#include "libtorrent/aux_/throw.hpp"
|
||||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||||
|
@ -55,11 +58,139 @@ namespace
|
||||||
// TODO: ip_change_notifier_sim
|
// TODO: ip_change_notifier_sim
|
||||||
#elif TORRENT_USE_NETLINK
|
#elif TORRENT_USE_NETLINK
|
||||||
// TODO: ip_change_notifier_nl
|
// TODO: ip_change_notifier_nl
|
||||||
|
#elif TORRENT_USE_SYSTEMCONFIGURATION
|
||||||
|
// see https://developer.apple.com/library/content/technotes/tn1145/_index.html
|
||||||
|
|
||||||
|
template <typename T> void CFRefRetain(T h) { CFRetain(h); }
|
||||||
|
template <typename T> void CFRefRelease(T h) { CFRelease(h); }
|
||||||
|
|
||||||
|
template <typename T
|
||||||
|
, void (*Retain)(T) = CFRefRetain<T>, void (*Release)(T) = CFRefRelease<T>>
|
||||||
|
struct CFRef
|
||||||
|
{
|
||||||
|
CFRef() {}
|
||||||
|
explicit CFRef(T h) : m_h(h) {} // take ownership
|
||||||
|
~CFRef() { release(); }
|
||||||
|
|
||||||
|
CFRef(CFRef const& rhs) : m_h(rhs.m_h) { retain(); }
|
||||||
|
CFRef& operator=(CFRef const& rhs)
|
||||||
|
{
|
||||||
|
if (m_h == rhs.m_h) return *this;
|
||||||
|
release();
|
||||||
|
m_h = rhs.m_h;
|
||||||
|
retain();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRef& operator=(T h) { m_h = h; return *this;}
|
||||||
|
CFRef& operator=(std::nullptr_t) { release(); return *this;}
|
||||||
|
|
||||||
|
T get() const { return m_h; }
|
||||||
|
explicit operator bool() const { return m_h != nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T m_h = nullptr; // handle
|
||||||
|
|
||||||
|
void retain() { if (m_h != nullptr) Retain(m_h); }
|
||||||
|
void release() { if (m_h != nullptr) Release(m_h); m_h = nullptr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void CFDispatchRetain(dispatch_queue_t q) { dispatch_retain(q); }
|
||||||
|
void CFDispatchRelease(dispatch_queue_t q) { dispatch_release(q); }
|
||||||
|
using CFDispatchRef = CFRef<dispatch_queue_t, CFDispatchRetain, CFDispatchRelease>;
|
||||||
|
|
||||||
|
CFRef<CFMutableArrayRef> create_keys_array()
|
||||||
|
{
|
||||||
|
CFRef<CFMutableArrayRef> keys{CFArrayCreateMutable(nullptr
|
||||||
|
, 0, &kCFTypeArrayCallBacks)};
|
||||||
|
|
||||||
|
// "State:/Network/Interface/[^/]+/IPv4"
|
||||||
|
CFRef<CFStringRef> key{SCDynamicStoreKeyCreateNetworkInterfaceEntity(nullptr
|
||||||
|
, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4)};
|
||||||
|
CFArrayAppendValue(keys.get(), key.get());
|
||||||
|
|
||||||
|
// NOTE: for IPv6, you can replicate the above setup with kSCEntNetIPv6
|
||||||
|
// but due to the current state of most common configurations, where
|
||||||
|
// IPv4 is used alongside with IPv6, you will end up with twice the
|
||||||
|
// notifications for the same change
|
||||||
|
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRef<SCDynamicStoreRef> create_dynamic_store(SCDynamicStoreCallBack callback, void* context_info)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(callback != nullptr);
|
||||||
|
|
||||||
|
SCDynamicStoreContext context = {0, nullptr, nullptr, nullptr, nullptr};
|
||||||
|
context.info = context_info;
|
||||||
|
CFRef<SCDynamicStoreRef> store{SCDynamicStoreCreate(nullptr
|
||||||
|
, CFSTR("libtorrent.IPChangeNotifierStore"), callback, &context)};
|
||||||
|
if (!store)
|
||||||
|
return CFRef<SCDynamicStoreRef>();
|
||||||
|
|
||||||
|
CFRef<CFMutableArrayRef> keys = create_keys_array();
|
||||||
|
return SCDynamicStoreSetNotificationKeys(store.get(), nullptr, keys.get())
|
||||||
|
? store : CFRef<SCDynamicStoreRef>();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ip_change_notifier_macos final : ip_change_notifier
|
||||||
|
{
|
||||||
|
explicit ip_change_notifier_macos(io_service& ios)
|
||||||
|
: m_ios(ios)
|
||||||
|
{
|
||||||
|
m_queue = dispatch_queue_create("libtorrent.IPChangeNotifierQueue", nullptr);
|
||||||
|
m_store = create_dynamic_store(
|
||||||
|
[](SCDynamicStoreRef /*store*/, CFArrayRef /*changedKeys*/, void *info)
|
||||||
|
{
|
||||||
|
auto obj = static_cast<ip_change_notifier_macos*>(info);
|
||||||
|
obj->m_ios.post([obj]() { if (obj->m_cb) obj->m_cb(error_code()); });
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (!m_queue || !m_store
|
||||||
|
|| !SCDynamicStoreSetDispatchQueue(m_store.get(), m_queue.get()))
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// noncopyable
|
||||||
|
ip_change_notifier_macos(ip_change_notifier_macos const&) = delete;
|
||||||
|
ip_change_notifier_macos& operator=(ip_change_notifier_macos const&) = delete;
|
||||||
|
|
||||||
|
~ip_change_notifier_macos() override
|
||||||
|
{ cancel(); }
|
||||||
|
|
||||||
|
void async_wait(std::function<void(error_code const&)> cb) override
|
||||||
|
{
|
||||||
|
if (m_queue)
|
||||||
|
m_cb = std::move(cb);
|
||||||
|
else
|
||||||
|
m_ios.post([cb]()
|
||||||
|
{ cb(make_error_code(boost::system::errc::not_supported)); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancel() override
|
||||||
|
{
|
||||||
|
if (m_store)
|
||||||
|
SCDynamicStoreSetDispatchQueue(m_store.get(), nullptr);
|
||||||
|
|
||||||
|
m_cb = nullptr;
|
||||||
|
m_store = nullptr;
|
||||||
|
m_queue = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
io_service& m_ios;
|
||||||
|
CFDispatchRef m_queue;
|
||||||
|
CFRef<SCDynamicStoreRef> m_store;
|
||||||
|
std::function<void(error_code const&)> m_cb = nullptr;
|
||||||
|
};
|
||||||
#elif defined TORRENT_WINDOWS
|
#elif defined TORRENT_WINDOWS
|
||||||
// TODO: ip_change_notifier_win
|
// TODO: ip_change_notifier_win
|
||||||
|
#else
|
||||||
|
// TODO: ip_change_notifier_default
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: to remove when separated per platform
|
// TODO: to remove when separated per platform
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR || TORRENT_USE_NETLINK || defined TORRENT_WINDOWS
|
||||||
struct ip_change_notifier_impl final : ip_change_notifier
|
struct ip_change_notifier_impl final : ip_change_notifier
|
||||||
{
|
{
|
||||||
explicit ip_change_notifier_impl(io_service& ios);
|
explicit ip_change_notifier_impl(io_service& ios);
|
||||||
|
@ -170,11 +301,28 @@ namespace
|
||||||
else
|
else
|
||||||
cb(ec);
|
cb(ec);
|
||||||
}
|
}
|
||||||
|
#endif // defined TORRENT_BUILD_SIMULATOR || TORRENT_USE_NETLINK || defined TORRENT_WINDOWS
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
std::unique_ptr<ip_change_notifier> create_ip_notifier(io_service& ios)
|
std::unique_ptr<ip_change_notifier> create_ip_notifier(io_service& ios)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<ip_change_notifier>(new ip_change_notifier_impl(ios));
|
return std::unique_ptr<ip_change_notifier>(
|
||||||
|
#if defined TORRENT_BUILD_SIMULATOR
|
||||||
|
// ip_change_notifier_sim
|
||||||
|
new ip_change_notifier_impl(ios)
|
||||||
|
#elif TORRENT_USE_NETLINK
|
||||||
|
// ip_change_notifier_nl
|
||||||
|
new ip_change_notifier_impl(ios)
|
||||||
|
#elif TORRENT_USE_SYSTEMCONFIGURATION
|
||||||
|
new ip_change_notifier_macos(ios)
|
||||||
|
#elif defined TORRENT_WINDOWS
|
||||||
|
// ip_change_notifier_win
|
||||||
|
new ip_change_notifier_impl(ios)
|
||||||
|
#else
|
||||||
|
// ip_change_notifier_default
|
||||||
|
new ip_change_notifier_impl(ios)
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -38,4 +38,5 @@ project tools
|
||||||
exe fuzz_torrent : fuzz_torrent.cpp ;
|
exe fuzz_torrent : fuzz_torrent.cpp ;
|
||||||
exe parse_access_log : parse_access_log.cpp ;
|
exe parse_access_log : parse_access_log.cpp ;
|
||||||
exe dht : dht_put.cpp : <include>../ed25519/src ;
|
exe dht : dht_put.cpp : <include>../ed25519/src ;
|
||||||
|
exe session_log_alerts : session_log_alerts.cpp ;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
tool_programs = \
|
tool_programs = \
|
||||||
fuzz_torrent
|
fuzz_torrent \
|
||||||
|
session_log_alerts
|
||||||
|
|
||||||
if ENABLE_EXAMPLES
|
if ENABLE_EXAMPLES
|
||||||
bin_PROGRAMS = $(tool_programs)
|
bin_PROGRAMS = $(tool_programs)
|
||||||
|
@ -20,6 +21,7 @@ EXTRA_DIST = Jamfile \
|
||||||
parse_utp_log.py
|
parse_utp_log.py
|
||||||
|
|
||||||
fuzz_torrent_SOURCES = fuzz_torrent.cpp
|
fuzz_torrent_SOURCES = fuzz_torrent.cpp
|
||||||
|
session_log_alerts_SOURCES = session_log_alerts.cpp
|
||||||
|
|
||||||
LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2017, Arvid Norberg, Alden Torres
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the author nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
std::printf("press Ctrl+C, kill the process or wait for 1000 alerts\n");
|
||||||
|
|
||||||
|
settings_pack sett;
|
||||||
|
sett.set_int(settings_pack::alert_mask, 0xffffffff);
|
||||||
|
session s(sett);
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
while (count <= 1000)
|
||||||
|
{
|
||||||
|
s.wait_for_alert(seconds(5));
|
||||||
|
|
||||||
|
std::vector<alert*> alerts;
|
||||||
|
s.pop_alerts(&alerts);
|
||||||
|
for (auto const a : alerts)
|
||||||
|
{
|
||||||
|
if (a->type() == log_alert::alert_type)
|
||||||
|
{
|
||||||
|
std::printf("log_alert - %s\n", a->message().c_str());
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue