static void externalAclHandleReply(void *data, char *reply) { externalAclState *state = data; externalAclState *next; int result = 0; char *status; char *token; char *value; char *t; char *user = NULL; char *error = NULL; external_acl_entry *entry = NULL; debug(82, 2) ("externalAclHandleReply: reply=\"%s\"\n", reply); if (reply) { status = strwordtok(reply, &t); if (status && strcmp(status, "OK") == 0) result = 1; while ((token = strwordtok(NULL, &t))) { value = strchr(token, '='); if (value) { *value++ = '\0'; /* terminate the token, and move up to the value */ if (strcmp(token, "user") == 0) user = value; else if (strcmp(token, "error") == 0) error = value; } } } dlinkDelete(&state->list, &state->def->queue); if (cbdataValid(state->def)) { if (reply) entry = external_acl_cache_add(state->def, state->key, result, user, error); else { external_acl_entry *oldentry = hash_lookup(state->def->cache, state->key); if (oldentry) external_acl_cache_delete(state->def, oldentry); } } do { cbdataUnlock(state->def); state->def = NULL; if (cbdataValid(state->callback_data)) state->callback(state->callback_data, entry); cbdataUnlock(state->callback_data); state->callback_data = NULL; next = state->queue; cbdataFree(state); state = next; } while (state); }
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 helperStatefulHandleRead(int fd, void *data) { int len; char *t = NULL; helper_stateful_server *srv = data; helper_stateful_request *r; statefulhelper *hlp = srv->parent; assert(fd == srv->rfd); assert(cbdataValid(data)); statCounter.syscalls.sock.reads++; len = FD_READ_METHOD(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset); fd_bytes(fd, len, FD_READ); debug(84, 5) ("helperStatefulHandleRead: %d bytes from %s #%d.\n", len, hlp->id_name, srv->index + 1); if (len <= 0) { if (len < 0) debug(84, 1) ("helperStatefulHandleRead: FD %d read: %s\n", fd, xstrerror()); comm_close(fd); return; } srv->offset += len; srv->buf[srv->offset] = '\0'; r = srv->request; if (r == NULL) { /* someone spoke without being spoken to */ debug(84, 1) ("helperStatefulHandleRead: unexpected read from %s #%d, %d bytes\n", hlp->id_name, srv->index + 1, len); srv->offset = 0; } else if ((t = strchr(srv->buf, '\n'))) { /* end of reply found */ debug(84, 3) ("helperStatefulHandleRead: end of reply found\n"); *t = '\0'; srv->flags.busy = 0; srv->offset = 0; srv->request = NULL; hlp->stats.replies++; hlp->stats.avg_svc_time = intAverage(hlp->stats.avg_svc_time, tvSubMsec(srv->dispatch_time, current_time), hlp->stats.replies, REDIRECT_AV_FACTOR); if (cbdataValid(r->data)) { r->callback(r->data, srv, srv->buf); } else { debug(84, 1) ("StatefulHandleRead: no callback data registered\n"); } helperStatefulRequestFree(r); } else { commSetSelect(srv->rfd, COMM_SELECT_READ, helperStatefulHandleRead, srv, 0); } }
static void peerMonitorFetchReplyHeaders(void *data, char *buf, ssize_t size) { PeerMonitor *pm = data; HttpReply *reply; http_status status; if (EBIT_TEST(pm->running.e->flags, ENTRY_ABORTED)) goto completed; if (size <= 0) goto completed; if (!cbdataValid(pm->peer)) goto completed; reply = pm->running.e->mem_obj->reply; assert(reply); status = reply->sline.status; pm->running.status = status; if (status != HTTP_OK) goto completed; if (size > reply->hdr_sz) { pm->running.size = size - reply->hdr_sz; pm->running.offset = size; } else { pm->running.size = 0; pm->running.offset = reply->hdr_sz; } storeClientCopy(pm->running.sc, pm->running.e, pm->running.offset, pm->running.offset, 4096, buf, peerMonitorFetchReply, pm); return; completed: /* We are fully done with this monitoring request. Clean up */ peerMonitorCompleted(pm); return; }
static void helperDispatch(helper_server * srv, helper_request * r) { helper *hlp = srv->parent; if (!cbdataValid(r->data)) { debug(84, 1) ("helperDispatch: invalid callback data\n"); helperRequestFree(r); return; } assert(!srv->flags.busy); srv->flags.busy = 1; srv->request = r; srv->dispatch_time = current_time; comm_write(srv->wfd, r->buf, strlen(r->buf), NULL, /* Handler */ NULL, /* Handler-data */ NULL); /* free */ commSetSelect(srv->rfd, COMM_SELECT_READ, helperHandleRead, srv, 0); debug(84, 5) ("helperDispatch: Request sent to %s #%d, %d bytes\n", hlp->id_name, srv->index + 1, (int) strlen(r->buf)); srv->stats.uses++; hlp->stats.requests++; }
static void storeAufsIOCallback(storeIOState * sio, int errflag) { STIOCB *callback = sio->callback; void *their_data = sio->callback_data; squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; int fd = aiostate->fd; debug(79, 3) ("storeAufsIOCallback: errflag=%d\n", errflag); sio->callback = NULL; sio->callback_data = NULL; debug(79, 9) ("%s:%d\n", __FILE__, __LINE__); if (callback) if (NULL == their_data || cbdataValid(their_data)) callback(their_data, errflag, sio); debug(79, 9) ("%s:%d\n", __FILE__, __LINE__); cbdataUnlock(their_data); aiostate->fd = -1; if (aiostate->flags.opening) Opening_FD--; cbdataFree(sio); if (fd < 0) return; debug(79, 9) ("%s:%d\n", __FILE__, __LINE__); #if ASYNC_CLOSE fd_close(fd); aioClose(fd); #else aioCancel(fd); file_close(fd); #endif store_open_disk_fd--; statCounter.syscalls.disk.closes++; debug(79, 9) ("%s:%d\n", __FILE__, __LINE__); }
/* 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); }
static void errorMapFetchAbort(ErrorMapState * state) { if (cbdataValid(state->callback_data)) state->callback(NULL, -1, -1, state->callback_data); errorMapFetchComplete(state); }
static void idnsCheckQueue(void *unused) { dlink_node *n; dlink_node *p = NULL; idns_query *q; event_queued = 0; for (n = lru_list.tail; n; n = p) { q = n->data; if (tvSubDsec(q->sent_t, current_time) < 5.0) break; debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); p = n->prev; dlinkDelete(&q->lru, &lru_list); if (q->nsends < IDNS_MAX_TRIES) { idnsSendQuery(q); } else { int v = cbdataValid(q->callback_data); debug(78, 1) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); cbdataUnlock(q->callback_data); if (v) q->callback(q->callback_data, NULL, 0); memFree(q, MEM_IDNS_QUERY); } } idnsTickleQueue(); }
static void peerSelectCallback(ps_state * psstate) { 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) (" 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; if (cbdataValid(data)) { psstate->servers = NULL; psstate->callback(fs, data); } cbdataUnlock(data); peerSelectStateFree(psstate); }
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); }
static void errorMapFetchHeaders(void *data, mem_node_ref nr, ssize_t size) { ErrorMapState *state = data; HttpReply *reply; http_status status; if (EBIT_TEST(state->e->flags, ENTRY_ABORTED)) goto abort; if (size == 0) goto abort; if (!cbdataValid(state->callback_data)) goto abort; reply = state->e->mem_obj->reply; status = reply->sline.status; if (status != HTTP_OK) goto abort; /* Send object to caller (cbdataValid verified above) */ state->callback(state->e, reply->hdr_sz, httpHeaderGetSize(&reply->header, HDR_CONTENT_LENGTH), state->callback_data); errorMapFetchComplete(state); stmemNodeUnref(&nr); return; abort: errorMapFetchAbort(state); stmemNodeUnref(&nr); return; }
static void storeUfsReadDone(int fd, const char *buf, int len, int errflag, void *my_data) { storeIOState *sio = my_data; ufsstate_t *ufsstate = (ufsstate_t *) sio->fsstate; STRCB *callback = sio->read.callback; void *their_data = sio->read.callback_data; ssize_t rlen; debug(79, 3) ("storeUfsReadDone: dirno %d, fileno %08X, FD %d, len %d\n", sio->swap_dirn, sio->swap_filen, fd, len); ufsstate->flags.reading = 0; if (errflag) { debug(79, 3) ("storeUfsReadDone: got failure (%d)\n", errflag); rlen = -1; } else { rlen = len; sio->offset += len; } assert(callback); assert(their_data); sio->read.callback = NULL; sio->read.callback_data = NULL; if (cbdataValid(their_data)) callback(their_data, buf, rlen); cbdataUnlock(their_data); }
static void identConnectDone(int fd, int status, void *data) { IdentStateData *state = data; IdentClient *c; MemBuf mb; if (status != COMM_OK) { /* Failed to connect */ comm_close(fd); return; } /* * see if our clients still care */ for (c = state->clients; c; c = c->next) { if (cbdataValid(c->callback_data)) break; } if (c == NULL) { /* no clients care */ comm_close(fd); return; } memBufDefInit(&mb); memBufPrintf(&mb, "%d, %d\r\n", ntohs(state->my_peer.sin_port), ntohs(state->me.sin_port)); comm_write_mbuf(fd, mb, NULL, state); commSetSelect(fd, COMM_SELECT_READ, identReadReply, state, 0); commSetTimeout(fd, Config.Timeout.ident, identTimeout, state); }
static void freePeerMonitor(void *data) { PeerMonitor *pm = data; if (cbdataValid(pm->peer)) pm->peer->monitor.data = NULL; cbdataUnlock(pm->peer); pm->peer = NULL; }
static void authenticateBasicHandleReply(void *data, char *reply) { authenticateStateData *r = data; auth_user_t *auth_user; basic_data *basic_auth; auth_basic_queue_node *tmpnode; int valid; char *t = NULL; debug(29, 9) ("authenticateBasicHandleReply: {%s}\n", reply ? reply : "<NULL>"); if (reply) { if ((t = strchr(reply, ' '))) *t++ = '\0'; if (*reply == '\0') reply = NULL; } assert(r->auth_user_request != NULL); assert(r->auth_user_request->auth_user->auth_type == AUTH_BASIC); auth_user = r->auth_user_request->auth_user; basic_auth = auth_user->scheme_data; if (reply && (strncasecmp(reply, "OK", 2) == 0)) basic_auth->flags.credentials_ok = 1; else { basic_auth->flags.credentials_ok = 3; safe_free(r->auth_user_request->message); if (t && *t) r->auth_user_request->message = xstrdup(t); } basic_auth->credentials_checkedtime = squid_curtime; valid = cbdataValid(r->data); if (valid) r->handler(r->data, NULL); cbdataUnlock(r->data); while (basic_auth->auth_queue) { tmpnode = basic_auth->auth_queue->next; valid = cbdataValid(basic_auth->auth_queue->data); if (valid) basic_auth->auth_queue->handler(basic_auth->auth_queue->data, NULL); cbdataUnlock(basic_auth->auth_queue->data); xfree(basic_auth->auth_queue); basic_auth->auth_queue = tmpnode; } authenticateStateFree(r); }
static void storeDiskdIOCallback(storeIOState * sio, int errflag) { void *p = sio->callback_data; debug(79, 3) ("storeDiskdIOCallback: errflag=%d\n", errflag); if (cbdataValid(p)) sio->callback(p, errflag, sio); cbdataUnlock(p); cbdataFree(sio); }
static void storeClientCallback(store_client * sc, ssize_t sz) { STCB *callback = sc->callback; char *buf = sc->copy_buf; assert(sc->callback); sc->callback = NULL; sc->copy_buf = NULL; if (cbdataValid(sc->callback_data)) callback(sc->callback_data, buf, sz); }
static void idnsCallback(idns_query * q, rfc1035_rr * answers, int n, const char *error) { int valid; valid = cbdataValid(q->callback_data); cbdataUnlock(q->callback_data); if (valid) q->callback(q->callback_data, answers, n, error); while (q->queue) { idns_query *q2 = q->queue; q->queue = q2->queue; valid = cbdataValid(q2->callback_data); cbdataUnlock(q2->callback_data); if (valid) q2->callback(q2->callback_data, answers, n, error); cbdataFree(q2); } if (q->hash.key) { hash_remove_link(idns_lookup_hash, &q->hash); q->hash.key = NULL; } }
static void peerMonitorFetchReply(void *data, char *buf, ssize_t size) { PeerMonitor *pm = data; if (size <= 0 || !cbdataValid(pm->peer)) { peerMonitorCompleted(pm); } else { pm->running.size += size; pm->running.offset += size; storeClientCopy(pm->running.sc, pm->running.e, pm->running.offset, pm->running.offset, 4096, buf, peerMonitorFetchReply, pm); } }
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 peerMonitorFetchReply(void *data, mem_node_ref nr, ssize_t size) { PeerMonitor *pm = data; if (size <= 0 || !cbdataValid(pm->peer)) { peerMonitorCompleted(pm); } else { pm->running.size += size; pm->running.offset += size; storeClientRef(pm->running.sc, pm->running.e, pm->running.offset, pm->running.offset, SM_PAGE_SIZE, peerMonitorFetchReply, pm); } stmemNodeUnref(&nr); }
static void identCallback(IdentStateData * state, char *result) { IdentClient *client; if (result && *result == '\0') result = NULL; while ((client = state->clients)) { state->clients = client->next; if (cbdataValid(client->callback_data)) client->callback(result, client->callback_data); cbdataUnlock(client->callback_data); xfree(client); } }
int storeUnregister(StoreEntry * e, void *data) { MemObject *mem = e->mem_obj; store_client *sc; store_client **S; STCB *callback; if (mem == NULL) return 0; debug(20, 3) ("storeUnregister: called for '%s'\n", storeKeyText(e->key)); for (S = &mem->clients; (sc = *S) != NULL; S = &(*S)->next) { if (sc->callback_data == data) break; } if (sc == NULL) return 0; if (sc == mem->clients) { /* * If we are unregistering the _first_ client for this * entry, then we have to reset the client FD to -1. */ mem->fd = -1; } *S = sc->next; mem->nclients--; sc->flags.disk_io_pending = 0; if (e->store_status == STORE_OK && e->swap_status != SWAPOUT_DONE) storeSwapOut(e); if (sc->swapin_sio) { storeClose(sc->swapin_sio); sc->swapin_sio = NULL; } if ((callback = sc->callback) != NULL) { /* callback with ssize = -1 to indicate unexpected termination */ debug(20, 3) ("storeUnregister: store_client for %s has a callback\n", mem->url); sc->callback = NULL; if (cbdataValid(sc->callback_data)) callback(sc->callback_data, sc->copy_buf, -1); } #if DELAY_POOLS delayUnregisterDelayIdPtr(&sc->delay_id); #endif cbdataUnlock(sc->callback_data); /* we're done with it now */ cbdataFree(sc); assert(e->lock_count > 0); if (mem->nclients == 0) CheckQuickAbort(e); return 1; }
/* Read from FD */ static void diskHandleRead(int fd, void *data) { dread_ctrl *ctrl_dat = data; fde *F = &fd_table[fd]; int len; int rc = DISK_OK; /* * FD < 0 indicates premature close; we just have to free * the state data. */ if (fd < 0) { memFree(ctrl_dat, MEM_DREAD_CTRL); return; } if (F->disk.offset != ctrl_dat->file_offset) { debug(6, 3) ("diskHandleRead: FD %d seeking to offset %d\n", fd, (int) ctrl_dat->file_offset); lseek(fd, ctrl_dat->file_offset, SEEK_SET); /* XXX ignore return? */ statCounter.syscalls.disk.seeks++; F->disk.offset = ctrl_dat->file_offset; } errno = 0; len = FD_READ_METHOD(fd, ctrl_dat->buf, ctrl_dat->req_len); if (len > 0) F->disk.offset += len; statCounter.syscalls.disk.reads++; fd_bytes(fd, len, FD_READ); if (len < 0) { if (ignoreErrno(errno)) { commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0); return; } debug(50, 1) ("diskHandleRead: FD %d: %s\n", fd, xstrerror()); len = 0; rc = DISK_ERROR; } else if (len == 0) { rc = DISK_EOF; } if (cbdataValid(ctrl_dat->client_data)) ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data); cbdataUnlock(ctrl_dat->client_data); memFree(ctrl_dat, MEM_DREAD_CTRL); }
static int storeAufsKickZCopyQueue(storeIOState * sio) { squidaiostate_t *aiostate = (squidaiostate_t *) sio->fsstate; struct _queued_zcopy *q = linklistShift(&(aiostate->pending_zcopies)); if (NULL == q) return 0; debug(79, 3) ("storeAufsKickReadQueue: zcopying queued request of %ld bytes\n",(long int) q->size); if (cbdataValid(q->callback_data)) storeAufsZCopy(INDEXSD(sio->swap_dirn), sio, q->zc_target_fd, q->size, q->offset, q->callback, q->callback_data); cbdataUnlock(q->callback_data); memPoolFree(aufs_qzcopy_pool, q); return 1; }
static void helperStatefulDispatch(helper_stateful_server * srv, helper_stateful_request * r) { statefulhelper *hlp = srv->parent; if (!cbdataValid(r->data)) { debug(84, 1) ("helperStatefulDispatch: invalid callback data\n"); helperStatefulRequestFree(r); return; } if (!r->buf) { if (cbdataValid(r->data)) { r->callback(r->data, srv, NULL); } else { debug(84, 1) ("helperStatefulDispatch: no callback data registered\n"); } helperStatefulRequestFree(r); return; } debug(84, 9) ("helperStatefulDispatch busying helper %s #%d\n", hlp->id_name, srv->index + 1); srv->flags.busy = 1; srv->request = r; srv->dispatch_time = current_time; comm_write(srv->wfd, r->buf, strlen(r->buf), NULL, /* Handler */ NULL, /* Handler-data */ NULL); /* free */ commSetSelect(srv->rfd, COMM_SELECT_READ, helperStatefulHandleRead, srv, 0); debug(84, 5) ("helperStatefulDispatch: Request sent to %s #%d, %d bytes\n", hlp->id_name, srv->index + 1, (int) strlen(r->buf)); srv->stats.uses++; hlp->stats.requests++; }
static void idnsGrokReply(const char *buf, size_t sz) { int n; int valid; rfc1035_rr *answers = NULL; unsigned short rid = 0xFFFF; idns_query *q; n = rfc1035AnswersUnpack(buf, sz, &answers, &rid); debug(78, 3) ("idnsGrokReply: ID %#hx, %d answers\n", rid, n); if (rid == 0xFFFF) { debug(78, 1) ("idnsGrokReply: Unknown error\n"); /* XXX leak answers? */ return; } q = idnsFindQuery(rid); if (q == NULL) { debug(78, 3) ("idnsGrokReply: Late response\n"); rfc1035RRDestroy(answers, n); return; } dlinkDelete(&q->lru, &lru_list); idnsRcodeCount(n, q->attempt); if (n < 0) { debug(78, 3) ("idnsGrokReply: error %d\n", rfc1035_errno); if (-2 == n && ++q->attempt < MAX_ATTEMPT) { /* * RCODE 2 is "Server failure - The name server was * unable to process this query due to a problem with * the name server." */ assert(NULL == answers); q->start_t = current_time; q->id = rfc1035RetryQuery(q->buf); idnsSendQuery(q); return; } } valid = cbdataValid(q->callback_data); cbdataUnlock(q->callback_data); if (valid) q->callback(q->callback_data, answers, n); rfc1035RRDestroy(answers, n); memFree(q, MEM_IDNS_QUERY); }
int aioCheckCallbacks(SwapDir * SD) { squidaio_result_t *resultp; squidaio_ctrl_t *ctrlp; AIOCB *done_handler; void *their_data; int retval = 0; assert(initialised); squidaio_counts.check_callback++; for (;;) { if ((resultp = squidaio_poll_done()) == NULL) break; ctrlp = (squidaio_ctrl_t *) resultp->data; if (ctrlp == NULL) continue; /* XXX Should not happen */ dlinkDelete(&ctrlp->node, &used_list); if ((done_handler = ctrlp->done_handler)) { their_data = ctrlp->done_handler_data; ctrlp->done_handler = NULL; ctrlp->done_handler_data = NULL; if (cbdataValid(their_data)) { retval = 1; /* Return that we've actually done some work */ done_handler(ctrlp->fd, their_data, ctrlp->bufp, ctrlp->result.aio_return, ctrlp->result.aio_errno); } else { if (ctrlp->operation == _AIO_OPEN) { /* The open operation was aborted.. */ int fd = ctrlp->result.aio_return; if (fd >= 0) aioClose(fd); } } cbdataUnlock(their_data); } /* free data if requested to aioWrite() */ if (ctrlp->free_func) ctrlp->free_func(ctrlp->bufp); /* free temporary read buffer */ if (ctrlp->operation == _AIO_READ) squidaio_xfree(ctrlp->bufp, ctrlp->len); if (ctrlp->operation == _AIO_CLOSE) aioFDWasClosed(ctrlp->fd); memPoolFree(squidaio_ctrl_pool, ctrlp); } return retval; }
static void storeDiskdReadDone(diomsg * M) { storeIOState *sio = M->callback_data; STRCB *callback = sio->read.callback; SwapDir *sd = INDEXSD(sio->swap_dirn); diskdstate_t *diskdstate = sio->fsstate; diskdinfo_t *diskdinfo = sd->fsdata; void *their_data = sio->read.callback_data; char *their_buf = diskdstate->read_buf; char *sbuf; size_t len; int valid; statCounter.syscalls.disk.reads++; diskdstate->flags.reading = 0; if (diskdstate->flags.close_request) { debug(79, 2) ("storeDiskReadDone: closing, so ignore!\n"); return; } valid = cbdataValid(sio->read.callback_data); cbdataUnlock(sio->read.callback_data); debug(79, 3) ("storeDiskdReadDone: dirno %d, fileno %08x status %d\n", sio->swap_dirn, sio->swap_filen, M->status); if (M->status < 0) { diskd_stats.read.fail++; storeDiskdIOCallback(sio, DISK_ERROR); return; } diskd_stats.read.success++; sbuf = diskdinfo->shm.buf + M->shm_offset; len = M->status; sio->offset += len; assert(callback); assert(their_data); sio->read.callback = NULL; sio->read.callback_data = NULL; if (valid) { assert(!diskdstate->flags.close_request); /* * Only copy the data if the callback is still valid, * if it isn't valid then the request should have been * aborted. * -- adrian */ xmemcpy(their_buf, sbuf, len); /* yucky copy */ callback(their_data, their_buf, len); } }