static void
private_fwdNegotiateSSL(int fd,void *data)
{
	SSL *ssl = fd_table[fd].ssl;
	int ret;

	server *s=(server *)data;

	//unsigned char key[22];
	errno = 0;
	ERR_clear_error();
	if ((ret = SSL_connect(ssl)) <= 0)
	{
		int ssl_error = SSL_get_error(ssl, ret);
		switch (ssl_error)
		{
			case SSL_ERROR_WANT_READ:
				commSetSelect(fd, COMM_SELECT_READ, private_fwdNegotiateSSL, s, 0);
				return;
			case SSL_ERROR_WANT_WRITE:
				commSetSelect(fd, COMM_SELECT_WRITE, private_fwdNegotiateSSL,s, 0);
				return;
			default:
				debug(153, 1) ("private_fwdNegotiateSSL: Error negotiating SSL connection on FD %d: %s (%d/%d/%d)\n", fd, ERR_error_string(ERR_get_error(), NULL), ssl_error, ret, errno);
			cbdataFree(s);
			comm_close(fd);
			return ;
		}
	}
	
	pconnPush(fd,s->ip_addr,s->port,NULL,NULL,0);
	commSetTimeout(fd,s->pconn_timeout,NULL,NULL);
	debug(153, 4) ("private_fwdNegotiateSSL: succeed negotiating SSL connection on FD:%d \n",fd);
	return;
}
Esempio n. 2
0
static void
idnsReadTcp(int fd, void *data)
{
    ssize_t n;
    idns_query *q = data;
    int ns = (q->nsends - 1) % nns;
    if (!q->tcp_buffer)
	q->tcp_buffer = memAllocBuf(1024, &q->tcp_buffer_size);
    statCounter.syscalls.sock.reads++;
    n = FD_READ_METHOD(q->tcp_socket, q->tcp_buffer + q->tcp_buffer_offset, q->tcp_buffer_size - q->tcp_buffer_offset);
    if (n < 0 && ignoreErrno(errno)) {
	commSetSelect(q->tcp_socket, COMM_SELECT_READ, idnsReadTcp, q, 0);
	return;
    }
    if (n <= 0) {
	debug(78, 1) ("idnsReadTcp: Short response from nameserver %d for %s.\n", ns + 1, q->name);
	idnsTcpCleanup(q);
	return;
    }
    fd_bytes(fd, n, FD_READ);
    q->tcp_buffer_offset += n;
    if (q->tcp_buffer_offset > 2) {
	unsigned short response_size = ntohs(*(short *) q->tcp_buffer);
	if (q->tcp_buffer_offset >= response_size + 2) {
	    nameservers[ns].nreplies++;
	    idnsGrokReply(q->tcp_buffer + 2, response_size);
	    return;
	}
	if (q->tcp_buffer_size < response_size + 2)
	    q->tcp_buffer = memReallocBuf(q->tcp_buffer, response_size + 2, &q->tcp_buffer_size);
    }
    commSetSelect(q->tcp_socket, COMM_SELECT_READ, idnsReadTcp, q, 0);
}
Esempio n. 3
0
void
wccpConnectionOpen(void)
{
    u_short port = WCCP_PORT;
    struct sockaddr_in router, local;
    int local_len, router_len;
    debug(80, 5) ("wccpConnectionOpen: Called\n");
    if (Config.Wccp.router.s_addr == any_addr.s_addr) {
	debug(1, 1) ("WCCP Disabled.\n");
	return;
    }
    theInWccpConnection = comm_open(SOCK_DGRAM,
	0,
	Config.Wccp.incoming,
	port,
	COMM_NONBLOCKING,
	"WCCP Socket");
    if (theInWccpConnection < 0)
	fatal("Cannot open WCCP Port");
    commSetSelect(theInWccpConnection,
	COMM_SELECT_READ,
	wccpHandleUdp,
	NULL,
	0);
    debug(1, 1) ("Accepting WCCP messages on port %d, FD %d.\n",
	(int) port, theInWccpConnection);
    if (Config.Wccp.outgoing.s_addr != no_addr.s_addr) {
	theOutWccpConnection = comm_open(SOCK_DGRAM,
	    0,
	    Config.Wccp.outgoing,
	    port,
	    COMM_NONBLOCKING,
	    "WCCP Socket");
	if (theOutWccpConnection < 0)
	    fatal("Cannot open Outgoing WCCP Port");
	commSetSelect(theOutWccpConnection,
	    COMM_SELECT_READ,
	    wccpHandleUdp,
	    NULL, 0);
	debug(1, 1) ("Outgoing WCCP messages on port %d, FD %d.\n",
	    (int) port, theOutWccpConnection);
	fd_note(theOutWccpConnection, "Outgoing WCCP socket");
	fd_note(theInWccpConnection, "Incoming WCCP socket");
    } else {
	theOutWccpConnection = theInWccpConnection;
    }
    router_len = sizeof(router);
    memset(&router, '\0', router_len);
    router.sin_family = AF_INET;
    router.sin_port = htons(port);
    router.sin_addr = Config.Wccp.router;
    if (connect(theOutWccpConnection, (struct sockaddr *) &router, router_len))
	fatal("Unable to connect WCCP out socket");
    local_len = sizeof(local);
    memset(&local, '\0', local_len);
    if (getsockname(theOutWccpConnection, (struct sockaddr *) &local, &local_len))
	fatal("Unable to getsockname on WCCP out socket");
    local_ip.s_addr = local.sin_addr.s_addr;
}
Esempio n. 4
0
static void
sslSetSelect(SslStateData * sslState)
{
    size_t read_sz = SQUID_TCP_SO_RCVBUF;
    assert(sslState->server.fd > -1 || sslState->client.fd > -1);
    if (sslState->client.fd > -1) {
	if (sslState->server.len > 0) {
	    commSetSelect(sslState->client.fd,
		COMM_SELECT_WRITE,
		sslWriteClient,
		sslState,
		0);
	}
	if (sslState->client.len < read_sz) {
	    commSetSelect(sslState->client.fd,
		COMM_SELECT_READ,
		sslReadClient,
		sslState,
		Config.Timeout.read);
	}
    } else if (sslState->client.len == 0) {
	comm_close(sslState->server.fd);
    }
    if (sslState->server.fd > -1) {
	if (sslState->client.len > 0) {
	    commSetSelect(sslState->server.fd,
		COMM_SELECT_WRITE,
		sslWriteServer,
		sslState,
		0);
	}
#if DELAY_POOLS
	/*
	 * If this was allowed to return 0, there would be a possibility
	 * of the socket becoming "hung" with data accumulating but no
	 * write handler (server.len==0) and no read handler (!(0<0)) and
	 * no data flowing in the other direction.  Hence the argument of
	 * 1 as min.
	 */
	read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz);
#endif
	if (sslState->server.len < read_sz) {
	    /* Have room to read more */
	    commSetSelect(sslState->server.fd,
		COMM_SELECT_READ,
		sslReadServer,
		sslState,
		Config.Timeout.read);
	}
    } else if (sslState->client.fd == -1) {
	/* client already closed, nothing more to do */
    } else if (sslState->server.len == 0) {
	comm_close(sslState->client.fd);
    }
}
static void
whoisReadReply(int fd, void *data)
{
    WhoisState *p = data;
    StoreEntry *entry = p->entry;
    char *buf = memAllocate(MEM_4K_BUF);
    MemObject *mem = entry->mem_obj;
    int len;
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, 4095);
    buf[len] = '\0';
    debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len);
    debug(75, 5) ("{%s}\n", buf);
    if (len > 0) {
	if (0 == mem->inmem_hi) {
	    http_reply *reply = mem->reply;
	    http_version_t version;
	    storeBuffer(entry);
	    httpBuildVersion(&version, 1, 0);
	    httpReplySetHeaders(reply, version, HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2);
	    httpReplySwapOut(reply, entry);
	}
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.http.kbytes_in, len);
	storeAppend(entry, buf, len);
	storeBufferFlush(entry);
	commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
    } else if (len < 0) {
	debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
	} else {
	    ErrorState *err;
	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, p->fwd->request);
	    err->xerrno = errno;
	    fwdFail(p->fwd, err);
	    comm_close(fd);
	}
    } else {
	storeTimestampsSet(entry);
	storeBufferFlush(entry);
	if (!EBIT_TEST(entry->flags, RELEASE_REQUEST))
	    storeSetPublicKey(entry);
	fwdComplete(p->fwd);
	debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
	comm_close(fd);
    }
    memFree(buf, MEM_4K_BUF);
}
void
icmpOpen(void)
{
#if USE_ICMP
    const char *args[2];
    int rfd;
    int wfd;
    args[0] = "(pinger)";
    args[1] = NULL;
    pid = ipcCreate(IPC_DGRAM,
	Config.Program.pinger,
	args,
	"Pinger Socket",
	&rfd,
	&wfd,
	&hIpc);
    if (pid < 0)
	return;
    assert(rfd == wfd);
    icmp_sock = rfd;
    fd_note(icmp_sock, "pinger");
    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0);
    commSetTimeout(icmp_sock, -1, NULL, NULL);
    debug(37, 1) ("Pinger socket opened on FD %d\n", icmp_sock);
