Hi,
I'm trying to fix a bug in tinyproxy 1.7.0 (old, dead project, http://tinyproxy.sourceforge.net/). I am trying to avoid an infinite blocking recv() call by using select first to test. I'm trying to do minimal changes to the code (so I don't want to make the socket non-blocking right from the get go). Hence this attempt at making an overloaded of sorts recv method.
So where there would normally be:
ret = recv(fd, buffer, SEGMENT_LEN, MSG_PEEK);
I wish to use:
ret = recv_timeout(fd, buffer, SEGMENT_LEN, MSG_PEEK);
recv_timeout uses select to make sure the code won't hang on a recv, then goes and performs the recv as per normal. My attempt at doing this fails, select() always times out, it never returns even when there is data in the fd. What am I doing wrong with select?
Code:
ssize_t
recv_timeout(int fd, void *buf, size_t len, int flags)
{
ssize_t ret;
struct timeval tv;
fd_set rset;
// init set
FD_ZERO(&rset);
// add to set
FD_SET(fd, &rset);
// UNCOMMENT THIS AND PROXY WORKS
// So safe to assume I'm passing correct arguments
//ret = recv(fd, buf, len, flags);
//return ret;
// this is set to 60 seconds
tv.tv_sec =
config.idletimeout;
tv.tv_usec = 0;
// NEVER returns before the timeout value.
ret = select(fd, &rset, NULL, NULL, &tv);
if (ret == 0) {
log_message(LOG_INFO,
"Idle Timeout (after select)");
return 0;
} else if (ret < 0) {
log_message(LOG_ERR,
"recv_timeout: select() error \"%s\". Closing connection (fd:%d)",
strerror(errno), fd);
return;
}
ret = recv(fd, buf, len, flags);
return ret;
}
Advice? I know that the correct arguments are passed through, as I can change this method to go straight to recv(bypass select) and the proxy works as per normal (and still hangs if the recv blocks).