示例#1
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);
}
/* resize a variable sized buffer using best-fit pool */
void *
memReallocBuf(void *oldbuf, size_t net_size, size_t * gross_size)
{
    /* XXX This can be optimized on very large buffers to use realloc() */
    size_t new_gross_size;
    void *newbuf = memAllocBuf(net_size, &new_gross_size);
    if (oldbuf) {
        int data_size = *gross_size;
        if (data_size > net_size)
            data_size = net_size;
        memcpy(newbuf, oldbuf, data_size);
        memFreeBuf(*gross_size, oldbuf);
    }
    *gross_size = new_gross_size;
    return newbuf;
}
示例#3
0
static void clientRecvFd(int sock, void *data)
{
	int retval;     
	struct msghdr msg;
	struct iovec vec;       
	char cmsgbuf[CMSG_SPACE(sizeof(int))];
	struct cmsghdr *p_cmsg;
	char iov_buf[CACHE_WATCH_RECV_MSG_LENGTH];

	vec.iov_base = iov_buf;
	vec.iov_len = CACHE_WATCH_RECV_MSG_LENGTH;
	msg.msg_name = NULL;    
	msg.msg_namelen = 0;
	msg.msg_iov = &vec; 
	msg.msg_iovlen = 1;
	msg.msg_control = cmsgbuf;
	msg.msg_controllen = sizeof(cmsgbuf);   
	msg.msg_flags = 0;      /* In case something goes wrong, set the fd to -1 before the syscall */
	retval = recvmsg(sock, &msg, 0);

	if( retval <= 0 )
	{       
		comm_close(sock);
		return; 
	}       

	if( (p_cmsg = CMSG_FIRSTHDR(&msg)) == NULL )
	{       
		comm_close(sock);
		return; 
	}       

    if (squidWatchReply(sock, &msg, iov_buf) != -1)
    {
        comm_close(sock);
        return;
    }

	int fd = *((int*)CMSG_DATA(p_cmsg));
	// for keep alive
	commSetSelect(sock, COMM_SELECT_READ, clientRecvFd, NULL, 0);
	// omm_close(sock);
	if(fd < 0)
	{
		return;
	}
	//comm_accept's jobs
	struct sockaddr_in peername;
	struct sockaddr_in sockname;
	socklen_t socklen;
	socklen = sizeof(struct sockaddr_in);
	memset(&peername, '\0', socklen);
	memset(&sockname, '\0', socklen);
	getpeername(fd, (struct sockaddr *)&peername, &socklen);
	getsockname(fd, (struct sockaddr *)&sockname, &socklen);
	commSetCloseOnExec(fd);
	fd_open(fd, FD_SOCKET, "HTTP Request");
	fde *F = &fd_table[fd];
	xstrncpy(F->ipaddr, xinet_ntoa(peername.sin_addr), 16);
	F->remote_port = htons(peername.sin_port);
	F->local_port = htons(sockname.sin_port);
	commSetNonBlocking(fd);
	//rest of httpAccept's jobs
    //
    //int on = 1;
    //if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0)
    //    debug(191, 0) ("commSetTcpNoDelay: FD %d: %s\n", fd, xstrerror());
    //fd_table[fd].flags.nodelay = 1;
#ifdef TCP_NODELAY
	commSetTcpNoDelay(fd); /*Fix tcp use Negale bug while send packet*/
#endif

#ifdef CC_FRAMEWORK
	cc_call_hook_func_private_http_accept(fd);
#endif

	debug(191, 4) ("clientRecvFd: FD %d: accepted port %d client %s:%d\n", fd, F->local_port, F->ipaddr, F->remote_port);
	fd_note_static(fd, "client http connect");
	ConnStateData * connState = cbdataAlloc(ConnStateData);
	assert(Config.Sockaddr.http);
	connState->port = Config.Sockaddr.http;
	cbdataLock(connState->port);
	connState->peer = peername; 
	connState->log_addr = peername.sin_addr;
	connState->log_addr.s_addr &= Config.Addrs.client_netmask.s_addr;
	connState->me = sockname;
	connState->fd = fd;
	connState->pinning.fd = -1;
	connState->in.buf = memAllocBuf(CLIENT_REQ_BUF_SZ, &connState->in.size);
	comm_add_close_handler(fd, connStateFree, connState);
	if (Config.onoff.log_fqdn)
		fqdncache_gethostbyaddr(peername.sin_addr, FQDN_LOOKUP_IF_MISS);
	commSetTimeout(fd, Config.Timeout.request, requestTimeout, connState);
#if USE_IDENT
	static aclCheck_t identChecklist;
	identChecklist.src_addr = peername.sin_addr;
	identChecklist.my_addr = sockname.sin_addr;
	identChecklist.my_port = ntohs(sockname.sin_port);
	if (aclCheckFast(Config.accessList.identLookup, &identChecklist))
		identStart(&sockname, &peername, clientIdentDone, connState);
#endif
	commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, connState, 0);
	commSetDefer(fd, clientReadDefer, connState);
	if (connState->port->tcp_keepalive.enabled)
	{       
		commSetTcpKeepalive(fd, connState->port->tcp_keepalive.idle, connState->port->tcp_keepalive.interval, connState->port->tcp_keepalive.timeout);
	}       

	clientdbEstablished(peername.sin_addr, 1);
	incoming_sockets_accepted++;
}