#endif
}
Esempio n. 7
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. 8
0
void
icmpOpen(void)
{
#if USE_ICMP
    char *args[2];
    int x;
    int rfd;
    int wfd;
    args[0] = "(pinger)";
    args[1] = NULL;
    x = ipcCreate(IPC_UDP_SOCKET,
	Config.Program.pinger,
	args,
	"Pinger Socket",
	&rfd,
	&wfd);
    if (x < 0)
	return;
    assert(rfd == wfd);
    icmp_sock = rfd;
    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0);
    commSetTimeout(icmp_sock, -1, NULL, NULL);
    debug(29, 1) ("Pinger socket opened on FD %d\n", icmp_sock);
#endif
}
Esempio n. 9
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++;
}
static void
squidaio_fdhandler(int fd, void *data)
{
    char junk[256];
    FD_READ_METHOD(done_fd_read, junk, sizeof(junk));
    commSetSelect(fd, COMM_SELECT_READ, squidaio_fdhandler, NULL, 0);
}
Esempio n. 11
0
static void
idnsSendQuery(idns_query * q)
{
    int x;
    int ns;
    if (DnsSocket < 0) {
	debug(78, 1) ("idnsSendQuery: Can't send query, no DNS socket!\n");
	return;
    }
    /* XXX Select nameserver */
    assert(nns > 0);
    assert(q->lru.next == NULL);
    assert(q->lru.prev == NULL);
    ns = q->nsends % nns;
    x = comm_udp_sendto(DnsSocket,
	&nameservers[ns].S,
	sizeof(nameservers[ns].S),
	q->buf,
	q->sz);
    if (x < 0) {
	debug(50, 1) ("idnsSendQuery: FD %d: sendto: %s\n",
	    DnsSocket, xstrerror());
    } else {
	fd_bytes(DnsSocket, x, FD_WRITE);
	commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0);
    }
    q->nsends++;
    q->sent_t = current_time;
    nameservers[ns].nqueries++;
    dlinkAdd(q, &q->lru, &lru_list);
    idnsTickleQueue();
}
Esempio n. 12
0
/*
 * icpConnectionShutdown only closes the 'in' socket if it is 
 * different than the 'out' socket.
 */
