static void peerCountMcastPeersDone(void *data) { ps_state *psstate = data; peer *p = psstate->callback_data; StoreEntry *fake = psstate->entry; if (cbdataValid(p)) { p->mcast.flags.counting = 0; p->mcast.avg_n_members = doubleAverage(p->mcast.avg_n_members, (double) psstate->ping.n_recv, ++p->mcast.n_times_counted, 10); debug(15, 1) ("Group %s: %d replies, %4.1f average, RTT %d\n", p->host, psstate->ping.n_recv, p->mcast.avg_n_members, p->stats.rtt); p->mcast.n_replies_expected = (int) p->mcast.avg_n_members; } cbdataUnlock(p); EBIT_SET(fake->flags, ENTRY_ABORTED); requestUnlink(fake->mem_obj->request); fake->mem_obj->request = NULL; storeReleaseRequest(fake); storeUnlockObject(fake); requestUnlink(psstate->request); cbdataFree(psstate); }
/* free fetch state structures * must be called only when fetch cbdata is valid */ static void peerDigestFetchFinish(DigestFetchState * fetch, int err) { assert(fetch->entry && fetch->request); if (fetch->old_entry) { debug(72, 2) ("peerDigestFetchFinish: deleting old entry\n"); storeUnregister(fetch->old_entry, fetch); storeReleaseRequest(fetch->old_entry); storeUnlockObject(fetch->old_entry); fetch->old_entry = NULL; } /* update global stats */ kb_incr(&Counter.cd.kbytes_sent, (size_t) fetch->sent.bytes); kb_incr(&Counter.cd.kbytes_recv, (size_t) fetch->recv.bytes); Counter.cd.msgs_sent += fetch->sent.msg; Counter.cd.msgs_recv += fetch->recv.msg; /* unlock everything */ storeUnregister(fetch->entry, fetch); storeUnlockObject(fetch->entry); requestUnlink(fetch->request); fetch->entry = NULL; fetch->request = NULL; assert(fetch->pd == NULL); cbdataUnlock(fetch); cbdataFree(fetch); }
static void asyncPrefetchTs(const char *url) { debug(207, 1) ("start asyncPrefetchTs async prefetch: '%s'\n", url); request_t *request = NULL; StoreEntry *entry = NULL; request = modifyRequestUrlstoreUrl(url); request->flags.cachable = CACHE; if (storeGetPublicByRequest(request) != NULL) { debug(207, 3) ("this entry has already exist,give up async prefetch: '%s'\n", request->store_url); return; } entry = storeCreateEntry(urlCanonical(request), request->flags, request->method); if (request->store_url) storeEntrySetStoreUrl(entry, request->store_url); if(Config.onoff.collapsed_forwarding) { EBIT_SET(entry->flags, KEY_EARLY_PUBLIC); storeSetPublicKey(entry); } fwdStart(-1, entry, request); requestUnlink(request); }
static void waisStateFree(int fdnotused, void *data) { WaisStateData *waisState = data; if (waisState == NULL) return; storeUnlockObject(waisState->entry); requestUnlink(waisState->request); cbdataFree(waisState); }
static void asStateFree(void *data) { ASState *asState = data; debug(53, 3) ("asStateFree: %s\n", storeUrl(asState->entry)); storeClientUnregister(asState->sc, asState->entry, asState); storeUnlockObject(asState->entry); requestUnlink(asState->request); cbdataFree(asState); }
static void netdbExchangeDone(void *data) { netdbExchangeState *ex = data; debug(38, 3) ("netdbExchangeDone: %s\n", storeUrl(ex->e)); requestUnlink(ex->r); storeClientUnregister(ex->sc, ex->e, ex); storeUnlockObject(ex->e); cbdataUnlock(ex->p); cbdataFree(ex); }
static inline void modify_request(clientHttpRequest * http) { debug(97, 3)("modify_request: start, uri=[%s]\n", http->uri); request_t* old_request = http->request; request_t* new_request = urlParse(old_request->method, http->uri); safe_free(http->uri); if (new_request) { safe_free(http->uri); http->uri = xstrdup(urlCanonical(new_request)); if(!http->log_uri) http->log_uri = xstrdup(urlCanonicalClean(old_request)); new_request->http_ver = old_request->http_ver; httpHeaderAppend(&new_request->header, &old_request->header); new_request->client_addr = old_request->client_addr; new_request->client_port = old_request->client_port; #if FOLLOW_X_FORWARDED_FOR new_request->indirect_client_addr = old_request->indirect_client_addr; #endif /* FOLLOW_X_FORWARDED_FOR */ new_request->my_addr = old_request->my_addr; new_request->my_port = old_request->my_port; new_request->flags = old_request->flags; new_request->flags.redirected = 1; if (old_request->auth_user_request) { new_request->auth_user_request = old_request->auth_user_request; authenticateAuthUserRequestLock(new_request->auth_user_request); } if (old_request->body_reader) { new_request->body_reader = old_request->body_reader; new_request->body_reader_data = old_request->body_reader_data; old_request->body_reader = NULL; old_request->body_reader_data = NULL; } new_request->content_length = old_request->content_length; if (strBuf(old_request->extacl_log)) new_request->extacl_log = stringDup(&old_request->extacl_log); if (old_request->extacl_user) new_request->extacl_user = xstrdup(old_request->extacl_user); if (old_request->extacl_passwd) new_request->extacl_passwd = xstrdup(old_request->extacl_passwd); if(old_request->cc_request_private_data) { new_request->cc_request_private_data = old_request->cc_request_private_data; old_request->cc_request_private_data = NULL; } requestUnlink(old_request); http->request = requestLink(new_request); } }
static void errorMapFetchComplete(ErrorMapState * state) { storeClientUnregister(state->sc, state->e, state); state->sc = NULL; storeUnlockObject(state->e); state->e = NULL; requestUnlink(state->req); state->req = NULL; cbdataUnlock(state->callback_data); state->callback_data = NULL; cbdataFree(state); }
static void peerMonitorCompleted(PeerMonitor * pm) { int state = PEER_ALIVE; peer *p = pm->peer; storeClientUnregister(pm->running.sc, pm->running.e, pm); storeUnlockObject(pm->running.e); requestUnlink(pm->running.req); memFree(pm->running.buf, MEM_4K_BUF); if (pm->running.timeout_set) { eventDelete(peerMonitorTimeout, pm); pm->running.timeout_set = 0; } if (!cbdataValid(pm->peer)) { cbdataFree(pm); return; } /* Figure out if the response was OK or not */ if (pm->running.status != HTTP_OK) { debug(DBG, 1) ("peerMonitor %s: Failed, status != 200 (%d)\n", p->name, pm->running.status); state = PEER_DEAD; } else if (pm->running.size < p->monitor.min) { debug(DBG, 1) ("peerMonitor %s: Failed, reply size %d < min %d\n", p->name, pm->running.size, p->monitor.min); state = PEER_DEAD; } else if (pm->running.size > p->monitor.max && p->monitor.max > 0) { debug(DBG, 1) ("peerMonitor %s: Failed, reply size %d > max %d\n", p->name, pm->running.size, p->monitor.max); state = PEER_DEAD; } else { debug(DBG, 2) ("peerMonitor %s: OK\n", p->name); } p->monitor.state = state; if (state != p->stats.logged_state) { switch (state) { case PEER_ALIVE: debug(DBG, 1) ("Detected REVIVED %s: %s\n", neighborTypeStr(p), p->name); peerClearRR(); break; case PEER_DEAD: debug(DBG, 1) ("Detected DEAD %s: %s\n", neighborTypeStr(p), p->name); break; } p->stats.logged_state = state; } memset(&pm->running, 0, sizeof(pm->running)); eventAdd(pm->name, peerMonitorRequest, pm, (double) (pm->last_probe + pm->peer->monitor.interval - current_dtime), 1); }
static void gopherStateFree(int fdnotused, void *data) { GopherStateData *gopherState = data; if (gopherState == NULL) return; if (gopherState->entry) { storeUnlockObject(gopherState->entry); } if (gopherState->req) { requestUnlink(gopherState->req); } memFree(gopherState->buf, MEM_4K_BUF); gopherState->buf = NULL; cbdataFree(gopherState); }
void errorStateFree(ErrorState * err) { requestUnlink(err->request); safe_free(err->redirect_url); safe_free(err->url); safe_free(err->dnsserver_msg); safe_free(err->request_hdrs); wordlistDestroy(&err->ftp.server_msg); safe_free(err->ftp.request); safe_free(err->ftp.reply); if (err->auth_user_request) authenticateAuthUserRequestUnlock(err->auth_user_request); err->auth_user_request = NULL; cbdataFree(err); }
static void authNegotiateRequestFree(negotiate_request_t * negotiate_request) { if (!negotiate_request) return; safe_free(negotiate_request->server_blob); safe_free(negotiate_request->client_blob); if (negotiate_request->authserver != NULL) { debug(29, 9) ("authenticateNegotiateRequestFree: releasing server '%p'\n", negotiate_request->authserver); authenticateNegotiateReleaseServer(negotiate_request); } if (negotiate_request->request) { requestUnlink(negotiate_request->request); negotiate_request->request = NULL; } memPoolFree(negotiate_request_pool, negotiate_request); }
static void peerSelectStateFree(ps_state * psstate) { if (psstate->acl_checklist) { debug(44, 1) ("calling aclChecklistFree() from peerSelectStateFree\n"); aclChecklistFree(psstate->acl_checklist); } requestUnlink(psstate->request); psstate->request = NULL; if (psstate->entry) { assert(psstate->entry->ping_status != PING_WAITING); storeUnlockObject(psstate->entry); psstate->entry = NULL; } cbdataFree(psstate); }
static void sslStateFree(SslStateData * sslState) { debug(26, 3) ("sslStateFree: sslState=%p\n", sslState); assert(sslState != NULL); assert(sslState->client.fd == -1); assert(sslState->server.fd == -1); safe_free(sslState->server.buf); safe_free(sslState->client.buf); safe_free(sslState->url); fwdServersFree(&sslState->servers); sslState->host = NULL; requestUnlink(sslState->request); sslState->request = NULL; #if DELAY_POOLS delayUnregisterDelayIdPtr(&sslState->delay_id); #endif cbdataFree(sslState); }
/* finishes swap out sequence for the digest; schedules next rewrite */ static void storeDigestRewriteFinish(StoreEntry * e) { assert(sd_state.rewrite_lock && e == sd_state.rewrite_lock->data); storeComplete(e); storeTimestampsSet(e); debug(71, 2) ("storeDigestRewriteFinish: digest expires at %ld (%+d)\n", (long int) e->expires, (int) (e->expires - squid_curtime)); /* is this the write order? @?@ */ requestUnlink(e->mem_obj->request); e->mem_obj->request = NULL; storeUnlockObject(e); cbdataFree(sd_state.rewrite_lock); e = NULL; sd_state.rewrite_lock = NULL; sd_state.rewrite_count++; eventAdd("storeDigestRewriteStart", storeDigestRewriteStart, NULL, (double) Config.digest.rewrite_period, 1); /* resume pending Rebuild if any */ if (sd_state.rebuild_lock) storeDigestRebuildResume(); }
static void authenticateNegotiateHandleReply(void *data, void *srv, char *reply) { authenticateStateData *r = data; int valid; auth_user_request_t *auth_user_request; auth_user_t *auth_user; negotiate_user_t *negotiate_user; negotiate_request_t *negotiate_request; char *blob, *arg; debug(29, 9) ("authenticateNegotiateHandleReply: Helper: '%p' {%s}\n", srv, reply ? reply : "<NULL>"); valid = cbdataValid(r->data); if (!valid) { debug(29, 2) ("AuthenticateNegotiateHandleReply: invalid callback data. Releasing helper '%p'.\n", srv); negotiate_request = r->auth_user_request->scheme_data; if (negotiate_request != NULL) { if (negotiate_request->authserver == NULL) negotiate_request->authserver = srv; authenticateNegotiateReleaseServer(negotiate_request); } cbdataUnlock(r->data); authenticateStateFree(r); return; } if (!reply) { debug(29, 1) ("AuthenticateNegotiateHandleReply: Helper '%p' crashed!.\n", srv); reply = (char *) "BH Internal error"; } auth_user_request = r->auth_user_request; negotiate_request = auth_user_request->scheme_data; assert(negotiate_request != NULL); assert(negotiate_request->waiting); negotiate_request->waiting = 0; safe_free(negotiate_request->client_blob); auth_user = auth_user_request->auth_user; assert(auth_user != NULL); assert(auth_user->auth_type == AUTH_NEGOTIATE); negotiate_user = auth_user_request->auth_user->scheme_data; if (negotiate_request->authserver == NULL) negotiate_request->authserver = srv; else assert(negotiate_request->authserver == srv); /* seperate out the useful data */ blob = strchr(reply, ' '); if (blob) { blob++; arg = strchr(blob + 1, ' '); } else { arg = NULL; } if (strncasecmp(reply, "TT ", 3) == 0) { /* we have been given a blob to send to the client */ if (arg) *arg++ = '\0'; safe_free(negotiate_request->server_blob); negotiate_request->request->flags.must_keepalive = 1; if (negotiate_request->request->flags.proxy_keepalive) { negotiate_request->server_blob = xstrdup(blob); negotiate_request->auth_state = AUTHENTICATE_STATE_NEGOTIATE; safe_free(auth_user_request->message); auth_user_request->message = xstrdup("Authentication in progress"); debug(29, 4) ("authenticateNegotiateHandleReply: Need to challenge the client with a server blob '%s'\n", blob); } else { negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; safe_free(auth_user_request->message); auth_user_request->message = xstrdup("NTLM authentication requires a persistent connection"); } } else if (strncasecmp(reply, "AF ", 3) == 0 && arg != NULL) { auth_user_hash_pointer *usernamehash; /* we're finished, release the helper */ if (arg) *arg++ = '\0'; safe_free(negotiate_user->username); negotiate_user->username = xstrdup(arg); safe_free(auth_user_request->message); auth_user_request->message = xstrdup("Login successful"); safe_free(negotiate_request->server_blob); negotiate_request->server_blob = xstrdup(blob); debug(29, 4) ("authenticateNegotiateHandleReply: Successfully validated user via Negotiate. Username '%s'\n", arg); /* this connection is authenticated */ debug(29, 4) ("authenticated user %s\n", negotiate_user->username); /* see if this is an existing user with a different proxy_auth * string */ usernamehash = hash_lookup(proxy_auth_username_cache, negotiate_user->username); if (usernamehash) { while (usernamehash && (usernamehash->auth_user->auth_type != auth_user->auth_type || authenticateNegotiatecmpUsername(usernamehash->auth_user->scheme_data, negotiate_user) != 0)) usernamehash = usernamehash->next; } if (usernamehash) { /* we can't seamlessly recheck the username due to the * challenge nature of the protocol. Just free the * temporary auth_user */ authenticateAuthUserMerge(auth_user, usernamehash->auth_user); auth_user = usernamehash->auth_user; auth_user_request->auth_user = auth_user; } else { /* store user in hash's */ authenticateUserNameCacheAdd(auth_user); } /* set these to now because this is either a new login from an * existing user or a new user */ auth_user->expiretime = current_time.tv_sec; authenticateNegotiateReleaseServer(negotiate_request); negotiate_request->auth_state = AUTHENTICATE_STATE_DONE; } else if (strncasecmp(reply, "NA ", 3) == 0 && arg != NULL) { if (arg) *arg++ = '\0'; safe_free(auth_user_request->message); auth_user_request->message = xstrdup(arg); negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; safe_free(negotiate_request->server_blob); negotiate_request->server_blob = xstrdup(blob); authenticateNegotiateReleaseServer(negotiate_request); debug(29, 4) ("authenticateNegotiateHandleReply: Failed validating user via Negotiate. Error returned '%s'\n", arg); } else if (strncasecmp(reply, "BH ", 3) == 0) { /* TODO kick off a refresh process. This can occur after a YR or after * a KK. If after a YR release the helper and resubmit the request via * Authenticate Negotiate start. * If after a KK deny the user's request w/ 407 and mark the helper as * Needing YR. */ auth_user_request->message = xstrdup(blob); negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; safe_free(negotiate_request->server_blob); authenticateNegotiateReleaseServer(negotiate_request); debug(29, 1) ("authenticateNegotiateHandleReply: Error validating user via Negotiate. Error returned '%s'\n", reply); } else { fatalf("authenticateNegotiateHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } requestUnlink(negotiate_request->request); negotiate_request->request = NULL; r->handler(r->data, NULL); cbdataUnlock(r->data); authenticateStateFree(r); }
static void urnHandleReply(void *data, char *buf, ssize_t size) { UrnState *urnState = data; StoreEntry *e = urnState->entry; StoreEntry *urlres_e = urnState->urlres_e; char *s = NULL; size_t k; HttpReply *rep; url_entry *urls; url_entry *u; url_entry *min_u; MemBuf mb; ErrorState *err; int i; int urlcnt = 0; http_version_t version; debug(52, 3) ("urnHandleReply: Called with size=%d.\n", (int) size); if (EBIT_TEST(urlres_e->flags, ENTRY_ABORTED)) { memFree(buf, MEM_4K_BUF); return; } if (size == 0) { memFree(buf, MEM_4K_BUF); return; } else if (size < 0) { memFree(buf, MEM_4K_BUF); return; } if (urlres_e->store_status == STORE_PENDING && size < SM_PAGE_SIZE) { storeClientCopy(urnState->sc, urlres_e, size, 0, SM_PAGE_SIZE, buf, urnHandleReply, urnState); return; } /* we know its STORE_OK */ k = headersEnd(buf, size); if (0 == k) { debug(52, 1) ("urnHandleReply: didn't find end-of-headers for %s\n", storeUrl(e)); return; } s = buf + k; assert(urlres_e->mem_obj->reply); httpReplyParse(urlres_e->mem_obj->reply, buf, k); debug(52, 3) ("mem->reply exists, code=%d.\n", urlres_e->mem_obj->reply->sline.status); if (urlres_e->mem_obj->reply->sline.status != HTTP_OK) { debug(52, 3) ("urnHandleReply: failed.\n"); err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND); err->request = requestLink(urnState->request); err->url = xstrdup(storeUrl(e)); errorAppendEntry(e, err); return; } while (xisspace(*s)) s++; urls = urnParseReply(s, urnState->request->method); for (i = 0; NULL != urls[i].url; i++) urlcnt++; debug(53, 3) ("urnFindMinRtt: Counted %d URLs\n", i); if (urls == NULL) { /* unkown URN error */ debug(52, 3) ("urnTranslateDone: unknown URN %s\n", storeUrl(e)); err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND); err->request = requestLink(urnState->request); err->url = xstrdup(storeUrl(e)); errorAppendEntry(e, err); return; } min_u = urnFindMinRtt(urls, urnState->request->method, NULL); qsort(urls, urlcnt, sizeof(*urls), url_entry_sort); storeBuffer(e); memBufDefInit(&mb); memBufPrintf(&mb, "<TITLE>Select URL for %s</TITLE>\n" "<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}--></STYLE>\n" "<H2>Select URL for %s</H2>\n" "<TABLE BORDER=\"0\" WIDTH=\"100%%\">\n", storeUrl(e), storeUrl(e)); for (i = 0; i < urlcnt; i++) { u = &urls[i]; debug(52, 3) ("URL {%s}\n", u->url); memBufPrintf(&mb, "<TR><TD><A HREF=\"%s\">%s</A></TD>", u->url, u->url); if (urls[i].rtt > 0) memBufPrintf(&mb, "<TD align=\"right\">%4d <it>ms</it></TD>", u->rtt); else memBufPrintf(&mb, "<TD align=\"right\">Unknown</TD>"); memBufPrintf(&mb, "<TD>%s</TD></TR>\n", u->flags.cached ? " [cached]" : " "); } memBufPrintf(&mb, "</TABLE>" "<HR noshade size=\"1px\">\n" "<ADDRESS>\n" "Generated by %s@%s\n" "</ADDRESS>\n", full_appname_string, getMyHostname()); rep = e->mem_obj->reply; httpReplyReset(rep); httpBuildVersion(&version, 1, 0); httpReplySetHeaders(rep, version, HTTP_MOVED_TEMPORARILY, NULL, "text/html", mb.size, 0, squid_curtime); if (urnState->flags.force_menu) { debug(51, 3) ("urnHandleReply: forcing menu\n"); } else if (min_u) { httpHeaderPutStr(&rep->header, HDR_LOCATION, min_u->url); } httpBodySet(&rep->body, &mb); httpReplySwapOut(rep, e); storeComplete(e); memFree(buf, MEM_4K_BUF); for (i = 0; i < urlcnt; i++) { safe_free(urls[i].url); safe_free(urls[i].host); } safe_free(urls); /* mb was absorbed in httpBodySet call, so we must not clean it */ storeUnregister(urnState->sc, urlres_e, urnState); storeUnlockObject(urlres_e); storeUnlockObject(urnState->entry); requestUnlink(urnState->request); requestUnlink(urnState->urlres_r); cbdataFree(urnState); }
static void authenticateNegotiateAuthenticateUser(auth_user_request_t * auth_user_request, request_t * request, ConnStateData * conn, http_hdr_type type) { const char *proxy_auth, *blob; auth_user_t *auth_user; negotiate_request_t *negotiate_request; auth_user = auth_user_request->auth_user; assert(auth_user); assert(auth_user->auth_type == AUTH_NEGOTIATE); assert(auth_user->scheme_data != NULL); assert(auth_user_request->scheme_data != NULL); negotiate_request = auth_user_request->scheme_data; /* Check that we are in the client side, where we can generate * auth challenges */ if (!conn) { negotiate_request->auth_state = AUTHENTICATE_STATE_FAILED; debug(29, 1) ("authenticateNegotiateAuthenticateUser: attempt to perform authentication without a connection!\n"); return; } if (negotiate_request->waiting) { debug(29, 1) ("authenticateNegotiateAuthenticateUser: waiting for helper reply!\n"); return; } if (negotiate_request->server_blob) { debug(29, 2) ("authenticateNegotiateAuthenticateUser: need to challenge client '%s'!\n", negotiate_request->server_blob); return; } /* get header */ proxy_auth = httpHeaderGetStr(&request->header, type); blob = proxy_auth; while (xisspace(*blob) && *blob) blob++; while (!xisspace(*blob) && *blob) blob++; while (xisspace(*blob) && *blob) blob++; switch (negotiate_request->auth_state) { case AUTHENTICATE_STATE_NONE: /* we've received a negotiate request. pass to a helper */ debug(29, 9) ("authenticateNegotiateAuthenticateUser: auth state negotiate none. %s\n", proxy_auth); negotiate_request->auth_state = AUTHENTICATE_STATE_INITIAL; safe_free(negotiate_request->client_blob); negotiate_request->client_blob = xstrdup(blob); conn->auth_type = AUTH_NEGOTIATE; conn->auth_user_request = auth_user_request; negotiate_request->conn = conn; /* and lock for the connection duration */ debug(29, 9) ("authenticateNegotiateAuthenticateUser: Locking auth_user from the connection.\n"); authenticateAuthUserRequestLock(auth_user_request); negotiate_request->request = requestLink(request); return; break; case AUTHENTICATE_STATE_INITIAL: debug(29, 1) ("authenticateNegotiateAuthenticateUser: need to ask helper!\n"); return; break; case AUTHENTICATE_STATE_NEGOTIATE: /* we should have received a blob from the clien. pass it to the same * helper process */ debug(29, 9) ("authenticateNegotiateAuthenticateUser: auth state challenge with header %s.\n", proxy_auth); /* do a cache lookup here. If it matches it's a successful negotiate * challenge - release the helper and use the existing auth_user * details. */ safe_free(negotiate_request->client_blob); negotiate_request->client_blob = xstrdup(blob); if (negotiate_request->request) requestUnlink(negotiate_request->request); negotiate_request->request = requestLink(request); return; break; case AUTHENTICATE_STATE_DONE: fatal("authenticateNegotiateAuthenticateUser: unexpect auth state DONE! Report a bug to the squid developers.\n"); break; case AUTHENTICATE_STATE_FAILED: /* we've failed somewhere in authentication */ debug(29, 9) ("authenticateNegotiateAuthenticateUser: auth state negotiate failed. %s\n", proxy_auth); return; } return; }