added reachability based ip_change_notifier_impl for iOS (#1902)
added reachability based ip_change_notifier_impl for iOS
This commit is contained in:
parent
79d7ae3638
commit
81d669399b
1
Jamfile
1
Jamfile
|
@ -161,6 +161,7 @@ rule linking ( properties * )
|
||||||
}
|
}
|
||||||
|
|
||||||
if <target-os>darwin in $(properties)
|
if <target-os>darwin in $(properties)
|
||||||
|
|| <target-os>iphone in $(properties)
|
||||||
{
|
{
|
||||||
# for ip_notifier
|
# for ip_notifier
|
||||||
result += <framework>CoreFoundation <framework>SystemConfiguration ;
|
result += <framework>CoreFoundation <framework>SystemConfiguration ;
|
||||||
|
|
|
@ -153,6 +153,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
# define TORRENT_USE_LOCALE 0
|
# define TORRENT_USE_LOCALE 0
|
||||||
# endif
|
# endif
|
||||||
#include <AvailabilityMacros.h>
|
#include <AvailabilityMacros.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||||
// on OSX, use the built-in common crypto for built-in
|
// on OSX, use the built-in common crypto for built-in
|
||||||
|
@ -168,6 +169,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#define TORRENT_USE_SYSTEMCONFIGURATION 1
|
#define TORRENT_USE_SYSTEMCONFIGURATION 1
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
#define TORRENT_USE_SC_NETWORK_REACHABILITY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#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
|
||||||
|
@ -442,6 +447,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_USE_SYSTEMCONFIGURATION 0
|
#define TORRENT_USE_SYSTEMCONFIGURATION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef TORRENT_USE_SC_NETWORK_REACHABILITY
|
||||||
|
#define TORRENT_USE_SC_NETWORK_REACHABILITY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TORRENT_USE_CRYPTOAPI
|
#ifndef TORRENT_USE_CRYPTOAPI
|
||||||
#define TORRENT_USE_CRYPTOAPI 0
|
#define TORRENT_USE_CRYPTOAPI 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -262,7 +262,7 @@ TORRENT_EXPORT void print_backtrace(char* out, int len, int max_depth
|
||||||
TORRENT_EXPORT void print_backtrace(char* out, int len, int /*max_depth*/, void* /* ctx */)
|
TORRENT_EXPORT void print_backtrace(char* out, int len, int /*max_depth*/, void* /* ctx */)
|
||||||
{
|
{
|
||||||
out[0] = 0;
|
out[0] = 0;
|
||||||
strncat(out, "<not supported>", len);
|
std::strncat(out, "<not supported>", std::size_t(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,7 +59,6 @@ namespace
|
||||||
#elif TORRENT_USE_NETLINK
|
#elif TORRENT_USE_NETLINK
|
||||||
// TODO: ip_change_notifier_nl
|
// TODO: ip_change_notifier_nl
|
||||||
#elif TORRENT_USE_SYSTEMCONFIGURATION
|
#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 CFRefRetain(T h) { CFRetain(h); }
|
||||||
template <typename T> void CFRefRelease(T h) { CFRelease(h); }
|
template <typename T> void CFRefRelease(T h) { CFRelease(h); }
|
||||||
|
@ -99,6 +98,86 @@ void CFDispatchRetain(dispatch_queue_t q) { dispatch_retain(q); }
|
||||||
void CFDispatchRelease(dispatch_queue_t q) { dispatch_release(q); }
|
void CFDispatchRelease(dispatch_queue_t q) { dispatch_release(q); }
|
||||||
using CFDispatchRef = CFRef<dispatch_queue_t, CFDispatchRetain, CFDispatchRelease>;
|
using CFDispatchRef = CFRef<dispatch_queue_t, CFDispatchRetain, CFDispatchRelease>;
|
||||||
|
|
||||||
|
#if TORRENT_USE_SC_NETWORK_REACHABILITY
|
||||||
|
CFRef<SCNetworkReachabilityRef> create_reachability(SCNetworkReachabilityCallBack callback
|
||||||
|
, void* context_info)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(callback != nullptr);
|
||||||
|
|
||||||
|
sockaddr_in addr = {};
|
||||||
|
addr.sin_len = sizeof(addr);
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
|
||||||
|
CFRef<SCNetworkReachabilityRef> reach{SCNetworkReachabilityCreateWithAddress(nullptr
|
||||||
|
, reinterpret_cast<sockaddr const*>(&addr))};
|
||||||
|
if (!reach)
|
||||||
|
return CFRef<SCNetworkReachabilityRef>();
|
||||||
|
|
||||||
|
SCNetworkReachabilityContext context = {0, nullptr, nullptr, nullptr, nullptr};
|
||||||
|
context.info = context_info;
|
||||||
|
|
||||||
|
return SCNetworkReachabilitySetCallback(reach.get(), callback, &context)
|
||||||
|
? reach : CFRef<SCNetworkReachabilityRef>();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ip_change_notifier_impl final : ip_change_notifier
|
||||||
|
{
|
||||||
|
explicit ip_change_notifier_impl(io_service& ios)
|
||||||
|
: m_ios(ios)
|
||||||
|
{
|
||||||
|
m_queue = dispatch_queue_create("libtorrent.IPChangeNotifierQueue", nullptr);
|
||||||
|
m_reach = create_reachability(
|
||||||
|
[](SCNetworkReachabilityRef /*target*/, SCNetworkReachabilityFlags /*flags*/, void *info)
|
||||||
|
{
|
||||||
|
auto obj = static_cast<ip_change_notifier_impl*>(info);
|
||||||
|
obj->m_ios.post([obj]()
|
||||||
|
{
|
||||||
|
if (!obj->m_cb) return;
|
||||||
|
auto cb = std::move(obj->m_cb);
|
||||||
|
obj->m_cb = nullptr;
|
||||||
|
cb(error_code());
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (!m_queue || !m_reach
|
||||||
|
|| !SCNetworkReachabilitySetDispatchQueue(m_reach.get(), m_queue.get()))
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// noncopyable
|
||||||
|
ip_change_notifier_impl(ip_change_notifier_impl const&) = delete;
|
||||||
|
ip_change_notifier_impl& operator=(ip_change_notifier_impl const&) = delete;
|
||||||
|
|
||||||
|
~ip_change_notifier_impl() 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_reach)
|
||||||
|
SCNetworkReachabilitySetDispatchQueue(m_reach.get(), nullptr);
|
||||||
|
|
||||||
|
m_cb = nullptr;
|
||||||
|
m_reach = nullptr;
|
||||||
|
m_queue = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
io_service& m_ios;
|
||||||
|
CFDispatchRef m_queue;
|
||||||
|
CFRef<SCNetworkReachabilityRef> m_reach;
|
||||||
|
std::function<void(error_code const&)> m_cb = nullptr;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
// see https://developer.apple.com/library/content/technotes/tn1145/_index.html
|
||||||
CFRef<CFMutableArrayRef> create_keys_array()
|
CFRef<CFMutableArrayRef> create_keys_array()
|
||||||
{
|
{
|
||||||
CFRef<CFMutableArrayRef> keys{CFArrayCreateMutable(nullptr
|
CFRef<CFMutableArrayRef> keys{CFArrayCreateMutable(nullptr
|
||||||
|
@ -143,7 +222,13 @@ struct ip_change_notifier_impl final : ip_change_notifier
|
||||||
[](SCDynamicStoreRef /*store*/, CFArrayRef /*changedKeys*/, void *info)
|
[](SCDynamicStoreRef /*store*/, CFArrayRef /*changedKeys*/, void *info)
|
||||||
{
|
{
|
||||||
auto obj = static_cast<ip_change_notifier_impl*>(info);
|
auto obj = static_cast<ip_change_notifier_impl*>(info);
|
||||||
obj->m_ios.post([obj]() { if (obj->m_cb) obj->m_cb(error_code()); });
|
obj->m_ios.post([obj]()
|
||||||
|
{
|
||||||
|
if (!obj->m_cb) return;
|
||||||
|
auto cb = std::move(obj->m_cb);
|
||||||
|
obj->m_cb = nullptr;
|
||||||
|
cb(error_code());
|
||||||
|
});
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
if (!m_queue || !m_store
|
if (!m_queue || !m_store
|
||||||
|
@ -183,6 +268,8 @@ private:
|
||||||
CFRef<SCDynamicStoreRef> m_store;
|
CFRef<SCDynamicStoreRef> m_store;
|
||||||
std::function<void(error_code const&)> m_cb = nullptr;
|
std::function<void(error_code const&)> m_cb = nullptr;
|
||||||
};
|
};
|
||||||
|
#endif // TORRENT_USE_SC_NETWORK_REACHABILITY
|
||||||
|
|
||||||
#elif defined TORRENT_WINDOWS
|
#elif defined TORRENT_WINDOWS
|
||||||
// TODO: ip_change_notifier_win
|
// TODO: ip_change_notifier_win
|
||||||
#else
|
#else
|
||||||
|
|
Loading…
Reference in New Issue