WriteData() and EAGAIN (Resource temporarily unavailable)
"Dmitry N. Fomin" <dif-Ojq+iQ4dngjh4wg/[email protected]> Wed, 15 Oct 2003 15:01:36 +0400
| Newsgroups | gmane.comp.security.zebedee.general |
|---|---|
| Organization | MEDLUX network, Moscow, Russia |
| Message-ID | <[email protected]> |
I. Topic.
send() returns errno = EAGAIN (Resource temporarily unavailable).
Product - Zebedee 2.4.1.
Platform - FreeBSD 4.8-STABLE.
II. Problem Description.
Let the server of application is located on the same host,
as Zebedee server. The server of application can create a stream of
the big messages, which are badly compressed.
For example, loading big .jpeg files through http.
Zebedee server has not time to transfer this stream in the tunnel
and returns errno = EAGAIN (Resource temporarily unavailable).
The increase maxbufsize up to 16383 does not solve a problem.
Configuration file:
verbosity 5
detached true
ipmode tcp
udpmode false
multiuse true
#
redirect 80 # HTTP
redirect 443 # HTTPS
#
target localhost:80
target localhost:443
#
compression zlib:9
#maxbufsize 16383
readtimeout 20
tcptimeout 3600
udptimeout 100
Part logfile:
......
read 8192 bytes from local socket 1
writeMessage: message compressed from 8192 to 4711 bytes
writeMessage: message size = 4711, encrypted, compressed
writeData: sending 4713 of 4713
writeData: sent 4713 byte(s)
read 8192 bytes from local socket 1
writeMessage: message compressed from 8192 to 4391 bytes
writeMessage: message size = 4391, encrypted, compressed
writeData: sending 4393 of 4393
writeData: EOF or error: (Resource temporarily unavailable)
connection closed or timed out
read 317 bytes (317 expanded) in 10 messages
wrote 60307 bytes (122754 expanded) in 25 messages
ERROR: failed communicating with remote client: (Resource temporarily unavailable)
.......
III. The possible solution.
======== cut zebedee.c.patch ==========================
--- zebedee.c Tue May 28 06:31:15 2002
+++ zebedee.c Wed Oct 15 09:19:30 2003
@@ -1163,25 +1163,89 @@
int
writeData(int fd, unsigned char *buffer, unsigned short size)
{
+ fd_set testSet;
+ int ready=0;
+ struct timeval delay;
int num = 0;
char *bufP = NULL;
unsigned short total = 0;
bufP = (char *)buffer;
+
+ /* Set up the delay for select */
+
+ delay.tv_usec=0;
+
+ if (ReadTimeout > 0)
+ {
+ delay.tv_sec=ReadTimeout;
+ }
+ else
+ {
+ delay.tv_sec=0;
+ }
+ message(5, 0, "writeData: writetimeout %d", delay.tv_sec);
+
+ /* Set up file descriptors in mask to test */
+
+ FD_ZERO(&testSet);
+ FD_SET(fd,&testSet);
+
+ /*Do a blocking select waiting for any i/o */
+
+ ready=select(fd+1,0,&testSet,0,&delay);
+
+ if(ready<=0 && errno!=EINTR)
+ {
+ message(5, errno, "writeData: error in select");
+ FD_CLR(fd, &testSet);
+ return -1;
+ }
do
{
message(5, 0, "writeData: sending %d of %d", (size - total), size);
- if ((num = send(fd, (bufP + total), (size - total), 0)) <= 0)
+/* if ((num = send(fd, (bufP + total), (size - total), 0)) <= 0)
{
+*/
+ do {
+ if ((num = send(fd, (bufP + total), (size - total), 0)) > 0)
+ {
+ break;
+ }
+
+ if (num<0 && errno==EAGAIN)
+ {
+ ready=select(fd+1,0,&testSet,0,&delay);
+
+ if(ready==0)
+ {
+ message(0, errno, "timed out writing data");
+ FD_CLR(fd, &testSet);
+ return -1;
+ }
+
+ if(ready<=0 && errno!=EINTR)
+ {
+ message(5, errno, "writeData: error in select");
+ FD_CLR(fd, &testSet);
+ return -1;
+ }
+
+ message(5, 0, "writeData: again sending to local socket %d", ready);
+ continue;
+ }
/* Premature EOF or error */
message(5, errno, "writeData: EOF or error");
+ FD_CLR(fd, &testSet);
return num;
}
+ while(1);
total += (unsigned short)num;
message(5, 0, "writeData: sent %d byte(s)", num);
}
while (total < size);
+ FD_CLR(fd, &testSet);
return total;
}
======== end cut zebedee.c.patch ======================
Timeout sendings are defined with a "readtimeout" option.
Look "ReadTimeout" variable.
Probably, it is necessary to add a "writetimeout" option.
P.S.
It is necessary to process also and other erroneous conditions for system calls
send() and recv(). For example, EPIPE (Broken pipe).
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
SourceForge.net hosts over 70,000 Open Source Projects.
See the people who have HELPED US provide better services:
Click here: http://sourceforge.net/supporters.php