void clientdbUpdate(struct in_addr addr, log_type ltype, protocol_t p, squid_off_t size) { const char *key; ClientInfo *c; if (!Config.onoff.client_db) return; key = xinet_ntoa(addr); c = (ClientInfo *) hash_lookup(client_table, key); if (c == NULL) c = clientdbAdd(addr); if (c == NULL) debug_trap("clientdbUpdate: Failed to add entry"); if (p == PROTO_HTTP) { c->Http.n_requests++; c->Http.result_hist[ltype]++; kb_incr(&c->Http.kbytes_out, size); if (isTcpHit(ltype)) kb_incr(&c->Http.hit_kbytes_out, size); } else if (p == PROTO_ICP) { c->Icp.n_requests++; c->Icp.result_hist[ltype]++; kb_incr(&c->Icp.kbytes_out, size); if (LOG_UDP_HIT == ltype) kb_incr(&c->Icp.hit_kbytes_out, size); } c->last_seen = squid_curtime; }
char *conn_ntoa(int fd) { uint32_t ip; if(cm_getval(fd, CONN_IP, &ip) < 0) return NULL; return xinet_ntoa(ip); }
static ClientInfo * clientdbAdd(struct in_addr addr) { ClientInfo *c; c = memAllocate(MEM_CLIENT_INFO); c->hash.key = xstrdup(xinet_ntoa(addr)); c->addr = addr; hash_join(client_table, &c->hash); statCounter.client_http.clients++; if ((statCounter.client_http.clients > max_clients) && !cleanup_running && cleanup_scheduled < 2) { cleanup_scheduled++; eventAdd("client_db garbage collector", clientdbScheduledGC, NULL, 90, 0); } return c; }
/* * clientdbEstablished() * This function tracks the number of currently established connections * for a client IP address. When a connection is accepted, call this * with delta = 1. When the connection is closed, call with delta = * -1. To get the current value, simply call with delta = 0. */ int clientdbEstablished(struct in_addr addr, int delta) { const char *key; ClientInfo *c; if (!Config.onoff.client_db) return 0; key = xinet_ntoa(addr); c = (ClientInfo *) hash_lookup(client_table, key); if (c == NULL) c = clientdbAdd(addr); if (c == NULL) debug_trap("clientdbUpdate: Failed to add entry"); c->n_established += delta; return c->n_established; }
int clientdbCutoffDenied(struct in_addr addr) { const char *key; int NR; int ND; double p; ClientInfo *c; if (!Config.onoff.client_db) return 0; key = xinet_ntoa(addr); c = (ClientInfo *) hash_lookup(client_table, key); if (c == NULL) return 0; /* * If we are in a cutoff window, we don't send a reply */ if (squid_curtime - c->cutoff.time < CUTOFF_SECONDS) return 1; /* * Calculate the percent of DENIED replies since the last * cutoff time. */ NR = c->Icp.n_requests - c->cutoff.n_req; if (NR < 150) NR = 150; ND = c->Icp.result_hist[LOG_UDP_DENIED] - c->cutoff.n_denied; p = 100.0 * ND / NR; if (p < 95.0) return 0; debug(1, 0) ("WARNING: Probable misconfigured neighbor at %s\n", key); debug(1, 0) ("WARNING: %d of the last %d ICP replies are DENIED\n", ND, NR); debug(1, 0) ("WARNING: No replies will be sent for the next %d seconds\n", CUTOFF_SECONDS); c->cutoff.time = squid_curtime; c->cutoff.n_req = c->Icp.n_requests; c->cutoff.n_denied = c->Icp.result_hist[LOG_UDP_DENIED]; return 1; }
struct in_addr * client_entry(struct in_addr *current) { ClientInfo *c = NULL; const char *key; if (current) { key = xinet_ntoa(*current); hash_first(client_table); while ((c = (ClientInfo *) hash_next(client_table))) { if (!strcmp(key, hashKeyStr(&c->hash))) break; } c = (ClientInfo *) hash_next(client_table); } else { hash_first(client_table); c = (ClientInfo *) hash_next(client_table); } hash_last(client_table); if (c) return (&c->addr); else return (NULL); }
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++; }