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; }
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); }
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; }
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 }
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); }
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 }
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); }
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(); }
/* * 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); }
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); }
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); }
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); }
/* * 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); }
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); } }
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); }
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); } }
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); }
/* 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); }
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; }
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); }
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; } }
/* * 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); }
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); }
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"); } }
/* * 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); }
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); }