void refreshCheckSubmit(StoreEntry * entry, REFRESHCHECK * callback, void *callback_data) { MemBuf buf; const char *key; refresh_check_helper *def = Config.Program.refresh_check; refreshCheckState *state; dlink_node *node; refreshCheckState *oldstate = NULL; if (!def) { callback(callback_data, 0, NULL); return; } key = makeRefreshCheckRequest(entry, def->format); if (!key) { callback(callback_data, 0, NULL); return; } debug(84, 2) ("refreshCheckSubmit: for '%s'\n", key); /* Check for a pending lookup to hook into */ for (node = def->queue.head; node; node = node->next) { refreshCheckState *oldstatetmp = node->data; if (entry == oldstatetmp->entry) { oldstate = oldstatetmp; break; } } state = cbdataAlloc(refreshCheckState); state->def = def; cbdataLock(state->def); state->entry = entry; storeLockObject(entry); state->callback = callback; state->callback_data = callback_data; cbdataLock(state->callback_data); if (oldstate) { /* Hook into pending lookup */ state->queue = oldstate->queue; oldstate->queue = state; } else { /* No pending lookup found. Sumbit to helper */ /* Check for queue overload */ if (refreshCheckOverload(def)) { debug(84, 1) ("refreshCheckSubmit: queue overload\n"); cbdataFree(state); callback(callback_data, 0, "Overload"); return; } /* Send it off to the helper */ memBufDefInit(&buf); memBufPrintf(&buf, "%s\n", key); helperSubmit(def->helper, buf.buf, refreshCheckHandleReply, state); dlinkAdd(state, &state->list, &def->queue); memBufClean(&buf); } }
/* send the initial data to a basic authenticator module */ static void authenticateBasicStart(auth_user_request_t * auth_user_request, RH * handler, void *data) { authenticateStateData *r = NULL; char buf[8192]; char user[1024], pass[1024]; basic_data *basic_auth; assert(auth_user_request); assert(handler); assert(auth_user_request->auth_user->auth_type == AUTH_BASIC); assert(auth_user_request->auth_user->scheme_data != NULL); basic_auth = auth_user_request->auth_user->scheme_data; debug(29, 9) ("authenticateStart: '%s:%s'\n", basic_auth->username, basic_auth->passwd); if (basicConfig->authenticate == NULL) { handler(data, NULL); return; } /* check to see if the auth_user already has a request outstanding */ if (basic_auth->flags.credentials_ok == 2) { /* there is a request with the same credentials already being verified */ auth_basic_queue_node *node; node = xmalloc(sizeof(auth_basic_queue_node)); assert(node); /* save the details */ node->next = basic_auth->auth_queue; basic_auth->auth_queue = node; node->handler = handler; node->data = data; cbdataLock(data); return; } else { r = cbdataAlloc(authenticateStateData); r->handler = handler; cbdataLock(data); r->data = data; r->auth_user_request = auth_user_request; authenticateAuthUserRequestLock(r->auth_user_request); /* mark the user as haveing verification in progress */ basic_auth->flags.credentials_ok = 2; if (basicConfig->utf8) { latin1_to_utf8(user, sizeof(user), basic_auth->username); latin1_to_utf8(pass, sizeof(pass), basic_auth->passwd); xstrncpy(user, rfc1738_escape(user), sizeof(user)); xstrncpy(pass, rfc1738_escape(pass), sizeof(pass)); } else { xstrncpy(user, rfc1738_escape(basic_auth->username), sizeof(user)); xstrncpy(pass, rfc1738_escape(basic_auth->passwd), sizeof(pass)); } snprintf(buf, sizeof(buf), "%s %s\n", user, pass); helperSubmit(basicauthenticators, buf, authenticateBasicHandleReply, r); } }
void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, void *data, helper_stateful_server * srv) { helper_stateful_request *r = memAllocate(MEM_HELPER_STATEFUL_REQUEST); if (hlp == NULL) { debug(84, 3) ("helperStatefulSubmit: hlp == NULL\n"); callback(data, 0, NULL); return; } r->callback = callback; r->data = data; if (buf) r->buf = xstrdup(buf); cbdataLock(r->data); if (!srv) srv = helperStatefulGetServer(hlp); if (srv) { debug(84, 5) ("helperStatefulSubmit: sever %p, buf '%s'.\n", srv, buf ? buf : "NULL"); assert(!srv->request); assert(!srv->flags.busy); helperStatefulDispatch(srv, r); } else { debug(84, 9) ("helperStatefulSubmit: enqueued, buf '%s'.\n", buf ? buf : "NULL"); StatefulEnqueue(hlp, r); } }
/* add client with fd to client list */ store_client * storeClientListAdd(StoreEntry * e, void *data) { MemObject *mem = e->mem_obj; store_client *sc; assert(mem); #if STORE_CLIENT_LIST_DEBUG if (storeClientListSearch(mem, data) != NULL) assert(1 == 0); /* XXX die! */ #endif e->refcount++; mem->nclients++; sc = cbdataAlloc(store_client); cbdataLock(data); /* locked while we point to it */ sc->callback_data = data; sc->seen_offset = 0; sc->copy_offset = 0; sc->flags.disk_io_pending = 0; sc->entry = e; sc->type = storeClientType(e); dlinkAdd(sc, &sc->node, &mem->clients); #if DELAY_POOLS sc->delay_id = 0; #endif return sc; }
/* send the initial data to a digest authenticator module */ static void authenticateDigestStart(auth_user_request_t * auth_user_request, RH * handler, void *data) { authenticateStateData *r = NULL; char buf[8192]; digest_request_h *digest_request; digest_user_h *digest_user; assert(auth_user_request); assert(handler); assert(auth_user_request->auth_user->auth_type == AUTH_DIGEST); assert(auth_user_request->auth_user->scheme_data != NULL); assert(auth_user_request->scheme_data != NULL); digest_request = auth_user_request->scheme_data; digest_user = auth_user_request->auth_user->scheme_data; debug(29, 9) ("authenticateStart: '\"%s\":\"%s\"'\n", digest_user->username, digest_request->realm); if (digestConfig->authenticate == NULL) { handler(data, NULL); return; } r = cbdataAlloc(authenticateStateData); r->handler = handler; cbdataLock(data); r->data = data; r->auth_user_request = auth_user_request; authenticateAuthUserRequestLock(r->auth_user_request); snprintf(buf, 8192, "\"%s\":\"%s\"\n", digest_user->username, digest_request->realm); helperSubmit(digestauthenticators, buf, authenticateDigestHandleReply, r); }
void idnsPTRLookup(const struct in_addr addr, IDNSCB * callback, void *data) { idns_query *q; const char *ip = inet_ntoa(addr); q = cbdataAlloc(idns_query); q->tcp_socket = -1; q->id = idnsQueryID(); q->sz = rfc1035BuildPTRQuery(addr, q->buf, sizeof(q->buf), q->id, &q->query); debug(78, 3) ("idnsPTRLookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, ip, q->id); if (q->sz < 0) { /* problem with query data -- query not sent */ callback(data, NULL, 0, "Internal error"); cbdataFree(q); return; } if (idnsCachedLookup(q->query.name, callback, data)) { cbdataFree(q); return; } q->callback = callback; q->callback_data = data; cbdataLock(q->callback_data); q->start_t = current_time; idnsCacheQuery(q); idnsSendQuery(q); }
void peerSelect(request_t * request, StoreEntry * entry, PSC * callback, void *callback_data) { ps_state *psstate; if (entry) debug(44, 3) ("peerSelect: %s\n", storeUrl(entry)); else debug(44, 3) ("peerSelect: %s\n", RequestMethods[request->method].str); psstate = cbdataAlloc(ps_state); psstate->request = requestLink(request); psstate->entry = entry; psstate->callback = callback; psstate->callback_data = callback_data; psstate->direct = DIRECT_UNKNOWN; #if USE_CACHE_DIGESTS request->hier.peer_select_start = current_time; #endif if (psstate->entry) storeLockObject(psstate->entry); cbdataLock(callback_data); peerSelectFoo(psstate); }
int errorMapStart(const errormap * map, request_t * client_req, HttpReply * reply, const char *aclname, ERRMAPCB * callback, void *callback_data) { char squid_error[100]; int len = 0; const char *errorUrl; ErrorMapState *state; const char *tmp; http_status status; request_t *req; HttpHeaderPos hdrpos; HttpHeaderEntry *hdr; if (!client_req || !reply) return 0; status = reply->sline.status; tmp = httpHeaderGetStr(&reply->header, HDR_X_SQUID_ERROR); squid_error[0] = '\0'; if (tmp) { xstrncpy(squid_error, tmp, sizeof(squid_error)); len = strcspn(squid_error, " "); } squid_error[len] = '\0'; errorUrl = getErrorMap(map, status, squid_error, aclname); if (!errorUrl) return 0; req = urlParse(urlMethodGetKnownByCode(METHOD_GET), (char *) errorUrl); if (!req) { debug(0, 0) ("errorMapStart: Invalid error URL '%s'\n", errorUrl); return 0; } req->urlgroup = xstrdup("error"); state = cbdataAlloc(ErrorMapState); state->req = requestLink(req); state->e = storeCreateEntry(errorUrl, req->flags, req->method); state->sc = storeClientRegister(state->e, state); state->callback = callback; state->callback_data = callback_data; cbdataLock(callback_data); hdrpos = HttpHeaderInitPos; while ((hdr = httpHeaderGetEntry(&client_req->header, &hdrpos)) != NULL) { if (CBIT_TEST(client_headers, hdr->id)) httpHeaderAddClone(&req->header, hdr); } hdrpos = HttpHeaderInitPos; while ((hdr = httpHeaderGetEntry(&reply->header, &hdrpos)) != NULL) { if (CBIT_TEST(server_headers, hdr->id)) httpHeaderAddClone(&req->header, hdr); } httpHeaderPutInt(&req->header, HDR_X_ERROR_STATUS, (int) reply->sline.status); httpHeaderPutStr(&req->header, HDR_X_REQUEST_URI, urlCanonical(client_req)); fwdStart(-1, state->e, req); storeClientRef(state->sc, state->e, 0, 0, SM_PAGE_SIZE, errorMapFetchHeaders, state); return 1; }
void aioWrite(int fd, int offset, char *bufp, int len, AIOCB * callback, void *callback_data, FREE * free_func) { squidaio_ctrl_t *ctrlp; int seekmode; assert(initialised); squidaio_counts.write++; ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = fd; ctrlp->done_handler = callback; ctrlp->done_handler_data = callback_data; ctrlp->operation = _AIO_WRITE; ctrlp->bufp = bufp; ctrlp->free_func = free_func; if (offset >= 0) seekmode = SEEK_SET; else { seekmode = SEEK_END; offset = 0; } cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_write(fd, bufp, len, offset, seekmode, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); } /* aioWrite */
void aioRead(int fd, int offset, int len, AIOCB * callback, void *callback_data) { squidaio_ctrl_t *ctrlp; int seekmode; assert(initialised); squidaio_counts.read++; ctrlp = memPoolAlloc(squidaio_ctrl_pool); ctrlp->fd = fd; ctrlp->done_handler = callback; ctrlp->done_handler_data = callback_data; ctrlp->operation = _AIO_READ; ctrlp->len = len; ctrlp->bufp = squidaio_xmalloc(len); if (offset >= 0) seekmode = SEEK_SET; else { seekmode = SEEK_CUR; offset = 0; } cbdataLock(callback_data); ctrlp->result.data = ctrlp; squidaio_read(fd, ctrlp->bufp, len, offset, seekmode, &ctrlp->result); dlinkAdd(ctrlp, &ctrlp->node, &used_list); return; } /* aioRead */
void aioOpen(const char *path, int oflag, mode_t mode, AIOCB * callback, void *callback_data) { aio_ctrl_t *ctrlp; int ret; assert(initialised); aio_counts.open++; ctrlp = memPoolAlloc(aio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; ctrlp->done_handler_data = callback_data; ctrlp->operation = _AIO_OPEN; cbdataLock(callback_data); if (aio_open(path, oflag, mode, &ctrlp->result) < 0) { ret = open(path, oflag, mode); if (callback) (callback) (ctrlp->fd, callback_data, ret, errno); cbdataUnlock(callback_data); memPoolFree(aio_ctrl_pool, ctrlp); return; } ctrlp->next = used_list; used_list = ctrlp; return; }
static void storeClientCopy2(StoreEntry * e, store_client * sc) { if (sc->flags.copy_event_pending) return; if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) { debug(20, 5) ("storeClientCopy2: returning because ENTRY_FWD_HDR_WAIT set\n"); return; } if (sc->flags.store_copying) { sc->flags.copy_event_pending = 1; debug(20, 3) ("storeClientCopy2: Queueing storeClientCopyEvent()\n"); eventAdd("storeClientCopyEvent", storeClientCopyEvent, sc, 0.0, 0); return; } cbdataLock(sc); /* ick, prevent sc from getting freed */ sc->flags.store_copying = 1; debug(20, 3) ("storeClientCopy2: %s\n", storeKeyText(e->hash.key)); assert(sc->callback != NULL); /* * We used to check for ENTRY_ABORTED here. But there were some * problems. For example, we might have a slow client (or two) and * the server-side is reading far ahead and swapping to disk. Even * if the server-side aborts, we want to give the client(s) * everything we got before the abort condition occurred. */ storeClientCopy3(e, sc); sc->flags.store_copying = 0; cbdataUnlock(sc); /* ick, allow sc to be freed */ }
void aioStat(char *path, struct stat *sb, AIOCB * callback, void *callback_data) { aio_ctrl_t *ctrlp; assert(initialised); aio_counts.stat++; ctrlp = memPoolAlloc(aio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; ctrlp->done_handler_data = callback_data; ctrlp->operation = _AIO_STAT; cbdataLock(callback_data); if (aio_stat(path, sb, &ctrlp->result) < 0) { if (errno == ENOMEM || errno == EAGAIN || errno == EINVAL) errno = EWOULDBLOCK; if (callback) (callback) (ctrlp->fd, callback_data, -1, errno); cbdataUnlock(callback_data); memPoolFree(aio_ctrl_pool, ctrlp); return; } ctrlp->next = used_list; used_list = ctrlp; return; } /* aioStat */
void aioUnlink(const char *pathname, AIOCB * callback, void *callback_data) { aio_ctrl_t *ctrlp; char *path; assert(initialised); aio_counts.unlink++; ctrlp = memPoolAlloc(aio_ctrl_pool); ctrlp->fd = -2; ctrlp->done_handler = callback; ctrlp->done_handler_data = callback_data; ctrlp->operation = _AIO_UNLINK; path = xstrdup(pathname); cbdataLock(callback_data); if (aio_unlink(path, &ctrlp->result) < 0) { int ret = unlink(path); (callback) (ctrlp->fd, callback_data, ret, errno); cbdataUnlock(callback_data); memPoolFree(aio_ctrl_pool, ctrlp); xfree(path); return; } ctrlp->next = used_list; used_list = ctrlp; xfree(path); } /* aioUnlink */
void storeSwapInStart(store_client * sc) { StoreEntry *e = sc->entry; assert(e->mem_status == NOT_IN_MEMORY); if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) { /* We're still reloading and haven't validated this entry yet */ return; } debug(20, 3) ("storeSwapInStart: called for %08X %s \n", e->swap_file_number, storeKeyText(e->key)); if (e->swap_status != SWAPOUT_WRITING && e->swap_status != SWAPOUT_DONE) { debug(20, 1) ("storeSwapInStart: bad swap_status (%s)\n", swapStatusStr[e->swap_status]); return; } if (e->swap_file_number < 0) { debug(20, 1) ("storeSwapInStart: swap_file_number < 0\n"); return; } assert(e->mem_obj != NULL); debug(20, 3) ("storeSwapInStart: Opening fileno %08X\n", e->swap_file_number); sc->swapin_sio = storeOpen(e->swap_file_number, O_RDONLY, storeSwapInFileClosed, sc); cbdataLock(sc->swapin_sio); }
void netdbExchangeStart(void *data) { #if USE_ICMP peer *p = data; char *uri; netdbExchangeState *ex; method_t *method_get; CBDATA_INIT_TYPE(netdbExchangeState); ex = cbdataAlloc(netdbExchangeState); cbdataLock(p); ex->p = p; uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", "netdb"); debug(38, 3) ("netdbExchangeStart: Requesting '%s'\n", uri); assert(NULL != uri); method_get = urlMethodGetKnownByCode(METHOD_GET); ex->r = urlParse(method_get, uri); if (NULL == ex->r) { debug(38, 1) ("netdbExchangeStart: Bad URI %s\n", uri); return; } requestLink(ex->r); assert(NULL != ex->r); httpBuildVersion(&ex->r->http_ver, 1, 0); ex->e = storeCreateEntry(uri, null_request_flags, method_get); assert(NULL != ex->e); ex->sc = storeClientRegister(ex->e, ex); storeClientRef(ex->sc, ex->e, ex->seen, ex->used, SM_PAGE_SIZE, netdbExchangeHandleReply, ex); ex->r->flags.loopdetect = 1; /* cheat! -- force direct */ if (p->login) xstrncpy(ex->r->login, p->login, MAX_LOGIN_SZ); fwdStart(-1, ex->e, ex->r); #endif }
/* add client with fd to client list */ void storeClientListAdd(StoreEntry * e, void *data) { MemObject *mem = e->mem_obj; store_client **T; store_client *sc; assert(mem); if (storeClientListSearch(mem, data) != NULL) return; e->refcount++; mem->nclients++; sc = memAllocate(MEM_STORE_CLIENT); cbdataAdd(sc, memFree, MEM_STORE_CLIENT); /* sc is callback_data for file_read */ cbdataLock(data); /* locked while we point to it */ sc->callback_data = data; sc->seen_offset = 0; sc->copy_offset = 0; sc->flags.disk_io_pending = 0; sc->entry = e; sc->type = storeClientType(e); if (sc->type == STORE_DISK_CLIENT) /* assert we'll be able to get the data we want */ /* maybe we should open swapin_fd here */ assert(e->swap_file_number > -1 || storeSwapOutAble(e)); for (T = &mem->clients; *T; T = &(*T)->next); *T = sc; #if DELAY_POOLS sc->delay_id = 0; #endif }
/* Read from client side and queue it for writing to the server */ static void sslReadClient(int fd, void *data) { SslStateData *sslState = data; int len; assert(fd == sslState->client.fd); debug(26, 3) ("sslReadClient: FD %d, reading %d bytes at offset %d\n", fd, SQUID_TCP_SO_RCVBUF - sslState->client.len, sslState->client.len); Counter.syscalls.sock.reads++; len = read(fd, sslState->client.buf + sslState->client.len, SQUID_TCP_SO_RCVBUF - sslState->client.len); debug(26, 3) ("sslReadClient: FD %d, read %d bytes\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_READ); kb_incr(&Counter.client_http.kbytes_in, len); sslState->client.len += len; } cbdataLock(sslState); if (len < 0) { debug(50, ECONNRESET == errno ? 3 : 1) ("sslReadClient: FD %d: read failure: %s\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } else if (len == 0) { comm_close(fd); } if (cbdataValid(sslState)) sslSetSelect(sslState); cbdataUnlock(sslState); }
storeIOState * storeDiskdCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data) { sfileno f; int x; storeIOState *sio; char *buf; int shm_offset; diskdinfo_t *diskdinfo = SD->fsdata; diskdstate_t *diskdstate; /* * Fail on open() if there are too many requests queued. */ if (diskdinfo->away > diskdinfo->magic1) { diskd_stats.open_fail_queue_len++; return NULL; } /* Allocate a number */ f = storeDiskdDirMapBitAllocate(SD); debug(79, 3) ("storeDiskdCreate: fileno %08X\n", f); CBDATA_INIT_TYPE_FREECB(storeIOState, storeDiskdIOFreeEntry); sio = cbdataAlloc(storeIOState); sio->fsstate = diskdstate = memPoolAlloc(diskd_state_pool); sio->swap_filen = f; sio->swap_dirn = SD->index; sio->mode = O_WRONLY | O_CREAT | O_TRUNC; sio->callback = callback; sio->callback_data = callback_data; sio->e = e; cbdataLock(callback_data); diskdstate->flags.writing = 0; diskdstate->flags.reading = 0; diskdstate->flags.close_request = 0; diskdstate->id = diskd_stats.sio_id++; buf = storeDiskdShmGet(SD, &shm_offset); xstrncpy(buf, storeDiskdDirFullPath(SD, f, NULL), SHMBUF_BLKSZ); x = storeDiskdSend(_MQD_OPEN, SD, diskdstate->id, sio, strlen(buf) + 1, sio->mode, shm_offset); if (x < 0) { debug(79, 1) ("storeDiskdSend OPEN: %s\n", xstrerror()); storeDiskdShmPut(SD, shm_offset); cbdataUnlock(sio->callback_data); cbdataFree(sio); return NULL; } storeDiskdDirReplAdd(SD, e); diskd_stats.create.ops++; return sio; }
void idnsALookup(const char *name, IDNSCB * callback, void *data) { unsigned int i; int nd = 0; idns_query *q; if (idnsCachedLookup(name, callback, data)) return; q = cbdataAlloc(idns_query); q->tcp_socket = -1; q->id = idnsQueryID(); for (i = 0; i < strlen(name); i++) { if (name[i] == '.') { nd++; } } if (Config.onoff.res_defnames && npc > 0 && name[strlen(name) - 1] != '.') { q->do_searchpath = 1; } else { q->do_searchpath = 0; } strcpy(q->orig, name); strcpy(q->name, q->orig); if (q->do_searchpath && nd < ndots) { q->domain = 0; strcat(q->name, "."); strcat(q->name, searchpath[q->domain].domain); debug(78, 3) ("idnsALookup: searchpath used for %s\n", q->name); } q->sz = rfc1035BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, &q->query); if (q->sz < 0) { /* problem with query data -- query not sent */ callback(data, NULL, 0, "Internal error"); cbdataFree(q); return; } debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, q->name, q->id); q->callback = callback; q->callback_data = data; cbdataLock(q->callback_data); q->start_t = current_time; idnsCacheQuery(q); idnsSendQuery(q); }
void redirectStart(clientHttpRequest * http, RH * handler, void *data) { ConnStateData *conn = http->conn; redirectStateData *r = NULL; const char *fqdn; char *urlgroup = conn->port->urlgroup; char buf[8192]; char claddr[20]; char myaddr[20]; assert(http); assert(handler); debug(61, 5) ("redirectStart: '%s'\n", http->uri); if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) { /* Skip redirector if there is one request queued */ n_bypassed++; handler(data, NULL); return; } r = cbdataAlloc(redirectStateData); r->orig_url = xstrdup(http->uri); r->client_addr = conn->log_addr; r->client_ident = NULL; if (http->request->auth_user_request) r->client_ident = authenticateUserRequestUsername(http->request->auth_user_request); else if (http->request->extacl_user) { r->client_ident = http->request->extacl_user; } if (!r->client_ident && conn->rfc931[0]) r->client_ident = conn->rfc931; #if USE_SSL if (!r->client_ident) r->client_ident = sslGetUserEmail(fd_table[conn->fd].ssl); #endif if (!r->client_ident) r->client_ident = dash_str; r->method_s = http->request->method->string; r->handler = handler; r->data = data; cbdataLock(r->data); if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL) fqdn = dash_str; xstrncpy(claddr, inet_ntoa(r->client_addr), 20); xstrncpy(myaddr, inet_ntoa(http->request->my_addr), 20); snprintf(buf, 8191, "%s %s/%s %s %s %s myip=%s myport=%d", r->orig_url, claddr, fqdn, r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str, r->method_s, urlgroup ? urlgroup : "-", myaddr, http->request->my_port); debug(61, 6) ("redirectStart: sending '%s' to the helper\n", buf); strcat(buf, "\n"); helperSubmit(redirectors, buf, redirectHandleReply, r); }
/* open for creating */ storeIOState * storeAufsCreate(SwapDir * SD, StoreEntry * e, STFNCB * file_callback, STIOCB * callback, void *callback_data) { char *path; storeIOState *sio; sfileno filn; sdirno dirn; #if !ASYNC_CREATE int fd; #endif /* Allocate a number */ dirn = SD->index; filn = storeAufsDirMapBitAllocate(SD); path = storeAufsDirFullPath(SD, filn, NULL); debug(79, 3) ("storeAufsCreate: fileno %08X\n", filn); /* * we should detect some 'too many files open' condition and return * NULL here. */ #ifdef MAGIC2 if (aioQueueSize() > MAGIC2) return NULL; #endif #if !ASYNC_CREATE fd = file_open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY); if (fd < 0) { debug(79, 3) ("storeAufsCreate: got failure (%d)\n", errno); return NULL; } #endif CBDATA_INIT_TYPE_FREECB(storeIOState, storeAufsIOFreeEntry); sio = cbdataAlloc(storeIOState); sio->fsstate = memPoolAlloc(squidaio_state_pool); ((squidaiostate_t *) (sio->fsstate))->fd = -1; ((squidaiostate_t *) (sio->fsstate))->flags.opening = 1; sio->swap_filen = filn; sio->swap_dirn = dirn; sio->mode = O_WRONLY | O_BINARY; sio->callback = callback; sio->callback_data = callback_data; sio->e = (StoreEntry *) e; cbdataLock(callback_data); Opening_FD++; statCounter.syscalls.disk.opens++; #if ASYNC_CREATE aioOpen(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644, storeAufsOpenDone, sio, INDEX_OF_SD(SD)); #else storeAufsOpenDone(fd, sio, fd, 0); #endif /* now insert into the replacement policy */ storeAufsDirReplAdd(SD, e); return sio; }
static void storeAufsWriteDone(int fd, int errflag, size_t len, void *my_data) #endif { static int loop_detect = 0; storeIOState *sio = my_data; squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; #if ASYNC_WRITE int errflag; int len = aio_return; /* Translate from errno to Squid disk error */ if (aio_errno) errflag = aio_errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR; else errflag = DISK_OK; #endif debug(79, 3) ("storeAufsWriteDone: dirno %d, fileno %08X, FD %d, len %ld, err=%d\n", sio->swap_dirn, sio->swap_filen, fd, (long int) len, errflag); assert(++loop_detect < 10); aiostate->flags.writing = 0; if (errflag) { debug(79, 0) ("storeAufsWriteDone: got failure (%d)\n", errflag); storeAufsIOCallback(sio, errflag); loop_detect--; return; } sio->offset += len; #if ASYNC_WRITE if (storeAufsKickWriteQueue(sio)) (void) 0; else if (aiostate->flags.close_request) storeAufsIOCallback(sio, errflag); #else /* loop around storeAufsKickWriteQueue to break recursion stack * overflow when large amounts of data has been queued for write. * As writes are blocking here we immediately get called again * without going via the I/O event loop.. */ if (!aiostate->flags.write_kicking) { /* cbdataLock to protect us from the storeAufsIOCallback on error above */ cbdataLock(sio); aiostate->flags.write_kicking = 1; while (storeAufsKickWriteQueue(sio)) if (!cbdataValid(sio)) break; if (cbdataValid(sio)) { aiostate->flags.write_kicking = 0; if (aiostate->flags.close_request) storeAufsIOCallback(sio, errflag); } cbdataUnlock(sio); } #endif loop_detect--; }
static void identClientAdd(IdentStateData * state, IDCB * callback, void *callback_data) { IdentClient *c = xcalloc(1, sizeof(*c)); IdentClient **C; c->callback = callback; c->callback_data = callback_data; cbdataLock(callback_data); for (C = &state->clients; *C; C = &(*C)->next); *C = c; }
/* allocate new peer digest, call Init, and lock everything */ PeerDigest * peerDigestCreate(peer * p) { PeerDigest *pd; assert(p); pd = memAllocate(MEM_PEER_DIGEST); cbdataAdd(pd, memFree, MEM_PEER_DIGEST); peerDigestInit(pd, p); cbdataLock(pd->peer); /* we will use the peer */ return pd; }
/* allocate new peer digest, call Init, and lock everything */ PeerDigest * peerDigestCreate(peer * p) { PeerDigest *pd; assert(p); CBDATA_INIT_TYPE(PeerDigest); pd = cbdataAlloc(PeerDigest); peerDigestInit(pd, p); cbdataLock(pd->peer); /* we will use the peer */ return pd; }
/* mighty zerocopy */ void storeAufsZCopy(SwapDir * SD, storeIOState * sio, int targetfd, size_t size, squid_off_t offset, STRCB * callback, void *callback_data) { squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; assert(sio->zcopy.callback == NULL); assert(sio->zcopy.callback_data == NULL); assert(!aiostate->flags.zcopying); if (aiostate->fd < 0) { struct _queued_zcopy *q; debug(79, 3) ("storeAufsRead: queueing read because FD < 0\n"); assert(aiostate->flags.opening); assert(aiostate->pending_zcopies == NULL); q = memPoolAlloc(aufs_qzcopy_pool); q->zc_target_fd = targetfd; q->size = size; q->offset = (off_t) offset; q->callback = callback; q->callback_data = callback_data; cbdataLock(q->callback_data); linklistPush(&(aiostate->pending_zcopies), q); return; } sio->zcopy.callback = callback; sio->zcopy.callback_data = callback_data; aiostate->zc_target_fd = targetfd; cbdataLock(callback_data); debug(79, 3) ("storeAufsRead: dirno %d, fileno %08X, FD %d\n", sio->swap_dirn, sio->swap_filen, aiostate->fd); sio->offset = offset; aiostate->flags.zcopying = 1; #if ASYNC_ZCOPY aioZCopy(aiostate->fd, (off_t) offset, size, storeAufsZCopyDone, sio, targetfd, INDEX_OF_SD(SD)); statCounter.syscalls.disk.zcopies++; #else //FIXME assert(0); #endif }
/* Read */ void storeAufsRead(SwapDir * SD, storeIOState * sio, char *buf, size_t size, squid_off_t offset, STRCB * callback, void *callback_data) { squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; assert(sio->read.callback == NULL); assert(sio->read.callback_data == NULL); assert(!aiostate->flags.reading); if (aiostate->fd < 0) { struct _queued_read *q; debug(79, 3) ("storeAufsRead: queueing read because FD < 0\n"); assert(aiostate->flags.opening); assert(aiostate->pending_reads == NULL); q = memPoolAlloc(aufs_qread_pool); q->buf = buf; q->size = size; q->offset = (off_t) offset; q->callback = callback; q->callback_data = callback_data; cbdataLock(q->callback_data); linklistPush(&(aiostate->pending_reads), q); return; } sio->read.callback = callback; sio->read.callback_data = callback_data; aiostate->read_buf = buf; cbdataLock(callback_data); debug(79, 3) ("storeAufsRead: dirno %d, fileno %08X, FD %d\n", sio->swap_dirn, sio->swap_filen, aiostate->fd); sio->offset = offset; aiostate->flags.reading = 1; #if ASYNC_READ aioRead(aiostate->fd, (off_t) offset, size, storeAufsReadDone, sio, INDEX_OF_SD(SD)); statCounter.syscalls.disk.reads++; #else file_read(aiostate->fd, buf, size, (off_t) offset, storeAufsReadDone, sio); /* file_read() increments syscalls.disk.reads */ #endif }
void idnsALookup(const char *name, IDNSCB * callback, void *data) { idns_query *q = memAllocate(MEM_IDNS_QUERY); q->sz = sizeof(q->buf); q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, name, q->id); q->callback = callback; q->callback_data = data; cbdataLock(q->callback_data); q->start_t = current_time; idnsSendQuery(q); }
void idnsPTRLookup(const struct in_addr addr, IDNSCB * callback, void *data) { idns_query *q = memAllocate(MEM_IDNS_QUERY); q->sz = sizeof(q->buf); q->id = rfc1035BuildPTRQuery(addr, q->buf, &q->sz); debug(78, 3) ("idnsPTRLookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, inet_ntoa(addr), q->id); q->callback = callback; q->callback_data = data; cbdataLock(q->callback_data); q->start_t = current_time; idnsSendQuery(q); }