--------------------- PatchSet 2182 Date: 2001/05/02 08:22:05 Author: rbcollins Branch: newhttp Tag: (none) Log: ugly but working peer selection. This needs to be shuffled to match broker layout but for getting the comms going it will suffice Members: src/broker.c:1.1.2.4->1.1.2.5 src/forward.c:1.1.1.3.8.7.2.3->1.1.1.3.8.7.2.3.2.1 src/http.c:1.1.1.3.4.1.4.12.2.16.2.2->1.1.1.3.4.1.4.12.2.16.2.3 src/peer_select.c:1.1.1.3.8.4.4.4->1.1.1.3.8.4.4.4.2.1 src/protos.h:1.1.1.3.8.11.2.20.2.3->1.1.1.3.8.11.2.20.2.4 src/structs.h:1.1.1.3.4.1.4.12.2.26.2.2->1.1.1.3.4.1.4.12.2.26.2.3 Index: squid/src/broker.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/Attic/broker.c,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -u -r1.1.2.4 -r1.1.2.5 --- squid/src/broker.c 2 May 2001 00:55:25 -0000 1.1.2.4 +++ squid/src/broker.c 2 May 2001 08:22:05 -0000 1.1.2.5 @@ -1,6 +1,6 @@ /* - * $Id: broker.c,v 1.1.2.4 2001/05/02 00:55:25 rbcollins Exp $ + * $Id: broker.c,v 1.1.2.5 2001/05/02 08:22:05 rbcollins Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Robert Collins @@ -399,13 +399,14 @@ switch (r->protocol) { case PROTO_HTTP: /* add the filter to call */ - filterChainAddTail(&http->reqfilters, identity_body,http_broker_entry,NULL,http); + filterChainAddTail(&http->reqfilters, identity_body,hierarchy_broker_entry,NULL,http); filterChainAdd(&http->repfilters, identity_body, broker_callback_hdr ,NULL,http); temp_filter=BrokerState->filters->node.next->data; rvflags = temp_filter->filter_hdr(BrokerState->rep,BrokerState->request,BrokerState->filter_list,temp_filter, BrokerState->flags, temp_filter->data); debug (3,3)("hroker got rvflags of %0x when forwarding the request\n",rvflags); cbdataUnlock(BrokerState); + return; break; case PROTO_NONE: Index: squid/src/forward.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/forward.c,v retrieving revision 1.1.1.3.8.7.2.3 retrieving revision 1.1.1.3.8.7.2.3.2.1 diff -u -r1.1.1.3.8.7.2.3 -r1.1.1.3.8.7.2.3.2.1 --- squid/src/forward.c 31 Mar 2001 11:28:54 -0000 1.1.1.3.8.7.2.3 +++ squid/src/forward.c 2 May 2001 08:22:05 -0000 1.1.1.3.8.7.2.3.2.1 @@ -1,6 +1,6 @@ /* - * $Id: forward.c,v 1.1.1.3.8.7.2.3 2001/03/31 11:28:54 rbcollins Exp $ + * $Id: forward.c,v 1.1.1.3.8.7.2.3.2.1 2001/05/02 08:22:05 rbcollins Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -188,6 +188,9 @@ assert(current != fwdState); current = fwdState; assert(fwdState->server_fd == server_fd); +/* hack */ + if (fwdState->http) + request=fwdState->http->request; if (status == COMM_ERR_DNS) { /* * Only set the dont_retry flag if the DNS lookup fails on @@ -226,11 +229,11 @@ } else { debug(17, 3) ("fwdConnectDone: FD %d: '%s'\n", server_fd, storeUrl(fwdState->entry)); if (fs->peer) - hierarchyNote(&fwdState->request->hier, fs->code, fs->peer->host); + hierarchyNote(&request->hier, fs->code, fs->peer->host); else if (Config.onoff.log_ip_on_direct) - hierarchyNote(&fwdState->request->hier, fs->code, fd_table[server_fd].ipaddr); + hierarchyNote(&request->hier, fs->code, fd_table[server_fd].ipaddr); else - hierarchyNote(&fwdState->request->hier, fs->code, request->host); + hierarchyNote(&request->hier, fs->code, request->host); fd_note(server_fd, storeUrl(fwdState->entry)); fd_table[server_fd].uses++; if (fs->peer) @@ -267,6 +270,75 @@ } static void +newfwdConnectStart(void *data) +{ + FwdState *fwdState = data; + int fd; + ErrorState *err; + FwdServer *fs = fwdState->servers; + const char *host; + unsigned short port; + time_t ctimeout; + assert(fs); + assert(fwdState->server_fd == -1); + debug(17, 3) ("fwdConnectStart: %s\n", fwdState->http->uri); + if (fs->peer) { + host = fs->peer->host; + port = fs->peer->http_port; + ctimeout = fs->peer->connect_timeout > 0 ? fs->peer->connect_timeout + : Config.Timeout.peer_connect; + } else if (fwdState->request->flags.accelerated && + Config.Accel.single_host && Config.Accel.host) { + host = Config.Accel.host; + port = Config.Accel.port; + ctimeout = Config.Timeout.connect; + } else { + host = fwdState->request->host; + port = fwdState->request->port; + ctimeout = Config.Timeout.connect; + } + if ((fd = pconnPop(host, port)) >= 0) { + debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd); + fwdState->server_fd = fd; + fwdState->n_tries++; + comm_add_close_handler(fd, fwdServerClosed, fwdState); + fwdConnectDone(fd, COMM_OK, fwdState); + return; + } + fd = comm_open(SOCK_STREAM, + 0, + Config.Addrs.tcp_outgoing, + 0, + COMM_NONBLOCKING, + fwdState->http->uri); + if (fd < 0) { + debug(50, 4) ("fwdConnectStart: %s\n", xstrerror()); + err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR); + err->xerrno = errno; + err->request = requestLink(fwdState->request); + fwdFail(fwdState, err); + fwdStateFree(fwdState); + return; + } + fwdState->server_fd = fd; + fwdState->n_tries++; + /* + * stats.conn_open is used to account for the number of + * connections that we have open to the peer, so we can limit + * based on the max-conn option. We need to increment here, + * even if the connection may fail. + */ + if (fs->peer) + fs->peer->stats.conn_open++; + comm_add_close_handler(fd, fwdServerClosed, fwdState); + commSetTimeout(fd, + ctimeout, + fwdConnectTimeout, + fwdState); + commConnectStart(fd, host, port, fwdConnectDone, fwdState); +} + +static void fwdConnectStart(void *data) { FwdState *fwdState = data; @@ -340,6 +412,19 @@ } static void +newfwdStartComplete(FwdServer * servers, void *data) +{ + FwdState *fwdState = data; + debug(17, 3) ("fwdStartComplete: %s\n", fwdState->http->uri); + if (servers != NULL) { + fwdState->servers = servers; + newfwdConnectStart(fwdState); + } else { + fwdStartFail(fwdState); + } +} + +static void fwdStartComplete(FwdServer * servers, void *data) { FwdState *fwdState = data; @@ -364,22 +449,24 @@ fwdStateFree(fwdState); } +/* handoff to the server side protocol +*/ static void fwdDispatch(FwdState * fwdState) { peer *p = NULL; - request_t *request = fwdState->request; - StoreEntry *entry = fwdState->entry; + request_t *request = fwdState->http->request; +// StoreEntry *entry = fwdState->entry; ErrorState *err; debug(17, 3) ("fwdDispatch: FD %d: Fetching '%s %s'\n", fwdState->client_fd, RequestMethodStr[request->method], - storeUrl(entry)); + fwdState->http->uri); /*assert(!EBIT_TEST(entry->flags, ENTRY_DISPATCHED)); */ - assert(entry->ping_status != PING_WAITING); +/* assert(entry->ping_status != PING_WAITING); assert(entry->lock_count); EBIT_SET(entry->flags, ENTRY_DISPATCHED); - netdbPingSite(request->host); + netdbPingSite(request->host); */ /* * Assert that server_fd is set. This is to guarantee that fwdState * is attached to something and will be deallocated when server_fd @@ -388,10 +475,10 @@ assert(fwdState->server_fd > -1); if (fwdState->servers && (p = fwdState->servers->peer)) { p->stats.fetches++; - fwdState->request->peer_login = p->login; + request->peer_login = p->login; httpStart(fwdState); } else { - fwdState->request->peer_login = NULL; + request->peer_login = NULL; switch (request->protocol) { case PROTO_HTTP: httpStart(fwdState); @@ -415,7 +502,7 @@ break; default: debug(17, 1) ("fwdDispatch: Cannot retrieve '%s'\n", - storeUrl(entry)); + fwdState->http->uri); err = errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST); err->request = requestLink(request); fwdFail(fwdState, err); @@ -489,6 +576,57 @@ } void +hierarchyHttpInit(void) +{ +} + +/* the broker calls this entry point to start a hierarchy based connection. + * We _do not_ handle the protocol locally. The protocol is handled by the protocol + * of the peer + */ +unsigned int +hierarchy_broker_entry(HttpReply *rep, clientHttpRequest *request, + dlink_list * filter_list,FILTER_list * filters, unsigned int flags, + void *data) +{ + clientHttpRequest *http=data; + FILTER_list *temp_filter; + FwdState *fwdState; + /* miss check are done by the broker before passing to us */ + debug(17, 3) ("fwdStart: '%s'\n", http->uri); + if (shutting_down) + return FILTER_ABORT; + /* in future we just lookup the handover function for the peer.. */ + + fwdState = cbdataAlloc(FwdState); + fwdState->rep=rep; + fwdState->http=request; + assert(request==http); + fwdState->filter_list=filter_list; + fwdState->filters=filters; + fwdState->filterflags=flags; + + +// fwdState->entry = e; +// fwdState->client_fd = fd; + fwdState->server_fd = -1; +// fwdState->request = requestLink(r); + fwdState->start = squid_curtime; +// storeLockObject(e); +// EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT); +// storeRegisterAbort(e, fwdAbort, fwdState); + newpeerSelect(http, newfwdStartComplete, fwdState); + + return 0; +// fatal("end of code\n"); +/* + temp_filter = filters->node.next->data; + return temp_filter->filter_hdr(rep, request, filter_list, + temp_filter, flags, temp_filter->data); +*/ +} + +void fwdStart(int fd, StoreEntry * e, request_t * r) { FwdState *fwdState; Index: squid/src/http.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/http.c,v retrieving revision 1.1.1.3.4.1.4.12.2.16.2.2 retrieving revision 1.1.1.3.4.1.4.12.2.16.2.3 diff -u -r1.1.1.3.4.1.4.12.2.16.2.2 -r1.1.1.3.4.1.4.12.2.16.2.3 --- squid/src/http.c 1 May 2001 23:32:18 -0000 1.1.1.3.4.1.4.12.2.16.2.2 +++ squid/src/http.c 2 May 2001 08:22:05 -0000 1.1.1.3.4.1.4.12.2.16.2.3 @@ -1,6 +1,6 @@ /* - * $Id: http.c,v 1.1.1.3.4.1.4.12.2.16.2.2 2001/05/01 23:32:18 rbcollins Exp $ + * $Id: http.c,v 1.1.1.3.4.1.4.12.2.16.2.3 2001/05/02 08:22:05 rbcollins Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -61,6 +61,7 @@ { } +/* this interface needs thought. */ unsigned int http_broker_entry(HttpReply *rep, clientHttpRequest *request, dlink_list * filter_list,FILTER_list * filters, unsigned int flags, Index: squid/src/peer_select.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/peer_select.c,v retrieving revision 1.1.1.3.8.4.4.4 retrieving revision 1.1.1.3.8.4.4.4.2.1 diff -u -r1.1.1.3.8.4.4.4 -r1.1.1.3.8.4.4.4.2.1 --- squid/src/peer_select.c 27 Apr 2001 14:39:05 -0000 1.1.1.3.8.4.4.4 +++ squid/src/peer_select.c 2 May 2001 08:22:05 -0000 1.1.1.3.8.4.4.4.2.1 @@ -1,6 +1,6 @@ /* - * $Id: peer_select.c,v 1.1.1.3.8.4.4.4 2001/04/27 14:39:05 rbcollins Exp $ + * $Id: peer_select.c,v 1.1.1.3.8.4.4.4.2.1 2001/05/02 08:22:05 rbcollins Exp $ * * DEBUG: section 44 Peer Selection Algorithm * AUTHOR: Duane Wessels @@ -74,7 +74,9 @@ "DIRECT_YES" }; +/* the new functions are storeentry clean */ static void peerSelectFoo(ps_state *); +static void newpeerSelectFoo(ps_state *); static void peerPingTimeout(void *data); static void peerSelectCallback(ps_state * psstate); static IRCB peerHandlePingReply; @@ -99,13 +101,15 @@ debug(44, 1) ("calling aclChecklistFree() from peerSelectStateFree\n"); aclChecklistFree(psstate->acl_checklist); } - requestUnlink(psstate->request); - psstate->request = NULL; +// requestUnlink(psstate->request); +// psstate->request = NULL; +/* if (psstate->entry) { assert(psstate->entry->ping_status != PING_WAITING); storeUnlockObject(psstate->entry); psstate->entry = NULL; } +*/ cbdataFree(psstate); } @@ -127,6 +131,29 @@ return n; } +void +newpeerSelect(clientHttpRequest *http, PSC * callback, + void *callback_data) +{ + ps_state *psstate; + debug(44, 3) ("peerSelect: %s\n", RequestMethodStr[http->request->method]); + psstate = cbdataAlloc(ps_state); +// psstate->request = requestLink(request); + psstate->request = NULL; + psstate->http=http; + psstate->entry = NULL; + psstate->callback = callback; + psstate->callback_data = callback_data; + psstate->direct = DIRECT_UNKNOWN; + psstate->never_direct=0; +#if USE_CACHE_DIGESTS + http->request->hier.peer_select_start = current_time; +#endif + if (psstate->entry) + storeLockObject(psstate->entry); + cbdataLock(callback_data); + newpeerSelectFoo(psstate); +} void peerSelect(request_t * request, @@ -155,6 +182,16 @@ } static void +newpeerCheckNeverDirectDone(int answer, void *data) +{ + ps_state *psstate = data; + psstate->acl_checklist = NULL; + debug(44, 3) ("peerCheckNeverDirectDone: %d\n", answer); + psstate->never_direct = answer ? 1 : -1; + newpeerSelectFoo(psstate); +} + +static void peerCheckNeverDirectDone(int answer, void *data) { ps_state *psstate = data; @@ -165,6 +202,17 @@ } static void +newpeerCheckAlwaysDirectDone(int answer, void *data) +{ + ps_state *psstate = data; + psstate->acl_checklist = NULL; + debug(44, 3) ("peerCheckAlwaysDirectDone: %d\n", answer); + psstate->always_direct = answer ? 1 : -1; + newpeerSelectFoo(psstate); +} + + +static void peerCheckAlwaysDirectDone(int answer, void *data) { ps_state *psstate = data; @@ -177,23 +225,25 @@ static void peerSelectCallback(ps_state * psstate) { - StoreEntry *entry = psstate->entry; +// StoreEntry *entry = psstate->entry; FwdServer *fs = psstate->servers; void *data = psstate->callback_data; +/* if (entry) { debug(44, 3) ("peerSelectCallback: %s\n", storeUrl(entry)); if (entry->ping_status == PING_WAITING) eventDelete(peerPingTimeout, psstate); entry->ping_status = PING_DONE; } +*/ if (fs == NULL) { - debug(44, 1) ("Failed to select source for '%s'\n", storeUrl(entry)); + debug(44, 1) ("Failed to select source for '%s'\n", psstate->http->uri); debug(44, 1) (" always_direct = %d\n", psstate->always_direct); debug(44, 1) (" never_direct = %d\n", psstate->never_direct); debug(44, 1) (" timedout = %d\n", psstate->ping.timedout); } psstate->ping.stop = current_time; - psstate->request->hier.ping = psstate->ping; + psstate->http->request->hier.ping = psstate->ping; if (cbdataValid(data)) { psstate->servers = NULL; psstate->callback(fs, data); @@ -233,6 +283,79 @@ } static void +newpeerSelectFoo(ps_state * ps) +{ + clientHttpRequest *http=ps->http; + request_t *request = http->request; + debug(44, 3) ("peerSelectFoo: '%s %s'\n", + RequestMethodStr[http->request->method], + http->request->host); + if (ps->direct == DIRECT_UNKNOWN) { + if (ps->always_direct == 0 && Config.accessList.AlwaysDirect) { + ps->acl_checklist = aclChecklistCreate( + Config.accessList.AlwaysDirect, + request, + NULL); /* ident */ + aclNBCheck(ps->acl_checklist, + newpeerCheckAlwaysDirectDone, + ps); + return; + } else if (ps->always_direct > 0) { + ps->direct = DIRECT_YES; + } else if (ps->never_direct == 0 && Config.accessList.NeverDirect) { + ps->acl_checklist = aclChecklistCreate( + Config.accessList.NeverDirect, + request, + NULL); /* ident */ + aclNBCheck(ps->acl_checklist, + newpeerCheckNeverDirectDone, + ps); + return; + } else if (ps->never_direct > 0) { + ps->direct = DIRECT_NO; + } else if (request->flags.loopdetect) { + ps->direct = DIRECT_YES; + } else if (peerCheckNetdbDirect(ps)) { + ps->direct = DIRECT_YES; + } else { + ps->direct = DIRECT_MAYBE; + } + debug(44, 3) ("peerSelectFoo: direct = %s\n", + DirectStr[ps->direct]); + } +/* FIXME: ping database that is not storeentry associated. + if (entry == NULL) { + (void) 0; + } else if (entry->ping_status == PING_NONE) { + peerGetSomeNeighbor(ps); + if (entry->ping_status == PING_WAITING) + return; + } else if (entry->ping_status == PING_WAITING) { + peerGetSomeNeighborReplies(ps); + entry->ping_status = PING_DONE; + } +*/ + switch (ps->direct) { + case DIRECT_YES: + peerGetSomeDirect(ps); + break; + case DIRECT_NO: + peerGetSomeParent(ps); + peerGetAllParents(ps); + break; + default: + if (Config.onoff.prefer_direct) + peerGetSomeDirect(ps); + if (request->flags.hierarchical || !Config.onoff.nonhierarchical_direct) + peerGetSomeParent(ps); + if (!Config.onoff.prefer_direct) + peerGetSomeDirect(ps); + break; + } + peerSelectCallback(ps); +} + +static void peerSelectFoo(ps_state * ps) { StoreEntry *entry = ps->entry; @@ -434,7 +557,7 @@ peerGetSomeParent(ps_state * ps) { peer *p; - request_t *request = ps->request; + request_t *request = ps->http->request; hier_code code = HIER_NONE; debug(44, 3) ("peerGetSomeParent: %s %s\n", RequestMethodStr[request->method], @@ -462,7 +585,7 @@ peerGetAllParents(ps_state * ps) { peer *p; - request_t *request = ps->request; + request_t *request = ps->http->request; /* Add all alive parents */ for (p = Config.peers; p; p = p->next) { /* XXX: neighbors.c lacks a public interface for enumerating Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.1.1.3.8.11.2.20.2.3 retrieving revision 1.1.1.3.8.11.2.20.2.4 diff -u -r1.1.1.3.8.11.2.20.2.3 -r1.1.1.3.8.11.2.20.2.4 --- squid/src/protos.h 2 May 2001 05:57:48 -0000 1.1.1.3.8.11.2.20.2.3 +++ squid/src/protos.h 2 May 2001 08:22:05 -0000 1.1.1.3.8.11.2.20.2.4 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.1.1.3.8.11.2.20.2.3 2001/05/02 05:57:48 adri Exp $ + * $Id: protos.h,v 1.1.1.3.8.11.2.20.2.4 2001/05/02 08:22:05 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -697,6 +697,7 @@ extern void cachemgrInit(void); extern void peerSelect(request_t *, StoreEntry *, PSC *, void *data); +extern void newpeerSelect(clientHttpRequest *,PSC *, void *data); extern void peerSelectInit(void); /* peer_digest.c */ Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.1.1.3.4.1.4.12.2.26.2.2 retrieving revision 1.1.1.3.4.1.4.12.2.26.2.3 diff -u -r1.1.1.3.4.1.4.12.2.26.2.2 -r1.1.1.3.4.1.4.12.2.26.2.3 --- squid/src/structs.h 1 May 2001 19:40:53 -0000 1.1.1.3.4.1.4.12.2.26.2.2 +++ squid/src/structs.h 2 May 2001 08:22:05 -0000 1.1.1.3.4.1.4.12.2.26.2.3 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.1.1.3.4.1.4.12.2.26.2.2 2001/05/01 19:40:53 adri Exp $ + * $Id: structs.h,v 1.1.1.3.4.1.4.12.2.26.2.3 2001/05/02 08:22:05 rbcollins Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1315,6 +1315,7 @@ struct _ps_state { request_t *request; + clientHttpRequest *http; StoreEntry *entry; int always_direct; int never_direct; @@ -1929,6 +1930,12 @@ }; struct _FwdState { +/* filter data */ + HttpReply *rep; + clientHttpRequest *http; + dlink_list * filter_list; + FILTER_list * filters; + unsigned int filterflags; int client_fd; StoreEntry *entry; request_t *request;