void
icpConnectionShutdown(void)
{
    if (theInIcpConnection < 0)
	return;
    if (theInIcpConnection != theOutIcpConnection) {
	debug(12, 1) ("FD %d Closing ICP connection\n", theInIcpConnection);
	comm_close(theInIcpConnection);
    }
    /*
     * Here we set 'theInIcpConnection' to -1 even though the ICP 'in'
     * and 'out' sockets might be just one FD.  This prevents this
     * function from executing repeatedly.  When we are really ready to
     * exit or restart, main will comm_close the 'out' descriptor.
     */
    theInIcpConnection = -1;
    /*
     * Normally we only write to the outgoing ICP socket, but
     * we also have a read handler there to catch messages sent
     * to that specific interface.  During shutdown, we must
     * disable reading on the outgoing socket.
     */
    assert(theOutIcpConnection > -1);
    commSetSelect(theOutIcpConnection, COMM_SELECT_READ, NULL, NULL, 0);
}
Esempio n. 13
0
void clientLscsConnectionsOpen(void)
{
        int fd; 
        enter_suid();
        struct sockaddr_un addr_UNIX;
        addr_UNIX.sun_family = AF_LOCAL;
        char path[4096];
        snprintf(path, 4096, "/tmp/xiaosi%d", opt_squid_id);
        strcpy(addr_UNIX.sun_path,path);
        unlink(path);
        fd = comm_open_un(SOCK_STREAM,
                        PF_LOCAL,
                        path,   
                        COMM_NONBLOCKING,
                        "LSCS Socket");
        leave_suid();
        comm_listen(fd);
        commSetSelect(fd, COMM_SELECT_READ, lscsAccept, NULL, 0);
        /*      
         * We need to set a defer handler here so that we don't
         * peg the CPU with select() when we hit the FD limit.
         */
        commSetDefer(fd, httpAcceptDefer, NULL);
        debug(191, 1) ("Accepting LSCS connections at %s, FD %d.\n",
                        path,   
                        fd);    
}
Esempio n. 14
0
static void
idnsRead(int fd, void *data)
{
    int *N = &incoming_sockets_accepted;
    ssize_t len;
    struct sockaddr_in from;
    socklen_t from_len;
    int max = INCOMING_DNS_MAX;
    static char rbuf[SQUID_UDP_SO_RCVBUF];
    int ns;
    while (max--) {
	from_len = sizeof(from);
	memset(&from, '\0', from_len);
	statCounter.syscalls.sock.recvfroms++;
	len = recvfrom(fd, rbuf, sizeof(rbuf), 0, (struct sockaddr *) &from, &from_len);
	if (len == 0)
	    break;
	if (len < 0) {
	    if (ignoreErrno(errno))
		break;
#ifdef _SQUID_LINUX_
	    /* Some Linux systems seem to set the FD for reading and then
	     * return ECONNREFUSED when sendto() fails and generates an ICMP
	     * port unreachable message. */
	    /* or maybe an EHOSTUNREACH "No route to host" message */
	    if (errno != ECONNREFUSED && errno != EHOSTUNREACH)
#endif
		debug(50, 1) ("idnsRead: FD %d recvfrom: %s\n",
		    fd, xstrerror());
	    break;
	}
	fd_bytes(DnsSocket, len, FD_READ);
	assert(N);
	(*N)++;
	debug(78, 3) ("idnsRead: FD %d: received %d bytes from %s.\n",
	    fd,
	    (int) len,
	    inet_ntoa(from.sin_addr));
	ns = idnsFromKnownNameserver(&from);
	if (ns >= 0) {
	    nameservers[ns].nreplies++;
	} else if (Config.onoff.ignore_unknown_nameservers) {
	    static time_t last_warning = 0;
	    if (squid_curtime - last_warning > 60) {
		debug(78, 1) ("WARNING: Reply from unknown nameserver [%s]\n",
		    inet_ntoa(from.sin_addr));
		last_warning = squid_curtime;
	    }
	    continue;
	}
	idnsGrokReply(rbuf, len);
    }
    if (lru_list.head)
	commSetSelect(DnsSocket, COMM_SELECT_READ, idnsRead, NULL, 0);
}
Esempio n. 15
0
static void
whoisReadReply(int fd, void *data)
{
    WhoisState *p = data;
    StoreEntry *entry = p->entry;
    char *buf = memAllocate(MEM_4K_BUF);
    MemObject *mem = entry->mem_obj;
    int len;
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, 4095);
    buf[len] = '\0';
    debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len);
    debug(75, 5) ("{%s}\n", buf);
    if (len > 0) {
	if (0 == mem->inmem_hi)
	    mem->reply->sline.status = HTTP_OK;
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.http.kbytes_in, len);
	storeAppend(entry, buf, len);
	commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
    } else if (len < 0) {
	debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
	} else if (mem->inmem_hi == 0) {
	    ErrorState *err;
	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
	    err->xerrno = errno;
	    fwdFail(p->fwd, err);
	    comm_close(fd);
	} else {
	    comm_close(fd);
	}
    } else {
	fwdComplete(p->fwd);
	debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
	comm_close(fd);
    }
    memFree(buf, MEM_4K_BUF);
}
Esempio n. 16
0
/*
 * copied from httpReadReply()
 *
 * by the time this is called, the ICAP headers have already
 * been read.
 */
