sched.c (26332B)
1 /* sched.c 2 * Links internal scheduler 3 * (c) 2002 Mikulas Patocka 4 * This file is a part of the Links program, released under GPL. 5 */ 6 7 #include <limits.h> 8 9 #include "links.h" 10 11 static tcount connection_count = 0; 12 13 static int active_connections = 0; 14 15 tcount netcfg_stamp = 0; 16 17 struct list_head queue = { &queue, &queue }; 18 19 struct h_conn { 20 list_entry_1st; 21 unsigned char *host; 22 int conn; 23 }; 24 25 static struct list_head h_conns = { &h_conns, &h_conns }; 26 27 struct list_head keepalive_connections = { &keepalive_connections, 28 &keepalive_connections }; 29 30 /* prototypes */ 31 static void send_connection_info(struct connection *c); 32 static void del_keepalive_socket(struct k_conn *kc); 33 static void check_keepalive_connections(void); 34 35 unsigned long 36 connect_info(int type) 37 { 38 int i = 0; 39 struct connection *ce = NULL; 40 struct list_head *lce; 41 switch (type) { 42 case CI_FILES: 43 return list_size(&queue); 44 case CI_CONNECTING: 45 foreach (struct connection, ce, lce, queue) 46 i += ce->state > S_WAIT && ce->state < S_TRANS; 47 return i; 48 case CI_TRANSFER: 49 foreach (struct connection, ce, lce, queue) 50 i += ce->state == S_TRANS; 51 return i; 52 case CI_KEEP: 53 check_keepalive_connections(); 54 return list_size(&keepalive_connections); 55 default: 56 internal("connect_info: bad request"); 57 } 58 return 0; 59 } 60 61 static int 62 getpri(struct connection *c) 63 { 64 int i; 65 for (i = 0; i < N_PRI; i++) 66 if (c->pri[i]) 67 return i; 68 internal("connection has no owner"); 69 return N_PRI; 70 } 71 72 static int 73 connection_disappeared(struct connection *c, tcount count) 74 { 75 struct connection *d = NULL; 76 struct list_head *ld; 77 foreach (struct connection, d, ld, queue) 78 if (c == d && count == d->count) 79 return 0; 80 return 1; 81 } 82 83 static struct h_conn * 84 is_host_on_list(struct connection *c) 85 { 86 char *ho = (char *)get_host_name(c->url); 87 struct h_conn *h = NULL; 88 struct list_head *lh; 89 if (!ho) 90 return NULL; 91 foreach (struct h_conn, h, lh, h_conns) 92 if (!strcmp((const char *)h->host, ho)) { 93 free(ho); 94 return h; 95 } 96 free(ho); 97 return NULL; 98 } 99 100 static int st_r = 0; 101 102 static void 103 stat_timer(void *c_) 104 { 105 struct connection *c = (struct connection *)c_; 106 struct remaining_info *r = &c->prg; 107 uttime now = get_time(); 108 uttime a = now - r->last_time; 109 if (a > SPD_DISP_TIME * 100) 110 a = SPD_DISP_TIME * 100; 111 if (getpri(c) == PRI_CANCEL 112 && (c->est_length > (long)memory_cache_size * MAX_CACHED_OBJECT 113 || c->from > (long)memory_cache_size * MAX_CACHED_OBJECT)) 114 register_bottom_half(check_queue, NULL); 115 if (c->state > S_WAIT) { 116 r->loaded = c->received; 117 if ((r->size = c->est_length) < (r->pos = c->from) 118 && r->size != -1) 119 r->size = c->from; 120 r->dis_b += a; 121 while (r->dis_b >= SPD_DISP_TIME * CURRENT_SPD_SEC) { 122 r->cur_loaded -= r->data_in_secs[0]; 123 memmove(r->data_in_secs, r->data_in_secs + 1, 124 sizeof(off_t) * (CURRENT_SPD_SEC - 1)); 125 r->data_in_secs[CURRENT_SPD_SEC - 1] = 0; 126 r->dis_b -= SPD_DISP_TIME; 127 } 128 r->data_in_secs[CURRENT_SPD_SEC - 1] += 129 r->loaded - r->last_loaded; 130 r->cur_loaded += r->loaded - r->last_loaded; 131 r->last_loaded = r->loaded; 132 r->elapsed += a; 133 } 134 r->last_time = now; 135 r->timer = install_timer(SPD_DISP_TIME, stat_timer, c); 136 if (!st_r) 137 send_connection_info(c); 138 } 139 140 void 141 setcstate(struct connection *c, int state) 142 { 143 struct status *stat = NULL; 144 struct list_head *lstat; 145 if (c->state < 0 && state >= 0) 146 c->prev_error = c->state; 147 if ((c->state = state) == S_TRANS) { 148 struct remaining_info *r = &c->prg; 149 if (!r->timer) { 150 tcount count = c->count; 151 if (!r->valid) { 152 memset(r, 0, sizeof(struct remaining_info)); 153 r->valid = 1; 154 } 155 r->last_time = get_time(); 156 r->last_loaded = r->loaded; 157 st_r = 1; 158 stat_timer(c); 159 st_r = 0; 160 if (connection_disappeared(c, count)) 161 return; 162 } 163 } else { 164 struct remaining_info *r = &c->prg; 165 if (r->timer) { 166 kill_timer(r->timer); 167 r->timer = NULL; 168 } 169 } 170 foreach (struct status, stat, lstat, c->statuss) { 171 stat->state = state; 172 stat->prev_error = c->prev_error; 173 } 174 if (state >= 0) 175 send_connection_info(c); 176 } 177 178 static struct k_conn * 179 is_host_on_keepalive_list(struct connection *c) 180 { 181 char *ho = (char *)get_keepalive_id(c->url); 182 const int po = get_port(c->url); 183 void (*ph)(struct connection *); 184 struct k_conn *h = NULL; 185 struct list_head *lh; 186 if (!(ph = get_protocol_handle(c->url))) 187 return NULL; 188 if (!ho || po < 0) 189 return NULL; 190 foreach (struct k_conn, h, lh, keepalive_connections) 191 if (h->protocol == ph && h->port == po 192 && !strcmp((char *)h->host, ho)) { 193 free(ho); 194 return h; 195 } 196 free(ho); 197 return NULL; 198 } 199 200 int 201 get_keepalive_socket(struct connection *c, int *protocol_data) 202 { 203 struct k_conn *k; 204 int cc; 205 if (c->tries > 0 || c->unrestartable) 206 return -1; 207 if (!(k = is_host_on_keepalive_list(c))) 208 return -1; 209 cc = k->conn; 210 if (protocol_data) 211 *protocol_data = k->protocol_data; 212 freeSSL(c->ssl); 213 c->ssl = k->ssl; 214 memcpy(&c->last_lookup_state, &k->last_lookup_state, 215 sizeof(struct lookup_state)); 216 del_from_list(k); 217 free(k->host); 218 free(k); 219 c->sock1 = cc; 220 if (max_tries == 1) 221 c->tries = -1; 222 c->keepalive = 1; 223 return 0; 224 } 225 226 static int 227 abort_all_keepalive_connections(void) 228 { 229 int did_something = 0; 230 while (!list_empty(keepalive_connections)) { 231 del_keepalive_socket( 232 list_struct(keepalive_connections.next, struct k_conn)); 233 did_something = 1; 234 } 235 check_keepalive_connections(); 236 return did_something; 237 } 238 239 static void 240 free_connection_data(struct connection *c) 241 { 242 struct h_conn *h; 243 int rs; 244 if (c->sock1 != -1) 245 set_handlers(c->sock1, NULL, NULL, NULL); 246 close_socket(&c->sock2); 247 if (c->pid) { 248 EINTRLOOP(rs, kill(c->pid, SIGINT)); 249 EINTRLOOP(rs, kill(c->pid, SIGTERM)); 250 EINTRLOOP(rs, kill(c->pid, SIGKILL)); 251 c->pid = 0; 252 } 253 if (!c->running) 254 internal("connection already suspended"); 255 c->running = 0; 256 if (c->dnsquery) 257 kill_dns_request(&c->dnsquery); 258 free(c->buffer); 259 free(c->newconn); 260 free(c->info); 261 c->buffer = NULL; 262 c->newconn = NULL; 263 c->info = NULL; 264 clear_connection_timeout(c); 265 if (--active_connections < 0) { 266 internal("active connections underflow"); 267 active_connections = 0; 268 } 269 if (c->state != S_WAIT) { 270 if ((h = is_host_on_list(c))) { 271 if (!--h->conn) { 272 del_from_list(h); 273 free(h->host); 274 free(h); 275 } 276 } else 277 internal("suspending connection that is not on the " 278 "list (state %d)", 279 c->state); 280 } 281 } 282 283 static void 284 send_connection_info(struct connection *c) 285 { 286 if (!list_empty(c->statuss)) { 287 const int st = c->state; 288 tcount count = c->count; 289 struct list_head *lstat = c->statuss.next; 290 while (1) { 291 int e; 292 struct status *xstat = 293 list_struct(lstat, struct status); 294 xstat->ce = c->cache; 295 lstat = lstat->next; 296 e = lstat == &c->statuss; 297 if (xstat->end) 298 xstat->end(xstat, xstat->data); 299 if (e || (st >= 0 && connection_disappeared(c, count))) 300 return; 301 } 302 } 303 } 304 305 static void 306 del_connection(struct connection *c) 307 { 308 struct cache_entry *ce = c->cache; 309 if (ce) 310 ce->refcount++; 311 del_from_list(c); 312 send_connection_info(c); 313 if (ce) 314 ce->refcount--; 315 if (c->detached) { 316 if (ce && !ce->url[0] && !is_entry_used(ce) && !ce->refcount) 317 delete_cache_entry(ce); 318 } else if (ce) 319 trim_cache_entry(ce); 320 free(c->url); 321 free(c->prev_url); 322 free(c->ssl); 323 free(c); 324 } 325 326 void 327 add_keepalive_socket(struct connection *c, uttime timeout, int protocol_data) 328 { 329 struct k_conn *k; 330 int rs; 331 free_connection_data(c); 332 if (c->sock1 == -1) { 333 internal("keepalive connection not connected"); 334 goto del; 335 } 336 k = xmalloc(sizeof(struct k_conn)); 337 if (c->netcfg_stamp != netcfg_stamp || ssl_not_reusable(c->ssl) 338 || (k->port = get_port(c->url)) == -1 339 || !(k->protocol = get_protocol_handle(c->url)) 340 || !(k->host = get_keepalive_id(c->url))) { 341 free(k); 342 del_connection(c); 343 goto clos; 344 } 345 k->conn = c->sock1; 346 k->timeout = timeout; 347 k->add_time = get_absolute_time(); 348 k->protocol_data = protocol_data; 349 k->ssl = c->ssl; 350 c->ssl = NULL; 351 memcpy(&k->last_lookup_state, &c->last_lookup_state, 352 sizeof(struct lookup_state)); 353 add_to_list(keepalive_connections, k); 354 del: 355 del_connection(c); 356 register_bottom_half(check_queue, NULL); 357 return; 358 clos: 359 EINTRLOOP(rs, close(c->sock1)); 360 register_bottom_half(check_queue, NULL); 361 } 362 363 static void 364 del_keepalive_socket(struct k_conn *kc) 365 { 366 int rs; 367 del_from_list(kc); 368 freeSSL(kc->ssl); 369 EINTRLOOP(rs, close(kc->conn)); 370 free(kc->host); 371 free(kc); 372 } 373 374 static struct timer *keepalive_timeout = NULL; 375 376 static void 377 keepalive_timer(void *x) 378 { 379 keepalive_timeout = NULL; 380 check_keepalive_connections(); 381 } 382 383 static void 384 check_keepalive_connections(void) 385 { 386 struct k_conn *kc = NULL; 387 struct list_head *lkc; 388 uttime ct = get_absolute_time(); 389 int p = 0; 390 if (keepalive_timeout) { 391 kill_timer(keepalive_timeout); 392 keepalive_timeout = NULL; 393 } 394 foreach (struct k_conn, kc, lkc, keepalive_connections) { 395 if (can_read(kc->conn) || ct - kc->add_time > kc->timeout) { 396 lkc = lkc->prev; 397 del_keepalive_socket(kc); 398 } else 399 p++; 400 } 401 for (; p > MAX_KEEPALIVE_CONNECTIONS; p--) 402 if (!list_empty(keepalive_connections)) 403 del_keepalive_socket(list_struct( 404 keepalive_connections.prev, struct k_conn)); 405 else 406 internal("keepalive list empty"); 407 if (!list_empty(keepalive_connections)) 408 keepalive_timeout = 409 install_timer(KEEPALIVE_CHECK_TIME, keepalive_timer, NULL); 410 } 411 412 static void 413 add_to_queue(struct connection *c) 414 { 415 struct connection *cc = NULL; 416 struct list_head *lcc; 417 int pri = getpri(c); 418 foreach (struct connection, cc, lcc, queue) 419 if (getpri(cc) > pri) 420 break; 421 add_before_list_entry(lcc, &c->list_entry); 422 } 423 424 static void 425 sort_queue(void) 426 { 427 struct connection *c = NULL, *n; 428 struct list_head *lc; 429 int swp; 430 do { 431 swp = 0; 432 foreach (struct connection, c, lc, queue) 433 if (c->list_entry.next != &queue) { 434 n = list_struct(c->list_entry.next, 435 struct connection); 436 if (getpri(n) < getpri(c)) { 437 del_from_list(c); 438 add_after_pos(n, c); 439 swp = 1; 440 } 441 } 442 } while (swp); 443 } 444 445 static void 446 interrupt_connection(struct connection *c) 447 { 448 freeSSL(c->ssl); 449 c->ssl = NULL; 450 close_socket(&c->sock1); 451 free_connection_data(c); 452 } 453 454 static void 455 suspend_connection(struct connection *c) 456 { 457 interrupt_connection(c); 458 setcstate(c, S_WAIT); 459 } 460 461 static int 462 try_to_suspend_connection(struct connection *c, unsigned char *ho) 463 { 464 int pri = getpri(c); 465 struct connection *d = NULL; 466 struct list_head *ld; 467 foreachback (struct connection, d, ld, queue) { 468 if (getpri(d) <= pri) 469 return -1; 470 if (d->state == S_WAIT) 471 continue; 472 if (d->unrestartable == 2 && getpri(d) < PRI_CANCEL) 473 continue; 474 if (ho) { 475 unsigned char *h; 476 if (!(h = get_host_name(d->url))) 477 continue; 478 if (strcmp((const char *)h, (const char *)ho)) { 479 free(h); 480 continue; 481 } 482 free(h); 483 } 484 suspend_connection(d); 485 return 0; 486 } 487 return -1; 488 } 489 490 int 491 is_noproxy_url(unsigned char *url) 492 { 493 unsigned char *host = get_host_name(url); 494 if (!proxies.only_proxies) { 495 unsigned char *np = proxies.no_proxy; 496 int host_l = (int)strlen(cast_const_char host); 497 if (*np) 498 while (1) { 499 int l = (int)strcspn(cast_const_char np, ","); 500 if (l > host_l) 501 goto no_match; 502 if (l < host_l && host[host_l - l - 1] != '.') 503 goto no_match; 504 if (casecmp(np, host + (host_l - l), l)) 505 goto no_match; 506 free(host); 507 return 1; 508 no_match: 509 if (!np[l]) 510 break; 511 np += l + 1; 512 } 513 } 514 free(host); 515 return 0; 516 } 517 518 static void 519 run_connection(struct connection *c) 520 { 521 struct h_conn *hc; 522 void (*func)(struct connection *); 523 if (c->running) { 524 internal("connection already running"); 525 return; 526 } 527 528 memset(&c->last_lookup_state, 0, sizeof(struct lookup_state)); 529 530 if (is_noproxy_url(remove_proxy_prefix(c->url))) { 531 c->socks_proxy[0] = 0; 532 c->dns_append[0] = 0; 533 } else { 534 safe_strncpy((unsigned char *)c->socks_proxy, 535 proxies.socks_proxy, sizeof(c->socks_proxy)); 536 safe_strncpy(c->dns_append, proxies.dns_append, 537 sizeof(c->dns_append)); 538 } 539 540 if (proxies.only_proxies && !is_proxy_url(c->url) 541 && casecmp(c->url, cast_uchar "data:", 5) 542 && (!*c->socks_proxy || url_bypasses_socks(c->url))) { 543 setcstate(c, S_NO_PROXY); 544 del_connection(c); 545 return; 546 } 547 548 if (!(func = get_protocol_handle(c->url))) { 549 s_bad_url: 550 if (is_proxy_url(c->url)) 551 setcstate(c, S_BAD_PROXY); 552 else 553 setcstate(c, S_BAD_URL); 554 del_connection(c); 555 return; 556 } 557 if (!(hc = is_host_on_list(c))) { 558 hc = xmalloc(sizeof(struct h_conn)); 559 if (!(hc->host = get_host_name(c->url))) { 560 free(hc); 561 goto s_bad_url; 562 } 563 hc->conn = 0; 564 add_to_list(h_conns, hc); 565 } 566 hc->conn++; 567 active_connections++; 568 c->keepalive = 0; 569 c->running = 1; 570 func(c); 571 } 572 573 static int 574 is_connection_seekable(struct connection *c) 575 { 576 unsigned char *protocol = get_protocol_name(c->url); 577 if (!casestrcmp(protocol, cast_uchar "http") 578 || !casestrcmp(protocol, cast_uchar "https") 579 || !casestrcmp(protocol, cast_uchar "proxy")) { 580 unsigned char *d; 581 free(protocol); 582 if (!c->cache || !c->cache->head) 583 return 1; 584 d = parse_http_header(c->cache->head, 585 cast_uchar "Accept-Ranges", NULL); 586 if (d) { 587 free(d); 588 return 1; 589 } 590 return 0; 591 } 592 if (!casestrcmp(protocol, cast_uchar "ftp")) { 593 free(protocol); 594 return 1; 595 } 596 free(protocol); 597 return 0; 598 } 599 600 int 601 is_connection_restartable(struct connection *c) 602 { 603 return !(c->unrestartable >= 2 604 || (c->tries + 1 >= (max_tries ? max_tries : 1000))); 605 } 606 607 int 608 is_last_try(struct connection *c) 609 { 610 int is_restartable; 611 c->tries++; 612 is_restartable = is_connection_restartable(c) && c->tries < 10; 613 c->tries--; 614 return !is_restartable; 615 } 616 617 void 618 retry_connection(struct connection *c) 619 { 620 interrupt_connection(c); 621 if (!is_connection_restartable(c)) { 622 del_connection(c); 623 register_bottom_half(check_queue, NULL); 624 } else { 625 c->tries++; 626 c->prev_error = c->state; 627 run_connection(c); 628 } 629 } 630 631 void 632 abort_connection(struct connection *c) 633 { 634 if (c->running) 635 interrupt_connection(c); 636 del_connection(c); 637 register_bottom_half(check_queue, NULL); 638 } 639 640 static int 641 try_connection(struct connection *c) 642 { 643 struct h_conn *hc = NULL; 644 if ((hc = is_host_on_list(c))) { 645 if (hc->conn >= max_connections_to_host) { 646 if (try_to_suspend_connection(c, hc->host)) 647 return 0; 648 else 649 return -1; 650 } 651 } 652 if (active_connections >= max_connections) { 653 if (try_to_suspend_connection(c, NULL)) 654 return 0; 655 else 656 return -1; 657 } 658 run_connection(c); 659 return 1; 660 } 661 662 void 663 check_queue(void *dummy) 664 { 665 struct connection *c = NULL; 666 struct list_head *lc; 667 again: 668 check_keepalive_connections(); 669 foreach (struct connection, c, lc, queue) { 670 struct connection *d = NULL; 671 struct list_head *ld; 672 const int cp = getpri(c); 673 foreachfrom (struct connection, d, ld, queue, &c->list_entry) { 674 if (getpri(d) != cp) 675 break; 676 if (!d->state && is_host_on_keepalive_list(d)) 677 if (try_connection(d)) 678 goto again; 679 } 680 foreachfrom (struct connection, d, ld, queue, &c->list_entry) { 681 if (getpri(d) != cp) 682 break; 683 if (!d->state) 684 if (try_connection(d)) 685 goto again; 686 } 687 lc = ld->prev; 688 } 689 again2: 690 foreachback (struct connection, c, lc, queue) { 691 if (getpri(c) < PRI_CANCEL) 692 break; 693 if (c->state == S_WAIT) { 694 setcstate(c, S_INTERRUPTED); 695 del_connection(c); 696 goto again2; 697 } else if (c->est_length 698 > (long)memory_cache_size * MAX_CACHED_OBJECT 699 || c->from > (long)memory_cache_size 700 * MAX_CACHED_OBJECT) { 701 setcstate(c, S_INTERRUPTED); 702 abort_connection(c); 703 goto again2; 704 } 705 } 706 } 707 708 unsigned char * 709 get_proxy_string(unsigned char *url) 710 { 711 if (is_noproxy_url(url)) 712 return NULL; 713 if (*proxies.http_proxy && !casecmp(url, cast_uchar "http://", 7)) 714 return proxies.http_proxy; 715 if (*proxies.https_proxy && !casecmp(url, cast_uchar "https://", 8)) 716 return proxies.https_proxy; 717 return NULL; 718 } 719 720 unsigned char * 721 get_proxy(unsigned char *url) 722 { 723 unsigned char *proxy = get_proxy_string(url); 724 unsigned char *u; 725 u = stracpy(cast_uchar ""); 726 if (proxy) { 727 add_to_strn(&u, cast_uchar "proxy://"); 728 add_to_strn(&u, proxy); 729 add_to_strn(&u, cast_uchar "/"); 730 } 731 add_to_strn(&u, url); 732 return u; 733 } 734 735 int 736 is_proxy_url(unsigned char *url) 737 { 738 return !casecmp(url, cast_uchar "proxy://", 8); 739 } 740 741 unsigned char * 742 remove_proxy_prefix(unsigned char *url) 743 { 744 unsigned char *x = NULL; 745 if (is_proxy_url(url)) 746 x = get_url_data(url); 747 if (!x) 748 x = url; 749 return x; 750 } 751 752 int 753 get_allow_flags(unsigned char *url) 754 { 755 return !casecmp(url, cast_uchar "smb://", 6) ? ALLOW_SMB 756 : !casecmp(url, cast_uchar "file://", 7) ? ALLOW_FILE 757 : 0; 758 } 759 760 int 761 disallow_url(unsigned char *url, int allow_flags) 762 { 763 if (!casecmp(url, cast_uchar "smb://", 6) && !(allow_flags & ALLOW_SMB)) 764 return S_SMB_NOT_ALLOWED; 765 if (!casecmp(url, cast_uchar "file://", 7) 766 && !(allow_flags & ALLOW_FILE)) 767 return S_FILE_NOT_ALLOWED; 768 return 0; 769 } 770 771 /* prev_url is a pointer to previous url or NULL */ 772 /* prev_url will NOT be deallocated */ 773 void 774 load_url(unsigned char *url, unsigned char *prev_url, struct status *stat, 775 int pri, int no_cache, int no_compress, int allow_flags, 776 off_t position) 777 { 778 struct cache_entry *e = NULL; 779 struct connection *c = NULL; 780 struct list_head *lc; 781 unsigned char *u; 782 int must_detach = 0; 783 const int err = disallow_url(url, allow_flags); 784 785 if (stat) { 786 stat->c = NULL; 787 stat->ce = NULL; 788 stat->state = S_OUT_OF_MEM; 789 stat->prev_error = 0; 790 stat->pri = pri; 791 } 792 if (err) { 793 if (stat) { 794 stat->state = err; 795 if (stat->end) 796 stat->end(stat, stat->data); 797 } 798 goto ret; 799 } 800 if (no_cache <= NC_CACHE && !find_in_cache(url, &e)) { 801 if (e->incomplete) { 802 e->refcount--; 803 goto skip_cache; 804 } 805 if (!aggressive_cache && no_cache > NC_ALWAYS_CACHE) { 806 if (e->expire_time && e->expire_time < time(NULL)) { 807 if (no_cache < NC_IF_MOD) 808 no_cache = NC_IF_MOD; 809 e->refcount--; 810 goto skip_cache; 811 } 812 } 813 if (no_compress) { 814 unsigned char *enc; 815 enc = parse_http_header( 816 e->head, cast_uchar "Content-Encoding", NULL); 817 if (enc) { 818 free(enc); 819 e->refcount--; 820 must_detach = 1; 821 goto skip_cache; 822 } 823 } 824 if (stat) { 825 stat->ce = e; 826 stat->state = S__OK; 827 if (stat->end) 828 stat->end(stat, stat->data); 829 } 830 e->refcount--; 831 goto ret; 832 } 833 skip_cache: 834 if (is_proxy_url(url)) { 835 if (stat) { 836 stat->state = S_BAD_URL; 837 if (stat->end) 838 stat->end(stat, stat->data); 839 } 840 goto ret; 841 } 842 u = get_proxy(url); 843 foreach (struct connection, c, lc, queue) 844 if (!c->detached 845 && !strcmp((const char *)c->url, (const char *)u)) { 846 if (c->from < position) 847 continue; 848 if (no_compress && !c->no_compress) { 849 unsigned char *enc; 850 if ((c->state >= S_WAIT && c->state < S_TRANS) 851 || !c->cache) { 852 must_detach = 1; 853 break; 854 } 855 enc = parse_http_header( 856 c->cache->head, 857 cast_uchar "Content-Encoding", NULL); 858 if (enc) { 859 free(enc); 860 must_detach = 1; 861 break; 862 } 863 } 864 free(u); 865 if (getpri(c) > pri) { 866 del_from_list(c); 867 c->pri[pri]++; 868 add_to_queue(c); 869 register_bottom_half(check_queue, NULL); 870 } else 871 c->pri[pri]++; 872 if (stat) { 873 stat->prg = &c->prg; 874 stat->c = c; 875 stat->ce = c->cache; 876 add_to_list(c->statuss, stat); 877 setcstate(c, c->state); 878 } 879 goto ret; 880 } 881 c = mem_calloc(sizeof(struct connection)); 882 c->count = connection_count++; 883 c->url = u; 884 c->prev_url = stracpy(prev_url); 885 c->running = 0; 886 c->prev_error = 0; 887 if (position || must_detach) 888 c->from = position; 889 else if (no_cache >= NC_IF_MOD || !e) 890 c->from = 0; 891 else { 892 struct fragment *frag = NULL; 893 struct list_head *lfrag; 894 c->from = 0; 895 foreach (struct fragment, frag, lfrag, e->frag) { 896 if (frag->offset != c->from) 897 break; 898 c->from += frag->length; 899 } 900 } 901 memset(c->pri, 0, sizeof c->pri); 902 c->pri[pri] = 1; 903 c->no_cache = no_cache; 904 c->sock1 = c->sock2 = -1; 905 c->dnsquery = NULL; 906 c->tries = 0; 907 c->netcfg_stamp = netcfg_stamp; 908 init_list(c->statuss); 909 c->info = NULL; 910 c->buffer = NULL; 911 c->newconn = NULL; 912 c->cache = NULL; 913 c->est_length = -1; 914 c->unrestartable = 0; 915 c->no_compress = 916 http_options.no_compression || no_compress || dmp == D_SOURCE; 917 c->prg.timer = NULL; 918 c->timer = NULL; 919 if (position || must_detach) { 920 if (new_cache_entry(cast_uchar "", &c->cache)) { 921 free(c->url); 922 free(c->prev_url); 923 free(c); 924 if (stat) { 925 stat->state = S_OUT_OF_MEM; 926 if (stat->end) 927 stat->end(stat, stat->data); 928 } 929 goto ret; 930 } 931 c->cache->refcount--; 932 detach_cache_entry(c->cache); 933 c->detached = 2; 934 } 935 if (stat) { 936 stat->prg = &c->prg; 937 stat->c = c; 938 stat->ce = NULL; 939 add_to_list(c->statuss, stat); 940 } 941 add_to_queue(c); 942 setcstate(c, S_WAIT); 943 register_bottom_half(check_queue, NULL); 944 945 ret: 946 return; 947 } 948 949 void 950 change_connection(struct status *oldstat, struct status *newstat, int newpri) 951 { 952 struct connection *c; 953 const int oldpri = oldstat->pri; 954 if (oldstat->state < 0) { 955 if (newstat) { 956 struct cache_entry *ce = oldstat->ce; 957 if (ce) 958 ce->refcount++; 959 newstat->ce = oldstat->ce; 960 newstat->state = oldstat->state; 961 newstat->prev_error = oldstat->prev_error; 962 if (newstat->end) 963 newstat->end(newstat, newstat->data); 964 if (ce) 965 ce->refcount--; 966 } 967 return; 968 } 969 c = oldstat->c; 970 if (--c->pri[oldpri] < 0) { 971 internal("priority counter underflow"); 972 c->pri[oldpri] = 0; 973 } 974 c->pri[newpri]++; 975 del_from_list(oldstat); 976 oldstat->state = S_INTERRUPTED; 977 if (newstat) { 978 newstat->prg = &c->prg; 979 add_to_list(c->statuss, newstat); 980 newstat->state = c->state; 981 newstat->prev_error = c->prev_error; 982 newstat->pri = newpri; 983 newstat->c = c; 984 newstat->ce = c->cache; 985 } 986 if (c->detached && !newstat) { 987 setcstate(c, S_INTERRUPTED); 988 abort_connection(c); 989 } 990 sort_queue(); 991 register_bottom_half(check_queue, NULL); 992 } 993 994 void 995 detach_connection(struct status *stat, off_t pos, int want_to_restart, 996 int dont_check_refcount) 997 { 998 struct connection *c; 999 int i, n_users; 1000 off_t l; 1001 if (stat->state < 0) 1002 return; 1003 c = stat->c; 1004 if (c->no_compress && want_to_restart) 1005 return; 1006 if (!c->cache || (!dont_check_refcount && c->cache->refcount)) 1007 return; 1008 want_to_restart |= pos > c->from && is_connection_seekable(c); 1009 if (c->detached) 1010 goto detach_done; 1011 if (c->est_length == -1) 1012 l = c->from; 1013 else 1014 l = c->est_length; 1015 if (!dont_check_refcount 1016 && l < (long)memory_cache_size * MAX_CACHED_OBJECT 1017 && !want_to_restart) 1018 return; 1019 n_users = 0; 1020 for (i = 0; i < PRI_CANCEL; i++) 1021 n_users += c->pri[i]; 1022 if (!n_users) 1023 internal("detaching free connection"); 1024 if (n_users != 1) 1025 return; 1026 shrink_memory(SH_CHECK_QUOTA); 1027 detach_cache_entry(c->cache); 1028 c->detached = 1; 1029 detach_done: 1030 free_entry_to(c->cache, pos); 1031 1032 if (c->detached < 2 && want_to_restart) { 1033 int running = c->running; 1034 c->no_compress = 1; 1035 if (running) 1036 interrupt_connection(c); 1037 c->from = pos; 1038 if (running) 1039 run_connection(c); 1040 c->detached = 2; 1041 } 1042 } 1043 1044 static uttime 1045 get_timeout_value(struct connection *c) 1046 { 1047 uttime t; 1048 if (c->state == S_CONN || c->state == S_CONN_ANOTHER) 1049 t = timeout_multiple_addresses 1050 * (c->tries < 1 ? 1 : c->tries + 1); 1051 else if (c->unrestartable) 1052 t = unrestartable_receive_timeout; 1053 else 1054 t = receive_timeout; 1055 t *= 500; 1056 return t; 1057 } 1058 1059 static void 1060 connection_timeout(void *c_) 1061 { 1062 struct connection *c = (struct connection *)c_; 1063 c->timer = NULL; 1064 if (c->state == S_CONN || c->state == S_CONN_ANOTHER) { 1065 retry_connect(c, get_error_from_errno(ETIMEDOUT), 0); 1066 return; 1067 } 1068 setcstate(c, S_TIMEOUT); 1069 retry_connection(c); 1070 } 1071 1072 static void 1073 connection_timeout_1(void *c_) 1074 { 1075 struct connection *c = (struct connection *)c_; 1076 c->timer = install_timer(get_timeout_value(c), connection_timeout, c); 1077 } 1078 1079 void 1080 clear_connection_timeout(struct connection *c) 1081 { 1082 if (c->timer) { 1083 kill_timer(c->timer); 1084 c->timer = NULL; 1085 } 1086 } 1087 1088 void 1089 set_connection_timeout(struct connection *c) 1090 { 1091 clear_connection_timeout(c); 1092 c->timer = install_timer(get_timeout_value(c), connection_timeout_1, c); 1093 } 1094 1095 void 1096 set_connection_timeout_keepal(struct connection *c) 1097 { 1098 if (c->keepalive && !c->unrestartable) { 1099 clear_connection_timeout(c); 1100 c->timer = install_timer(timeout_multiple_addresses * 1000, 1101 connection_timeout, c); 1102 return; 1103 } 1104 set_connection_timeout(c); 1105 } 1106 1107 void 1108 abort_all_connections(void) 1109 { 1110 while (!list_empty(queue)) { 1111 struct connection *c = 1112 list_struct(queue.next, struct connection); 1113 setcstate(c, S_INTERRUPTED); 1114 abort_connection(c); 1115 } 1116 abort_all_keepalive_connections(); 1117 } 1118 1119 int 1120 abort_background_connections(void) 1121 { 1122 int did_something = 0; 1123 struct connection *c = NULL; 1124 struct list_head *lc; 1125 again: 1126 foreach (struct connection, c, lc, queue) { 1127 if (getpri(c) >= PRI_CANCEL) { 1128 setcstate(c, S_INTERRUPTED); 1129 abort_connection(c); 1130 did_something = 1; 1131 goto again; 1132 } 1133 } 1134 return did_something | abort_all_keepalive_connections(); 1135 } 1136 1137 int 1138 is_entry_used(struct cache_entry *e) 1139 { 1140 struct connection *c = NULL; 1141 struct list_head *lc; 1142 foreach (struct connection, c, lc, queue) 1143 if (c->cache == e) 1144 return 1; 1145 return 0; 1146 } 1147 1148 struct blacklist_entry { 1149 list_entry_1st; 1150 int flags; 1151 unsigned char host[1]; 1152 }; 1153 1154 static struct list_head blacklist = { &blacklist, &blacklist }; 1155 1156 void 1157 add_blacklist_entry(unsigned char *host, int flags) 1158 { 1159 struct blacklist_entry *b = NULL; 1160 struct list_head *lb; 1161 size_t sl; 1162 foreach (struct blacklist_entry, b, lb, blacklist) 1163 if (!casestrcmp(host, b->host)) { 1164 b->flags |= flags; 1165 return; 1166 } 1167 sl = strlen((const char *)host); 1168 if (sl > INT_MAX - sizeof(struct blacklist_entry)) 1169 overalloc(); 1170 b = xmalloc(sizeof(struct blacklist_entry) + sl); 1171 b->flags = flags; 1172 strcpy((char *)b->host, (const char *)host); 1173 add_to_list(blacklist, b); 1174 } 1175 1176 void 1177 del_blacklist_entry(unsigned char *host, int flags) 1178 { 1179 struct blacklist_entry *b = NULL; 1180 struct list_head *lb; 1181 foreach (struct blacklist_entry, b, lb, blacklist) 1182 if (!casestrcmp(host, b->host)) { 1183 b->flags &= ~flags; 1184 if (!b->flags) { 1185 del_from_list(b); 1186 free(b); 1187 } 1188 return; 1189 } 1190 } 1191 1192 int 1193 get_blacklist_flags(unsigned char *host) 1194 { 1195 struct blacklist_entry *b = NULL; 1196 struct list_head *lb; 1197 foreach (struct blacklist_entry, b, lb, blacklist) 1198 if (!casestrcmp(host, b->host)) 1199 return b->flags; 1200 return 0; 1201 } 1202 1203 void 1204 free_blacklist(void) 1205 { 1206 free_list(struct blacklist_entry, blacklist); 1207 }