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 int sslDeferServerRead(int fdnotused, void *data) { SslStateData *s = data; int i = delayBytesWanted(s->delay_id, 0, INT_MAX); if (i == INT_MAX) return 0; if (i == 0) return 1; return -1; }
/* This will be called when data is ready to be read from fd. Read until * error or connection closed. */ static void gopherReadReply(int fd, void *data) { GopherStateData *gopherState = data; StoreEntry *entry = gopherState->entry; char *buf = NULL; int len; int clen; int bin; size_t read_sz; #if DELAY_POOLS delay_id delay_id = delayMostBytesAllowed(entry->mem_obj); #endif if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) { comm_close(fd); return; } errno = 0; buf = memAllocate(MEM_4K_BUF); read_sz = 4096 - 1; /* leave room for termination */ #if DELAY_POOLS read_sz = delayBytesWanted(delay_id, 1, read_sz); #endif /* leave one space for \0 in gopherToHTML */ statCounter.syscalls.sock.reads++; len = FD_READ_METHOD(fd, buf, read_sz); if (len > 0) { fd_bytes(fd, len, FD_READ); #if DELAY_POOLS delayBytesIn(delay_id, len); #endif kb_incr(&statCounter.server.all.kbytes_in, len); kb_incr(&statCounter.server.other.kbytes_in, len); } debug(10, 5) ("gopherReadReply: FD %d read len=%d\n", fd, len); if (len > 0) { commSetTimeout(fd, Config.Timeout.read, NULL, NULL); IOStats.Gopher.reads++; for (clen = len - 1, bin = 0; clen; bin++) clen >>= 1; IOStats.Gopher.read_hist[bin]++; }
/* This will be called when data is ready to be read from fd. Read until * error or connection closed. */ static void waisReadReply(int fd, void *data) { WaisStateData *waisState = data; LOCAL_ARRAY(char, buf, 4096); StoreEntry *entry = waisState->entry; int len; int clen; int bin; size_t read_sz; #if DELAY_POOLS delay_id delay_id = delayMostBytesAllowed(entry->mem_obj); #endif if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) { comm_close(fd); return; } errno = 0; read_sz = 4096; #if DELAY_POOLS read_sz = delayBytesWanted(delay_id, 1, read_sz); #endif Counter.syscalls.sock.reads++; len = read(fd, buf, read_sz); if (len > 0) { fd_bytes(fd, len, FD_READ); #if DELAY_POOLS delayBytesIn(delay_id, len); #endif kb_incr(&Counter.server.all.kbytes_in, len); kb_incr(&Counter.server.other.kbytes_in, len); } debug(24, 5) ("waisReadReply: FD %d read len:%d\n", fd, len); if (len > 0) { commSetTimeout(fd, Config.Timeout.read, NULL, NULL); IOStats.Wais.reads++; for (clen = len - 1, bin = 0; clen; bin++) clen >>= 1; IOStats.Wais.read_hist[bin]++; }
/* Read from server side and queue it for writing to the client */ static void sslReadServer(int fd, void *data) { SslStateData *sslState = data; int len; size_t read_sz = SQUID_TCP_SO_RCVBUF - sslState->server.len; assert(fd == sslState->server.fd); debug(26, 3) ("sslReadServer: FD %d, reading %d bytes at offset %d\n", fd, read_sz, sslState->server.len); errno = 0; #if DELAY_POOLS read_sz = delayBytesWanted(sslState->delay_id, 1, read_sz); #endif Counter.syscalls.sock.reads++; len = read(fd, sslState->server.buf + sslState->server.len, read_sz); debug(26, 3) ("sslReadServer: FD %d, read %d bytes\n", fd, len); if (len > 0) { fd_bytes(fd, len, FD_READ); #if DELAY_POOLS delayBytesIn(sslState->delay_id, len); #endif kb_incr(&Counter.server.all.kbytes_in, len); kb_incr(&Counter.server.other.kbytes_in, len); sslState->server.len += len; } cbdataLock(sslState); if (len < 0) { debug(50, ignoreErrno(errno) ? 3 : 1) ("sslReadServer: FD %d: read failure: %s\n", fd, xstrerror()); if (!ignoreErrno(errno)) comm_close(fd); } else if (len == 0) { comm_close(sslState->server.fd); } if (cbdataValid(sslState)) sslSetSelect(sslState); cbdataUnlock(sslState); }