void
icapReadReply(int fd, void *data)
{
    IcapStateData *icap = data;
    StoreEntry *entry = icap->respmod.entry;
    const request_t *request = icap->request;
    int len;
    debug(81, 5) ("icapReadReply: FD %d: icap %p.\n", fd, data);
    if (icap->flags.no_content && !icap->flags.http_server_eof) {	//AI

	return;
    }
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    statCounter.syscalls.sock.reads++;
    len = memBufRead(fd, &icap->chunk_buf);
    debug(81, 5) ("icapReadReply: FD %d: len %d.\n", fd, len);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.icap.all.kbytes_in, len);
	commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
	if (icap->chunk_buf.size < icap->chunk_buf.capacity) {
	    *(icap->chunk_buf.buf + icap->chunk_buf.size) = '\0';
	    debug(81, 9) ("{%s}\n", icap->chunk_buf.buf);
	}
    }
    if (len <= 0) {
	debug(81, 2) ("icapReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    debug(81, 2) ("icapReadReply: FD %d: ignored errno\n", fd);
	    commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
	} else if (entry->mem_obj->inmem_hi == 0) {
	    ErrorState *err;
	    debug(81, 2) ("icapReadReply: FD %d: generating error page\n", fd);
	    err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	    err->request = requestLink((request_t *) request);
	    err->xerrno = errno;
	    errorAppendEntry(entry, err);
	    comm_close(fd);
	} else {
	    debug(81, 2) ("icapReadReply: FD %d: just calling comm_close()\n",
		fd);
	    comm_close(fd);
	}
	return;
    }
    if (icapReadReply2(icap) < 0)
	comm_close(fd);
}
Esempio n. 17
0
static void lscsAccept(int sock, void *data)
{
        int fd = -1;
//        fde *F;
        ConnStateData *connState = NULL;
        int max = INCOMING_HTTP_MAX;
        commSetSelect(sock, COMM_SELECT_READ, lscsAccept, data, 0);
        while (max-- && !httpAcceptDefer(sock, NULL))
        {
                if ((fd = comm_accept_un(sock)) < 0)
                {
                        if (!ignoreErrno(errno))
                                debug(191, 1) ("lscsAccept: FD %d: accept failure: %s\n",
                                                          sock, xstrerror());
                        break;
                }



                commSetSelect(fd, COMM_SELECT_READ, clientRecvFd, connState, 0);
        }
}
Esempio n. 18
0
void
wccpConnectionShutdown(void)
{
    if (theInWccpConnection < 0)
	return;
    if (theInWccpConnection != theOutWccpConnection) {
	debug(80, 1) ("FD %d Closing WCCP socket\n", theInWccpConnection);
	comm_close(theInWccpConnection);
	theInWccpConnection = -1;
    }
    assert(theOutWccpConnection > -1);
    commSetSelect(theOutWccpConnection, COMM_SELECT_READ, NULL, NULL, 0);
}
Esempio n. 19
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. 20
0
static void
idnsSendTcpQueryDone(int fd, char *bufnotused, size_t size, int errflag, void *data)
{
    idns_query *q = data;
    if (size > 0)
	fd_bytes(fd, size, FD_WRITE);
    if (errflag == COMM_ERR_CLOSING)
	return;
    if (errflag) {
	idnsTcpCleanup(q);
	return;
    }
    commSetSelect(q->tcp_socket, COMM_SELECT_READ, idnsReadTcp, q, 0);
}
Esempio n. 21
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. 22
0
int
icpUdpSend(int fd,
    const struct sockaddr_in *to,
    icp_common_t * msg,
    log_type logcode,
    int delay)
{
    icpUdpData *queue;
    int x;
    int len;
    len = (int) ntohs(msg->length);
    debug(12, 5) ("icpUdpSend: FD %d sending %s, %d bytes to %s:%d\n",
	fd,
	icp_opcode_str[msg->opcode],
	len,
	inet_ntoa(to->sin_addr),
	ntohs(to->sin_port));
    x = comm_udp_sendto(fd, to, sizeof(*to), msg, len);
    if (x >= 0) {
	/* successfully written */
	icpLogIcp(to->sin_addr, logcode, len, (char *) (msg + 1), delay);
	icpCount(msg, SENT, (size_t) len, delay);
	safe_free(msg);
    } else if (0 == delay) {
	/* send failed, but queue it */
	queue = xcalloc(1, sizeof(icpUdpData));
	queue->address = *to;
	queue->msg = msg;
	queue->len = (int) ntohs(msg->length);
	queue->queue_time = current_time;
	queue->logcode = logcode;
	if (IcpQueueHead == NULL) {
	    IcpQueueHead = queue;
	    IcpQueueTail = queue;
	} else if (IcpQueueTail == IcpQueueHead) {
	    IcpQueueTail = queue;
	    IcpQueueHead->next = queue;
	} else {
	    IcpQueueTail->next = queue;
	    IcpQueueTail = queue;
	}
	commSetSelect(fd, COMM_SELECT_WRITE, icpUdpSendQueue, NULL, 0);
	statCounter.icp.replies_queued++;
    } else {
	/* don't queue it */
	statCounter.icp.replies_dropped++;
    }
    return x;
}
Esempio n. 23
0
void
icapConnectOver(int fd, int status, void *data)
{
    ErrorState *err;
    IcapStateData *icap = data;
    debug(81, 3) ("icapConnectOver: FD %d, status=%d\n", fd, status);
    icap->flags.connect_pending = 0;
    if (status < 0) {
	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	err->xerrno = errno;
	err->request = requestLink(icap->request);
	errorAppendEntry(icap->respmod.entry, err);
	comm_close(fd);
	debug(81, 3) ("icapConnectOver: status < 0, unreachable=1\n");
	icapOptSetUnreachable(icap->current_service);
	return;
    }
    commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
}
Esempio n. 24
0
static void
icmpRecv(int unused1, void *unused2)
{
    int n;
    static int fail_count = 0;
    pingerReplyData preply;
    static struct sockaddr_in F;
    commSetSelect(icmp_sock, COMM_SELECT_READ, icmpRecv, NULL, 0);
    memset(&preply, '\0', sizeof(pingerReplyData));
    Counter.syscalls.sock.recvfroms++;
    n = recv(icmp_sock,
	(char *) &preply,
	sizeof(pingerReplyData),
	0);
    if (n < 0) {
	debug(50, 1) ("icmpRecv: recv: %s\n", xstrerror());
	if (++fail_count == 10 || errno == ECONNREFUSED)
	    icmpClose();
	return;
    }
    fail_count = 0;
    if (n == 0)			/* test probe from pinger */
	return;
    F.sin_family = AF_INET;
    F.sin_addr = preply.from;
    F.sin_port = 0;
    switch (preply.opcode) {
    case S_ICMP_ECHO:
	break;
#if ALLOW_SOURCE_PING
    case S_ICMP_ICP:
	icmpHandleSourcePing(&F, preply.payload);
	break;
#endif
    case S_ICMP_DOM:
	netdbHandlePingReply(&F, preply.hops, preply.rtt);
	break;
    default:
	debug(37, 1) ("icmpRecv: Bad opcode: %d\n", (int) preply.opcode);
	break;
    }
}
Esempio n. 25
0
/*
 * Gobble up (read) some bytes until we get to the start of the body
 */
