From 1ed9e6d2f86bf727873f3782fc7924e4eb53f4b2 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 7 Apr 2009 15:55:05 +0000 Subject: [PATCH] more C bindings and added getters for max_uploads on session and torrent --- bindings/c/Jamfile | 4 +- bindings/c/library.cpp | 175 +++++++++++++++++++++++-- bindings/c/libtorrent.h | 179 +++++++++++++++++++------- bindings/c/simple_client.c | 8 +- docs/manual.rst | 15 ++- include/libtorrent/session.hpp | 1 + include/libtorrent/torrent_handle.hpp | 1 + src/session.cpp | 5 + src/torrent_handle.cpp | 6 + 9 files changed, 329 insertions(+), 65 deletions(-) diff --git a/bindings/c/Jamfile b/bindings/c/Jamfile index fd3db9885..1933a901d 100755 --- a/bindings/c/Jamfile +++ b/bindings/c/Jamfile @@ -17,7 +17,7 @@ rule libtorrent_linking ( properties * ) return $(result) ; } -lib torrentc-rasterbar +lib torrentc : # sources library.cpp @@ -34,5 +34,5 @@ lib torrentc-rasterbar . ; -exe simple_client : simple_client.c torrentc-rasterbar ; +exe simple_client : simple_client.c torrentc ; diff --git a/bindings/c/library.cpp b/bindings/c/library.cpp index 33288d7ba..e2e33912e 100644 --- a/bindings/c/library.cpp +++ b/bindings/c/library.cpp @@ -68,12 +68,29 @@ namespace handles.push_back(h); return handles.size() - 1; } + + int set_int_value(void* dst, int* size, int val) + { + if (*size < sizeof(int)) return -2; + *((int*)dst) = val; + *size = sizeof(int); + return 0; + } + + void copy_proxy_setting(libtorrent::proxy_settings* s, proxy_setting const* ps) + { + s->hostname.assign(ps->hostname); + s->port = ps->port; + s->username.assign(ps->username); + s->password.assign(ps->password); + s->type = (libtorrent::proxy_settings::proxy_type)ps->type; + } } extern "C" { -TORRENT_EXPORT void* create_session(int tag, ...) +TORRENT_EXPORT void* session_create(int tag, ...) { using namespace libtorrent; @@ -140,12 +157,12 @@ TORRENT_EXPORT void* create_session(int tag, ...) return new (std::nothrow) session(fing, listen_range, listen_interface, flags, alert_mask); } -TORRENT_EXPORT void close_session(void* ses) +TORRENT_EXPORT void session_close(void* ses) { delete (libtorrent::session*)ses; } -TORRENT_EXPORT int add_torrent(void* ses, int tag, ...) +TORRENT_EXPORT int session_add_torrent(void* ses, int tag, ...) { using namespace libtorrent; @@ -265,7 +282,7 @@ TORRENT_EXPORT int add_torrent(void* ses, int tag, ...) return i; } -void remove_torrent(void* ses, int tor, int flags) +void session_remove_torrent(void* ses, int tor, int flags) { using namespace libtorrent; torrent_handle h = get_handle(tor); @@ -275,7 +292,7 @@ void remove_torrent(void* ses, int tor, int flags) s->remove_torrent(h, flags); } -int set_session_settings(void* ses, int tag, ...) +int session_set_settings(void* ses, int tag, ...) { using namespace libtorrent; @@ -303,6 +320,43 @@ int set_session_settings(void* ses, int tag, ...) case SET_HALF_OPEN_LIMIT: s->set_max_half_open_connections(va_arg(lp, int)); break; + case SET_PEER_PROXY: + { + libtorrent::proxy_settings ps; + copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*)); + s->set_peer_proxy(ps); + } + case SET_WEB_SEED_PROXY: + { + libtorrent::proxy_settings ps; + copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*)); + s->set_web_seed_proxy(ps); + } + case SET_TRACKER_PROXY: + { + libtorrent::proxy_settings ps; + copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*)); + s->set_tracker_proxy(ps); + } +#ifndef TORRENT_DISABLE_DHT + case SET_DHT_PROXY: + { + libtorrent::proxy_settings ps; + copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*)); + s->set_dht_proxy(ps); + } +#endif + case SET_PROXY: + { + libtorrent::proxy_settings ps; + copy_proxy_setting(&ps, va_arg(lp, struct proxy_setting const*)); + s->set_peer_proxy(ps); + s->set_web_seed_proxy(ps); + s->set_tracker_proxy(ps); +#ifndef TORRENT_DISABLE_DHT + s->set_dht_proxy(ps); +#endif + } default: // ignore unknown tags va_arg(lp, void*); @@ -314,15 +368,93 @@ int set_session_settings(void* ses, int tag, ...) return 0; } -int get_torrent_status(int tor, torrent_status* s, int struct_size) +int session_get_setting(void* ses, int tag, void* value, int* value_size) { using namespace libtorrent; - torrent_handle h = get_handle(tor); + session* s = (session*)ses; + + switch (tag) + { + case SET_UPLOAD_RATE_LIMIT: + return set_int_value(value, value_size, s->upload_rate_limit()); + case SET_DOWNLOAD_RATE_LIMIT: + return set_int_value(value, value_size, s->download_rate_limit()); + case SET_MAX_UPLOAD_SLOTS: + return set_int_value(value, value_size, s->max_uploads()); + case SET_MAX_CONNECTIONS: + return set_int_value(value, value_size, s->max_connections()); + case SET_HALF_OPEN_LIMIT: + return set_int_value(value, value_size, s->max_half_open_connections()); + default: + return -2; + } +} + +int session_get_status(void* sesptr, struct session_status* s, int struct_size) +{ + libtorrent::session* ses = (libtorrent::session*)sesptr; + + libtorrent::session_status ss = ses->status(); + if (struct_size != sizeof(session_status)) return -1; + + s->has_incoming_connections = ss.has_incoming_connections; + + s->upload_rate = ss.upload_rate; + s->download_rate = ss.download_rate; + s->total_download = ss.total_download; + s->total_upload = ss.total_upload; + + s->payload_upload_rate = ss.payload_upload_rate; + s->payload_download_rate = ss.payload_download_rate; + s->total_payload_download = ss.total_payload_download; + s->total_payload_upload = ss.total_payload_upload; + + s->ip_overhead_upload_rate = ss.ip_overhead_upload_rate; + s->ip_overhead_download_rate = ss.ip_overhead_download_rate; + s->total_ip_overhead_download = ss.total_ip_overhead_download; + s->total_ip_overhead_upload = ss.total_ip_overhead_upload; + + s->dht_upload_rate = ss.dht_upload_rate; + s->dht_download_rate = ss.dht_download_rate; + s->total_dht_download = ss.total_dht_download; + s->total_dht_upload = ss.total_dht_upload; + + s->tracker_upload_rate = ss.tracker_upload_rate; + s->tracker_download_rate = ss.tracker_download_rate; + s->total_tracker_download = ss.total_tracker_download; + s->total_tracker_upload = ss.total_tracker_upload; + + s->total_redundant_bytes = ss.total_redundant_bytes; + s->total_failed_bytes = ss.total_failed_bytes; + + s->num_peers = ss.num_peers; + s->num_unchoked = ss.num_unchoked; + s->allowed_upload_slots = ss.allowed_upload_slots; + + s->up_bandwidth_queue = ss.up_bandwidth_queue; + s->down_bandwidth_queue = ss.down_bandwidth_queue; + + s->up_bandwidth_bytes_queue = ss.up_bandwidth_bytes_queue; + s->down_bandwidth_bytes_queue = ss.down_bandwidth_bytes_queue; + + s->optimistic_unchoke_counter = ss.optimistic_unchoke_counter; + s->unchoke_counter = ss.unchoke_counter; + + s->dht_nodes = ss.dht_nodes; + s->dht_node_cache = ss.dht_node_cache; + s->dht_torrents = ss.dht_torrents; + s->dht_global_nodes = ss.dht_global_nodes; + return 0; +} + +int torrent_get_status(int tor, torrent_status* s, int struct_size) +{ + libtorrent::torrent_handle h = get_handle(tor); if (!h.is_valid()) return -1; libtorrent::torrent_status ts = h.status(); - if (struct_size != sizeof(::torrent_status)) return -1; + if (struct_size != sizeof(torrent_status)) return -1; s->state = (state_t)ts.state; s->paused = ts.paused; @@ -373,7 +505,7 @@ int get_torrent_status(int tor, torrent_status* s, int struct_size) return 0; } -int set_torrent_settings(int tor, int tag, ...) +int torrent_set_settings(int tor, int tag, ...) { using namespace libtorrent; torrent_handle h = get_handle(tor); @@ -415,5 +547,30 @@ int set_torrent_settings(int tor, int tag, ...) return 0; } +int torrent_get_setting(int tor, int tag, void* value, int* value_size) +{ + using namespace libtorrent; + torrent_handle h = get_handle(tor); + if (!h.is_valid()) return -1; + + switch (tag) + { + case SET_UPLOAD_RATE_LIMIT: + return set_int_value(value, value_size, h.upload_limit()); + case SET_DOWNLOAD_RATE_LIMIT: + return set_int_value(value, value_size, h.download_limit()); + case SET_MAX_UPLOAD_SLOTS: + return set_int_value(value, value_size, h.max_uploads()); + case SET_MAX_CONNECTIONS: + return set_int_value(value, value_size, h.max_connections()); + case SET_SEQUENTIAL_DOWNLOAD: + return set_int_value(value, value_size, h.is_sequential_download()); + case SET_SUPER_SEEDING: + return set_int_value(value, value_size, h.super_seeding()); + default: + return -2; + } +} + } // extern "C" diff --git a/bindings/c/libtorrent.h b/bindings/c/libtorrent.h index a6ef5e1ab..0a9c178fb 100644 --- a/bindings/c/libtorrent.h +++ b/bindings/c/libtorrent.h @@ -35,51 +35,75 @@ POSSIBILITY OF SUCH DAMAGE. enum tags { - SES_FINGERPRINT, - SES_LISTENPORT, - SES_LISTENPORT_END, - SES_VERSION_MAJOR, - SES_VERSION_MINOR, - SES_VERSION_TINY, - SES_VERSION_TAG, - SES_FLAGS, - SES_ALERT_MASK, - SES_LISTEN_INTERFACE, + TAG_END = 0, + + SES_FINGERPRINT, // char const*, 2 character string + SES_LISTENPORT, // int + SES_LISTENPORT_END, // int + SES_VERSION_MAJOR, // int + SES_VERSION_MINOR, // int + SES_VERSION_TINY, // int + SES_VERSION_TAG, // int + SES_FLAGS, // int + SES_ALERT_MASK, // int + SES_LISTEN_INTERFACE, // char const* // === add_torrent tags === // identifying the torrent to add - TOR_FILENAME = 0x100, - TOR_TORRENT, - TOR_TORRENT_SIZE, - TOR_INFOHASH, - TOR_INFOHASH_HEX, - TOR_MAGNETLINK, + TOR_FILENAME = 0x100, // char const* + TOR_TORRENT, // char const*, specify size of buffer with TOR_TORRENT_SIZE + TOR_TORRENT_SIZE, // int + TOR_INFOHASH, // char const*, must point to a 20 byte array + TOR_INFOHASH_HEX, // char const*, must point to a 40 byte string + TOR_MAGNETLINK, // char const*, url - TOR_TRACKER_URL, - TOR_RESUME_DATA, - TOR_RESUME_DATA_SIZE, - TOR_SAVE_PATH, - TOR_NAME, - TOR_PAUSED, - TOR_AUTO_MANAGED, - TOR_DUPLICATE_IS_ERROR, - TOR_USER_DATA, - TOR_SEED_MODE, - TOR_OVERRIDE_RESUME_DATA, - TOR_STORAGE_MODE, + TOR_TRACKER_URL, // char const* + TOR_RESUME_DATA, // char const* + TOR_RESUME_DATA_SIZE, // int + TOR_SAVE_PATH, // char const* + TOR_NAME, // char const* + TOR_PAUSED, // int + TOR_AUTO_MANAGED, // int + TOR_DUPLICATE_IS_ERROR, // int + TOR_USER_DATA, //void* + TOR_SEED_MODE, // int + TOR_OVERRIDE_RESUME_DATA, // int + TOR_STORAGE_MODE, // int - SET_UPLOAD_RATE_LIMIT = 0x200, - SET_DOWNLOAD_RATE_LIMIT, - SET_MAX_UPLOAD_SLOTS, - SET_MAX_CONNECTIONS, - SET_SEQUENTIAL_DOWNLOAD, // torrent only - SET_SUPER_SEEDING, // torrent only - SET_HALF_OPEN_LIMIT, // session only + SET_UPLOAD_RATE_LIMIT = 0x200, // int + SET_DOWNLOAD_RATE_LIMIT, // int + SET_MAX_UPLOAD_SLOTS, // int + SET_MAX_CONNECTIONS, // int + SET_SEQUENTIAL_DOWNLOAD, // int, torrent only + SET_SUPER_SEEDING, // int, torrent only + SET_HALF_OPEN_LIMIT, // int, session only + SET_PEER_PROXY, // proxy_setting const*, session_only + SET_WEB_SEED_PROXY, // proxy_setting const*, session_only + SET_TRACKER_PROXY, // proxy_setting const*, session_only + SET_DHT_PROXY, // proxy_setting const*, session_only + SET_PROXY, // proxy_setting const*, session_only +}; +struct proxy_setting +{ + char hostname[256]; + int port; + char username[256]; + char password[256]; - TAG_END = 0x7fffffff + int type; +}; + +enum proxy_type_t +{ + proxy_none, + proxy_socks4, + proxy_socks5, + proxy_socks5_pw, + proxy_http, + proxy_http_pw }; enum storage_mode_t @@ -155,25 +179,92 @@ struct torrent_status int seed_mode; }; +struct session_status +{ + int has_incoming_connections; + + float upload_rate; + float download_rate; + long long total_download; + long long total_upload; + + float payload_upload_rate; + float payload_download_rate; + long long total_payload_download; + long long total_payload_upload; + + float ip_overhead_upload_rate; + float ip_overhead_download_rate; + long long total_ip_overhead_download; + long long total_ip_overhead_upload; + + float dht_upload_rate; + float dht_download_rate; + long long total_dht_download; + long long total_dht_upload; + + float tracker_upload_rate; + float tracker_download_rate; + long long total_tracker_download; + long long total_tracker_upload; + + long long total_redundant_bytes; + long long total_failed_bytes; + + int num_peers; + int num_unchoked; + int allowed_upload_slots; + + int up_bandwidth_queue; + int down_bandwidth_queue; + + int up_bandwidth_bytes_queue; + int down_bandwidth_bytes_queue; + + int optimistic_unchoke_counter; + int unchoke_counter; + + int dht_nodes; + int dht_node_cache; + int dht_torrents; + long long dht_global_nodes; +// std::vector active_requests; +}; + #ifdef __cplusplus extern "C" { #endif +// the functions whose signature ends with: +// , int first_tag, ...); +// takes a tag list. The tag list is a series +// of tag-value pairs. The tags are constants +// identifying which property the value controls. +// The type of the value varies between tags. +// The enumeration above specifies which type +// it expects. All tag lists must always be +// terminated by TAG_END. + // use SES_* tags in tag list -void* create_session(int first_tag, ...); -void close_session(void* ses); +void* session_create(int first_tag, ...); +void session_close(void* ses); // use TOR_* tags in tag list -int add_torrent(void* ses, int first_tag, ...); -void remove_torrent(void* ses, int tor, int flags); -// use SET_* tags in tag list -int set_session_settings(void* ses, int first_tag, ...); +int session_add_torrent(void* ses, int first_tag, ...); +void session_remove_torrent(void* ses, int tor, int flags); -int get_torrent_status(int tor, struct torrent_status* s, int struct_size); +int session_get_status(void* ses, struct session_status* s, int struct_size); // use SET_* tags in tag list -int set_torrent_settings(int tor, int first_tag, ...); +int session_set_settings(void* ses, int first_tag, ...); +int session_get_setting(void* ses, int tag, void* value, int* value_size); + +int torrent_get_status(int tor, struct torrent_status* s, int struct_size); + +// use SET_* tags in tag list +int torrent_set_settings(int tor, int first_tag, ...); +int torrent_get_setting(int tor, int tag, void* value, int* value_size); #ifdef __cplusplus } diff --git a/bindings/c/simple_client.c b/bindings/c/simple_client.c index ee4f094b8..cce5fe078 100644 --- a/bindings/c/simple_client.c +++ b/bindings/c/simple_client.c @@ -52,12 +52,12 @@ int main(int argc, char* argv[]) } int ret = 0; - void* ses = create_session( + void* ses = session_create( SES_LISTENPORT, 6881, SES_LISTENPORT_END, 6889, TAG_END); - int t = add_torrent(ses, + int t = session_add_torrent(ses, TOR_FILENAME, argv[1], TOR_SAVE_PATH, "./", TAG_END); @@ -85,7 +85,7 @@ int main(int argc, char* argv[]) , "downloading", "finished", "seeding", "allocating" , "checking_resume_data"}; - if (get_torrent_status(t, &st, sizeof(st)) < 0) break; + if (torrent_get_status(t, &st, sizeof(st)) < 0) break; printf("\r%3.f%% %d kB (%5.f kB/s) up: %d kB (%5.f kB/s) peers: %d '%s' %s " , (double)st.progress * 100. , (int)(st.total_payload_download / 1000) @@ -110,7 +110,7 @@ int main(int argc, char* argv[]) exit: - close_session(ses); + session_close(ses); return ret; } diff --git a/docs/manual.rst b/docs/manual.rst index 470dafee6..c737684fe 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -459,13 +459,14 @@ of upload rate. set limits. -set_max_uploads() set_max_connections() max_connections() ---------------------------------------------------------- +set_max_uploads() set_max_connections() max_uploads() max_connections() +----------------------------------------------------------------------- :: void set_max_uploads(int limit); void set_max_connections(int limit); + int max_uploads() const; int max_connections() const; These functions will set a global limit on the number of unchoked peers (uploads) @@ -474,7 +475,7 @@ minimum of at least two connections per torrent, so if you set a too low connections limit, and open too many torrents, the limit will not be met. The number of uploads is at least one per torrent. -``max_connections()`` returns the current setting. +``max_uploads()`` and ``max_connections()`` returns the current settings. The number of unchoke slots may be ignored. In order to make this setting take effect, disable ``session_settings::auto_upload_slots_rate_based``. @@ -1777,6 +1778,7 @@ Its declaration looks like this:: std::set http_seeds() const; void set_ratio(float ratio) const; + int max_uploads() const; void set_max_uploads(int max_uploads) const; void set_max_connections(int max_connections) const; int max_connections() const; @@ -2408,12 +2410,13 @@ info_hash() ``info_hash()`` returns the info-hash for the torrent. -set_max_uploads() set_max_connections() max_connections() ---------------------------------------------------------- +set_max_uploads() max_uploads() set_max_connections() max_connections() +----------------------------------------------------------------------- :: void set_max_uploads(int max_uploads) const; + int max_uploads() const; void set_max_connections(int max_connections) const; int max_connections() const; @@ -2425,7 +2428,7 @@ connections are used up, incoming connections may be refused or poor connections This must be at least 2. The default is unlimited number of connections. If -1 is given to the function, it means unlimited. -``max_connections()`` returns the current setting. +``max_uploads()`` and ``max_connections()`` returns the current settings. save_resume_data() diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 3916aeee4..892740424 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -380,6 +380,7 @@ namespace libtorrent void set_max_half_open_connections(int limit); int max_connections() const; + int max_uploads() const; std::auto_ptr pop_alert(); #ifndef TORRENT_NO_DEPRECATE diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 57fb50feb..79dc7e80a 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -476,6 +476,7 @@ namespace libtorrent // -1 means unlimited unchokes void set_max_uploads(int max_uploads) const; + int max_uploads() const; // -1 means unlimited connections void set_max_connections(int max_connections) const; diff --git a/src/session.cpp b/src/session.cpp index 3dbd2b2cf..43de651cd 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -529,6 +529,11 @@ namespace libtorrent } #endif + int session::max_uploads() const + { + return m_impl->max_uploads(); + } + void session::set_max_uploads(int limit) { m_impl->set_max_uploads(limit); diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 5f96095be..e59d16e02 100644 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -142,6 +142,12 @@ namespace libtorrent TORRENT_FORWARD_RETURN(torrent_file().info_hash(), empty); } + int torrent_handle::max_uploads() const + { + INVARIANT_CHECK; + TORRENT_FORWARD_RETURN(max_uploads(), 0); + } + void torrent_handle::set_max_uploads(int max_uploads) const { INVARIANT_CHECK;