Changeset 14081
- Timestamp:
- May 23, 2013, 5:43:12 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/session.c
r14077 r14081 60 60 { 61 61 #ifdef TR_LIGHTWEIGHT 62 63 62 DEFAULT_CACHE_SIZE_MB = 2, 63 DEFAULT_PREFETCH_ENABLED = false, 64 64 #else 65 66 65 DEFAULT_CACHE_SIZE_MB = 4, 66 DEFAULT_PREFETCH_ENABLED = true, 67 67 #endif 68 68 SAVE_INTERVAL_SECS = 360 69 69 }; 70 70 … … 81 81 getRandomPort (tr_session * s) 82 82 { 83 83 return tr_cryptoWeakRandInt (s->randomPortHigh - s->randomPortLow + 1) + s->randomPortLow; 84 84 } 85 85 … … 91 91 tr_peerIdInit (uint8_t * buf) 92 92 { 93 int i; 94 int val; 95 int total = 0; 96 const char * pool = "0123456789abcdefghijklmnopqrstuvwxyz"; 97 const int base = 36; 98 99 memcpy (buf, PEERID_PREFIX, 8); 100 101 tr_cryptoRandBuf (buf+8, 11); 102 for (i=8; i<19; ++i) { 103 val = buf[i] % base; 104 total += val; 105 buf[i] = pool[val]; 106 } 107 108 val = total % base ? base - (total % base) : 0; 109 buf[19] = pool[val]; 110 buf[20] = '\0'; 93 int i; 94 int val; 95 int total = 0; 96 const char * pool = "0123456789abcdefghijklmnopqrstuvwxyz"; 97 const int base = 36; 98 99 memcpy (buf, PEERID_PREFIX, 8); 100 101 tr_cryptoRandBuf (buf+8, 11); 102 for (i=8; i<19; ++i) 103 { 104 val = buf[i] % base; 105 total += val; 106 buf[i] = pool[val]; 107 } 108 109 val = total % base ? base - (total % base) : 0; 110 buf[19] = pool[val]; 111 buf[20] = '\0'; 111 112 } 112 113 … … 118 119 tr_sessionGetEncryption (tr_session * session) 119 120 { 120 121 122 123 } 124 125 void 126 tr_sessionSetEncryption (tr_session *session,127 tr_encryption_mode mode)128 { 129 130 131 132 133 134 121 assert (session); 122 123 return session->encryptionMode; 124 } 125 126 void 127 tr_sessionSetEncryption (tr_session * session, 128 tr_encryption_mode mode) 129 { 130 assert (session); 131 assert (mode == TR_ENCRYPTION_PREFERRED 132 || mode == TR_ENCRYPTION_REQUIRED 133 || mode == TR_CLEAR_PREFERRED); 134 135 session->encryptionMode = mode; 135 136 } 136 137 … … 141 142 struct tr_bindinfo 142 143 { 143 144 145 144 int socket; 145 tr_address addr; 146 struct event * ev; 146 147 }; 147 148 … … 150 151 close_bindinfo (struct tr_bindinfo * b) 151 152 { 152 153 { 154 155 156 153 if ((b != NULL) && (b->socket >=0)) 154 { 155 event_free (b->ev); 156 b->ev = NULL; 157 tr_netCloseSocket (b->socket); 157 158 } 158 159 } … … 161 162 close_incoming_peer_port (tr_session * session) 162 163 { 163 164 164 close_bindinfo (session->public_ipv4); 165 close_bindinfo (session->public_ipv6); 165 166 } 166 167 … … 168 169 free_incoming_peer_port (tr_session * session) 169 170 { 170 171 172 173 174 175 176 171 close_bindinfo (session->public_ipv4); 172 tr_free (session->public_ipv4); 173 session->public_ipv4 = NULL; 174 175 close_bindinfo (session->public_ipv6); 176 tr_free (session->public_ipv6); 177 session->public_ipv6 = NULL; 177 178 } 178 179 … … 180 181 accept_incoming_peer (int fd, short what UNUSED, void * vsession) 181 182 { 182 int clientSocket; 183 tr_port clientPort; 184 tr_address clientAddr; 185 tr_session * session = vsession; 186 187 clientSocket = tr_netAccept (session, fd, &clientAddr, &clientPort); 188 if (clientSocket > 0) { 189 tr_logAddDeep (__FILE__, __LINE__, NULL, "new incoming connection %d (%s)", 183 int clientSocket; 184 tr_port clientPort; 185 tr_address clientAddr; 186 tr_session * session = vsession; 187 188 clientSocket = tr_netAccept (session, fd, &clientAddr, &clientPort); 189 if (clientSocket > 0) 190 { 191 tr_logAddDeep (__FILE__, __LINE__, NULL, "new incoming connection %d (%s)", 190 192 clientSocket, tr_peerIoAddrStr (&clientAddr, clientPort)); 191 192 193 tr_peerMgrAddIncoming (session->peerMgr, &clientAddr, clientPort, 194 clientSocket, NULL); 193 195 } 194 196 } … … 197 199 open_incoming_peer_port (tr_session * session) 198 200 { 199 struct tr_bindinfo * b; 200 201 /* bind an ipv4 port to listen for incoming peers... */ 202 b = session->public_ipv4; 203 b->socket = tr_netBindTCP (&b->addr, session->private_peer_port, false); 204 if (b->socket >= 0) { 205 b->ev = event_new (session->event_base, b->socket, EV_READ | EV_PERSIST, accept_incoming_peer, session); 206 event_add (b->ev, NULL); 207 } 208 209 /* and do the exact same thing for ipv6, if it's supported... */ 210 if (tr_net_hasIPv6 (session->private_peer_port)) { 211 b = session->public_ipv6; 212 b->socket = tr_netBindTCP (&b->addr, session->private_peer_port, false); 213 if (b->socket >= 0) { 214 b->ev = event_new (session->event_base, b->socket, EV_READ | EV_PERSIST, accept_incoming_peer, session); 215 event_add (b->ev, NULL); 201 struct tr_bindinfo * b; 202 203 /* bind an ipv4 port to listen for incoming peers... */ 204 b = session->public_ipv4; 205 b->socket = tr_netBindTCP (&b->addr, session->private_peer_port, false); 206 if (b->socket >= 0) 207 { 208 b->ev = event_new (session->event_base, b->socket, EV_READ | EV_PERSIST, accept_incoming_peer, session); 209 event_add (b->ev, NULL); 210 } 211 212 /* and do the exact same thing for ipv6, if it's supported... */ 213 if (tr_net_hasIPv6 (session->private_peer_port)) 214 { 215 b = session->public_ipv6; 216 b->socket = tr_netBindTCP (&b->addr, session->private_peer_port, false); 217 if (b->socket >= 0) 218 { 219 b->ev = event_new (session->event_base, b->socket, EV_READ | EV_PERSIST, accept_incoming_peer, session); 220 event_add (b->ev, NULL); 216 221 } 217 222 } … … 221 226 tr_sessionGetPublicAddress (const tr_session * session, int tr_af_type, bool * is_default_value) 222 227 { 223 224 225 226 227 { 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 } 243 244 245 246 247 228 const char * default_value; 229 const struct tr_bindinfo * bindinfo; 230 231 switch (tr_af_type) 232 { 233 case TR_AF_INET: 234 bindinfo = session->public_ipv4; 235 default_value = TR_DEFAULT_BIND_ADDRESS_IPV4; 236 break; 237 238 case TR_AF_INET6: 239 bindinfo = session->public_ipv6; 240 default_value = TR_DEFAULT_BIND_ADDRESS_IPV6; 241 break; 242 243 default: 244 bindinfo = NULL; 245 default_value = ""; 246 break; 247 } 248 249 if (is_default_value && bindinfo) 250 *is_default_value = !tr_strcmp0 (default_value, tr_address_to_string (&bindinfo->addr)); 251 252 return bindinfo ? &bindinfo->addr : NULL; 248 253 } 249 254 … … 261 266 parse_tos (const char *str) 262 267 { 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 268 char *p; 269 int value; 270 271 if (!evutil_ascii_strcasecmp (str, "")) 272 return 0; 273 if (!evutil_ascii_strcasecmp (str, "default")) 274 return 0; 275 276 if (!evutil_ascii_strcasecmp (str, "lowcost")) 277 return 0x10; 278 if (!evutil_ascii_strcasecmp (str, "mincost")) 279 return 0x10; 280 281 if (!evutil_ascii_strcasecmp (str, "throughput")) 282 return 0x08; 283 if (!evutil_ascii_strcasecmp (str, "reliability")) 284 return 0x04; 285 if (!evutil_ascii_strcasecmp (str, "lowdelay")) 286 return 0x02; 287 288 value = strtol (str, &p, 0); 289 if (!p || (p == str)) 290 return 0; 291 292 return value; 288 293 } 289 294 … … 291 296 format_tos (int value) 292 297 { 293 static char buf[8]; 294 switch (value) { 295 case 0: return "default"; 296 case 0x10: return "lowcost"; 297 case 0x08: return "throughput"; 298 case 0x04: return "reliability"; 299 case 0x02: return "lowdelay"; 300 default: 298 static char buf[8]; 299 switch (value) 300 { 301 case 0: return "default"; 302 case 0x10: return "lowcost"; 303 case 0x08: return "throughput"; 304 case 0x04: return "reliability"; 305 case 0x02: return "lowdelay"; 306 default: 301 307 tr_snprintf (buf, 8, "%d", value); 302 308 return buf; … … 307 313 tr_sessionGetDefaultSettings (tr_variant * d) 308 314 { 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 315 assert (tr_variantIsDict (d)); 316 317 tr_variantDictReserve (d, 63); 318 tr_variantDictAddBool (d, TR_KEY_blocklist_enabled, false); 319 tr_variantDictAddStr (d, TR_KEY_blocklist_url, "http://www.example.com/blocklist"); 320 tr_variantDictAddInt (d, TR_KEY_cache_size_mb, DEFAULT_CACHE_SIZE_MB); 321 tr_variantDictAddBool (d, TR_KEY_dht_enabled, true); 322 tr_variantDictAddBool (d, TR_KEY_utp_enabled, true); 323 tr_variantDictAddBool (d, TR_KEY_lpd_enabled, false); 324 tr_variantDictAddStr (d, TR_KEY_download_dir, tr_getDefaultDownloadDir ()); 325 tr_variantDictAddInt (d, TR_KEY_speed_limit_down, 100); 326 tr_variantDictAddBool (d, TR_KEY_speed_limit_down_enabled, false); 327 tr_variantDictAddInt (d, TR_KEY_encryption, TR_DEFAULT_ENCRYPTION); 328 tr_variantDictAddInt (d, TR_KEY_idle_seeding_limit, 30); 329 tr_variantDictAddBool (d, TR_KEY_idle_seeding_limit_enabled, false); 330 tr_variantDictAddStr (d, TR_KEY_incomplete_dir, tr_getDefaultDownloadDir ()); 331 tr_variantDictAddBool (d, TR_KEY_incomplete_dir_enabled, false); 332 tr_variantDictAddInt (d, TR_KEY_message_level, TR_LOG_INFO); 333 tr_variantDictAddInt (d, TR_KEY_download_queue_size, 5); 334 tr_variantDictAddBool (d, TR_KEY_download_queue_enabled, true); 335 tr_variantDictAddInt (d, TR_KEY_peer_limit_global, atoi (TR_DEFAULT_PEER_LIMIT_GLOBAL_STR)); 336 tr_variantDictAddInt (d, TR_KEY_peer_limit_per_torrent, atoi (TR_DEFAULT_PEER_LIMIT_TORRENT_STR)); 337 tr_variantDictAddInt (d, TR_KEY_peer_port, atoi (TR_DEFAULT_PEER_PORT_STR)); 338 tr_variantDictAddBool (d, TR_KEY_peer_port_random_on_start, false); 339 tr_variantDictAddInt (d, TR_KEY_peer_port_random_low, 49152); 340 tr_variantDictAddInt (d, TR_KEY_peer_port_random_high, 65535); 341 tr_variantDictAddStr (d, TR_KEY_peer_socket_tos, TR_DEFAULT_PEER_SOCKET_TOS_STR); 342 tr_variantDictAddBool (d, TR_KEY_pex_enabled, true); 343 tr_variantDictAddBool (d, TR_KEY_port_forwarding_enabled, true); 344 tr_variantDictAddInt (d, TR_KEY_preallocation, TR_PREALLOCATE_SPARSE); 345 tr_variantDictAddBool (d, TR_KEY_prefetch_enabled, DEFAULT_PREFETCH_ENABLED); 346 tr_variantDictAddInt (d, TR_KEY_peer_id_ttl_hours, 6); 347 tr_variantDictAddBool (d, TR_KEY_queue_stalled_enabled, true); 348 tr_variantDictAddInt (d, TR_KEY_queue_stalled_minutes, 30); 349 tr_variantDictAddReal (d, TR_KEY_ratio_limit, 2.0); 350 tr_variantDictAddBool (d, TR_KEY_ratio_limit_enabled, false); 351 tr_variantDictAddBool (d, TR_KEY_rename_partial_files, true); 352 tr_variantDictAddBool (d, TR_KEY_rpc_authentication_required, false); 353 tr_variantDictAddStr (d, TR_KEY_rpc_bind_address, "0.0.0.0"); 354 tr_variantDictAddBool (d, TR_KEY_rpc_enabled, false); 355 tr_variantDictAddStr (d, TR_KEY_rpc_password, ""); 356 tr_variantDictAddStr (d, TR_KEY_rpc_username, ""); 357 tr_variantDictAddStr (d, TR_KEY_rpc_whitelist, TR_DEFAULT_RPC_WHITELIST); 358 tr_variantDictAddBool (d, TR_KEY_rpc_whitelist_enabled, true); 359 tr_variantDictAddInt (d, TR_KEY_rpc_port, atoi (TR_DEFAULT_RPC_PORT_STR)); 360 tr_variantDictAddStr (d, TR_KEY_rpc_url, TR_DEFAULT_RPC_URL_STR); 361 tr_variantDictAddBool (d, TR_KEY_scrape_paused_torrents_enabled, true); 362 tr_variantDictAddStr (d, TR_KEY_script_torrent_done_filename, ""); 363 tr_variantDictAddBool (d, TR_KEY_script_torrent_done_enabled, false); 364 tr_variantDictAddInt (d, TR_KEY_seed_queue_size, 10); 365 tr_variantDictAddBool (d, TR_KEY_seed_queue_enabled, false); 366 tr_variantDictAddBool (d, TR_KEY_alt_speed_enabled, false); 367 tr_variantDictAddInt (d, TR_KEY_alt_speed_up, 50); /* half the regular */ 368 tr_variantDictAddInt (d, TR_KEY_alt_speed_down, 50); /* half the regular */ 369 tr_variantDictAddInt (d, TR_KEY_alt_speed_time_begin, 540); /* 9am */ 370 tr_variantDictAddBool (d, TR_KEY_alt_speed_time_enabled, false); 371 tr_variantDictAddInt (d, TR_KEY_alt_speed_time_end, 1020); /* 5pm */ 372 tr_variantDictAddInt (d, TR_KEY_alt_speed_time_day, TR_SCHED_ALL); 373 tr_variantDictAddInt (d, TR_KEY_speed_limit_up, 100); 374 tr_variantDictAddBool (d, TR_KEY_speed_limit_up_enabled, false); 375 tr_variantDictAddInt (d, TR_KEY_umask, 022); 376 tr_variantDictAddInt (d, TR_KEY_upload_slots_per_torrent, 14); 377 tr_variantDictAddStr (d, TR_KEY_bind_address_ipv4, TR_DEFAULT_BIND_ADDRESS_IPV4); 378 tr_variantDictAddStr (d, TR_KEY_bind_address_ipv6, TR_DEFAULT_BIND_ADDRESS_IPV6); 379 tr_variantDictAddBool (d, TR_KEY_start_added_torrents, true); 380 tr_variantDictAddBool (d, TR_KEY_trash_original_torrent_files, false); 375 381 } 376 382 … … 543 549 onSaveTimer (int foo UNUSED, short bar UNUSED, void * vsession) 544 550 { 545 546 547 548 549 550 551 552 553 554 555 556 551 tr_torrent * tor = NULL; 552 tr_session * session = vsession; 553 554 if (tr_cacheFlushDone (session->cache)) 555 tr_logAddError ("Error while flushing completed pieces from cache"); 556 557 while ((tor = tr_torrentNext (session, tor))) 558 tr_torrentSave (tor); 559 560 tr_statsSaveDirty (session); 561 562 tr_timerAdd (session->saveTimer, SAVE_INTERVAL_SECS, 0); 557 563 } 558 564 … … 565 571 struct init_data 566 572 { 567 tr_session * session;568 const char * configDir;569 bool done;570 bool messageQueuingEnabled;571 tr_variant* clientSettings;573 bool done; 574 bool messageQueuingEnabled; 575 tr_session * session; 576 const char * configDir; 577 tr_variant * clientSettings; 572 578 }; 573 579 … … 578 584 tr_variant * clientSettings) 579 585 { 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 586 int64_t i; 587 tr_session * session; 588 struct init_data data; 589 590 assert (tr_variantIsDict (clientSettings)); 591 592 tr_timeUpdate (time (NULL)); 593 594 /* initialize the bare skeleton of the session object */ 595 session = tr_new0 (tr_session, 1); 596 session->udp_socket = -1; 597 session->udp6_socket = -1; 598 session->lock = tr_lockNew (); 599 session->cache = tr_cacheNew (1024*1024*2); 600 session->tag = tr_strdup (tag); 601 session->magicNumber = SESSION_MAGIC_NUMBER; 602 tr_bandwidthConstruct (&session->bandwidth, session, NULL); 603 tr_variantInitList (&session->removedTorrents, 0); 604 605 /* nice to start logging at the very beginning */ 606 if (tr_variantDictFindInt (clientSettings, TR_KEY_message_level, &i)) 607 tr_logSetLevel (i); 608 609 /* start the libtransmission thread */ 610 tr_netInit (); /* must go before tr_eventInit */ 611 tr_eventInit (session); 612 assert (session->events != NULL); 613 614 /* run the rest in the libtransmission thread */ 615 data.done = false; 616 data.session = session; 617 data.configDir = configDir; 618 data.messageQueuingEnabled = messageQueuingEnabled; 619 data.clientSettings = clientSettings; 620 tr_runInEventThread (session, tr_sessionInitImpl, &data); 621 while (!data.done) 622 tr_wait_msec (50); 623 624 return session; 619 625 } 620 626 … … 624 630 onNowTimer (int foo UNUSED, short bar UNUSED, void * vsession) 625 631 { 626 int usec; 627 const int min = 100; 628 const int max = 999999; 629 struct timeval tv; 630 tr_torrent * tor = NULL; 631 tr_session * session = vsession; 632 const time_t now = time (NULL); 633 634 assert (tr_isSession (session)); 635 assert (session->nowTimer != NULL); 636 637 /** 638 *** tr_session things to do once per second 639 **/ 640 641 tr_timeUpdate (now); 642 643 tr_dhtUpkeep (session); 644 645 if (session->turtle.isClockEnabled) 646 turtleCheckClock (session, &session->turtle); 647 648 while ((tor = tr_torrentNext (session, tor))) { 649 if (tor->isRunning) { 650 if (tr_torrentIsSeed (tor)) 651 ++tor->secondsSeeding; 652 else 653 ++tor->secondsDownloading; 632 int usec; 633 const int min = 100; 634 const int max = 999999; 635 struct timeval tv; 636 tr_torrent * tor = NULL; 637 tr_session * session = vsession; 638 const time_t now = time (NULL); 639 640 assert (tr_isSession (session)); 641 assert (session->nowTimer != NULL); 642 643 /** 644 *** tr_session things to do once per second 645 **/ 646 647 tr_timeUpdate (now); 648 649 tr_dhtUpkeep (session); 650 651 if (session->turtle.isClockEnabled) 652 turtleCheckClock (session, &session->turtle); 653 654 while ((tor = tr_torrentNext (session, tor))) 655 { 656 if (tor->isRunning) 657 { 658 if (tr_torrentIsSeed (tor)) 659 ++tor->secondsSeeding; 660 else 661 ++tor->secondsDownloading; 654 662 } 655 663 } 656 664 657 /** 658 *** Set the timer 659 **/ 660 661 /* schedule the next timer for right after the next second begins */ 662 gettimeofday (&tv, NULL); 663 usec = 1000000 - tv.tv_usec; 664 if (usec > max) usec = max; 665 if (usec < min) usec = min; 666 tr_timerAdd (session->nowTimer, 0, usec); 667 /* fprintf (stderr, "time %zu sec, %zu microsec\n", (size_t)tr_time (), (size_t)tv.tv_usec); */ 665 /** 666 *** Set the timer 667 **/ 668 669 /* schedule the next timer for right after the next second begins */ 670 gettimeofday (&tv, NULL); 671 usec = 1000000 - tv.tv_usec; 672 if (usec > max) 673 usec = max; 674 if (usec < min) 675 usec = min; 676 tr_timerAdd (session->nowTimer, 0, usec); 677 /* fprintf (stderr, "time %zu sec, %zu microsec\n", (size_t)tr_time (), (size_t)tv.tv_usec); */ 668 678 } 669 679 … … 673 683 tr_sessionInitImpl (void * vdata) 674 684 { 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 685 tr_variant settings; 686 struct init_data * data = vdata; 687 tr_variant * clientSettings = data->clientSettings; 688 tr_session * session = data->session; 689 690 assert (tr_amInEventThread (session)); 691 assert (tr_variantIsDict (clientSettings)); 692 693 dbgmsg ("tr_sessionInit: the session's top-level bandwidth object is %p", 694 &session->bandwidth); 695 696 tr_variantInitDict (&settings, 0); 697 tr_sessionGetDefaultSettings (&settings); 698 tr_variantMergeDicts (&settings, clientSettings); 699 700 assert (session->event_base != NULL); 701 session->nowTimer = evtimer_new (session->event_base, onNowTimer, session); 702 onNowTimer (0, 0, session); 693 703 694 704 #ifndef WIN32 695 696 705 /* Don't exit when writing on a broken socket */ 706 signal (SIGPIPE, SIG_IGN); 697 707 #endif 698 708 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 709 tr_logSetQueueEnabled (data->messageQueuingEnabled); 710 711 tr_setConfigDir (session, data->configDir); 712 713 session->peerMgr = tr_peerMgrNew (session); 714 715 session->shared = tr_sharedInit (session); 716 717 /** 718 *** Blocklist 719 **/ 720 721 { 722 char * filename = tr_buildPath (session->configDir, "blocklists", NULL); 723 tr_mkdirp (filename, 0777); 724 tr_free (filename); 725 loadBlocklists (session); 726 } 727 728 assert (tr_isSession (session)); 729 730 session->saveTimer = evtimer_new (session->event_base, onSaveTimer, session); 731 tr_timerAdd (session->saveTimer, SAVE_INTERVAL_SECS, 0); 732 733 tr_announcerInit (session); 734 735 /* first %s is the application name 736 second %s is the version number */ 737 tr_logAddInfo (_("%s %s started"), TR_NAME, LONG_VERSION_STRING); 738 739 tr_statsInit (session); 740 741 tr_sessionSet (session, &settings); 742 743 tr_udpInit (session); 744 745 if (session->isLPDEnabled) 746 tr_lpdInit (session, &session->public_ipv4->addr); 747 748 /* cleanup */ 749 tr_variantFree (&settings); 750 data->done = true; 741 751 } 742 752 … … 747 757 sessionSetImpl (void * vdata) 748 758 { 749 int64_t i; 750 double d; 751 bool boolVal; 752 const char * str; 753 struct tr_bindinfo b; 754 struct init_data * data = vdata; 755 tr_session * session = data->session; 756 tr_variant * settings = data->clientSettings; 757 struct tr_turtle_info * turtle = &session->turtle; 758 759 assert (tr_isSession (session)); 760 assert (tr_variantIsDict (settings)); 761 assert (tr_amInEventThread (session)); 762 763 if (tr_variantDictFindInt (settings, TR_KEY_message_level, &i)) 764 tr_logSetLevel (i); 765 766 if (tr_variantDictFindInt (settings, TR_KEY_umask, &i)) { 767 session->umask = (mode_t)i; 768 umask (session->umask); 769 } 770 771 /* misc features */ 772 if (tr_variantDictFindInt (settings, TR_KEY_cache_size_mb, &i)) 773 tr_sessionSetCacheLimit_MB (session, i); 774 if (tr_variantDictFindInt (settings, TR_KEY_peer_limit_per_torrent, &i)) 775 tr_sessionSetPeerLimitPerTorrent (session, i); 776 if (tr_variantDictFindBool (settings, TR_KEY_pex_enabled, &boolVal)) 777 tr_sessionSetPexEnabled (session, boolVal); 778 if (tr_variantDictFindBool (settings, TR_KEY_dht_enabled, &boolVal)) 779 tr_sessionSetDHTEnabled (session, boolVal); 780 if (tr_variantDictFindBool (settings, TR_KEY_utp_enabled, &boolVal)) 781 tr_sessionSetUTPEnabled (session, boolVal); 782 if (tr_variantDictFindBool (settings, TR_KEY_lpd_enabled, &boolVal)) 783 tr_sessionSetLPDEnabled (session, boolVal); 784 if (tr_variantDictFindInt (settings, TR_KEY_encryption, &i)) 785 tr_sessionSetEncryption (session, i); 786 if (tr_variantDictFindStr (settings, TR_KEY_peer_socket_tos, &str, NULL)) 787 session->peerSocketTOS = parse_tos (str); 788 if (tr_variantDictFindStr (settings, TR_KEY_peer_congestion_algorithm, &str, NULL)) 789 session->peer_congestion_algorithm = tr_strdup (str); 790 else 791 session->peer_congestion_algorithm = tr_strdup (""); 792 if (tr_variantDictFindBool (settings, TR_KEY_blocklist_enabled, &boolVal)) 793 tr_blocklistSetEnabled (session, boolVal); 794 if (tr_variantDictFindStr (settings, TR_KEY_blocklist_url, &str, NULL)) 795 tr_blocklistSetURL (session, str); 796 if (tr_variantDictFindBool (settings, TR_KEY_start_added_torrents, &boolVal)) 797 tr_sessionSetPaused (session, !boolVal); 798 if (tr_variantDictFindBool (settings, TR_KEY_trash_original_torrent_files, &boolVal)) 799 tr_sessionSetDeleteSource (session, boolVal); 800 if (tr_variantDictFindInt (settings, TR_KEY_peer_id_ttl_hours, &i)) 801 session->peer_id_ttl_hours = i; 802 803 /* torrent queues */ 804 if (tr_variantDictFindInt (settings, TR_KEY_queue_stalled_minutes, &i)) 805 tr_sessionSetQueueStalledMinutes (session, i); 806 if (tr_variantDictFindBool (settings, TR_KEY_queue_stalled_enabled, &boolVal)) 807 tr_sessionSetQueueStalledEnabled (session, boolVal); 808 if (tr_variantDictFindInt (settings, TR_KEY_download_queue_size, &i)) 809 tr_sessionSetQueueSize (session, TR_DOWN, i); 810 if (tr_variantDictFindBool (settings, TR_KEY_download_queue_enabled, &boolVal)) 811 tr_sessionSetQueueEnabled (session, TR_DOWN, boolVal); 812 if (tr_variantDictFindInt (settings, TR_KEY_seed_queue_size, &i)) 813 tr_sessionSetQueueSize (session, TR_UP, i); 814 if (tr_variantDictFindBool (settings, TR_KEY_seed_queue_enabled, &boolVal)) 815 tr_sessionSetQueueEnabled (session, TR_UP, boolVal); 816 817 /* files and directories */ 818 if (tr_variantDictFindBool (settings, TR_KEY_prefetch_enabled, &boolVal)) 819 session->isPrefetchEnabled = boolVal; 820 if (tr_variantDictFindInt (settings, TR_KEY_preallocation, &i)) 821 session->preallocationMode = i; 822 if (tr_variantDictFindStr (settings, TR_KEY_download_dir, &str, NULL)) 823 tr_sessionSetDownloadDir (session, str); 824 if (tr_variantDictFindStr (settings, TR_KEY_incomplete_dir, &str, NULL)) 825 tr_sessionSetIncompleteDir (session, str); 826 if (tr_variantDictFindBool (settings, TR_KEY_incomplete_dir_enabled, &boolVal)) 827 tr_sessionSetIncompleteDirEnabled (session, boolVal); 828 if (tr_variantDictFindBool (settings, TR_KEY_rename_partial_files, &boolVal)) 829 tr_sessionSetIncompleteFileNamingEnabled (session, boolVal); 830 831 /* rpc server */ 832 if (session->rpcServer != NULL) /* close the old one */ 833 tr_rpcClose (&session->rpcServer); 834 session->rpcServer = tr_rpcInit (session, settings); 835 836 /* public addresses */ 837 838 free_incoming_peer_port (session); 839 840 tr_variantDictFindStr (settings, TR_KEY_bind_address_ipv4, &str, NULL); 841 if (!tr_address_from_string (&b.addr, str) || (b.addr.type != TR_AF_INET)) 842 b.addr = tr_inaddr_any; 843 b.socket = -1; 844 session->public_ipv4 = tr_memdup (&b, sizeof (struct tr_bindinfo)); 845 846 tr_variantDictFindStr (settings, TR_KEY_bind_address_ipv6, &str, NULL); 847 if (!tr_address_from_string (&b.addr, str) || (b.addr.type != TR_AF_INET6)) 848 b.addr = tr_in6addr_any; 849 b.socket = -1; 850 session->public_ipv6 = tr_memdup (&b, sizeof (struct tr_bindinfo)); 851 852 /* incoming peer port */ 853 if (tr_variantDictFindInt (settings, TR_KEY_peer_port_random_low, &i)) 854 session->randomPortLow = i; 855 if (tr_variantDictFindInt (settings, TR_KEY_peer_port_random_high, &i)) 856 session->randomPortHigh = i; 857 if (tr_variantDictFindBool (settings, TR_KEY_peer_port_random_on_start, &boolVal)) 858 tr_sessionSetPeerPortRandomOnStart (session, boolVal); 859 if (!tr_variantDictFindInt (settings, TR_KEY_peer_port, &i)) 860 i = session->private_peer_port; 861 setPeerPort (session, boolVal ? getRandomPort (session) : i); 862 if (tr_variantDictFindBool (settings, TR_KEY_port_forwarding_enabled, &boolVal)) 863 tr_sessionSetPortForwardingEnabled (session, boolVal); 864 865 if (tr_variantDictFindInt (settings, TR_KEY_peer_limit_global, &i)) 866 session->peerLimit = i; 867 868 /** 869 **/ 870 871 if (tr_variantDictFindInt (settings, TR_KEY_upload_slots_per_torrent, &i)) 872 session->uploadSlotsPerTorrent = i; 873 874 if (tr_variantDictFindInt (settings, TR_KEY_speed_limit_up, &i)) 875 tr_sessionSetSpeedLimit_KBps (session, TR_UP, i); 876 if (tr_variantDictFindBool (settings, TR_KEY_speed_limit_up_enabled, &boolVal)) 877 tr_sessionLimitSpeed (session, TR_UP, boolVal); 878 879 if (tr_variantDictFindInt (settings, TR_KEY_speed_limit_down, &i)) 880 tr_sessionSetSpeedLimit_KBps (session, TR_DOWN, i); 881 if (tr_variantDictFindBool (settings, TR_KEY_speed_limit_down_enabled, &boolVal)) 882 tr_sessionLimitSpeed (session, TR_DOWN, boolVal); 883 884 if (tr_variantDictFindReal (settings, TR_KEY_ratio_limit, &d)) 885 tr_sessionSetRatioLimit (session, d); 886 if (tr_variantDictFindBool (settings, TR_KEY_ratio_limit_enabled, &boolVal)) 887 tr_sessionSetRatioLimited (session, boolVal); 888 889 if (tr_variantDictFindInt (settings, TR_KEY_idle_seeding_limit, &i)) 890 tr_sessionSetIdleLimit (session, i); 891 if (tr_variantDictFindBool (settings, TR_KEY_idle_seeding_limit_enabled, &boolVal)) 892 tr_sessionSetIdleLimited (session, boolVal); 893 894 /** 895 *** Turtle Mode 896 **/ 897 898 /* update the turtle mode's fields */ 899 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_up, &i)) 900 turtle->speedLimit_Bps[TR_UP] = toSpeedBytes (i); 901 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_down, &i)) 902 turtle->speedLimit_Bps[TR_DOWN] = toSpeedBytes (i); 903 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_time_begin, &i)) 904 turtle->beginMinute = i; 905 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_time_end, &i)) 906 turtle->endMinute = i; 907 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_time_day, &i)) 908 turtle->days = i; 909 if (tr_variantDictFindBool (settings, TR_KEY_alt_speed_time_enabled, &boolVal)) 910 turtle->isClockEnabled = boolVal; 911 if (tr_variantDictFindBool (settings, TR_KEY_alt_speed_enabled, &boolVal)) 912 turtle->isEnabled = boolVal; 913 turtleBootstrap (session, turtle); 914 915 /** 916 *** Scripts 917 **/ 918 919 if (tr_variantDictFindBool (settings, TR_KEY_script_torrent_done_enabled, &boolVal)) 920 tr_sessionSetTorrentDoneScriptEnabled (session, boolVal); 921 if (tr_variantDictFindStr (settings, TR_KEY_script_torrent_done_filename, &str, NULL)) 922 tr_sessionSetTorrentDoneScript (session, str); 923 924 925 if (tr_variantDictFindBool (settings, TR_KEY_scrape_paused_torrents_enabled, &boolVal)) 926 session->scrapePausedTorrents = boolVal; 927 928 data->done = true; 759 int64_t i; 760 double d; 761 bool boolVal; 762 const char * str; 763 struct tr_bindinfo b; 764 struct init_data * data = vdata; 765 tr_session * session = data->session; 766 tr_variant * settings = data->clientSettings; 767 struct tr_turtle_info * turtle = &session->turtle; 768 769 assert (tr_isSession (session)); 770 assert (tr_variantIsDict (settings)); 771 assert (tr_amInEventThread (session)); 772 773 if (tr_variantDictFindInt (settings, TR_KEY_message_level, &i)) 774 tr_logSetLevel (i); 775 776 if (tr_variantDictFindInt (settings, TR_KEY_umask, &i)) 777 { 778 session->umask = (mode_t)i; 779 umask (session->umask); 780 } 781 782 /* misc features */ 783 if (tr_variantDictFindInt (settings, TR_KEY_cache_size_mb, &i)) 784 tr_sessionSetCacheLimit_MB (session, i); 785 if (tr_variantDictFindInt (settings, TR_KEY_peer_limit_per_torrent, &i)) 786 tr_sessionSetPeerLimitPerTorrent (session, i); 787 if (tr_variantDictFindBool (settings, TR_KEY_pex_enabled, &boolVal)) 788 tr_sessionSetPexEnabled (session, boolVal); 789 if (tr_variantDictFindBool (settings, TR_KEY_dht_enabled, &boolVal)) 790 tr_sessionSetDHTEnabled (session, boolVal); 791 if (tr_variantDictFindBool (settings, TR_KEY_utp_enabled, &boolVal)) 792 tr_sessionSetUTPEnabled (session, boolVal); 793 if (tr_variantDictFindBool (settings, TR_KEY_lpd_enabled, &boolVal)) 794 tr_sessionSetLPDEnabled (session, boolVal); 795 if (tr_variantDictFindInt (settings, TR_KEY_encryption, &i)) 796 tr_sessionSetEncryption (session, i); 797 if (tr_variantDictFindStr (settings, TR_KEY_peer_socket_tos, &str, NULL)) 798 session->peerSocketTOS = parse_tos (str); 799 if (tr_variantDictFindStr (settings, TR_KEY_peer_congestion_algorithm, &str, NULL)) 800 session->peer_congestion_algorithm = tr_strdup (str); 801 else 802 session->peer_congestion_algorithm = tr_strdup (""); 803 if (tr_variantDictFindBool (settings, TR_KEY_blocklist_enabled, &boolVal)) 804 tr_blocklistSetEnabled (session, boolVal); 805 if (tr_variantDictFindStr (settings, TR_KEY_blocklist_url, &str, NULL)) 806 tr_blocklistSetURL (session, str); 807 if (tr_variantDictFindBool (settings, TR_KEY_start_added_torrents, &boolVal)) 808 tr_sessionSetPaused (session, !boolVal); 809 if (tr_variantDictFindBool (settings, TR_KEY_trash_original_torrent_files, &boolVal)) 810 tr_sessionSetDeleteSource (session, boolVal); 811 if (tr_variantDictFindInt (settings, TR_KEY_peer_id_ttl_hours, &i)) 812 session->peer_id_ttl_hours = i; 813 814 /* torrent queues */ 815 if (tr_variantDictFindInt (settings, TR_KEY_queue_stalled_minutes, &i)) 816 tr_sessionSetQueueStalledMinutes (session, i); 817 if (tr_variantDictFindBool (settings, TR_KEY_queue_stalled_enabled, &boolVal)) 818 tr_sessionSetQueueStalledEnabled (session, boolVal); 819 if (tr_variantDictFindInt (settings, TR_KEY_download_queue_size, &i)) 820 tr_sessionSetQueueSize (session, TR_DOWN, i); 821 if (tr_variantDictFindBool (settings, TR_KEY_download_queue_enabled, &boolVal)) 822 tr_sessionSetQueueEnabled (session, TR_DOWN, boolVal); 823 if (tr_variantDictFindInt (settings, TR_KEY_seed_queue_size, &i)) 824 tr_sessionSetQueueSize (session, TR_UP, i); 825 if (tr_variantDictFindBool (settings, TR_KEY_seed_queue_enabled, &boolVal)) 826 tr_sessionSetQueueEnabled (session, TR_UP, boolVal); 827 828 /* files and directories */ 829 if (tr_variantDictFindBool (settings, TR_KEY_prefetch_enabled, &boolVal)) 830 session->isPrefetchEnabled = boolVal; 831 if (tr_variantDictFindInt (settings, TR_KEY_preallocation, &i)) 832 session->preallocationMode = i; 833 if (tr_variantDictFindStr (settings, TR_KEY_download_dir, &str, NULL)) 834 tr_sessionSetDownloadDir (session, str); 835 if (tr_variantDictFindStr (settings, TR_KEY_incomplete_dir, &str, NULL)) 836 tr_sessionSetIncompleteDir (session, str); 837 if (tr_variantDictFindBool (settings, TR_KEY_incomplete_dir_enabled, &boolVal)) 838 tr_sessionSetIncompleteDirEnabled (session, boolVal); 839 if (tr_variantDictFindBool (settings, TR_KEY_rename_partial_files, &boolVal)) 840 tr_sessionSetIncompleteFileNamingEnabled (session, boolVal); 841 842 /* rpc server */ 843 if (session->rpcServer != NULL) /* close the old one */ 844 tr_rpcClose (&session->rpcServer); 845 session->rpcServer = tr_rpcInit (session, settings); 846 847 /* public addresses */ 848 849 free_incoming_peer_port (session); 850 851 tr_variantDictFindStr (settings, TR_KEY_bind_address_ipv4, &str, NULL); 852 if (!tr_address_from_string (&b.addr, str) || (b.addr.type != TR_AF_INET)) 853 b.addr = tr_inaddr_any; 854 b.socket = -1; 855 session->public_ipv4 = tr_memdup (&b, sizeof (struct tr_bindinfo)); 856 857 tr_variantDictFindStr (settings, TR_KEY_bind_address_ipv6, &str, NULL); 858 if (!tr_address_from_string (&b.addr, str) || (b.addr.type != TR_AF_INET6)) 859 b.addr = tr_in6addr_any; 860 b.socket = -1; 861 session->public_ipv6 = tr_memdup (&b, sizeof (struct tr_bindinfo)); 862 863 /* incoming peer port */ 864 if (tr_variantDictFindInt (settings, TR_KEY_peer_port_random_low, &i)) 865 session->randomPortLow = i; 866 if (tr_variantDictFindInt (settings, TR_KEY_peer_port_random_high, &i)) 867 session->randomPortHigh = i; 868 if (tr_variantDictFindBool (settings, TR_KEY_peer_port_random_on_start, &boolVal)) 869 tr_sessionSetPeerPortRandomOnStart (session, boolVal); 870 if (!tr_variantDictFindInt (settings, TR_KEY_peer_port, &i)) 871 i = session->private_peer_port; 872 setPeerPort (session, boolVal ? getRandomPort (session) : i); 873 if (tr_variantDictFindBool (settings, TR_KEY_port_forwarding_enabled, &boolVal)) 874 tr_sessionSetPortForwardingEnabled (session, boolVal); 875 876 if (tr_variantDictFindInt (settings, TR_KEY_peer_limit_global, &i)) 877 session->peerLimit = i; 878 879 /** 880 **/ 881 882 if (tr_variantDictFindInt (settings, TR_KEY_upload_slots_per_torrent, &i)) 883 session->uploadSlotsPerTorrent = i; 884 885 if (tr_variantDictFindInt (settings, TR_KEY_speed_limit_up, &i)) 886 tr_sessionSetSpeedLimit_KBps (session, TR_UP, i); 887 if (tr_variantDictFindBool (settings, TR_KEY_speed_limit_up_enabled, &boolVal)) 888 tr_sessionLimitSpeed (session, TR_UP, boolVal); 889 890 if (tr_variantDictFindInt (settings, TR_KEY_speed_limit_down, &i)) 891 tr_sessionSetSpeedLimit_KBps (session, TR_DOWN, i); 892 if (tr_variantDictFindBool (settings, TR_KEY_speed_limit_down_enabled, &boolVal)) 893 tr_sessionLimitSpeed (session, TR_DOWN, boolVal); 894 895 if (tr_variantDictFindReal (settings, TR_KEY_ratio_limit, &d)) 896 tr_sessionSetRatioLimit (session, d); 897 if (tr_variantDictFindBool (settings, TR_KEY_ratio_limit_enabled, &boolVal)) 898 tr_sessionSetRatioLimited (session, boolVal); 899 900 if (tr_variantDictFindInt (settings, TR_KEY_idle_seeding_limit, &i)) 901 tr_sessionSetIdleLimit (session, i); 902 if (tr_variantDictFindBool (settings, TR_KEY_idle_seeding_limit_enabled, &boolVal)) 903 tr_sessionSetIdleLimited (session, boolVal); 904 905 /** 906 *** Turtle Mode 907 **/ 908 909 /* update the turtle mode's fields */ 910 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_up, &i)) 911 turtle->speedLimit_Bps[TR_UP] = toSpeedBytes (i); 912 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_down, &i)) 913 turtle->speedLimit_Bps[TR_DOWN] = toSpeedBytes (i); 914 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_time_begin, &i)) 915 turtle->beginMinute = i; 916 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_time_end, &i)) 917 turtle->endMinute = i; 918 if (tr_variantDictFindInt (settings, TR_KEY_alt_speed_time_day, &i)) 919 turtle->days = i; 920 if (tr_variantDictFindBool (settings, TR_KEY_alt_speed_time_enabled, &boolVal)) 921 turtle->isClockEnabled = boolVal; 922 if (tr_variantDictFindBool (settings, TR_KEY_alt_speed_enabled, &boolVal)) 923 turtle->isEnabled = boolVal; 924 turtleBootstrap (session, turtle); 925 926 /** 927 *** Scripts 928 **/ 929 930 if (tr_variantDictFindBool (settings, TR_KEY_script_torrent_done_enabled, &boolVal)) 931 tr_sessionSetTorrentDoneScriptEnabled (session, boolVal); 932 if (tr_variantDictFindStr (settings, TR_KEY_script_torrent_done_filename, &str, NULL)) 933 tr_sessionSetTorrentDoneScript (session, str); 934 935 936 if (tr_variantDictFindBool (settings, TR_KEY_scrape_paused_torrents_enabled, &boolVal)) 937 session->scrapePausedTorrents = boolVal; 938 939 data->done = true; 929 940 } 930 941 … … 993 1004 tr_sessionSetIncompleteFileNamingEnabled (tr_session * session, bool b) 994 1005 { 995 996 997 998 1006 assert (tr_isSession (session)); 1007 assert (tr_isBool (b)); 1008 1009 session->isIncompleteFileNamingEnabled = b; 999 1010 } 1000 1011 … … 1002 1013 tr_sessionIsIncompleteFileNamingEnabled (const tr_session * session) 1003 1014 { 1004 1005 1006 1015 assert (tr_isSession (session)); 1016 1017 return session->isIncompleteFileNamingEnabled; 1007 1018 } 1008 1019 … … 1015 1026 tr_sessionSetIncompleteDir (tr_session * session, const char * dir) 1016 1027 { 1017 1018 1019 1020 { 1021 1022 1023 1028 assert (tr_isSession (session)); 1029 1030 if (session->incompleteDir != dir) 1031 { 1032 tr_free (session->incompleteDir); 1033 1034 session->incompleteDir = tr_strdup (dir); 1024 1035 } 1025 1036 } … … 1028 1039 tr_sessionGetIncompleteDir (const tr_session * session) 1029 1040 { 1030 1031 1032 1041 assert (tr_isSession (session)); 1042 1043 return session->incompleteDir; 1033 1044 } 1034 1045 … … 1036 1047 tr_sessionSetIncompleteDirEnabled (tr_session * session, bool b) 1037 1048 { 1038 1039 1040 1041 1049 assert (tr_isSession (session)); 1050 assert (tr_isBool (b)); 1051 1052 session->isIncompleteDirEnabled = b; 1042 1053 } 1043 1054 … … 1045 1056 tr_sessionIsIncompleteDirEnabled (const tr_session * session) 1046 1057 { 1047 1048 1049 1058 assert (tr_isSession (session)); 1059 1060 return session->isIncompleteDirEnabled; 1050 1061 } 1051 1062 … … 1057 1068 tr_sessionLock (tr_session * session) 1058 1069 { 1059 1060 1061 1070 assert (tr_isSession (session)); 1071 1072 tr_lockLock (session->lock); 1062 1073 } 1063 1074 … … 1065 1076 tr_sessionUnlock (tr_session * session) 1066 1077 { 1067 1068 1069 1078 assert (tr_isSession (session)); 1079 1080 tr_lockUnlock (session->lock); 1070 1081 } 1071 1082 … … 1073 1084 tr_sessionIsLocked (const tr_session * session) 1074 1085 { 1075 return tr_isSession (session) && tr_lockHave (session->lock); 1076 } 1077 1078 /*********************************************************************** 1079 * tr_setBindPort 1080 *********************************************************************** 1081 * 1082 **********************************************************************/ 1086 return tr_isSession (session) && tr_lockHave (session->lock); 1087 } 1088 1089 /*** 1090 **** Peer Port 1091 ***/ 1083 1092 1084 1093 static void 1085 1094 peerPortChanged (void * session) 1086 1095 { 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1096 tr_torrent * tor = NULL; 1097 1098 assert (tr_isSession (session)); 1099 1100 close_incoming_peer_port (session); 1101 open_incoming_peer_port (session); 1102 tr_sharedPortChanged (session); 1103 1104 while ((tor = tr_torrentNext (session, tor))) 1105 tr_torrentChangeMyPort (tor); 1097 1106 } 1098 1107 … … 1100 1109 setPeerPort (tr_session * session, tr_port port) 1101 1110 { 1102 1103 1104 1105 1111 session->private_peer_port = port; 1112 session->public_peer_port = port; 1113 1114 tr_runInEventThread (session, peerPortChanged, session); 1106 1115 } 1107 1116 … … 1109 1118 tr_sessionSetPeerPort (tr_session * session, tr_port port) 1110 1119 { 1111 1112 { 1113 1120 if (tr_isSession (session) && (session->private_peer_port != port)) 1121 { 1122 setPeerPort (session, port); 1114 1123 } 1115 1124 } … … 1118 1127 tr_sessionGetPeerPort (const tr_session * session) 1119 1128 { 1120 1129 return tr_isSession (session) ? session->private_peer_port : 0; 1121 1130 } 1122 1131 … … 1124 1133 tr_sessionSetPeerPortRandom (tr_session * session) 1125 1134 { 1126 1127 1128 1129 1135 assert (tr_isSession (session)); 1136 1137 tr_sessionSetPeerPort (session, getRandomPort (session)); 1138 return session->private_peer_port; 1130 1139 } 1131 1140 … … 1134 1143 bool random) 1135 1144 { 1136 1137 1138 1145 assert (tr_isSession (session)); 1146 1147 session->isPortRandom = random; 1139 1148 } 1140 1149 … … 1142 1151 tr_sessionGetPeerPortRandomOnStart (tr_session * session) 1143 1152 { 1144 1145 1146 1153 assert (tr_isSession (session)); 1154 1155 return session->isPortRandom; 1147 1156 } 1148 1157 … … 1150 1159 tr_sessionGetPortForwarding (const tr_session * session) 1151 1160 { 1152 1153 1154 1161 assert (tr_isSession (session)); 1162 1163 return tr_sharedTraversalStatus (session->shared); 1155 1164 } 1156 1165 … … 1162 1171 tr_sessionSetRatioLimited (tr_session * session, bool isLimited) 1163 1172 { 1164 1165 1166 1173 assert (tr_isSession (session)); 1174 1175 session->isRatioLimited = isLimited; 1167 1176 } 1168 1177 … … 1170 1179 tr_sessionSetRatioLimit (tr_session * session, double desiredRatio) 1171 1180 { 1172 1173 1174 1181 assert (tr_isSession (session)); 1182 1183 session->desiredRatio = desiredRatio; 1175 1184 } 1176 1185 … … 1178 1187 tr_sessionIsRatioLimited (const tr_session * session) 1179 1188 { 1180 1181 1182 1189 assert (tr_isSession (session)); 1190 1191 return session->isRatioLimited; 1183 1192 } 1184 1193 … … 1186 1195 tr_sessionGetRatioLimit (const tr_session * session) 1187 1196 { 1188 1189 1190 1197 assert (tr_isSession (session)); 1198 1199 return session->desiredRatio; 1191 1200 } 1192 1201 … … 1198 1207 tr_sessionSetIdleLimited (tr_session * session, bool isLimited) 1199 1208 { 1200 1201 1202 1209 assert (tr_isSession (session)); 1210 1211 session->isIdleLimited = isLimited; 1203 1212 } 1204 1213 … … 1206 1215 tr_sessionSetIdleLimit (tr_session * session, uint16_t idleMinutes) 1207 1216 { 1208 1209 1210 1217 assert (tr_isSession (session)); 1218 1219 session->idleLimitMinutes = idleMinutes; 1211 1220 } 1212 1221 … … 1214 1223 tr_sessionIsIdleLimited (const tr_session * session) 1215 1224 { 1216 1217 1218 1225 assert (tr_isSession (session)); 1226 1227 return session->isIdleLimited; 1219 1228 } 1220 1229 … … 1222 1231 tr_sessionGetIdleLimit (const tr_session * session) 1223 1232 { 1224 1225 1226 1233 assert (tr_isSession (session)); 1234 1235 return session->idleLimitMinutes; 1227 1236 } 1228 1237 … … 1236 1245 tr_sessionGetActiveSpeedLimit_Bps (const tr_session * session, tr_direction dir, unsigned int * setme_Bps) 1237 1246 { 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1247 int isLimited = true; 1248 1249 if (!tr_isSession (session)) 1250 return false; 1251 1252 if (tr_sessionUsesAltSpeed (session)) 1253 *setme_Bps = tr_sessionGetAltSpeed_Bps (session, dir); 1254 else if (tr_sessionIsSpeedLimited (session, dir)) 1255 *setme_Bps = tr_sessionGetSpeedLimit_Bps (session, dir); 1256 else 1257 isLimited = false; 1258 1259 return isLimited; 1251 1260 } 1252 1261 bool … … 1255 1264 double * setme_KBps) 1256 1265 { 1257 1258 1259 1260 1266 unsigned int Bps = 0; 1267 const bool is_active = tr_sessionGetActiveSpeedLimit_Bps (session, dir, &Bps); 1268 *setme_KBps = toSpeedKBps (Bps); 1269 return is_active; 1261 1270 } 1262 1271 … … 1264 1273 updateBandwidth (tr_session * session, tr_direction dir) 1265 1274 { 1266 1267 1268 1269 1270 1271 1272 1275 unsigned int limit_Bps = 0; 1276 const bool isLimited = tr_sessionGetActiveSpeedLimit_Bps (session, dir, &limit_Bps); 1277 const bool zeroCase = isLimited && !limit_Bps; 1278 1279 tr_bandwidthSetLimited (&session->bandwidth, dir, isLimited && !zeroCase); 1280 1281 tr_bandwidthSetDesiredSpeed_Bps (&session->bandwidth, dir, limit_Bps); 1273 1282 } 1274 1283 1275 1284 enum 1276 1285 { 1277 1278 1279 1286 MINUTES_PER_HOUR = 60, 1287 MINUTES_PER_DAY = MINUTES_PER_HOUR * 24, 1288 MINUTES_PER_WEEK = MINUTES_PER_DAY * 7 1280 1289 }; 1281 1290 … … 1283 1292 turtleUpdateTable (struct tr_turtle_info * t) 1284 1293 { 1285 1286 1287 1288 1289 1290 1291 { 1292 1294 int day; 1295 tr_bitfield * b = &t->minutes; 1296 1297 tr_bitfieldSetHasNone (b); 1298 1299 for (day=0; day<7; ++day) 1300 { 1301 if (t->days & (1<<day)) 1293 1302 { 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 int i; 1304 const time_t begin = t->beginMinute; 1305 time_t end = t->endMinute; 1306 1307 if (end <= begin) 1308 end += MINUTES_PER_DAY; 1309 1310 for (i=begin; i<end; ++i) 1311 tr_bitfieldAdd (b, (i+day*MINUTES_PER_DAY) % MINUTES_PER_WEEK); 1303 1312 } 1304 1313 } … … 1308 1317 altSpeedToggled (void * vsession) 1309 1318 { 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1319 tr_session * session = vsession; 1320 struct tr_turtle_info * t = &session->turtle; 1321 1322 assert (tr_isSession (session)); 1323 1324 updateBandwidth (session, TR_UP); 1325 updateBandwidth (session, TR_DOWN); 1326 1327 if (t->callback != NULL) 1328 (*t->callback)(session, t->isEnabled, t->changedByUser, t->callbackUserData); 1320 1329 } 1321 1330 … … 1324 1333 bool enabled, bool byUser) 1325 1334 { 1326 1327 1328 1329 1330 1331 1332 { 1333 1334 1335 1335 assert (tr_isSession (s)); 1336 assert (t != NULL); 1337 assert (tr_isBool (enabled)); 1338 assert (tr_isBool (byUser)); 1339 1340 if (t->isEnabled != enabled) 1341 { 1342 t->isEnabled = enabled; 1343 t->changedByUser = byUser; 1344 tr_runInEventThread (s, altSpeedToggled, s); 1336 1345 } 1337 1346 } … … 1343 1352 getInTurtleTime (const struct tr_turtle_info * t) 1344 1353 { 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1354 struct tm tm; 1355 size_t minute_of_the_week; 1356 const time_t now = tr_time (); 1357 1358 tr_localtime_r (&now, &tm); 1359 1360 minute_of_the_week = tm.tm_wday * MINUTES_PER_DAY 1361 + tm.tm_hour * MINUTES_PER_HOUR 1362 + tm.tm_min; 1363 if (minute_of_the_week >= MINUTES_PER_WEEK) /* leap minutes? */ 1364 minute_of_the_week = MINUTES_PER_WEEK - 1; 1365 1366 return tr_bitfieldHas (&t->minutes, minute_of_the_week); 1358 1367 } 1359 1368 … … 1367 1376 turtleCheckClock (tr_session * s, struct tr_turtle_info * t) 1368 1377 { 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 { 1381 1382 1383 1378 bool enabled; 1379 bool alreadySwitched; 1380 tr_auto_switch_state_t newAutoTurtleState; 1381 1382 assert (t->isClockEnabled); 1383 1384 enabled = getInTurtleTime (t); 1385 newAutoTurtleState = autoSwitchState (enabled); 1386 alreadySwitched = (t->autoTurtleState == newAutoTurtleState); 1387 1388 if (!alreadySwitched) 1389 { 1390 tr_logAddInfo ("Time to turn %s turtle mode!", (enabled?"on":"off")); 1391 t->autoTurtleState = newAutoTurtleState; 1392 useAltSpeed (s, t, enabled, false); 1384 1393 } 1385 1394 } … … 1391 1400 turtleBootstrap (tr_session * session, struct tr_turtle_info * turtle) 1392 1401 { 1393 1394 1395 1396 1397 1398 1399 1400 1401 { 1402 1403 1404 } 1405 1406 1402 turtle->changedByUser = false; 1403 turtle->autoTurtleState = TR_AUTO_SWITCH_UNUSED; 1404 1405 tr_bitfieldConstruct (&turtle->minutes, MINUTES_PER_WEEK); 1406 1407 turtleUpdateTable (turtle); 1408 1409 if (turtle->isClockEnabled) 1410 { 1411 turtle->isEnabled = getInTurtleTime (turtle); 1412 turtle->autoTurtleState = autoSwitchState (turtle->isEnabled); 1413 } 1414 1415 altSpeedToggled (session); 1407 1416 1408 1417 } … … 1415 1424 tr_sessionSetSpeedLimit_Bps (tr_session * s, tr_direction d, unsigned int Bps) 1416 1425 { 1417 1418 1419 1420 1421 1422 1426 assert (tr_isSession (s)); 1427 assert (tr_isDirection (d)); 1428 1429 s->speedLimit_Bps[d] = Bps; 1430 1431 updateBandwidth (s, d); 1423 1432 } 1424 1433 void 1425 1434 tr_sessionSetSpeedLimit_KBps (tr_session * s, tr_direction d, unsigned int KBps) 1426 1435 { 1427 1436 tr_sessionSetSpeedLimit_Bps (s, d, toSpeedBytes (KBps)); 1428 1437 } 1429 1438 … … 1431 1440 tr_sessionGetSpeedLimit_Bps (const tr_session * s, tr_direction d) 1432 1441 { 1433 1434 1435 1436 1442 assert (tr_isSession (s)); 1443 assert (tr_isDirection (d)); 1444 1445 return s->speedLimit_Bps[d]; 1437 1446 } 1438 1447 unsigned int … … 1445 1454 tr_sessionLimitSpeed (tr_session * s, tr_direction d, bool b) 1446 1455 { 1447 1448 1449 1450 1451 1452 1453 1456 assert (tr_isSession (s)); 1457 assert (tr_isDirection (d)); 1458 assert (tr_isBool (b)); 1459 1460 s->speedLimitEnabled[d] = b; 1461 1462 updateBandwidth (s, d); 1454 1463 } 1455 1464 … … 1457 1466 tr_sessionIsSpeedLimited (const tr_session * s, tr_direction d) 1458 1467 { 1459 1460 1461 1462 1468 assert (tr_isSession (s)); 1469 assert (tr_isDirection (d)); 1470 1471 return s->speedLimitEnabled[d]; 1463 1472 } 1464 1473 … … 1470 1479 tr_sessionSetAltSpeed_Bps (tr_session * s, tr_direction d, unsigned int Bps) 1471 1480 { 1472 1473 1474 1475 1476 1477 1481 assert (tr_isSession (s)); 1482 assert (tr_isDirection (d)); 1483 1484 s->turtle.speedLimit_Bps[d] = Bps; 1485 1486 updateBandwidth (s, d); 1478 1487 } 1479 1488 … … 1481 1490 tr_sessionSetAltSpeed_KBps (tr_session * s, tr_direction d, unsigned int KBps) 1482 1491 { 1483 1492 tr_sessionSetAltSpeed_Bps (s, d, toSpeedBytes (KBps)); 1484 1493 } 1485 1494 … … 1487 1496 tr_sessionGetAltSpeed_Bps (const tr_session * s, tr_direction d) 1488 1497 { 1489 1490 1491 1492 1498 assert (tr_isSession (s)); 1499 assert (tr_isDirection (d)); 1500 1501 return s->turtle.speedLimit_Bps[d]; 1493 1502 } 1494 1503 unsigned int 1495 1504 tr_sessionGetAltSpeed_KBps (const tr_session * s, tr_direction d) 1496 1505 { 1497 1506 return toSpeedKBps (tr_sessionGetAltSpeed_Bps (s, d)); 1498 1507 } 1499 1508 … … 1501 1510 userPokedTheClock (tr_session * s, struct tr_turtle_info * t) 1502 1511 { 1503 1504 1505 1506 1507 1508 1509 1510 { 1511 1512 1513 1512 tr_logAddDebug ("Refreshing the turtle mode clock due to user changes"); 1513 1514 t->autoTurtleState = TR_AUTO_SWITCH_UNUSED; 1515 1516 turtleUpdateTable (t); 1517 1518 if (t->isClockEnabled) 1519 { 1520 const bool enabled = getInTurtleTime (t); 1521 useAltSpeed (s, t, enabled, true); 1522 t->autoTurtleState = autoSwitchState (enabled); 1514 1523 } 1515 1524 } … … 1518 1527 tr_sessionUseAltSpeedTime (tr_session * s, bool b) 1519 1528 { 1520 struct tr_turtle_info * t = &s->turtle; 1521 1522 assert (tr_isSession (s)); 1523 assert (tr_isBool (b)); 1524 1525 if (t->isClockEnabled != b) { 1526 t->isClockEnabled = b; 1527 userPokedTheClock (s, t); 1529 struct tr_turtle_info * t = &s->turtle; 1530 1531 assert (tr_isSession (s)); 1532 assert (tr_isBool (b)); 1533 1534 if (t->isClockEnabled != b) 1535 { 1536 t->isClockEnabled = b; 1537 userPokedTheClock (s, t); 1528 1538 } 1529 1539 } … … 1532 1542 tr_sessionUsesAltSpeedTime (const tr_session * s) 1533 1543 { 1534 1535 1536 1544 assert (tr_isSession (s)); 1545 1546 return s->turtle.isClockEnabled; 1537 1547 } 1538 1548 … … 1540 1550 tr_sessionSetAltSpeedBegin (tr_session * s, int minute) 1541 1551 { 1542 assert (tr_isSession (s)); 1543 assert (0<=minute && minute< (60*24)); 1544 1545 if (s->turtle.beginMinute != minute) { 1546 s->turtle.beginMinute = minute; 1547 userPokedTheClock (s, &s->turtle); 1552 assert (tr_isSession (s)); 1553 assert (0<=minute && minute< (60*24)); 1554 1555 if (s->turtle.beginMinute != minute) 1556 { 1557 s->turtle.beginMinute = minute; 1558 userPokedTheClock (s, &s->turtle); 1548 1559 } 1549 1560 } … … 1552 1563 tr_sessionGetAltSpeedBegin (const tr_session * s) 1553 1564 { 1554 1555 1556 1565 assert (tr_isSession (s)); 1566 1567 return s->turtle.beginMinute; 1557 1568 } 1558 1569 … … 1560 1571 tr_sessionSetAltSpeedEnd (tr_session * s, int minute) 1561 1572 { 1562 assert (tr_isSession (s)); 1563 assert (0<=minute && minute< (60*24)); 1564 1565 if (s->turtle.endMinute != minute) { 1566 s->turtle.endMinute = minute; 1567 userPokedTheClock (s, &s->turtle); 1573 assert (tr_isSession (s)); 1574 assert (0<=minute && minute< (60*24)); 1575 1576 if (s->turtle.endMinute != minute) 1577 { 1578 s->turtle.endMinute = minute; 1579 userPokedTheClock (s, &s->turtle); 1568 1580 } 1569 1581 } … … 1572 1584 tr_sessionGetAltSpeedEnd (const tr_session * s) 1573 1585 { 1574 1575 1576 1586 assert (tr_isSession (s)); 1587 1588 return s->turtle.endMinute; 1577 1589 } 1578 1590 … … 1580 1592 tr_sessionSetAltSpeedDay (tr_session * s, tr_sched_day days) 1581 1593 { 1582 assert (tr_isSession (s)); 1583 1584 if (s->turtle.days != days) { 1585 s->turtle.days = days; 1586 userPokedTheClock (s, &s->turtle); 1594 assert (tr_isSession (s)); 1595 1596 if (s->turtle.days != days) 1597 { 1598 s->turtle.days = days; 1599 userPokedTheClock (s, &s->turtle); 1587 1600 } 1588 1601 } … … 1591 1604 tr_sessionGetAltSpeedDay (const tr_session * s) 1592 1605 { 1593 1594 1595 1606 assert (tr_isSession (s)); 1607 1608 return s->turtle.days; 1596 1609 } 1597 1610 … … 1599 1612 tr_sessionUseAltSpeed (tr_session * session, bool enabled) 1600 1613 { 1601 1614 useAltSpeed (session, &session->turtle, enabled, true); 1602 1615 } 1603 1616 … … 1605 1618 tr_sessionUsesAltSpeed (const tr_session * s) 1606 1619 { 1607 1608 1609 1620 assert (tr_isSession (s)); 1621 1622 return s->turtle.isEnabled; 1610 1623 } 1611 1624 … … 1615 1628 void * userData) 1616 1629 { 1617 1618 1619 1620 1630 assert (tr_isSession (session)); 1631 1632 session->turtle.callback = func; 1633 session->turtle.callbackUserData = userData; 1621 1634 } 1622 1635 … … 1624 1637 tr_sessionClearAltSpeedFunc (tr_session * session) 1625 1638 { 1626 1639 tr_sessionSetAltSpeedFunc (session, NULL, NULL); 1627 1640 } 1628 1641 … … 1634 1647 tr_sessionSetPeerLimit (tr_session * session, uint16_t n) 1635 1648 { 1636 1637 1638 1649 assert (tr_isSession (session)); 1650 1651 session->peerLimit = n; 1639 1652 } 1640 1653 … … 1642 1655 tr_sessionGetPeerLimit (const tr_session * session) 1643 1656 { 1644 1645 1646 1657 assert (tr_isSession (session)); 1658 1659 return session->peerLimit; 1647 1660 } 1648 1661 … … 1658 1671 tr_sessionGetPeerLimitPerTorrent (const tr_session * session) 1659 1672 { 1660 1661 1662 1673 assert (tr_isSession (session)); 1674 1675 return session->peerLimitPerTorrent; 1663 1676 } 1664 1677 … … 1670 1683 tr_sessionSetPaused (tr_session * session, bool isPaused) 1671 1684 { 1672 1673 1674 1685 assert (tr_isSession (session)); 1686 1687 session->pauseAddedTorrent = isPaused; 1675 1688 } 1676 1689 … … 1678 1691 tr_sessionGetPaused (const tr_session * session) 1679 1692 { 1680 1681 1682 1693 assert (tr_isSession (session)); 1694 1695 return session->pauseAddedTorrent; 1683 1696 } 1684 1697 … … 1686 1699 tr_sessionSetDeleteSource (tr_session * session, bool deleteSource) 1687 1700 { 1688 1689 1690 1701 assert (tr_isSession (session)); 1702 1703 session->deleteSourceTorrent = deleteSource; 1691 1704 } 1692 1705 … … 1694 1707 tr_sessionGetDeleteSource (const tr_session * session) 1695 1708 { 1696 1697 1698 1709 assert (tr_isSession (session)); 1710 1711 return session->deleteSourceTorrent; 1699 1712 } 1700 1713 … … 1706 1719 tr_sessionGetPieceSpeed_Bps (const tr_session * session, tr_direction dir) 1707 1720 { 1708 1721 return tr_isSession (session) ? tr_bandwidthGetPieceSpeed_Bps (&session->bandwidth, 0, dir) : 0; 1709 1722 } 1710 1723 … … 1712 1725 tr_sessionGetRawSpeed_Bps (const tr_session * session, tr_direction dir) 1713 1726 { 1714 1727 return tr_isSession (session) ? tr_bandwidthGetRawSpeed_Bps (&session->bandwidth, 0, dir) : 0; 1715 1728 } 1716 1729 double 1717 1730 tr_sessionGetRawSpeed_KBps (const tr_session * session, tr_direction dir) 1718 1731 { 1719 1732 return toSpeedKBps (tr_sessionGetRawSpeed_Bps (session, dir)); 1720 1733 } 1721 1734 … … 1724 1737 tr_sessionCountTorrents (const tr_session * session) 1725 1738 { 1726 1739 return tr_isSession (session) ? session->torrentCount : 0; 1727 1740 } 1728 1741 … … 1730 1743 compareTorrentByCur (const void * va, const void * vb) 1731 1744 { 1732 1733 1734 const uint64_taCur = a->downloadedCur + a->uploadedCur;1735 const uint64_tbCur = b->downloadedCur + b->uploadedCur;1736 1737 1738 1739 1740 1745 const tr_torrent * a = * (const tr_torrent**)va; 1746 const tr_torrent * b = * (const tr_torrent**)vb; 1747 const uint64_t aCur = a->downloadedCur + a->uploadedCur; 1748 const uint64_t bCur = b->downloadedCur + b->uploadedCur; 1749 1750 if (aCur != bCur) 1751 return aCur > bCur ? -1 : 1; /* close the biggest torrents first */ 1752 1753 return 0; 1741 1754 } 1742 1755 … … 1746 1759 sessionCloseImpl (void * vsession) 1747 1760 { 1748 tr_session * session = vsession; 1749 tr_torrent * tor; 1750 int i, n; 1751 tr_torrent ** torrents; 1752 1753 assert (tr_isSession (session)); 1754 1755 session->isClosing = true; 1756 1757 free_incoming_peer_port (session); 1758 1759 if (session->isLPDEnabled) 1760 tr_lpdUninit (session); 1761 1762 tr_utpClose (session); 1763 tr_dhtUninit (session); 1764 1765 event_free (session->saveTimer); 1766 session->saveTimer = NULL; 1767 1768 event_free (session->nowTimer); 1769 session->nowTimer = NULL; 1770 1771 tr_verifyClose (session); 1772 tr_sharedClose (session); 1773 tr_rpcClose (&session->rpcServer); 1774 1775 /* Close the torrents. Get the most active ones first so that 1776 * if we can't get them all closed in a reasonable amount of time, 1777 * at least we get the most important ones first. */ 1778 tor = NULL; 1779 n = session->torrentCount; 1780 torrents = tr_new (tr_torrent *, session->torrentCount); 1781 for (i = 0; i < n; ++i) 1782 torrents[i] = tor = tr_torrentNext (session, tor); 1783 qsort (torrents, n, sizeof (tr_torrent*), compareTorrentByCur); 1784 for (i = 0; i < n; ++i) 1785 tr_torrentFree (torrents[i]); 1786 tr_free (torrents); 1787 1788 /* Close the announcer *after* closing the torrents 1789 so that all the &event=stopped messages will be 1790 queued to be sent by tr_announcerClose () */ 1791 tr_announcerClose (session); 1792 1793 /* and this goes *after* announcer close so that 1794 it won't be idle until the announce events are sent... */ 1795 tr_webClose (session, TR_WEB_CLOSE_WHEN_IDLE); 1796 1797 tr_cacheFree (session->cache); 1798 session->cache = NULL; 1799 1800 /* gotta keep udp running long enough to send out all 1801 the &event=stopped UDP tracker messages */ 1802 while (!tr_tracker_udp_is_idle (session)) { 1803 tr_tracker_udp_upkeep (session); 1804 tr_wait_msec (100); 1805 } 1806 1807 /* we had to wait until UDP trackers were closed before closing these: */ 1808 evdns_base_free (session->evdns_base, 0); 1809 session->evdns_base = NULL; 1810 tr_tracker_udp_close (session); 1811 tr_udpUninit (session); 1812 1813 tr_statsClose (session); 1814 tr_peerMgrFree (session->peerMgr); 1815 1816 closeBlocklists (session); 1817 1818 tr_fdClose (session); 1819 1820 session->isClosed = true; 1761 int i, n; 1762 tr_torrent * tor; 1763 tr_torrent ** torrents; 1764 tr_session * session = vsession; 1765 1766 assert (tr_isSession (session)); 1767 1768 session->isClosing = true; 1769 1770 free_incoming_peer_port (session); 1771 1772 if (session->isLPDEnabled) 1773 tr_lpdUninit (session); 1774 1775 tr_utpClose (session); 1776 tr_dhtUninit (session); 1777 1778 event_free (session->saveTimer); 1779 session->saveTimer = NULL; 1780 1781 event_free (session->nowTimer); 1782 session->nowTimer = NULL; 1783 1784 tr_verifyClose (session); 1785 tr_sharedClose (session); 1786 tr_rpcClose (&session->rpcServer); 1787 1788 /* Close the torrents. Get the most active ones first so that 1789 * if we can't get them all closed in a reasonable amount of time, 1790 * at least we get the most important ones first. */ 1791 tor = NULL; 1792 n = session->torrentCount; 1793 torrents = tr_new (tr_torrent *, session->torrentCount); 1794 for (i=0; i<n; ++i) 1795 torrents[i] = tor = tr_torrentNext (session, tor); 1796 qsort (torrents, n, sizeof (tr_torrent*), compareTorrentByCur); 1797 for (i=0; i<n; ++i) 1798 tr_torrentFree (torrents[i]); 1799 tr_free (torrents); 1800 1801 /* Close the announcer *after* closing the torrents 1802 so that all the &event=stopped messages will be 1803 queued to be sent by tr_announcerClose () */ 1804 tr_announcerClose (session); 1805 1806 /* and this goes *after* announcer close so that 1807 it won't be idle until the announce events are sent... */ 1808 tr_webClose (session, TR_WEB_CLOSE_WHEN_IDLE); 1809 1810 tr_cacheFree (session->cache); 1811 session->cache = NULL; 1812 1813 /* gotta keep udp running long enough to send out all 1814 the &event=stopped UDP tracker messages */ 1815 while (!tr_tracker_udp_is_idle (session)) 1816 { 1817 tr_tracker_udp_upkeep (session); 1818 tr_wait_msec (100); 1819 } 1820 1821 /* we had to wait until UDP trackers were closed before closing these: */ 1822 evdns_base_free (session->evdns_base, 0); 1823 session->evdns_base = NULL; 1824 tr_tracker_udp_close (session); 1825 tr_udpUninit (session); 1826 1827 tr_statsClose (session); 1828 tr_peerMgrFree (session->peerMgr); 1829 1830 closeBlocklists (session); 1831 1832 tr_fdClose (session); 1833 1834 session->isClosed = true; 1821 1835 } 1822 1836 … … 1824 1838 deadlineReached (const time_t deadline) 1825 1839 { 1826 1840 return time (NULL) >= deadline; 1827 1841 } 1828 1842 … … 1832 1846 tr_sessionClose (tr_session * session) 1833 1847 { 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 { 1844 1845 1846 } 1847 1848 1849 1850 1851 1852 1848 const time_t deadline = time (NULL) + SHUTDOWN_MAX_SECONDS; 1849 1850 assert (tr_isSession (session)); 1851 1852 dbgmsg ("shutting down transmission session %p... now is %zu, deadline is %zu", session, (size_t)time (NULL), (size_t)deadline); 1853 1854 /* close the session */ 1855 tr_runInEventThread (session, sessionCloseImpl, session); 1856 while (!session->isClosed && !deadlineReached (deadline)) 1857 { 1858 dbgmsg ("waiting for the libtransmission thread to finish"); 1859 tr_wait_msec (100); 1860 } 1861 1862 /* "shared" and "tracker" have live sockets, 1863 * so we need to keep the transmission thread alive 1864 * for a bit while they tell the router & tracker 1865 * that we're closing now */ 1866 while ((session->shared || session->web || session->announcer || session->announcer_udp) 1853 1867 && !deadlineReached (deadline)) 1854 1868 { 1855 dbgmsg ("waiting on port unmap (%p) or announcer (%p)... now %zu deadline %zu", 1856 session->shared, session->announcer, (size_t)time (NULL), (size_t)deadline); 1857 tr_wait_msec (50); 1858 } 1859 1860 tr_webClose (session, TR_WEB_CLOSE_NOW); 1861 1862 /* close the libtransmission thread */ 1863 tr_eventClose (session); 1864 while (session->events != NULL) 1865 { 1866 static bool forced = false; 1867 dbgmsg ("waiting for libtransmission thread to finish... now %zu deadline %zu", (size_t)time (NULL), (size_t)deadline); 1868 tr_wait_msec (100); 1869 if (deadlineReached (deadline) && !forced) 1869 dbgmsg ("waiting on port unmap (%p) or announcer (%p)... now %zu deadline %zu", 1870 session->shared, session->announcer, (size_t)time (NULL), (size_t)deadline); 1871 tr_wait_msec (50); 1872 } 1873 1874 tr_webClose (session, TR_WEB_CLOSE_NOW); 1875 1876 /* close the libtransmission thread */ 1877 tr_eventClose (session); 1878 while (session->events != NULL) 1879 { 1880 static bool forced = false; 1881 dbgmsg ("waiting for libtransmission thread to finish... now %zu deadline %zu", (size_t)time (NULL), (size_t)deadline); 1882 tr_wait_msec (100); 1883 1884 if (deadlineReached (deadline) && !forced) 1870 1885 { 1871 1872 1873 1886 dbgmsg ("calling event_loopbreak ()"); 1887 forced = true; 1888 event_base_loopbreak (session->event_base); 1874 1889 } 1875 if (deadlineReached (deadline+3)) 1890 1891 if (deadlineReached (deadline+3)) 1876 1892 { 1877 1878 1893 dbgmsg ("deadline+3 reached... calling break...\n"); 1894 break; 1879 1895 } 1880 1896 } 1881 1897 1882 /* free the session memory */ 1883 tr_variantFree (&session->removedTorrents); 1884 tr_bandwidthDestruct (&session->bandwidth); 1885 tr_bitfieldDestruct (&session->turtle.minutes); 1886 tr_lockFree (session->lock); 1887 if (session->metainfoLookup) { 1888 tr_variantFree (session->metainfoLookup); 1889 tr_free (session->metainfoLookup); 1890 } 1891 tr_device_info_free (session->downloadDir); 1892 tr_free (session->torrentDoneScript); 1893 tr_free (session->tag); 1894 tr_free (session->configDir); 1895 tr_free (session->resumeDir); 1896 tr_free (session->torrentDir); 1897 tr_free (session->incompleteDir); 1898 tr_free (session->blocklist_url); 1899 tr_free (session->peer_congestion_algorithm); 1900 tr_free (session); 1898 /* free the session memory */ 1899 tr_variantFree (&session->removedTorrents); 1900 tr_bandwidthDestruct (&session->bandwidth); 1901 tr_bitfieldDestruct (&session->turtle.minutes); 1902 tr_lockFree (session->lock); 1903 if (session->metainfoLookup) 1904 { 1905 tr_variantFree (session->metainfoLookup); 1906 tr_free (session->metainfoLookup); 1907 } 1908 tr_device_info_free (session->downloadDir); 1909 tr_free (session->torrentDoneScript); 1910 tr_free (session->tag); 1911 tr_free (session->configDir); 1912 tr_free (session->resumeDir); 1913 tr_free (session->torrentDir); 1914 tr_free (session->incompleteDir); 1915 tr_free (session->blocklist_url); 1916 tr_free (session->peer_congestion_algorithm); 1917 tr_free (session); 1901 1918 } 1902 1919 1903 1920 struct sessionLoadTorrentsData 1904 1921 { 1905 1906 1907 1908 1909 1922 tr_session * session; 1923 tr_ctor * ctor; 1924 int * setmeCount; 1925 tr_torrent ** torrents; 1926 bool done; 1910 1927 }; 1911 1928 … … 1913 1930 sessionLoadTorrents (void * vdata) 1914 1931 { 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1932 int i; 1933 int n = 0; 1934 struct stat sb; 1935 DIR * odir = NULL; 1936 tr_list * l = NULL; 1937 tr_list * list = NULL; 1938 struct sessionLoadTorrentsData * data = vdata; 1939 const char * dirname = tr_getTorrentDir (data->session); 1940 1941 assert (tr_isSession (data->session)); 1942 1943 tr_ctorSetSave (data->ctor, false); /* since we already have them */ 1944 1945 if (!stat (dirname, &sb) 1929 1946 && S_ISDIR (sb.st_mode) 1930 1947 && ((odir = opendir (dirname)))) 1931 1948 { 1932 1933 1949 struct dirent *d; 1950 for (d = readdir (odir); d != NULL; d = readdir (odir)) 1934 1951 { 1935 1952 if (tr_str_has_suffix (d->d_name, ".torrent")) 1936 1953 { 1937 1938 1939 1940 1954 tr_torrent * tor; 1955 char * path = tr_buildPath (dirname, d->d_name, NULL); 1956 tr_ctorSetMetainfoFromFile (data->ctor, path); 1957 if ((tor = tr_torrentNew (data->ctor, NULL, NULL))) 1941 1958 { 1942 1943 1959 tr_list_prepend (&list, tor); 1960 ++n; 1944 1961 } 1945 1962 tr_free (path); 1946 1963 } 1947 1964 } 1948 1949 } 1950 1951 1952 for (i = 0, l = list; l != NULL; l =l->next)1953 1954 1965 closedir (odir); 1966 } 1967 1968 data->torrents = tr_new (tr_torrent *, n); 1969 for (i=0, l=list; l!=NULL; l=l->next) 1970 data->torrents[i++] = (tr_torrent*) l->data; 1971 assert (i == n); 1955 1972 1956 1973 tr_list_free (&list, NULL); 1957 1974 1958 1959 1960 1961 1962 1963 1964 1975 if (n) 1976 tr_logAddInfo (_("Loaded %d torrents"), n); 1977 1978 if (data->setmeCount) 1979 *data->setmeCount = n; 1980 1981 data->done = true; 1965 1982 } 1966 1983 … … 1970 1987 int * setmeCount) 1971 1988 { 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1989 struct sessionLoadTorrentsData data; 1990 1991 data.session = session; 1992 data.ctor = ctor; 1993 data.setmeCount = setmeCount; 1994 data.torrents = NULL; 1995 data.done = false; 1996 1997 tr_runInEventThread (session, sessionLoadTorrents, &data); 1998 while (!data.done) 1999 tr_wait_msec (100); 2000 2001 return data.torrents; 1985 2002 } 1986 2003 … … 1992 2009 tr_sessionSetPexEnabled (tr_session * session, bool enabled) 1993 2010 { 1994 1995 1996 2011 assert (tr_isSession (session)); 2012 2013 session->isPexEnabled = enabled != 0; 1997 2014 } 1998 2015 … … 2000 2017 tr_sessionIsPexEnabled (const tr_session * session) 2001 2018 { 2002 2003 2004 2019 assert (tr_isSession (session)); 2020 2021 return session->isPexEnabled; 2005 2022 } 2006 2023 … … 2008 2025 tr_sessionAllowsDHT (const tr_session * session) 2009 2026 { 2010 2027 return tr_sessionIsDHTEnabled (session); 2011 2028 } 2012 2029 … … 2014 2031 tr_sessionIsDHTEnabled (const tr_session * session) 2015 2032 { 2016 2017 2018 2033 assert (tr_isSession (session)); 2034 2035 return session->isDHTEnabled; 2019 2036 } 2020 2037 … … 2022 2039 toggleDHTImpl (void * data) 2023 2040 { 2024 2025 2026 2027 2028 2029 2041 tr_session * session = data; 2042 assert (tr_isSession (session)); 2043 2044 tr_udpUninit (session); 2045 session->isDHTEnabled = !session->isDHTEnabled; 2046 tr_udpInit (session); 2030 2047 } 2031 2048 … … 2033 2050 tr_sessionSetDHTEnabled (tr_session * session, bool enabled) 2034 2051 { 2035 2036 2037 2038 2039 2052 assert (tr_isSession (session)); 2053 assert (tr_isBool (enabled)); 2054 2055 if ((enabled != 0) != (session->isDHTEnabled != 0)) 2056 tr_runInEventThread (session, toggleDHTImpl, session); 2040 2057 } 2041 2058 … … 2047 2064 tr_sessionIsUTPEnabled (const tr_session * session) 2048 2065 { 2049 2066 assert (tr_isSession (session)); 2050 2067 2051 2068 #ifdef WITH_UTP 2052 2069 return session->isUTPEnabled; 2053 2070 #else 2054 2071 return false; 2055 2072 #endif 2056 2073 } … … 2059 2076 toggle_utp (void * data) 2060 2077 { 2061 tr_session * session = data; 2062 assert (tr_isSession (session)); 2063 2064 session->isUTPEnabled = !session->isUTPEnabled; 2065 2066 tr_udpSetSocketBuffers (session); 2067 2068 /* But don't call tr_utpClose -- see reset_timer in tr-utp.c for an 2069 explanation. */ 2078 tr_session * session = data; 2079 2080 assert (tr_isSession (session)); 2081 2082 session->isUTPEnabled = !session->isUTPEnabled; 2083 2084 tr_udpSetSocketBuffers (session); 2085 2086 /* But don't call tr_utpClose -- see reset_timer in tr-utp.c for an 2087 explanation. */ 2070 2088 } 2071 2089 … … 2073 2091 tr_sessionSetUTPEnabled (tr_session * session, bool enabled) 2074 2092 { 2075 2076 2077 2078 2079 2093 assert (tr_isSession (session)); 2094 assert (tr_isBool (enabled)); 2095 2096 if ((enabled != 0) != (session->isUTPEnabled != 0)) 2097 tr_runInEventThread (session, toggle_utp, session); 2080 2098 } 2081 2099 … … 2087 2105 toggleLPDImpl (void * data) 2088 2106 { 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2107 tr_session * session = data; 2108 assert (tr_isSession (session)); 2109 2110 if (session->isLPDEnabled) 2111 tr_lpdUninit (session); 2112 2113 session->isLPDEnabled = !session->isLPDEnabled; 2114 2115 if (session->isLPDEnabled) 2116 tr_lpdInit (session, &session->public_ipv4->addr); 2099 2117 } 2100 2118 … … 2102 2120 tr_sessionSetLPDEnabled (tr_session * session, bool enabled) 2103 2121 { 2104 2105 2106 2107 2108 2122 assert (tr_isSession (session)); 2123 assert (tr_isBool (enabled)); 2124 2125 if ((enabled != 0) != (session->isLPDEnabled != 0)) 2126 tr_runInEventThread (session, toggleLPDImpl, session); 2109 2127 } 2110 2128 … … 2112 2130 tr_sessionIsLPDEnabled (const tr_session * session) 2113 2131 { 2114 2115 2116 2132 assert (tr_isSession (session)); 2133 2134 return session->isLPDEnabled; 2117 2135 } 2118 2136 … … 2120 2138 tr_sessionAllowsLPD (const tr_session * session) 2121 2139 { 2122 2140 return tr_sessionIsLPDEnabled (session); 2123 2141 } 2124 2142 … … 2130 2148 tr_sessionSetCacheLimit_MB (tr_session * session, int max_bytes) 2131 2149 { 2132 2133 2134 2150 assert (tr_isSession (session)); 2151 2152 tr_cacheSetLimit (session->cache, toMemBytes (max_bytes)); 2135 2153 } 2136 2154 … … 2138 2156 tr_sessionGetCacheLimit_MB (const tr_session * session) 2139 2157 { 2140 2141 2142 2158 assert (tr_isSession (session)); 2159 2160 return toMemMB (tr_cacheGetLimit (session->cache)); 2143 2161 } 2144 2162 … … 2149 2167 struct port_forwarding_data 2150 2168 { 2151 2152 2169 bool enabled; 2170 struct tr_shared * shared; 2153 2171 }; 2154 2172 … … 2156 2174 setPortForwardingEnabled (void * vdata) 2157 2175 { 2158 2159 2160 2176 struct port_forwarding_data * data = vdata; 2177 tr_sharedTraversalEnable (data->shared, data->enabled); 2178 tr_free (data); 2161 2179 } 2162 2180 … … 2164 2182 tr_sessionSetPortForwardingEnabled (tr_session * session, bool enabled) 2165 2183 { 2166 2167 2168 2169 2170 2184 struct port_forwarding_data * d; 2185 d = tr_new0 (struct port_forwarding_data, 1); 2186 d->shared = session->shared; 2187 d->enabled = enabled; 2188 tr_runInEventThread (session, setPortForwardingEnabled, d); 2171 2189 } 2172 2190 … … 2174 2192 tr_sessionIsPortForwardingEnabled (const tr_session * session) 2175 2193 { 2176 2177 2178 2194 assert (tr_isSession (session)); 2195 2196 return tr_sharedTraversalIsEnabled (session->shared); 2179 2197 } 2180 2198 … … 2186 2204 tr_stringEndsWith (const char * str, const char * end) 2187 2205 { 2188 2189 2190 2191 2206 const size_t slen = strlen (str); 2207 const size_t elen = strlen (end); 2208 2209 return slen >= elen && !memcmp (&str[slen - elen], end, elen); 2192 2210 } 2193 2211 … … 2296 2314 closeBlocklists (tr_session * session) 2297 2315 { 2298 tr_list_free (&session->blocklists, 2299 (TrListForeachFunc)tr_blocklistFileFree); 2316 tr_list_free (&session->blocklists, (TrListForeachFunc)tr_blocklistFileFree); 2300 2317 } 2301 2318 … … 2303 2320 tr_sessionReloadBlocklists (tr_session * session) 2304 2321 { 2305 2306 2307 2308 2322 closeBlocklists (session); 2323 loadBlocklists (session); 2324 2325 tr_peerMgrOnBlocklistChanged (session->peerMgr); 2309 2326 } 2310 2327 … … 2312 2329 tr_blocklistGetRuleCount (const tr_session * session) 2313 2330 { 2314 int n = 0; 2315 tr_list * l; 2316 2317 assert (tr_isSession (session)); 2318 2319 for (l = session->blocklists; l; l = l->next) 2320 n += tr_blocklistFileGetRuleCount (l->data); 2321 return n; 2331 tr_list * l; 2332 int n = 0; 2333 2334 assert (tr_isSession (session)); 2335 2336 for (l = session->blocklists; l; l = l->next) 2337 n += tr_blocklistFileGetRuleCount (l->data); 2338 2339 return n; 2322 2340 } 2323 2341 … … 2325 2343 tr_blocklistIsEnabled (const tr_session * session) 2326 2344 { 2327 2328 2329 2345 assert (tr_isSession (session)); 2346 2347 return session->isBlocklistEnabled; 2330 2348 } 2331 2349 … … 2333 2351 tr_blocklistSetEnabled (tr_session * session, bool isEnabled) 2334 2352 { 2335 2336 2337 2338 2339 2340 2341 2342 2353 tr_list * l; 2354 2355 assert (tr_isSession (session)); 2356 2357 session->isBlocklistEnabled = isEnabled != 0; 2358 2359 for (l=session->blocklists; l!=NULL; l=l->next) 2360 tr_blocklistFileSetEnabled (l->data, isEnabled); 2343 2361 } 2344 2362 … … 2346 2364 tr_blocklistExists (const tr_session * session) 2347 2365 { 2348 2349 2350 2366 assert (tr_isSession (session)); 2367 2368 return session->blocklists != NULL; 2351 2369 } 2352 2370 … … 2354 2372 tr_blocklistSetContent (tr_session * session, const char * contentFilename) 2355 2373 { 2356 tr_list * l; 2357 int ruleCount; 2358 tr_blocklistFile * b; 2359 const char * defaultName = DEFAULT_BLOCKLIST_FILENAME; 2360 tr_sessionLock (session); 2361 2362 for (b = NULL, l = session->blocklists; !b && l; l = l->next) 2363 if (tr_stringEndsWith (tr_blocklistFileGetFilename (l->data), 2364 defaultName)) 2365 b = l->data; 2366 2367 if (!b) 2368 { 2369 char * path = tr_buildPath (session->configDir, "blocklists", defaultName, NULL); 2370 b = tr_blocklistFileNew (path, session->isBlocklistEnabled); 2371 tr_list_append (&session->blocklists, b); 2372 tr_free (path); 2373 } 2374 2375 ruleCount = tr_blocklistFileSetContent (b, contentFilename); 2376 tr_sessionUnlock (session); 2377 return ruleCount; 2374 tr_list * l; 2375 int ruleCount; 2376 tr_blocklistFile * b; 2377 const char * defaultName = DEFAULT_BLOCKLIST_FILENAME; 2378 tr_sessionLock (session); 2379 2380 for (b=NULL, l=session->blocklists; !b && l; l=l->next) 2381 if (tr_stringEndsWith (tr_blocklistFileGetFilename (l->data), defaultName)) 2382 b = l->data; 2383 2384 if (!b) 2385 { 2386 char * path = tr_buildPath (session->configDir, "blocklists", defaultName, NULL); 2387 b = tr_blocklistFileNew (path, session->isBlocklistEnabled); 2388 tr_list_append (&session->blocklists, b); 2389 tr_free (path); 2390 } 2391 2392 ruleCount = tr_blocklistFileSetContent (b, contentFilename); 2393 tr_sessionUnlock (session); 2394 return ruleCount; 2378 2395 } 2379 2396 … … 2382 2399 const tr_address * addr) 2383 2400 { 2384 tr_list * l; 2385 2386 assert (tr_isSession (session)); 2387 2388 for (l = session->blocklists; l; l = l->next) 2389 if (tr_blocklistFileHasAddress (l->data, addr)) 2390 return true; 2391 return false; 2401 tr_list * l; 2402 2403 assert (tr_isSession (session)); 2404 2405 for (l = session->blocklists; l; l = l->next) 2406 if (tr_blocklistFileHasAddress (l->data, addr)) 2407 return true; 2408 2409 return false; 2392 2410 } 2393 2411 … … 2395 2413 tr_blocklistSetURL (tr_session * session, const char * url) 2396 2414 { 2397 2398 { 2399 2400 2415 if (session->blocklist_url != url) 2416 { 2417 tr_free (session->blocklist_url); 2418 session->blocklist_url = tr_strdup (url); 2401 2419 } 2402 2420 } … … 2405 2423 tr_blocklistGetURL (const tr_session * session) 2406 2424 { 2407 2425 return session->blocklist_url; 2408 2426 } 2409 2427 … … 2416 2434 metainfoLookupInit (tr_session * session) 2417 2435 { 2418 struct statsb;2419 2420 DIR *odir = NULL;2421 tr_ctor *ctor = NULL;2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 { 2434 2435 2436 struct stat sb; 2437 const char * dirname = tr_getTorrentDir (session); 2438 DIR * odir = NULL; 2439 tr_ctor * ctor = NULL; 2440 tr_variant * lookup; 2441 int n = 0; 2442 2443 assert (tr_isSession (session)); 2444 2445 /* walk through the directory and find the mappings */ 2446 lookup = tr_new0 (tr_variant, 1); 2447 tr_variantInitDict (lookup, 0); 2448 ctor = tr_ctorNew (session); 2449 tr_ctorSetSave (ctor, false); /* since we already have them */ 2450 if (!stat (dirname, &sb) && S_ISDIR (sb.st_mode) && ((odir = opendir (dirname)))) 2451 { 2452 struct dirent *d; 2453 while ((d = readdir (odir))) 2436 2454 { 2437 2455 if (tr_str_has_suffix (d->d_name, ".torrent")) 2438 2456 { 2439 2440 2441 2442 2457 tr_info inf; 2458 char * path = tr_buildPath (dirname, d->d_name, NULL); 2459 tr_ctorSetMetainfoFromFile (ctor, path); 2460 if (!tr_torrentParse (ctor, &inf)) 2443 2461 { 2444 2445 2462 ++n; 2463 tr_variantDictAddStr (lookup, tr_quark_new(inf.hashString,-1), path); 2446 2464 } 2447 2465 tr_free (path); 2448 2466 } 2449 2467 } 2450 2451 } 2452 2453 2454 2455 2468 closedir (odir); 2469 } 2470 tr_ctorFree (ctor); 2471 2472 session->metainfoLookup = lookup; 2473 tr_logAddDebug ("Found %d torrents in \"%s\"", n, dirname); 2456 2474 } 2457 2475 … … 2460 2478 const char * hashString) 2461 2479 { 2462 const char * filename = NULL; 2463 if (!session->metainfoLookup) 2464 metainfoLookupInit ((tr_session*)session); 2465 tr_variantDictFindStr (session->metainfoLookup, tr_quark_new(hashString,-1), &filename, NULL); 2466 return filename; 2480 const char * filename = NULL; 2481 2482 if (!session->metainfoLookup) 2483 metainfoLookupInit ((tr_session*)session); 2484 tr_variantDictFindStr (session->metainfoLookup, tr_quark_new(hashString,-1), &filename, NULL); 2485 2486 return filename; 2467 2487 } 2468 2488 … … 2472 2492 const char * filename) 2473 2493 { 2474 2475 2476 2477 2478 2479 2494 /* since we walk session->configDir/torrents/ to build the lookup table, 2495 * and tr_sessionSetTorrentFile () is just to tell us there's a new file 2496 * in that same directory, we don't need to do anything here if the 2497 * lookup table hasn't been built yet */ 2498 if (session->metainfoLookup) 2499 tr_variantDictAddStr (session->metainfoLookup, tr_quark_new(hashString,-1), filename); 2480 2500 } 2481 2501 … … 2487 2507 tr_sessionSetRPCEnabled (tr_session * session, bool isEnabled) 2488 2508 { 2489 2490 2491 2509 assert (tr_isSession (session)); 2510 2511 tr_rpcSetEnabled (session->rpcServer, isEnabled); 2492 2512 } 2493 2513 … … 2495 2515 tr_sessionIsRPCEnabled (const tr_session * session) 2496 2516 { 2497 2498 2499 2517 assert (tr_isSession (session)); 2518 2519 return tr_rpcIsEnabled (session->rpcServer); 2500 2520 } 2501 2521 … … 2504 2524 tr_port port) 2505 2525 { 2506 2507 2508 2526 assert (tr_isSession (session)); 2527 2528 tr_rpcSetPort (session->rpcServer, port); 2509 2529 } 2510 2530 … … 2512 2532 tr_sessionGetRPCPort (const tr_session * session) 2513 2533 { 2514 2515 2516 2534 assert (tr_isSession (session)); 2535 2536 return tr_rpcGetPort (session->rpcServer); 2517 2537 } 2518 2538 … … 2521 2541 const char * url) 2522 2542 { 2523 2524 2525 2543 assert (tr_isSession (session)); 2544 2545 tr_rpcSetUrl (session->rpcServer, url); 2526 2546 } 2527 2547 … … 2529 2549 tr_sessionGetRPCUrl (const tr_session * session) 2530 2550 { 2531 2532 2533 2551 assert (tr_isSession (session)); 2552 2553 return tr_rpcGetUrl (session->rpcServer); 2534 2554 } 2535 2555 … … 2539 2559 void * user_data) 2540 2560 { 2541 2542 2543 2544 2561 assert (tr_isSession (session)); 2562 2563 session->rpc_func = func; 2564 session->rpc_func_user_data = user_data; 2545 2565 } 2546 2566 … … 2549 2569 const char * whitelist) 2550 2570 { 2551 2552 2553 2571 assert (tr_isSession (session)); 2572 2573 tr_rpcSetWhitelist (session->rpcServer, whitelist); 2554 2574 } 2555 2575 … … 2557 2577 tr_sessionGetRPCWhitelist (const tr_session * session) 2558 2578 { 2559 2560 2561 2579 assert (tr_isSession (session)); 2580 2581 return tr_rpcGetWhitelist (session->rpcServer); 2562 2582 } 2563 2583 … … 2565 2585 tr_sessionSetRPCWhitelistEnabled (tr_session * session, bool isEnabled) 2566 2586 { 2567 2568 2569 2587 assert (tr_isSession (session)); 2588 2589 tr_rpcSetWhitelistEnabled (session->rpcServer, isEnabled); 2570 2590 } 2571 2591 … … 2573 2593 tr_sessionGetRPCWhitelistEnabled (const tr_session * session) 2574 2594 { 2575 2576 2577 2595 assert (tr_isSession (session)); 2596 2597 return tr_rpcGetWhitelistEnabled (session->rpcServer); 2578 2598 } 2579 2599 … … 2583 2603 const char * password) 2584 2604 { 2585 2586 2587 2605 assert (tr_isSession (session)); 2606 2607 tr_rpcSetPassword (session->rpcServer, password); 2588 2608 } 2589 2609 … … 2591 2611 tr_sessionGetRPCPassword (const tr_session * session) 2592 2612 { 2593 2594 2595 2613 assert (tr_isSession (session)); 2614 2615 return tr_rpcGetPassword (session->rpcServer); 2596 2616 } 2597 2617 … … 2600 2620 const char * username) 2601 2621 { 2602 2603 2604 2622 assert (tr_isSession (session)); 2623 2624 tr_rpcSetUsername (session->rpcServer, username); 2605 2625 } 2606 2626 … … 2608 2628 tr_sessionGetRPCUsername (const tr_session * session) 2609 2629 { 2610 2611 2612 2630 assert (tr_isSession (session)); 2631 2632 return tr_rpcGetUsername (session->rpcServer); 2613 2633 } 2614 2634 … … 2616 2636 tr_sessionSetRPCPasswordEnabled (tr_session * session, bool isEnabled) 2617 2637 { 2618 2619 2620 2638 assert (tr_isSession (session)); 2639 2640 tr_rpcSetPasswordEnabled (session->rpcServer, isEnabled); 2621 2641 } 2622 2642 … … 2624 2644 tr_sessionIsRPCPasswordEnabled (const tr_session * session) 2625 2645 { 2626 2627 2628 2646 assert (tr_isSession (session)); 2647 2648 return tr_rpcIsPasswordEnabled (session->rpcServer); 2629 2649 } 2630 2650 … … 2632 2652 tr_sessionGetRPCBindAddress (const tr_session * session) 2633 2653 { 2634 2635 2636 2654 assert (tr_isSession (session)); 2655 2656 return tr_rpcGetBindAddress (session->rpcServer); 2637 2657 } 2638 2658 … … 2644 2664 tr_sessionIsTorrentDoneScriptEnabled (const tr_session * session) 2645 2665 { 2646 2647 2648 2666 assert (tr_isSession (session)); 2667 2668 return session->isTorrentDoneScriptEnabled; 2649 2669 } 2650 2670 … … 2652 2672 tr_sessionSetTorrentDoneScriptEnabled (tr_session * session, bool isEnabled) 2653 2673 { 2654 2655 2656 2657 2674 assert (tr_isSession (session)); 2675 assert (tr_isBool (isEnabled)); 2676 2677 session->isTorrentDoneScriptEnabled = isEnabled; 2658 2678 } 2659 2679 … … 2661 2681 tr_sessionGetTorrentDoneScript (const tr_session * session) 2662 2682 { 2663 2664 2665 2683 assert (tr_isSession (session)); 2684 2685 return session->torrentDoneScript; 2666 2686 } 2667 2687 … … 2669 2689 tr_sessionSetTorrentDoneScript (tr_session * session, const char * scriptFilename) 2670 2690 { 2671 2672 2673 2674 { 2675 2676 2691 assert (tr_isSession (session)); 2692 2693 if (session->torrentDoneScript != scriptFilename) 2694 { 2695 tr_free (session->torrentDoneScript); 2696 session->torrentDoneScript = tr_strdup (scriptFilename); 2677 2697 } 2678 2698 } … … 2685 2705 tr_sessionSetQueueSize (tr_session * session, tr_direction dir, int n) 2686 2706 { 2687 2688 2689 2690 2707 assert (tr_isSession (session)); 2708 assert (tr_isDirection (dir)); 2709 2710 session->queueSize[dir] = n; 2691 2711 } 2692 2712 … … 2694 2714 tr_sessionGetQueueSize (const tr_session * session, tr_direction dir) 2695 2715 { 2696 2697 2698 2699 2716 assert (tr_isSession (session)); 2717 assert (tr_isDirection (dir)); 2718 2719 return session->queueSize[dir]; 2700 2720 } 2701 2721 … … 2703 2723 tr_sessionSetQueueEnabled (tr_session * session, tr_direction dir, bool is_enabled) 2704 2724 { 2705 2706 2707 2708 2709 2725 assert (tr_isSession (session)); 2726 assert (tr_isDirection (dir)); 2727 assert (tr_isBool (is_enabled)); 2728 2729 session->queueEnabled[dir] = is_enabled; 2710 2730 } 2711 2731 … … 2713 2733 tr_sessionGetQueueEnabled (const tr_session * session, tr_direction dir) 2714 2734 { 2715 2716 2717 2718 2735 assert (tr_isSession (session)); 2736 assert (tr_isDirection (dir)); 2737 2738 return session->queueEnabled[dir]; 2719 2739 } 2720 2740 … … 2722 2742 tr_sessionSetQueueStalledMinutes (tr_session * session, int minutes) 2723 2743 { 2724 2725 2726 2727 2744 assert (tr_isSession (session)); 2745 assert (minutes > 0); 2746 2747 session->queueStalledMinutes = minutes; 2728 2748 } 2729 2749 … … 2731 2751 tr_sessionSetQueueStalledEnabled (tr_session * session, bool is_enabled) 2732 2752 { 2733 2734 2735 2736 2753 assert (tr_isSession (session)); 2754 assert (tr_isBool (is_enabled)); 2755 2756 session->stalledEnabled = is_enabled; 2737 2757 } 2738 2758 … … 2740 2760 tr_sessionGetQueueStalledEnabled (const tr_session * session) 2741 2761 { 2742 2743 2744 2762 assert (tr_isSession (session)); 2763 2764 return session->stalledEnabled; 2745 2765 } 2746 2766 … … 2748 2768 tr_sessionGetQueueStalledMinutes (const tr_session * session) 2749 2769 { 2750 2751 2752 2770 assert (tr_isSession (session)); 2771 2772 return session->queueStalledMinutes; 2753 2773 } 2754 2774 … … 2827 2847 tr_sessionCountQueueFreeSlots (tr_session * session, tr_direction dir) 2828 2848 { 2829 2830 2831 2832 2833 2834 2835 2849 tr_torrent * tor; 2850 int active_count; 2851 const int max = tr_sessionGetQueueSize (session, dir); 2852 const tr_torrent_activity activity = dir == TR_UP ? TR_STATUS_SEED : TR_STATUS_DOWNLOAD; 2853 2854 if (!tr_sessionGetQueueEnabled (session, dir)) 2855 return INT_MAX; 2836 2856 2837 2857 tor = NULL;
Note: See TracChangeset
for help on using the changeset viewer.