static void
icapRespModGobble(int fd, void *data)
{
    IcapStateData *icap = data;
    int len;
    LOCAL_ARRAY(char, junk, SQUID_TCP_SO_RCVBUF);
    debug(81, 3) ("icapRespModGobble: FD %d gobbling %d bytes\n", fd,
	icap->bytes_to_gobble);
    len = FD_READ_METHOD(fd, junk, icap->bytes_to_gobble);
    debug(81, 3) ("icapRespModGobble: gobbled %d bytes\n", len);
    if (len < 0) {
	/* XXX error */
	abort();
    }
    icap->bytes_to_gobble -= len;
    if (icap->bytes_to_gobble)
	commSetSelect(fd, COMM_SELECT_READ, icapRespModGobble, icap, 0);
    else
	icapReadReply(fd, icap);
}
Esempio n. 26
0
int
pconnPop(const char *host, u_short port, const char *domain, struct in_addr *client_address, u_short client_port, int *idle)
{
    struct _pconn *p;
    hash_link *hptr;
    int fd = -1;
    assert(table != NULL);
    hptr = pconnLookup(host, port, domain, client_address, client_port);
    if (hptr != NULL) {
	p = (struct _pconn *) hptr;
	assert(p->nfds > 0);
	fd = p->fds[p->nfds - 1];
	if (idle)
	    *idle = p->nfds - 1;
	pconnRemoveFD(p, fd);
	commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
	commSetTimeout(fd, -1, NULL, NULL);
    }
    return fd;
}
void
whoisStart(FwdState * fwd)
{
    WhoisState *p;
    int fd = fwd->server_fd;
    char *buf;
    size_t l;
    CBDATA_INIT_TYPE(WhoisState);
    p = cbdataAlloc(WhoisState);
    p->request = fwd->request;
    p->entry = fwd->entry;
    p->fwd = fwd;
    storeLockObject(p->entry);
    comm_add_close_handler(fd, whoisClose, p);
    l = strLen(p->request->urlpath) + 3;
    buf = xmalloc(l);
    snprintf(buf, l, "%s\r\n", strBuf(p->request->urlpath) + 1);
    comm_write(fd, buf, strlen(buf), NULL, p, xfree);
    commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, 0);
    commSetTimeout(fd, Config.Timeout.read, whoisTimeout, p);
}
Esempio n. 28
0
static void
icapReadReply3(IcapStateData * icap)
{
    StoreEntry *entry = icap->respmod.entry;
    int fd = icap->icap_fd;
    debug(81, 3) ("icapReadReply3\n");
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	debug(81, 3) ("icapReadReply3: Entry Aborded\n");
	comm_close(fd);
    } else if (icapPconnTransferDone(fd, icap)) {
	storeComplete(entry);
	icapRespModKeepAliveOrClose(icap);
    } else if (!icap->flags.no_content) {
	/* Wait for EOF condition */
	commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
	debug(81,
	    3)
	    ("icapReadReply3: Going to read mode data throught icapReadReply\n");
    } else {
	debug(81, 3) ("icapReadReply3: Nothing\n");
    }
}
Esempio n. 29
0
/*
 * icapRespModKeepAliveOrClose
 *
 * Called when we are done reading from the ICAP server.
 * Either close the connection or keep it open for a future
 * transaction.
 */
