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)
|
||||
|| <target-os>iphone in $(properties)
|
||||
{
|
||||
# for ip_notifier
|
||||
result += <framework>CoreFoundation <framework>SystemConfiguration ;
|
||||
|
|
|
@ -153,6 +153,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
# define TORRENT_USE_LOCALE 0
|
||||
# endif
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
|
||||
// on OSX, use the built-in common crypto for built-in
|
||||
|
@ -168,6 +169,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#define TORRENT_USE_SYSTEMCONFIGURATION 1
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#define TORRENT_USE_SC_NETWORK_REACHABILITY 1
|
||||
#endif
|
||||
|
||||
#else // __APPLE__
|
||||
// FreeBSD has a reasonable iconv signature
|
||||
// unless we're on glibc
|
||||
|
@ -442,6 +447,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_USE_SYSTEMCONFIGURATION 0
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_USE_SC_NETWORK_REACHABILITY
|
||||
#define TORRENT_USE_SC_NETWORK_REACHABILITY 0
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_USE_CRYPTOAPI
|
||||
#define TORRENT_USE_CRYPTOAPI 0
|
||||
#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 */)
|
||||
{
|
||||
out[0] = 0;
|
||||
strncat(out, "<not supported>", len);
|
||||
std::strncat(out, "<not supported>", std::size_t(len));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,7 +59,6 @@ namespace
|
|||
#elif TORRENT_USE_NETLINK
|
||||
// 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); }
|
||||
|
@ -99,6 +98,86 @@ 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>;
|
||||
|
||||
#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> keys{CFArrayCreateMutable(nullptr
|
||||
|
@ -143,7 +222,13 @@ struct ip_change_notifier_impl final : ip_change_notifier
|
|||
[](SCDynamicStoreRef /*store*/, CFArrayRef /*changedKeys*/, void *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);
|
||||
|
||||
if (!m_queue || !m_store
|
||||
|
@ -183,6 +268,8 @@ private:
|
|||
CFRef<SCDynamicStoreRef> m_store;
|
||||
std::function<void(error_code const&)> m_cb = nullptr;
|
||||
};
|
||||
#endif // TORRENT_USE_SC_NETWORK_REACHABILITY
|
||||
|
||||
#elif defined TORRENT_WINDOWS
|
||||
// TODO: ip_change_notifier_win
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue