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; }
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++; }