static void
icapRespModKeepAliveOrClose(IcapStateData * icap)
{
    int fd = icap->icap_fd;
    if (fd < 0)
	return;
    if (!icap->flags.keep_alive) {
	debug(81, 3) ("%s:%d keep_alive not set, closing\n", __FILE__,
	    __LINE__);
	comm_close(fd);
	return;
    }
    debug(81, 3) ("%s:%d FD %d looks good, keeping alive\n", __FILE__, __LINE__,
	fd);
    commSetDefer(fd, NULL, NULL);
    commSetTimeout(fd, -1, NULL, NULL);
    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
    comm_remove_close_handler(fd, icapStateFree, icap);
    pconnPush(fd, icap->current_service->hostname, icap->current_service->port);
    icap->icap_fd = -1;
    icapStateFree(-1, icap);
}
Esempio n. 30
0
void
pconnPush(int fd, const char *host, u_short port, const char *domain, struct in_addr *client_address, u_short client_port)
{
    struct _pconn *p;
    int *old;
    LOCAL_ARRAY(char, desc, FD_DESC_SZ);
    LOCAL_ARRAY(char, key, PCONN_KEYLEN);
    if (fdUsageHigh()) {
	debug(48, 3) ("pconnPush: Not many unused FDs\n");
	comm_close(fd);
	return;
    } else if (shutting_down) {
	comm_close(fd);
	return;
    }
    assert(table != NULL);
    pconnKey(key, host, port, domain, client_address, client_port);
    p = (struct _pconn *) hash_lookup(table, key);
    if (p == NULL)
	p = pconnNew(key);
    if (p->nfds == p->nfds_alloc) {
	debug(48, 3) ("pconnPush: growing FD array\n");
	p->nfds_alloc <<= 1;
	old = p->fds;
	p->fds = xmalloc(p->nfds_alloc * sizeof(int));
	xmemcpy(p->fds, old, p->nfds * sizeof(int));
	if (p->nfds == PCONN_FDS_SZ)
	    memPoolFree(pconn_fds_pool, old);
	else
	    xfree(old);
    }
    p->fds[p->nfds++] = fd;
    commSetSelect(fd, COMM_SELECT_READ, pconnRead, p, 0);
    commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p);
    snprintf(desc, FD_DESC_SZ, "%s idle connection", host);
    fd_note(fd, desc);
    debug(48, 3) ("pconnPush: pushed FD %d for %s\n", fd, key);
}