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);
}
Esempio n. 2
0
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--;
}
Esempio n. 3
0
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);
    }
}
Esempio n. 4
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;
}
Esempio n. 5
0
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++;
}
Esempio n. 6
0
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__);
}
Esempio n. 7
0
/* 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);
}
Esempio n. 8
0
static void
errorMapFetchAbort(ErrorMapState * state)
{
    if (cbdataValid(state->callback_data))
	state->callback(NULL, -1, -1, state->callback_data);
    errorMapFetchComplete(state);
}
Esempio n. 9
0
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();
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
static void
freePeerMonitor(void *data)
{
    PeerMonitor *pm = data;
    if (cbdataValid(pm->peer))
	pm->peer->monitor.data = NULL;
    cbdataUnlock(pm->peer);
    pm->peer = NULL;
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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;
    }
}
Esempio n. 20
0
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);
    }
}
Esempio n. 21
0
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);
}
Esempio n. 22
0
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);
}
Esempio n. 23
0
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);
    }
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
File: disk.c Progetto: selecli/squid
/* 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);
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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++;
}
Esempio n. 28
0
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;
}
Esempio n. 30
0
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);
    }
}