]> git.ipfire.org Git - thirdparty/squid.git/blame - src/structs.h
Unwrap globals.h
[thirdparty/squid.git] / src / structs.h
CommitLineData
a8258824 1
9cef6668 2/*
b5638623 3 * $Id: structs.h,v 1.402 2001/10/08 16:18:33 hno Exp $
9cef6668 4 *
5 *
2b6662ba 6 * SQUID Web Proxy Cache http://www.squid-cache.org/
9cef6668 7 * ----------------------------------------------------------
8 *
2b6662ba 9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
9cef6668 17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
31 *
32 */
33
b5638623 34#ifndef SQUID_STRUCTS_H
35#define SQUID_STRUCTS_H
36
0009ba2f 37#include "config.h"
38#include "splay.h"
39
0f1bc304 40struct _dlink_node {
41 void *data;
42 dlink_node *prev;
43 dlink_node *next;
44};
45
46struct _dlink_list {
47 dlink_node *head;
48 dlink_node *tail;
49};
50
cf86841e 51struct _acl_user_data {
0009ba2f 52 splayNode *names;
53 struct {
54 unsigned int case_insensitive:1;
55 unsigned int required:1;
56 } flags;
57};
58
60d096f4 59struct _acl_user_ip_data {
60 size_t max;
61 struct {
62 unsigned int strict:1;
63 } flags;
64};
0009ba2f 65
a8258824 66struct _acl_ip_data {
67 struct in_addr addr1; /* if addr2 non-zero then its a range */
68 struct in_addr addr2;
69 struct in_addr mask;
1a106e18 70 acl_ip_data *next; /* used for parsing, not for storing */
a8258824 71};
72
73struct _acl_time_data {
74 int weekbits;
75 int start;
76 int stop;
74fbf3c9 77 acl_time_data *next;
a8258824 78};
79
80struct _acl_name_list {
81 char name[ACL_NAME_SZ];
74fbf3c9 82 acl_name_list *next;
a8258824 83};
84
94439e4e 85struct _acl_proxy_auth_match_cache {
86 dlink_node link;
87 int matchrv;
88 void *acl_data;
89};
90
91struct _auth_user_hash_pointer {
92 /* first two items must be same as hash_link */
93 char *key;
94 auth_user_hash_pointer *next;
95 auth_user_t *auth_user;
96 dlink_node link; /* other hash entries that point to the same auth_user */
97};
98
60d096f4 99struct _auth_user_ip_t {
100 dlink_node node;
101 /* IP addr this user authenticated from */
102 struct in_addr ipaddr;
103 time_t ip_expiretime;
104};
105
94439e4e 106struct _auth_user_t {
73e67ee0 107 /* extra fields for proxy_auth */
94439e4e 108 /* this determines what scheme owns the user data. */
109 auth_type_t auth_type;
110 /* the index +1 in the authscheme_list to the authscheme entry */
111 int auth_module;
112 /* we only have one username associated with a given auth_user struct */
113 auth_user_hash_pointer *usernamehash;
114 /* we may have many proxy-authenticate strings that decode to the same user */
115 dlink_list proxy_auth_list;
116 dlink_list proxy_match_cache;
bd507204 117 /* what ip addresses has this user been seen at?, plus a list length cache */
60d096f4 118 dlink_list ip_list;
119 size_t ipcount;
73e67ee0 120 long expiretime;
94439e4e 121 /* how many references are outstanding to this instance */
122 size_t references;
123 /* the auth scheme has it's own private data area */
124 void *scheme_data;
125 /* the auth_user_request structures that link to this. Yes it could be a splaytree
126 * but how many requests will a single username have in parallel? */
127 dlink_list requests;
128};
129
130struct _auth_user_request_t {
131 /* this is the object passed around by client_side and acl functions */
132 /* it has request specific data, and links to user specific data */
133 /* the user */
134 auth_user_t *auth_user;
135 /* return a message on the 407 error pages */
066ed5c1 136 char *message;
94439e4e 137 /* any scheme specific request related data */
138 void *scheme_data;
139 /* how many 'processes' are working on this data */
140 size_t references;
141};
142
143
144/*
145 * This defines an auth scheme module
146 */
147
148struct _authscheme_entry {
149 char *typestr;
150 AUTHSACTIVE *Active;
151 AUTHSADDHEADER *AddHeader;
152 AUTHSADDTRAILER *AddTrailer;
153 AUTHSAUTHED *authenticated;
154 AUTHSAUTHUSER *authAuthenticate;
2d70df72 155 AUTHSCONFIGURED *configured;
94439e4e 156 AUTHSDUMP *dump;
157 AUTHSFIXERR *authFixHeader;
158 AUTHSFREE *FreeUser;
159 AUTHSFREECONFIG *freeconfig;
160 AUTHSUSERNAME *authUserUsername;
161 AUTHSONCLOSEC *oncloseconnection; /*optional */
60d096f4 162 AUTHSCONNLASTHEADER *authConnLastHeader;
94439e4e 163 AUTHSDECODE *decodeauth;
164 AUTHSDIRECTION *getdirection;
165 AUTHSPARSE *parse;
166 AUTHSINIT *init;
167 AUTHSREQFREE *requestFree;
168 AUTHSSHUTDOWN *donefunc;
169 AUTHSSTART *authStart;
170 AUTHSSTATS *authStats;
171};
172
173/*
174 * This is a configured auth scheme
175 */
176
177/* private data types */
178struct _authScheme {
179 /* pointer to the authscheme_list's string entry */
180 char *typestr;
181 /* the scheme id in the authscheme_list */
182 int Id;
183 /* the scheme's configuration details. */
184 void *scheme_data;
ec878047 185};
186
a8258824 187struct _acl_deny_info_list {
02922e76 188 int err_page_id;
189 char *err_page_name;
74fbf3c9 190 acl_name_list *acl_list;
191 acl_deny_info_list *next;
a8258824 192};
193
66c75c41 194#if USE_ARP_ACL
cbe3a719 195
66c75c41 196struct _acl_arp_data {
74b7003b 197 char eth[6];
66c75c41 198};
cbe3a719 199
66c75c41 200#endif
201
02922e76 202struct _String {
203 /* never reference these directly! */
a369131d 204 unsigned short int size; /* buffer size; 64K limit */
205 unsigned short int len; /* current length */
02922e76 206 char *buf;
207};
208
6bccf575 209struct _header_mangler {
210 acl_access *access_list;
211 char *replacement;
212};
213
a560ee93 214struct _body_size {
215 dlink_node node;
216 acl_access *access_list;
217 size_t maxsize;
218};
219
ccf44862 220struct _http_version_t {
221 unsigned int major;
222 unsigned int minor;
223};
224
1df370e3 225#if SQUID_SNMP
43d4303e 226
a9ddb359 227struct _snmp_request_t {
5e29a294 228 u_char *buf;
229 u_char *outbuf;
2ac76861 230 int len;
231 int sock;
232 long reqid;
233 int outlen;
234 struct sockaddr_in from;
235 struct snmp_pdu *PDU;
236 aclCheck_t *acl_checklist;
5e29a294 237 u_char *community;
a9ddb359 238};
bdf18524 239
1df370e3 240#endif
a97cfa48 241
a8258824 242struct _acl {
243 char name[ACL_NAME_SZ];
244 squid_acl type;
245 void *data;
246 char *cfgline;
bd05e3e3 247 acl *next;
a8258824 248};
249
250struct _acl_list {
251 int op;
bd05e3e3 252 acl *acl;
253 acl_list *next;
a8258824 254};
255
256struct _acl_access {
257 int allow;
bd05e3e3 258 acl_list *acl_list;
a8258824 259 char *cfgline;
bd05e3e3 260 acl_access *next;
a8258824 261};
262
263struct _aclCheck_t {
bd05e3e3 264 const acl_access *access_list;
a8258824 265 struct in_addr src_addr;
266 struct in_addr dst_addr;
ae2c08a2 267 struct in_addr my_addr;
7e3ce7b9 268 unsigned short my_port;
a8258824 269 request_t *request;
c4ab8329 270 /* for acls that look at reply data */
8e8d4f30 271 HttpReply *reply;
94439e4e 272 ConnStateData *conn; /* hack for ident and NTLM */
273 char rfc931[USER_IDENT_SZ];
274 auth_user_request_t *auth_user_request;
a8258824 275 acl_lookup_state state[ACL_ENUM_MAX];
dba79ac5 276#if SQUID_SNMP
277 char *snmp_community;
278#endif
a8258824 279 PF *callback;
280 void *callback_data;
281};
282
a8258824 283struct _wordlist {
284 char *key;
bd05e3e3 285 wordlist *next;
a8258824 286};
287
288struct _intlist {
289 int i;
bd05e3e3 290 intlist *next;
a8258824 291};
292
8f663d72 293struct _intrange {
294 int i;
295 int j;
296 intrange *next;
297};
298
a8258824 299struct _ushortlist {
300 u_short i;
bd05e3e3 301 ushortlist *next;
a8258824 302};
303
304struct _relist {
305 char *pattern;
306 regex_t regex;
bd05e3e3 307 relist *next;
a8258824 308};
309
7e3ce7b9 310struct _sockaddr_in_list {
311 struct sockaddr_in s;
312 sockaddr_in_list *next;
313};
314
d193a436 315#if USE_SSL
316struct _https_port_list {
317 https_port_list *next;
318 struct sockaddr_in s;
319 char *cert;
320 char *key;
321};
322
323#endif
94439e4e 324
56e64999 325#if DELAY_POOLS
59715b38 326struct _delaySpec {
95e36d02 327 int restore_bps;
328 int max_bytes;
329};
1dfa1d81 330
59715b38 331/* malloc()'d only as far as used (class * sizeof(delaySpec)!
332 * order of elements very important!
333 */
334struct _delaySpecSet {
335 delaySpec aggregate;
336 delaySpec individual;
337 delaySpec network;
338};
339
340struct _delayConfig {
341 unsigned short pools;
342 unsigned short initial;
343 unsigned char *class;
344 delaySpecSet **rates;
345 acl_access **access;
346};
347
56e64999 348#endif
95e36d02 349
6a566b9c 350struct _RemovalPolicySettings {
351 char *type;
352 wordlist *args;
353};
354
a8258824 355struct _SquidConfig {
356 struct {
9906e724 357 size_t maxSize;
a8258824 358 int highWaterMark;
359 int lowWaterMark;
43a70238 360 } Swap;
361 size_t memMaxSize;
a8258824 362 struct {
363 char *relayHost;
364 u_short relayPort;
db1cd23c 365 peer *peer;
a8258824 366 } Wais;
367 struct {
9906e724 368 size_t min;
a8258824 369 int pct;
9906e724 370 size_t max;
a8258824 371 } quickAbort;
6a566b9c 372 RemovalPolicySettings *replPolicy;
373 RemovalPolicySettings *memPolicy;
a8258824 374 time_t referenceAge;
375 time_t negativeTtl;
376 time_t negativeDnsTtl;
377 time_t positiveDnsTtl;
378 time_t shutdownLifetime;
a8258824 379 struct {
380 time_t read;
a8258824 381 time_t lifetime;
382 time_t connect;
3f62decd 383 time_t peer_connect;
a8258824 384 time_t request;
603a02fd 385 time_t pconn;
23d92c64 386 time_t siteSelect;
dc835977 387 time_t deadPeer;
98829f69 388 int icp_query; /* msec */
28993292 389 int icp_query_max; /* msec */
98829f69 390 int mcast_icp_query; /* msec */
3898f57f 391#if USE_IDENT
05832ae1 392 time_t ident;
4fe0e1d0 393#endif
394#if !USE_DNSSERVERS
395 time_t idns_retransmit;
396 time_t idns_query;
3898f57f 397#endif
a8258824 398 } Timeout;
0483b991 399 size_t maxRequestHeaderSize;
400 size_t maxRequestBodySize;
a560ee93 401 dlink_list ReplyBodySize;
a8258824 402 struct {
a8258824 403 u_short icp;
ace287ee 404#if USE_HTCP
405 u_short htcp;
406#endif
1df370e3 407#if SQUID_SNMP
678c6099 408 u_short snmp;
1df370e3 409#endif
a8258824 410 } Port;
7e3ce7b9 411 struct {
412 sockaddr_in_list *http;
1f7c9178 413#if USE_SSL
d193a436 414 https_port_list *https;
1f7c9178 415#endif
7e3ce7b9 416 } Sockaddr;
1df370e3 417#if SQUID_SNMP
2bbd722b 418 struct {
419 char *configFile;
420 char *agentInfo;
2ac237e2 421 } Snmp;
320e9f36 422#endif
eb824054 423#if USE_WCCP
320e9f36 424 struct {
425 struct in_addr router;
eb824054 426 struct in_addr incoming;
427 struct in_addr outgoing;
d20b1cd0 428 int version;
320e9f36 429 } Wccp;
1df370e3 430#endif
53ad48e6 431 char *as_whois_server;
a8258824 432 struct {
433 char *log;
434 char *access;
435 char *store;
436 char *swap;
82839306 437#if USE_USERAGENT_LOG
a8258824 438 char *useragent;
fd2c5549 439#endif
440#if USE_REFERER_LOG
441 char *referer;
225644d7 442#endif
443#if WIP_FWD_LOG
444 char *forward;
82839306 445#endif
a8258824 446 int rotateNumber;
a8258824 447 } Log;
a8258824 448 char *adminEmail;
449 char *effectiveUser;
450 char *effectiveGroup;
451 struct {
82839306 452#if USE_DNSSERVERS
a8258824 453 char *dnsserver;
efd900cb 454#endif
c6d5b87b 455 wordlist *redirect;
82839306 456#if USE_ICMP
a8258824 457 char *pinger;
82839306 458#endif
a3d0a19d 459#if USE_UNLINKD
a8258824 460 char *unlinkd;
a3d0a19d 461#endif
be7d89d4 462 char *diskd;
a8258824 463 } Program;
82839306 464#if USE_DNSSERVERS
a8258824 465 int dnsChildren;
efd900cb 466#endif
a8258824 467 int redirectChildren;
94439e4e 468 time_t authenticateGCInterval;
70a76033 469 time_t authenticateTTL;
470 time_t authenticateIpTTL;
a8258824 471 struct {
13c7936a 472 int single_host;
a8258824 473 char *host;
474 u_short port;
a8258824 475 } Accel;
476 char *appendDomain;
477 size_t appendDomainLen;
478 char *debugOptions;
479 char *pidFilename;
480 char *mimeTablePathname;
0e70aa1e 481 char *etcHostsPath;
a8258824 482 char *visibleHostname;
98829f69 483 char *uniqueHostname;
1f38f50a 484 wordlist *hostnameAliases;
a8258824 485 char *errHtmlText;
486 struct {
487 char *host;
488 char *file;
489 time_t period;
a8258824 490 u_short port;
491 } Announce;
492 struct {
a8258824 493 struct in_addr tcp_outgoing;
494 struct in_addr udp_incoming;
2bbd722b 495 struct in_addr udp_outgoing;
15dcc168 496#if SQUID_SNMP
678c6099 497 struct in_addr snmp_incoming;
2bbd722b 498 struct in_addr snmp_outgoing;
15dcc168 499#endif
a8258824 500 struct in_addr client_netmask;
501 } Addrs;
9906e724 502 size_t tcpRcvBufsz;
503 size_t udpMaxHitObjsz;
a8258824 504 wordlist *hierarchy_stoplist;
505 wordlist *mcast_group_list;
506 wordlist *dns_testname_list;
09c483ec 507 wordlist *dns_nameservers;
40a1495e 508 peer *peers;
509 int npeers;
a8258824 510 struct {
89de058c 511 int size;
a8258824 512 int low;
513 int high;
514 } ipcache;
e55650e3 515 struct {
516 int size;
517 } fqdncache;
a8258824 518 int minDirectHops;
5f84d830 519 int minDirectRtt;
a8258824 520 cachemgr_passwd *passwd_list;
521 struct {
522 int objectsPerBucket;
9906e724 523 size_t avgObjectSize;
524 size_t maxObjectSize;
d20b1cd0 525 size_t minObjectSize;
16689110 526 size_t maxInMemObjSize;
a8258824 527 } Store;
528 struct {
529 int high;
530 int low;
531 time_t period;
532 } Netdb;
533 struct {
534 int log_udp;
82839306 535#if USE_DNSSERVERS
a8258824 536 int res_defnames;
efd900cb 537#endif
a8258824 538 int anonymizer;
539 int client_db;
540 int query_icmp;
88738790 541 int icp_hit_stale;
78f1250a 542 int buffered_logs;
0ab965da 543#if ALLOW_SOURCE_PING
9b312a19 544 int source_ping;
0ab965da 545#endif
9b312a19 546 int common_log;
547 int log_mime_hdrs;
17a0a4ee 548 int log_fqdn;
549 int announce;
550 int accel_with_proxy;
3f6c0fb2 551 int mem_pools;
194dd3b8 552 int test_reachability;
ea285003 553 int half_closed_clients;
9f60cfdf 554#if HTTP_VIOLATIONS
465dc415 555 int reload_into_ims;
9f60cfdf 556#endif
b540e168 557 int offline;
c68e9c6b 558 int redir_rewrites_host;
9b094667 559 int prefer_direct;
168dfda9 560 int nonhierarchical_direct;
bcbc11b0 561 int strip_query_terms;
07476a7f 562 int redirector_bypass;
9bc73deb 563 int ignore_unknown_nameservers;
efd900cb 564 int client_pconns;
565 int server_pconns;
7e3ce7b9 566#if USE_CACHE_DIGESTS
567 int digest_generation;
568#endif
890b0fa8 569 int log_ip_on_direct;
7613d09c 570 int ie_refresh;
f66a9ef4 571 int vary_ignore_expire;
3d15e2d7 572 int pipeline_prefetch;
17a0a4ee 573 } onoff;
bd05e3e3 574 acl *aclList;
a8258824 575 struct {
bd05e3e3 576 acl_access *http;
577 acl_access *icp;
578 acl_access *miss;
579 acl_access *NeverDirect;
580 acl_access *AlwaysDirect;
581 acl_access *ASlists;
582 acl_access *noCache;
dba79ac5 583#if SQUID_SNMP
584 acl_access *snmp;
585#endif
376bb137 586 acl_access *brokenPosts;
3898f57f 587#if USE_IDENT
a40699cd 588 acl_access *identLookup;
3898f57f 589#endif
9bc73deb 590 acl_access *redirector;
c4ab8329 591 acl_access *reply;
a8258824 592 } accessList;
bd05e3e3 593 acl_deny_info_list *denyInfoList;
94439e4e 594 struct _authConfig {
595 authScheme *schemes;
596 int n_allocated;
597 int n_configured;
598 } authConfig;
a8258824 599 struct {
600 size_t list_width;
601 int list_wrap;
a8258824 602 char *anon_user;
d20b1cd0 603 int passive;
a8258824 604 } Ftp;
605 refresh_t *Refresh;
606 struct _cacheSwap {
a47b9029 607 SwapDir *swapDirs;
608 int n_allocated;
609 int n_configured;
a8258824 610 } cacheSwap;
365cb147 611 struct {
612 char *directory;
365cb147 613 } icons;
9b312a19 614 char *errorDirectory;
22c653cd 615 struct {
616 time_t timeout;
617 int maxtries;
618 } retry;
7021844c 619 struct {
620 size_t limit;
621 } MemPools;
95e36d02 622#if DELAY_POOLS
59715b38 623 delayConfig Delay;
95e36d02 624#endif
6be2389e 625 struct {
626 int icp_average;
ef523f99 627 int dns_average;
6be2389e 628 int http_average;
629 int icp_min_poll;
ef523f99 630 int dns_min_poll;
6be2389e 631 int http_min_poll;
632 } comm_incoming;
c5f627c2 633 int max_open_disk_fds;
d548ee64 634 int uri_whitespace;
c68e9c6b 635 size_t rangeOffsetLimit;
e66d7923 636#if MULTICAST_MISS_STREAM
637 struct {
638 struct in_addr addr;
7e3ce7b9 639 int ttl;
e66d7923 640 unsigned short port;
641 char *encode_key;
642 } mcast_miss;
643#endif
6bccf575 644 header_mangler header_access[HDR_ENUM_END];
b6a2f15e 645 char *coredump_dir;
efd900cb 646 char *chroot_dir;
7e3ce7b9 647#if USE_CACHE_DIGESTS
648 struct {
649 int bits_per_entry;
efd900cb 650 time_t rebuild_period;
651 time_t rewrite_period;
652 size_t swapout_chunk_size;
7e3ce7b9 653 int rebuild_chunk_percentage;
654 } digest;
1f7c9178 655#endif
656#if USE_SSL
657 struct {
658 char *certificate;
659 char *key;
660 int version;
661 } SSL;
7e3ce7b9 662#endif
56fe752e 663 wordlist *ext_methods;
b8a46de0 664 struct {
665 int high_rptm;
666 int high_pf;
1d53aa49 667 size_t high_memory;
b8a46de0 668 } warnings;
65a53c8e 669 char *store_dir_select_algorithm;
1fbbdcb0 670 int sleep_after_fork; /* microseconds */
a8258824 671};
672
673struct _SquidConfig2 {
674 struct {
675 char *prefix;
676 int on;
677 } Accel;
53cb32a9 678 struct {
679 int enable_purge;
680 } onoff;
d20b1cd0 681 uid_t effectiveUserID;
682 gid_t effectiveGroupID;
a8258824 683};
684
685struct _close_handler {
686 PF *handler;
687 void *data;
688 close_handler *next;
689};
690
691struct _dread_ctrl {
692 int fd;
693 off_t offset;
694 int req_len;
695 char *buf;
696 int end_of_file;
697 DRCB *handler;
698 void *client_data;
699};
700
701struct _dnsserver_t {
702 int id;
a8258824 703 int inpipe;
704 int outpipe;
705 time_t answer;
78f1250a 706 off_t offset;
707 size_t size;
e144eae4 708 char ip_inbuf[DNS_INBUF_SZ];
a8258824 709 struct timeval dispatch_time;
710 void *data;
711};
712
a8258824 713struct _dwrite_q {
d377699f 714 off_t file_offset;
a8258824 715 char *buf;
716 int len;
d377699f 717 off_t buf_offset;
bd05e3e3 718 dwrite_q *next;
74fbf3c9 719 FREE *free_func;
a8258824 720};
721
a9771e51 722
723/* ETag support is rudimantal;
724 * this struct is likely to change
725 * Note: "str" points to memory in HttpHeaderEntry (for now)
726 * so ETags should be used as tmp variables only (for now) */
727struct _ETag {
98829f69 728 const char *str; /* quoted-string */
729 int weak; /* true if it is a weak validator */
a9771e51 730};
731
a8258824 732struct _fde {
733 unsigned int type;
a8258824 734 u_short local_port;
735 u_short remote_port;
736 char ipaddr[16]; /* dotted decimal address of peer */
737 char desc[FD_DESC_SZ];
58a6c186 738 struct {
60c0b5a2 739 unsigned int open:1;
3d94aed0 740 unsigned int close_request:1;
741 unsigned int write_daemon:1;
742 unsigned int closing:1;
743 unsigned int socket_eof:1;
744 unsigned int nolinger:1;
745 unsigned int nonblocking:1;
746 unsigned int ipc:1;
b5568a61 747 unsigned int called_connect:1;
58a6c186 748 } flags;
a8258824 749 int bytes_read;
750 int bytes_written;
b716a8ad 751 int uses; /* ie # req's over persistent conn */
a8258824 752 struct _fde_disk {
753 DWCB *wrt_handle;
754 void *wrt_handle_data;
755 dwrite_q *write_q;
756 dwrite_q *write_q_tail;
711982d8 757 off_t offset;
a8258824 758 } disk;
759 PF *read_handler;
760 void *read_data;
761 PF *write_handler;
762 void *write_data;
763 PF *timeout_handler;
764 time_t timeout;
765 void *timeout_data;
cb69b4c7 766 void *lifetime_data;
a8258824 767 close_handler *close_handler; /* linked list */
da2b3a17 768 DEFER *defer_check; /* check if we should defer read */
70a9dab4 769 void *defer_data;
a8258824 770 CommWriteStateData *rwstate; /* State data for comm_write */
1f7c9178 771 READ_HANDLER *read_method;
772 WRITE_HANDLER *write_method;
773#if USE_SSL
774 SSL *ssl;
775#endif
a8258824 776};
777
778struct _fileMap {
779 int max_n_files;
780 int n_files_in_map;
a8258824 781 int toggle;
782 int nwords;
783 unsigned long *file_map;
784};
785
1d21d91d 786/* auto-growing memory-resident buffer with printf interface */
787/* note: when updating this struct, update MemBufNULL #define */
788struct _MemBuf {
789 /* public, read-only */
790 char *buf;
791 mb_size_t size; /* used space, does not count 0-terminator */
792
793 /* private, stay away; use interface function instead */
794 mb_size_t max_capacity; /* when grows: assert(new_capacity <= max_capacity) */
795 mb_size_t capacity; /* allocated space */
796 FREE *freefunc; /* what to use to free the buffer, NULL after memBufFreeFunc() is called */
797};
798
799/* see Packer.c for description */
800struct _Packer {
801 /* protected, use interface functions instead */
802 append_f append;
803 vprintf_f vprintf;
804 void *real_handler; /* first parameter to real append and vprintf */
805};
806
adba4a64 807/* http status line */
808struct _HttpStatusLine {
809 /* public, read only */
ccf44862 810 http_version_t version;
2ac76861 811 const char *reason; /* points to a _constant_ string (default or supplied), never free()d */
adba4a64 812 http_status status;
813};
814
815/*
1d21d91d 816 * Note: HttpBody is used only for messages with a small content that is
adba4a64 817 * known a priory (e.g., error messages).
818 */
819struct _HttpBody {
1d21d91d 820 /* private */
821 MemBuf mb;
adba4a64 822};
823
2ecaa5e7 824/* http header extention field */
825struct _HttpHdrExtField {
a369131d 826 String name; /* field-name from HTTP/1.1 (no column after name) */
827 String value; /* field-value from HTTP/1.1 */
2ecaa5e7 828};
adba4a64 829
399e85ea 830/* http cache control header field */
7faf2bdb 831struct _HttpHdrCc {
4f087419 832 int mask;
d8b249ef 833 int max_age;
7e3ce7b9 834 int s_maxage;
49ff0930 835 int max_stale;
a8258824 836};
ee1679df 837
b5107edb 838/* http byte-range-spec */
839struct _HttpHdrRangeSpec {
9bc73deb 840 ssize_t offset;
841 ssize_t length;
b5107edb 842};
843
844/* There may be more than one byte range specified in the request.
59c4d35b 845 * This object holds all range specs in order of their appearence
846 * in the request because we SHOULD preserve that order.
847 */
b5107edb 848struct _HttpHdrRange {
849 Stack specs;
850};
7faf2bdb 851
d76fcfa7 852/* http content-range header field */
853struct _HttpHdrContRange {
854 HttpHdrRangeSpec spec;
9bc73deb 855 ssize_t elength; /* entity length, not content length */
d76fcfa7 856};
857
a9771e51 858/* some fields can hold either time or etag specs (e.g. If-Range) */
859struct _TimeOrTag {
98829f69 860 ETag tag; /* entity tag */
a9771e51 861 time_t time;
98829f69 862 int valid; /* true if struct is usable */
a9771e51 863};
864
d192d11f 865/* data for iterating thru range specs */
98829f69 866struct _HttpHdrRangeIter {
d192d11f 867 HttpHdrRangePos pos;
98829f69 868 const HttpHdrRangeSpec *spec; /* current spec at pos */
9bc73deb 869 ssize_t debt_size; /* bytes left to send from the current spec */
870 ssize_t prefix_size; /* the size of the incoming HTTP msg prefix */
98829f69 871 String boundary; /* boundary for multipart responses */
d192d11f 872};
d76fcfa7 873
fcd2d3ef 874/* constant attributes of http header fields */
875struct _HttpHeaderFieldAttrs {
876 const char *name;
877 http_hdr_type id;
878 field_type type;
879};
880
7faf2bdb 881/* per field statistics */
882struct _HttpHeaderFieldStat {
399e85ea 883 int aliveCount; /* created but not destroyed (count) */
d8b249ef 884 int seenCount; /* #fields we've seen */
399e85ea 885 int parsCount; /* #parsing attempts */
886 int errCount; /* #pasring errors */
887 int repCount; /* #repetitons */
7faf2bdb 888};
889
d8b249ef 890/* compiled version of HttpHeaderFieldAttrs plus stats */
de336bbe 891struct _HttpHeaderFieldInfo {
892 http_hdr_type id;
893 String name;
894 field_type type;
7faf2bdb 895 HttpHeaderFieldStat stat;
896};
897
d8b249ef 898struct _HttpHeaderEntry {
899 http_hdr_type id;
900 String name;
901 String value;
902};
4f087419 903
d8b249ef 904struct _HttpHeader {
4f087419 905 /* protected, do not use these, use interface functions instead */
ec878047 906 Array entries; /* parsed fields in raw format */
907 HttpHeaderMask mask; /* bit set <=> entry present */
eeb423fb 908 http_hdr_owner_type owner; /* request or reply */
909 int len; /* length when packed, not counting terminating '\0' */
4f087419 910};
911
adba4a64 912struct _HttpReply {
913 /* unsupported, writable, may disappear/change in the future */
2ac76861 914 int hdr_sz; /* sums _stored_ status-line, headers, and <CRLF> */
adba4a64 915
d8b249ef 916 /* public, readable; never update these or their .hdr equivalents directly */
917 int content_length;
918 time_t date;
919 time_t last_modified;
920 time_t expires;
ec878047 921 String content_type;
d8b249ef 922 HttpHdrCc *cache_control;
923 HttpHdrContRange *content_range;
9f5a2895 924 short int keep_alive;
d8b249ef 925
adba4a64 926 /* public, readable */
2ac76861 927 HttpMsgParseState pstate; /* the current parsing state */
4f087419 928
de336bbe 929 /* public, writable, but use httpReply* interfaces when possible */
adba4a64 930 HttpStatusLine sline;
d8b249ef 931 HttpHeader header;
932 HttpBody body; /* for small constant memory-resident text bodies only */
a560ee93 933 size_t maxBodySize;
adba4a64 934};
cb69b4c7 935
b515fc11 936struct _http_state_flags {
79618ba9 937 unsigned int proxying:1;
938 unsigned int keepalive:1;
db1cd23c 939 unsigned int only_if_cached:1;
b515fc11 940};
a8258824 941
942struct _HttpStateData {
943 StoreEntry *entry;
944 request_t *request;
945 char *reply_hdr;
304d289e 946 size_t reply_hdr_size;
a8258824 947 int reply_hdr_state;
1294c0fc 948 peer *peer; /* peer request made to */
a8258824 949 int eof; /* reached end-of-object? */
950 request_t *orig_request;
1294c0fc 951 int fd;
b515fc11 952 http_state_flags flags;
db1cd23c 953 FwdState *fwd;
a8258824 954};
955
956struct _icpUdpData {
957 struct sockaddr_in address;
958 void *msg;
959 size_t len;
960 icpUdpData *next;
961#ifndef LESS_TIMING
962 struct timeval start;
963#endif
964 log_type logcode;
17b6e784 965 struct timeval queue_time;
a8258824 966};
967
b4e7f82d 968struct _ping_data {
a8258824 969 struct timeval start;
970 struct timeval stop;
971 int n_sent;
972 int n_recv;
973 int n_replies_expected;
98829f69 974 int timeout; /* msec */
465dc415 975 int timedout;
a8258824 976 int w_rtt;
b3264694 977 int p_rtt;
a8258824 978};
979
980struct _HierarchyLogEntry {
981 hier_code code;
982 char host[SQUIDHOSTNAMELEN];
b4e7f82d 983 ping_data ping;
4b4cd312 984 char cd_host[SQUIDHOSTNAMELEN]; /* the host of selected by cd peer */
985 peer_select_alg_t alg; /* peer selection algorithm */
986 lookup_t cd_lookup; /* cd prediction: none, miss, hit */
987 int n_choices; /* #peers we selected from (cd only) */
988 int n_ichoices; /* #peers with known rtt we selected from (cd only) */
39edba21 989 struct timeval peer_select_start;
990 struct timeval store_complete_stop;
a8258824 991};
992
993struct _AccessLogEntry {
994 const char *url;
995 struct {
996 method_t method;
997 int code;
998 const char *content_type;
bffee5af 999 http_version_t version;
a8258824 1000 } http;
1001 struct {
1002 icp_opcode opcode;
1003 } icp;
1004 struct {
1005 struct in_addr caddr;
1006 size_t size;
1007 log_type code;
1008 int msec;
94439e4e 1009 const char *rfc931;
1010 const char *authuser;
a8258824 1011 } cache;
a8258824 1012 struct {
1013 char *request;
1014 char *reply;
1015 } headers;
1016 struct {
1017 const char *method_str;
1018 } private;
bd05e3e3 1019 HierarchyLogEntry hier;
a8258824 1020};
1021
1022struct _clientHttpRequest {
1023 ConnStateData *conn;
1024 request_t *request; /* Parsed URL ... */
06d2839d 1025 store_client *sc; /* The store_client we're using */
57ec8214 1026 store_client *old_sc; /* ... for entry to be validated */
23d92c64 1027 char *uri;
1028 char *log_uri;
a8258824 1029 struct {
78f1250a 1030 off_t offset;
1031 size_t size;
a8258824 1032 } out;
98829f69 1033 HttpHdrRangeIter range_iter; /* data for iterating thru range specs */
1034 size_t req_sz; /* raw request size on input, not current request size */
a8258824 1035 StoreEntry *entry;
1036 StoreEntry *old_entry;
1037 log_type log_type;
6cfa8966 1038#if USE_CACHE_DIGESTS
04f0c415 1039 const char *lookup_type; /* temporary hack: storeGet() result: HIT/MISS/NONE */
1040#endif
a8258824 1041 struct timeval start;
ccf44862 1042 http_version_t http_ver;
a8258824 1043 int redirect_state;
1044 aclCheck_t *acl_checklist; /* need ptr back so we can unreg if needed */
1045 clientHttpRequest *next;
bd05e3e3 1046 AccessLogEntry al;
77ed547a 1047 struct {
3d94aed0 1048 unsigned int accel:1;
1049 unsigned int internal:1;
1050 unsigned int done_copying:1;
f66a9ef4 1051 unsigned int purging:1;
77ed547a 1052 } flags;
6d38ef86 1053 struct {
1054 http_status status;
1055 char *location;
1056 } redirect;
0f1bc304 1057 dlink_node active;
a8258824 1058};
1059
1060struct _ConnStateData {
1061 int fd;
1062 struct {
1063 char *buf;
78f1250a 1064 off_t offset;
1065 size_t size;
a8258824 1066 } in;
94439e4e 1067 struct {
1068 size_t size_left; /* How much body left to process */
1069 request_t *request; /* Parameters passed to clientReadBody */
1070 char *buf;
1071 size_t bufsize;
1072 CBCB *callback;
1073 void *cbdata;
1074 } body;
1075 auth_type_t auth_type; /* Is this connection based authentication ? if so
1076 * what type it is. */
1077 /* note this is ONLY connection based because NTLM is against HTTP spec */
1078 /* the user details for connection based authentication */
1079 auth_user_request_t *auth_user_request;
a8258824 1080 clientHttpRequest *chr;
1081 struct sockaddr_in peer;
1082 struct sockaddr_in me;
1083 struct in_addr log_addr;
94439e4e 1084 char rfc931[USER_IDENT_SZ];
a8258824 1085 int nrequests;
da2b3a17 1086 struct {
1087 int n;
1088 time_t until;
1089 } defer;
a8258824 1090};
1091
1092struct _ipcache_addrs {
6d1c0d53 1093 struct in_addr *in_addrs;
1094 unsigned char *bad_mask;
a8258824 1095 unsigned char count;
1096 unsigned char cur;
22c653cd 1097 unsigned char badcount;
a8258824 1098};
1099
a8258824 1100struct _domain_ping {
1101 char *domain;
1102 int do_ping; /* boolean */
bd05e3e3 1103 domain_ping *next;
a8258824 1104};
1105
1106struct _domain_type {
1107 char *domain;
1108 peer_t type;
bd05e3e3 1109 domain_type *next;
a8258824 1110};
1111
c68e9c6b 1112#if USE_CACHE_DIGESTS
e41e6dcd 1113struct _Version {
4b4cd312 1114 short int current; /* current version */
1115 short int required; /* minimal version that can safely handle current version */
e41e6dcd 1116};
1117
1118/* digest control block; used for transmission and storage */
1119struct _StoreDigestCBlock {
1120 Version ver;
1121 int capacity;
1122 int count;
1123 int del_count;
1124 int mask_size;
04f0c415 1125 unsigned char bits_per_entry;
1126 unsigned char hash_func_count;
1127 short int reserved_short;
4b4cd312 1128 int reserved[32 - 6];
e41e6dcd 1129};
1130
1131struct _DigestFetchState {
e13ee7ad 1132 PeerDigest *pd;
e41e6dcd 1133 StoreEntry *entry;
1134 StoreEntry *old_entry;
06d2839d 1135 store_client *sc;
1136 store_client *old_sc;
e13ee7ad 1137 request_t *request;
e41e6dcd 1138 int offset;
1139 int mask_offset;
1140 time_t start_time;
e13ee7ad 1141 time_t resp_time;
1142 time_t expires;
1143 struct {
1144 int msg;
1145 int bytes;
1146 } sent, recv;
e41e6dcd 1147};
1148
1149/* statistics for cache digests and other hit "predictors" */
1150struct _cd_guess_stats {
1151 /* public, read-only */
1152 int true_hits;
1153 int false_hits;
1154 int true_misses;
1155 int false_misses;
4b4cd312 1156 int close_hits; /* tmp, remove it later */
e41e6dcd 1157};
1158
1159struct _PeerDigest {
4d62b0af 1160 peer *peer; /* pointer back to peer structure, argh */
1161 CacheDigest *cd; /* actual digest structure */
1162 String host; /* copy of peer->host */
e13ee7ad 1163 const char *req_result; /* text status of the last request */
b515fc11 1164 struct {
4d62b0af 1165 unsigned int needed:1; /* there were requests for this digest */
e13ee7ad 1166 unsigned int usable:1; /* can be used for lookups */
79618ba9 1167 unsigned int requested:1; /* in process of receiving [fresh] digest */
b515fc11 1168 } flags;
e13ee7ad 1169 struct {
1170 /* all times are absolute unless augmented with _delay */
1171 time_t initialized; /* creation */
1172 time_t needed; /* first lookup/use by a peer */
1173 time_t next_check; /* next scheduled check/refresh event */
1174 time_t retry_delay; /* delay before re-checking _invalid_ digest */
1175 time_t requested; /* requested a fresh copy of a digest */
4d62b0af 1176 time_t req_delay; /* last request response time */
e13ee7ad 1177 time_t received; /* received the current copy of a digest */
1178 time_t disabled; /* disabled for good */
1179 } times;
e41e6dcd 1180 struct {
1181 cd_guess_stats guess;
1182 int used_count;
e13ee7ad 1183 struct {
1184 int msgs;
1185 kb_t kbytes;
1186 } sent, recv;
e41e6dcd 1187 } stats;
1188};
1189
c68e9c6b 1190#endif
1191
a8258824 1192struct _peer {
1193 char *host;
1194 peer_t type;
1195 struct sockaddr_in in_addr;
1196 struct {
1197 int pings_sent;
1198 int pings_acked;
a8258824 1199 int fetches;
1200 int rtt;
a8258824 1201 int ignored_replies;
1294c0fc 1202 int n_keepalives_sent;
1203 int n_keepalives_recv;
83b381d5 1204 time_t probe_start;
dc835977 1205 time_t last_query;
1206 time_t last_reply;
eb406bb7 1207 time_t last_connect_failure;
1208 time_t last_connect_probe;
dc835977 1209 int logged_state; /* so we can print dead/revived msgs */
c7f9eb6d 1210 int conn_open; /* current opened connections */
a8258824 1211 } stats;
399cabec 1212 struct {
886f2785 1213 int version;
399cabec 1214 int counts[ICP_END];
886f2785 1215 u_short port;
399cabec 1216 } icp;
1217#if USE_HTCP
1218 struct {
1219 double version;
1220 int counts[2];
886f2785 1221 u_short port;
399cabec 1222 } htcp;
1223#endif
a8258824 1224 u_short http_port;
b6a2f15e 1225 domain_ping *peer_domain;
bd05e3e3 1226 domain_type *typelist;
505e35db 1227 acl_access *access;
cd196bc8 1228 struct {
79618ba9 1229 unsigned int proxy_only:1;
1230 unsigned int no_query:1;
1231 unsigned int no_digest:1;
1232 unsigned int default_parent:1;
1233 unsigned int roundrobin:1;
1234 unsigned int mcast_responder:1;
1235 unsigned int closest_only:1;
cd196bc8 1236#if USE_HTCP
79618ba9 1237 unsigned int htcp:1;
cd196bc8 1238#endif
79618ba9 1239 unsigned int no_netdb_exchange:1;
cd196bc8 1240#if DELAY_POOLS
79618ba9 1241 unsigned int no_delay:1;
cd196bc8 1242#endif
987de783 1243 unsigned int allow_miss:1;
cd196bc8 1244 } options;
a8258824 1245 int weight;
1246 struct {
1247 double avg_n_members;
1248 int n_times_counted;
1249 int n_replies_expected;
1250 int ttl;
007b8be4 1251 int id;
b515fc11 1252 struct {
79618ba9 1253 unsigned int count_event_pending:1;
1254 unsigned int counting:1;
ff283ec1 1255 } flags;
a8258824 1256 } mcast;
c68e9c6b 1257#if USE_CACHE_DIGESTS
e13ee7ad 1258 PeerDigest *digest;
7e3ce7b9 1259 char *digest_url;
c68e9c6b 1260#endif
a8258824 1261 int tcp_up; /* 0 if a connect() fails */
a8258824 1262 struct in_addr addresses[10];
1263 int n_addresses;
1264 int rr_count;
82056f1e 1265 int rr_lastcount;
bd05e3e3 1266 peer *next;
a8258824 1267 int test_fd;
afd88fbe 1268#if USE_CARP
1269 struct {
8ee9b49f 1270 unsigned int hash;
1271 double load_multiplier;
afd88fbe 1272 float load_factor;
1273 } carp;
1274#endif
c68e9c6b 1275 char *login; /* Proxy authorization */
3f62decd 1276 time_t connect_timeout;
c7f9eb6d 1277 int max_conn;
a8258824 1278};
1279
1280struct _net_db_name {
186477c1 1281 hash_link hash; /* must be first */
74fbf3c9 1282 net_db_name *next;
1283 netdbEntry *net_db_entry;
a8258824 1284};
1285
1286struct _net_db_peer {
6b53c392 1287 const char *peername;
a8258824 1288 double hops;
1289 double rtt;
1290 time_t expires;
1291};
1292
1293struct _netdbEntry {
186477c1 1294 hash_link hash; /* must be first */
a8258824 1295 char network[16];
1296 int pings_sent;
1297 int pings_recv;
1298 double hops;
1299 double rtt;
1300 time_t next_ping_time;
1301 time_t last_use_time;
1302 int link_count;
1303 net_db_name *hosts;
1304 net_db_peer *peers;
1305 int n_peers_alloc;
1306 int n_peers;
1307};
1308
1309struct _ps_state {
1310 request_t *request;
1311 StoreEntry *entry;
1312 int always_direct;
1313 int never_direct;
db1cd23c 1314 int direct;
a8258824 1315 PSC *callback;
a8258824 1316 void *callback_data;
db1cd23c 1317 FwdServer *servers;
85223cd7 1318 /*
1319 * Why are these struct sockaddr_in instead of peer *? Because a
1320 * peer structure can become invalid during the peer selection
1321 * phase, specifically after a reconfigure. Thus we need to lookup
1322 * the peer * based on the address when we are finally ready to
1323 * reference the peer structure.
1324 */
1325 struct sockaddr_in first_parent_miss;
1326 struct sockaddr_in closest_parent_miss;
db1cd23c 1327 /*
1328 * ->hit and ->secho can be peer* because they should only be
1329 * accessed during the thread when they are set
1330 */
1331 peer *hit;
1332 peer_t hit_type;
1333#if ALLOW_SOURCE_PING
1334 peer *secho;
1335#endif
b4e7f82d 1336 ping_data ping;
a8258824 1337 aclCheck_t *acl_checklist;
1338};
1339
6b53c392 1340#if USE_ICMP
a8258824 1341struct _pingerEchoData {
1342 struct in_addr to;
1343 unsigned char opcode;
1344 int psize;
65ae9f56 1345 char payload[PINGER_PAYLOAD_SZ];
a8258824 1346};
1347
1348struct _pingerReplyData {
1349 struct in_addr from;
1350 unsigned char opcode;
1351 int rtt;
1352 int hops;
1353 int psize;
65ae9f56 1354 char payload[PINGER_PAYLOAD_SZ];
a8258824 1355};
a4b8110e 1356
6b53c392 1357#endif
a8258824 1358
1359struct _icp_common_t {
1360 unsigned char opcode; /* opcode */
1361 unsigned char version; /* version number */
1362 unsigned short length; /* total length (bytes) */
1363 u_num32 reqnum; /* req number (req'd for UDP) */
1364 u_num32 flags;
1365 u_num32 pad;
a8258824 1366 u_num32 shostid; /* sender host id */
1367};
1368
a8258824 1369struct _iostats {
1370 struct {
1371 int reads;
1372 int reads_deferred;
1373 int read_hist[16];
1374 int writes;
1375 int write_hist[16];
1376 } Http, Ftp, Gopher, Wais;
1377};
1378
1379struct _mem_node {
d1a68966 1380 char data[SM_PAGE_SIZE];
a8258824 1381 int len;
1382 mem_node *next;
1383};
1384
1385struct _mem_hdr {
1386 mem_node *head;
1387 mem_node *tail;
1388 int origin_offset;
1389};
1390
a8258824 1391/* keep track each client receiving data from that particular StoreEntry */
1392struct _store_client {
43329771 1393 int type;
a8258824 1394 off_t copy_offset;
1395 off_t seen_offset;
1396 size_t copy_size;
1397 char *copy_buf;
1398 STCB *callback;
1399 void *callback_data;
07304bf9 1400 StoreEntry *entry; /* ptr to the parent StoreEntry, argh! */
2391a162 1401 storeIOState *swapin_sio;
f115fadd 1402 struct {
3d94aed0 1403 unsigned int disk_io_pending:1;
1404 unsigned int store_copying:1;
1405 unsigned int copy_event_pending:1;
f115fadd 1406 } flags;
447e176b 1407#if DELAY_POOLS
1408 delay_id delay_id;
1409#endif
06d2839d 1410 dlink_node node;
a8258824 1411};
1412
1a3db59c 1413
6a566b9c 1414/* Removal policies */
1415
1416struct _RemovalPolicyNode {
1417 void *data;
1418};
1419
1420struct _RemovalPolicy {
1421 char *_type;
1422 void *_data;
c1dd71ae 1423 void (*Free) (RemovalPolicy * policy);
1424 void (*Add) (RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node);
1425 void (*Remove) (RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node);
1426 void (*Referenced) (RemovalPolicy * policy, const StoreEntry * entry, RemovalPolicyNode * node);
1427 void (*Dereferenced) (RemovalPolicy * policy, const StoreEntry * entry, RemovalPolicyNode * node);
1428 RemovalPolicyWalker *(*WalkInit) (RemovalPolicy * policy);
1429 RemovalPurgeWalker *(*PurgeInit) (RemovalPolicy * policy, int max_scan);
8a3e7d9e 1430 void (*Stats) (RemovalPolicy * policy, StoreEntry * entry);
6a566b9c 1431};
1432
1433struct _RemovalPolicyWalker {
1434 RemovalPolicy *_policy;
1435 void *_data;
c1dd71ae 1436 const StoreEntry *(*Next) (RemovalPolicyWalker * walker);
1437 void (*Done) (RemovalPolicyWalker * walker);
6a566b9c 1438};
1439
1440struct _RemovalPurgeWalker {
1441 RemovalPolicy *_policy;
1442 void *_data;
1443 int scanned, max_scan, locked;
c1dd71ae 1444 StoreEntry *(*Next) (RemovalPurgeWalker * walker);
1445 void (*Done) (RemovalPurgeWalker * walker);
6a566b9c 1446};
1447
a8258824 1448/* This structure can be freed while object is purged out from memory */
1449struct _MemObject {
2ac237e2 1450 method_t method;
9fb13bb6 1451 char *url;
18fe65d0 1452 mem_hdr data_hdr;
8350fe9b 1453 off_t inmem_hi;
1454 off_t inmem_lo;
06d2839d 1455 dlink_list clients;
a8258824 1456 int nclients;
8350fe9b 1457 struct {
e3ef2b09 1458 off_t queue_offset; /* relative to in-mem data */
a4b8110e 1459 mem_node *memnode; /* which node we're currently paging out */
2391a162 1460 storeIOState *sio;
8350fe9b 1461 } swapout;
cb69b4c7 1462 HttpReply *reply;
a8258824 1463 request_t *request;
1464 struct timeval start_ping;
b4e7f82d 1465 IRCB *ping_reply_callback;
a8258824 1466 void *ircb_data;
1467 int fd; /* FD of client creating this entry */
1468 struct {
1469 STABH *callback;
1470 void *data;
1471 } abort;
88738790 1472 char *log_url;
6a566b9c 1473 RemovalPolicyNode repl;
007b8be4 1474 int id;
07304bf9 1475 ssize_t object_sz;
e3ef2b09 1476 size_t swap_hdr_sz;
bc87dc25 1477#if URL_CHECKSUM_DEBUG
1478 unsigned int chksum;
1479#endif
e7106f62 1480 const char *vary_headers;
a8258824 1481};
1482
a8258824 1483struct _StoreEntry {
186477c1 1484 hash_link hash; /* must be first */
a8258824 1485 MemObject *mem_obj;
103b5a56 1486 RemovalPolicyNode repl;
329e2e6d 1487 /* START OF ON-DISK STORE_META_STD TLV field */
a8258824 1488 time_t timestamp;
1489 time_t lastref;
1490 time_t expires;
1491 time_t lastmod;
07304bf9 1492 size_t swap_file_sz;
a21fbb54 1493 u_short refcount;
d46a87a8 1494 u_short flags;
329e2e6d 1495 /* END OF ON-DISK STORE_META_STD */
1496 sfileno swap_filen:25;
1497 sdirno swap_dirn:7;
a3cb7458 1498 u_short lock_count; /* Assume < 65536! */
a8258824 1499 mem_status_t mem_status:3;
1500 ping_status_t ping_status:3;
1501 store_status_t store_status:3;
1502 swap_status_t swap_status:3;
a8258824 1503};
1504
1505struct _SwapDir {
cd748f27 1506 char *type;
a8258824 1507 int cur_size;
c6844e77 1508 int low_size;
a8258824 1509 int max_size;
0e4e0e7d 1510 char *path;
b2c141d4 1511 int index; /* This entry's index into the swapDirs array */
e8dbac8b 1512 ssize_t max_objsize;
6a566b9c 1513 RemovalPolicy *repl;
fc8b9fc0 1514 int removals;
1515 int scanned;
72615e4a 1516 struct {
1517 unsigned int selected:1;
b6a2f15e 1518 unsigned int read_only:1;
72615e4a 1519 } flags;
cd748f27 1520 STINIT *init; /* Initialise the fs */
1521 STNEWFS *newfs; /* Create a new fs */
1522 STDUMP *dump; /* Dump fs config snippet */
1523 STFREE *freefs; /* Free the fs data */
1524 STDBLCHECK *dblcheck; /* Double check the obj integrity */
1525 STSTATFS *statfs; /* Dump fs statistics */
1526 STMAINTAINFS *maintainfs; /* Replacement maintainence */
1527 STCHECKOBJ *checkobj; /* Check if the fs will store an object */
1528 /* These two are notifications */
1529 STREFOBJ *refobj; /* Reference this object */
1530 STUNREFOBJ *unrefobj; /* Unreference this object */
1531 STCALLBACK *callback; /* Handle pending callbacks */
1532 STSYNC *sync; /* Sync the directory */
1533 struct {
a4b8110e 1534 STOBJCREATE *create;
b2c141d4 1535 STOBJOPEN *open;
1536 STOBJCLOSE *close;
1537 STOBJREAD *read;
1538 STOBJWRITE *write;
1539 STOBJUNLINK *unlink;
b2c141d4 1540 } obj;
1541 struct {
1542 STLOGOPEN *open;
1543 STLOGCLOSE *close;
200ba06e 1544 STLOGWRITE *write;
b2c141d4 1545 struct {
6a566b9c 1546 STLOGCLEANSTART *start;
1547 STLOGCLEANNEXTENTRY *nextentry;
b2c141d4 1548 STLOGCLEANWRITE *write;
6a566b9c 1549 STLOGCLEANDONE *done;
b2c141d4 1550 void *state;
1551 } clean;
add5d21f 1552 int writes_since_clean;
b2c141d4 1553 } log;
90d42c28 1554 struct {
1555 int blksize;
90d42c28 1556 } fs;
cd748f27 1557 void *fsdata;
a8258824 1558};
1559
92695e5e 1560struct _request_flags {
3d94aed0 1561 unsigned int range:1;
1562 unsigned int nocache:1;
1563 unsigned int ims:1;
1564 unsigned int auth:1;
1565 unsigned int cachable:1;
1566 unsigned int hierarchical:1;
1567 unsigned int loopdetect:1;
1568 unsigned int proxy_keepalive:1;
1569 unsigned int proxying:1;
1570 unsigned int refresh:1;
3d94aed0 1571 unsigned int redirected:1;
9689d97c 1572 unsigned int need_validation:1;
9f60cfdf 1573#if HTTP_VIOLATIONS
886f2785 1574 unsigned int nocache_hack:1; /* for changing/ignoring no-cache requests */
9f60cfdf 1575#endif
c68e9c6b 1576 unsigned int accelerated:1;
1577 unsigned int internal:1;
94439e4e 1578 unsigned int body_sent:1;
92695e5e 1579};
1580
d03d26fb 1581struct _link_list {
1582 void *ptr;
1583 struct _link_list *next;
1584};
1585
2391a162 1586struct _storeIOState {
cd748f27 1587 sdirno swap_dirn;
1588 sfileno swap_filen;
1589 StoreEntry *e; /* Need this so the FS layers can play god */
2391a162 1590 mode_t mode;
1591 size_t st_size; /* do stat(2) after read open */
cd748f27 1592 off_t offset; /* current on-disk offset pointer */
1593 STFNCB *file_callback; /* called on delayed sfileno assignments */
2391a162 1594 STIOCB *callback;
1595 void *callback_data;
1596 struct {
1597 STRCB *callback;
1598 void *callback_data;
1599 } read;
1600 struct {
1601 unsigned int closing:1; /* debugging aid */
1602 } flags;
cd748f27 1603 void *fsstate;
2391a162 1604};
1605
a8258824 1606struct _request_t {
1607 method_t method;
1608 protocol_t protocol;
1609 char login[MAX_LOGIN_SZ];
1610 char host[SQUIDHOSTNAMELEN + 1];
94439e4e 1611 auth_user_request_t *auth_user_request;
a8258824 1612 u_short port;
02922e76 1613 String urlpath;
e4a45101 1614 char *canonical;
a8258824 1615 int link_count; /* free when zero */
92695e5e 1616 request_flags flags;
8e092300 1617 HttpHdrCc *cache_control;
d192d11f 1618 HttpHdrRange *range;
ccf44862 1619 http_version_t http_ver;
a8258824 1620 time_t ims;
1621 int imslen;
1622 int max_forwards;
7e3ce7b9 1623 /* these in_addr's could probably be sockaddr_in's */
a8258824 1624 struct in_addr client_addr;
3c11d1f5 1625 struct in_addr my_addr;
7e3ce7b9 1626 unsigned short my_port;
99edd1c3 1627 HttpHeader header;
94439e4e 1628 ConnStateData *body_connection; /* used by clientReadBody() */
1f38f50a 1629 int content_length;
bd05e3e3 1630 HierarchyLogEntry hier;
88aad2e5 1631 err_type err_type;
c68e9c6b 1632 char *peer_login; /* Configured peer login:password */
9bc73deb 1633 time_t lastmod; /* Used on refreshes */
e7106f62 1634 const char *vary_headers; /* Used when varying entities are detected. Changes how the store key is calculated */
a8258824 1635};
1636
1637struct _cachemgr_passwd {
1638 char *passwd;
22f3fd98 1639 wordlist *actions;
bd05e3e3 1640 cachemgr_passwd *next;
a8258824 1641};
1642
1643struct _refresh_t {
1644 char *pattern;
1645 regex_t compiled_pattern;
1646 time_t min;
c3f6d204 1647 double pct;
a8258824 1648 time_t max;
bd05e3e3 1649 refresh_t *next;
c3f6d204 1650 struct {
1dfa1d81 1651 unsigned int icase:1;
9f60cfdf 1652#if HTTP_VIOLATIONS
1dfa1d81 1653 unsigned int override_expire:1;
1654 unsigned int override_lastmod:1;
cbe3a719 1655 unsigned int reload_into_ims:1;
1656 unsigned int ignore_reload:1;
9f60cfdf 1657#endif
c3f6d204 1658 } flags;
a8258824 1659};
1660
1661struct _CommWriteStateData {
1662 char *buf;
1663 size_t size;
1664 off_t offset;
1665 CWCB *handler;
1666 void *handler_data;
74fbf3c9 1667 FREE *free_func;
a8258824 1668};
9b312a19 1669
1670struct _ErrorState {
1671 err_type type;
02922e76 1672 int page_id;
9b312a19 1673 http_status http_status;
94439e4e 1674 auth_user_request_t *auth_user_request;
9b312a19 1675 request_t *request;
1676 char *url;
c45ed9ad 1677 int xerrno;
9b312a19 1678 char *host;
1679 u_short port;
1680 char *dnsserver_msg;
1681 time_t ttl;
1682 struct in_addr src_addr;
1683 char *redirect_url;
1684 ERCB *callback;
1685 void *callback_data;
b515fc11 1686 struct {
79618ba9 1687 unsigned int flag_cbdata:1;
b515fc11 1688 } flags;
b9916917 1689 struct {
9bc73deb 1690 wordlist *server_msg;
b9916917 1691 char *request;
1692 char *reply;
1693 } ftp;
e144eae4 1694 char *request_hdrs;
9b312a19 1695};
f2908497 1696
12cf1be2 1697/*
1698 * "very generic" histogram;
1699 * see important comments on hbase_f restrictions in StatHist.c
1700 */
1701struct _StatHist {
1702 int *bins;
1703 int capacity;
e9a13293 1704 double min;
1705 double max;
1706 double scale;
95c297ec 1707 hbase_f *val_in; /* e.g., log() for log-based histogram */
1708 hbase_f *val_out; /* e.g., exp() for log based histogram */
7ae52c25 1709};
1710
12cf1be2 1711/*
1712 * if you add a field to StatCounters,
1d803566 1713 * you MUST sync statCountersInitSpecial, statCountersClean, and statCountersCopy
12cf1be2 1714 */
f2908497 1715struct _StatCounters {
1716 struct {
98829f69 1717 int clients;
f2908497 1718 int requests;
1719 int hits;
4f4d1d6e 1720 int mem_hits;
1721 int disk_hits;
f2908497 1722 int errors;
a7c05555 1723 kb_t kbytes_in;
1724 kb_t kbytes_out;
1725 kb_t hit_kbytes_out;
12cf1be2 1726 StatHist miss_svc_time;
1727 StatHist nm_svc_time;
7c9c84ad 1728 StatHist nh_svc_time;
12cf1be2 1729 StatHist hit_svc_time;
1730 StatHist all_svc_time;
f2908497 1731 } client_http;
7ae52c25 1732 struct {
a0f32775 1733 struct {
1734 int requests;
1735 int errors;
1736 kb_t kbytes_in;
1737 kb_t kbytes_out;
399e85ea 1738 } all , http, ftp, other;
7ae52c25 1739 } server;
f2908497 1740 struct {
1741 int pkts_sent;
071a3ae7 1742 int queries_sent;
1743 int replies_sent;
f2908497 1744 int pkts_recv;
071a3ae7 1745 int queries_recv;
1746 int replies_recv;
a7c05555 1747 int hits_sent;
1748 int hits_recv;
8064065e 1749 int replies_queued;
17b6e784 1750 int replies_dropped;
a7c05555 1751 kb_t kbytes_sent;
071a3ae7 1752 kb_t q_kbytes_sent;
1753 kb_t r_kbytes_sent;
a7c05555 1754 kb_t kbytes_recv;
071a3ae7 1755 kb_t q_kbytes_recv;
1756 kb_t r_kbytes_recv;
12cf1be2 1757 StatHist query_svc_time;
1758 StatHist reply_svc_time;
4b4cd312 1759 int query_timeouts;
c127134a 1760 int times_used;
f2908497 1761 } icp;
1762 struct {
1763 int requests;
1764 } unlink;
9973e9fe 1765 struct {
12cf1be2 1766 StatHist svc_time;
9973e9fe 1767 } dns;
c127134a 1768 struct {
1769 int times_used;
26b164ac 1770 kb_t kbytes_sent;
1771 kb_t kbytes_recv;
c127134a 1772 kb_t memory;
00485c29 1773 int msgs_sent;
1774 int msgs_recv;
c68e9c6b 1775#if USE_CACHE_DIGESTS
4b4cd312 1776 cd_guess_stats guess;
c68e9c6b 1777#endif
69c95dd3 1778 StatHist on_xition_count;
c127134a 1779 } cd;
69c95dd3 1780 struct {
1781 int times_used;
1782 } netdb;
f2908497 1783 int page_faults;
1784 int select_loops;
d239c2f5 1785 int select_fds;
1786 double select_time;
f2908497 1787 double cputime;
d5649d9f 1788 struct timeval timestamp;
c6ecdbc3 1789 StatHist comm_icp_incoming;
ef523f99 1790 StatHist comm_dns_incoming;
c6ecdbc3 1791 StatHist comm_http_incoming;
26d6ee93 1792 StatHist select_fds_hist;
886f2785 1793 struct {
1794 struct {
1795 int opens;
1796 int closes;
1797 int reads;
1798 int writes;
1799 int seeks;
64b54eed 1800 int unlinks;
886f2785 1801 } disk;
1802 struct {
1803 int accepts;
1804 int sockets;
1805 int connects;
1806 int binds;
1807 int closes;
1808 int reads;
1809 int writes;
1810 int recvfroms;
1811 int sendtos;
1812 } sock;
1813#if HAVE_POLL
1814 int polls;
1815#else
1816 int selects;
1817#endif
1818 } syscalls;
bfae3379 1819 int aborted_requests;
23dc8aca 1820 struct {
1821 int files_cleaned;
1822 int outs;
1823 int ins;
1824 } swap;
f2908497 1825};
69c01cd7 1826
fcd2d3ef 1827/* per header statistics */
1828struct _HttpHeaderStat {
1829 const char *label;
1830 HttpHeaderMask *owner_mask;
1831
1832 StatHist hdrUCountDistr;
1833 StatHist fieldTypeDistr;
1834 StatHist ccTypeDistr;
1835
1836 int parsedCount;
1837 int ccParsedCount;
1838 int destroyedCount;
1839 int busyDestroyedCount;
1840};
1841
1842
69c01cd7 1843struct _tlv {
5830cdb3 1844 char type;
1845 int length;
1846 void *value;
bd05e3e3 1847 tlv *next;
5830cdb3 1848};
1849
cd748f27 1850/*
1851 * Do we need to have the dirn in here? I don't think so, since we already
1852 * know the dirn ..
1853 */
07304bf9 1854struct _storeSwapLogData {
5830cdb3 1855 char op;
cd748f27 1856 sfileno swap_filen;
5830cdb3 1857 time_t timestamp;
1858 time_t lastref;
1859 time_t expires;
1860 time_t lastmod;
07304bf9 1861 size_t swap_file_sz;
5830cdb3 1862 u_short refcount;
d46a87a8 1863 u_short flags;
7363fc17 1864 unsigned char key[MD5_DIGEST_CHARS];
69c01cd7 1865};
59c4d35b 1866
02922e76 1867/* object to track per-action memory usage (e.g. #idle objects) */
1868struct _MemMeter {
9bc73deb 1869 ssize_t level; /* current level (count or volume) */
1870 ssize_t hwater_level; /* high water mark */
d8b249ef 1871 time_t hwater_stamp; /* timestamp of last high water mark change */
02922e76 1872};
1873
1874/* object to track per-pool memory usage (alloc = inuse+idle) */
1875struct _MemPoolMeter {
1876 MemMeter alloc;
1877 MemMeter inuse;
1878 MemMeter idle;
1879 gb_t saved;
7f8bbdcd 1880 gb_t total;
02922e76 1881};
1882
1883/* a pool is a [growing] space for objects of the same size */
1884struct _MemPool {
1885 const char *label;
1886 size_t obj_size;
1887 Stack pstack; /* stack for free pointers */
1888 MemPoolMeter meter;
1889};
1890
59c4d35b 1891struct _ClientInfo {
186477c1 1892 hash_link hash; /* must be first */
59c4d35b 1893 struct in_addr addr;
1894 struct {
1895 int result_hist[LOG_TYPE_MAX];
1896 int n_requests;
ec878047 1897 kb_t kbytes_in;
1898 kb_t kbytes_out;
1899 kb_t hit_kbytes_out;
59c4d35b 1900 } Http, Icp;
1901 struct {
1902 time_t time;
1903 int n_req;
1904 int n_denied;
1905 } cutoff;
9bc73deb 1906 int n_established; /* number of current established connections */
59c4d35b 1907};
c411be12 1908
c411be12 1909struct _CacheDigest {
1910 /* public, read-only */
1afe05c5 1911 char *mask; /* bit mask */
1912 size_t mask_size; /* mask size in bytes */
1913 int capacity; /* expected maximum for .count, not a hard limit */
04f0c415 1914 int bits_per_entry; /* number of bits allocated for each entry from capacity */
1afe05c5 1915 int count; /* number of digested entries */
1916 int del_count; /* number of deletions performed so far */
c411be12 1917};
910169e5 1918
db1cd23c 1919struct _FwdServer {
1920 peer *peer; /* NULL --> origin server */
1921 hier_code code;
1922 FwdServer *next;
1923};
1924
910169e5 1925struct _FwdState {
1926 int client_fd;
1927 StoreEntry *entry;
1928 request_t *request;
1929 FwdServer *servers;
6801f8a8 1930 int server_fd;
ec250dfd 1931 ErrorState *err;
f563eea9 1932 time_t start;
68bd6892 1933 int n_tries;
225644d7 1934#if WIP_FWD_LOG
1935 http_status last_status;
1936#endif
ee08bdf5 1937 struct {
1938 unsigned int dont_retry:1;
9bc73deb 1939 unsigned int ftp_pasv_failed:1;
ee08bdf5 1940 } flags;
910169e5 1941};
1942
86aebcda 1943#if USE_HTCP
1944struct _htcpReplyData {
886f2785 1945 int hit;
1946 HttpHeader hdr;
1947 u_num32 msg_id;
1948 double version;
1949 struct {
b4e7f82d 1950 /* cache-to-origin */
886f2785 1951 double rtt;
1952 int samp;
1953 int hops;
1954 } cto;
86aebcda 1955};
886f2785 1956
86aebcda 1957#endif
74addf6c 1958
1959
1960struct _helper_request {
1961 char *buf;
1962 HLPCB *callback;
1963 void *data;
1964};
1965
94439e4e 1966struct _helper_stateful_request {
1967 char *buf;
1968 HLPSCB *callback;
1969 int placeholder; /* if 1, this is a dummy request waiting for a stateful helper
1970 * to become available for deferred requests.*/
1971 void *data;
1972};
1973
1974
74addf6c 1975struct _helper {
1976 wordlist *cmdline;
1977 dlink_list servers;
1978 dlink_list queue;
1f5f60dd 1979 const char *id_name;
74addf6c 1980 int n_to_start;
1981 int n_running;
1982 int ipc_type;
1983 time_t last_queue_warn;
1984 struct {
1985 int requests;
1986 int replies;
1987 int queue_size;
1988 int avg_svc_time;
1989 } stats;
1990};
1991
94439e4e 1992struct _helper_stateful {
1993 wordlist *cmdline;
1994 dlink_list servers;
1995 dlink_list queue;
1996 const char *id_name;
1997 int n_to_start;
1998 int n_running;
1999 int ipc_type;
2000 MemPool *datapool;
2001 HLPSAVAIL *IsAvailable;
2002 HLPSONEQ *OnEmptyQueue;
2003 time_t last_queue_warn;
2004 struct {
2005 int requests;
2006 int replies;
2007 int queue_size;
2008 int avg_svc_time;
2009 } stats;
2010};
2011
74addf6c 2012struct _helper_server {
2013 int index;
2014 int rfd;
2015 int wfd;
2016 char *buf;
2017 size_t buf_sz;
2018 off_t offset;
2019 struct timeval dispatch_time;
2020 struct timeval answer_time;
2021 dlink_node link;
2022 helper *parent;
2023 helper_request *request;
838b993c 2024 struct _helper_flags {
2025 unsigned int alive:1;
2026 unsigned int busy:1;
2027 unsigned int closing:1;
2028 unsigned int shutdown:1;
2029 } flags;
74addf6c 2030 struct {
2031 int uses;
2032 } stats;
2033};
2034
94439e4e 2035
2036struct _helper_stateful_server {
2037 int index;
5d146f7d 2038 int pid;
94439e4e 2039 int rfd;
2040 int wfd;
2041 char *buf;
2042 size_t buf_sz;
2043 off_t offset;
2044 struct timeval dispatch_time;
2045 struct timeval answer_time;
2046 dlink_node link;
2047 dlink_list queue;
2048 statefulhelper *parent;
2049 helper_stateful_request *request;
2050 struct _helper_stateful_flags {
2051 unsigned int alive:1;
2052 unsigned int busy:1;
2053 unsigned int closing:1;
2054 unsigned int shutdown:1;
2055 stateful_helper_reserve_t reserved:2;
2056 } flags;
2057 struct {
2058 int uses;
60d096f4 2059 int submits;
2060 int releases;
2061 int deferbyfunc;
2062 int deferbycb;
94439e4e 2063 } stats;
2064 size_t deferred_requests; /* current number of deferred requests */
2065 void *data; /* State data used by the calling routines */
2066};
2067
74addf6c 2068/*
2069 * use this when you need to pass callback data to a blocking
2070 * operation, but you don't want to add that pointer to cbdata
2071 */
2072struct _generic_cbdata {
2073 void *data;
2074};
b2c141d4 2075
2076struct _store_rebuild_data {
2077 int objcount; /* # objects successfully reloaded */
2078 int expcount; /* # objects expired */
2079 int scancount; /* # entries scanned or read from state file */
2080 int clashcount; /* # swapfile clashes avoided */
2081 int dupcount; /* # duplicates purged */
2082 int cancelcount; /* # SWAP_LOG_DEL objects purged */
2083 int invalid; /* # bad lines */
2084 int badflags; /* # bad e->flags */
2085 int bad_log_op;
2086 int zero_object_sz;
2087};
5673c2e2 2088
cd748f27 2089/*
2090 * This defines an fs type
2091 */
2092
2093struct _storefs_entry {
2094 char *typestr;
2095 STFSPARSE *parsefunc;
2096 STFSRECONFIGURE *reconfigurefunc;
2097 STFSSHUTDOWN *donefunc;
2098};
2099
22d38e05 2100/*
2101 * This defines an repl type
2102 */
2103
2104struct _storerepl_entry {
2105 char *typestr;
2106 REMOVALPOLICYCREATE *create;
2107};
2108
cd748f27 2109/*
2110 * Async disk IO - this defines a async disk io queue
2111 */
2112
2113struct _diskd_queue {
2114 int smsgid; /* send sysvmsg id */
2115 int rmsgid; /* recv sysvmsg id */
2116 int wfd; /* queue file descriptor ? */
2117 int away; /* number of requests away */
2118 int sent_count; /* number of messages sent */
2119 int recv_count; /* number of messages received */
2120 struct {
2121 char *buf; /* shm buffer */
a4b8110e 2122 link_list *stack;
cd748f27 2123 int id; /* sysvshm id */
2124 } shm;
2125};
2126
5673c2e2 2127struct _Logfile {
2128 int fd;
2129 char path[MAXPATHLEN];
2130 char *buf;
2131 size_t bufsz;
2132 off_t offset;
08e8e020 2133 struct {
2134 unsigned int fatal:1;
2135 } flags;
5673c2e2 2136};
8e8d4f30 2137
2138struct cache_dir_option {
2139 char *name;
2140 void (*parse) (SwapDir * sd, const char *option, const char *value, int reconfiguring);
25a77f03 2141 void (*dump) (StoreEntry * e, const char *option, SwapDir * sd);
8e8d4f30 2142};
b5638623 2143
2144#endif /* SQUID_STRUCTS_H */