Try the following patch to amanda that resolves potential
issues with UDP and blocking receive.
--- amanda-2.4.4p3/common-src/dgram.c.orig 2004-10-26 09:51:27.000000000
-0700
+++ amanda-2.4.4p3/common-src/dgram.c 2004-10-26 10:01:56.622775784 -0700
@@ -248,9 +248,31 @@
socklen_t addrlen;
int nfound;
int save_errno;
+ int flags;
sock = dgram->socket;
+ /* Need to be in non-blocking mode before doing receive,
+ * because select on Linux will return true when there is
+ * a UDP message with checksum error, but receive will
+ * then hang.
+ */
+ flags = fcntl(sock, F_GETFL);
+ if (flags < 0) {
+ save_errno = errno;
+ dbprintf(("%s: dgram_recv: fcntl get flags failed %s\n",
+ debug_prefix(NULL), strerror(save_errno)));
+ return -1;
+ }
+
+ if(fcntl(sock, F_SETFL, flags|O_NONBLOCK) < 0) {
+ save_errno = errno;
+ dbprintf(("%s: dgram_recv: fcntl set flags failed %s\n",
+ debug_prefix(NULL), strerror(save_errno)));
+ return -1;
+ }
+
+ retry:
FD_ZERO(&ready);
FD_SET(sock, &ready);
to.tv_sec = timeout;
@@ -284,6 +306,7 @@
nfound = -1;
}
errno = save_errno;
+ fcntl(sock, F_SETFL, flags);
return nfound;
}
@@ -291,13 +314,19 @@
size = recvfrom(sock, dgram->data, MAX_DGRAM, 0,
(struct sockaddr *)fromaddr, &addrlen);
if(size == -1) {
+ if (errno == EINTR || errno == EAGAIN)
+ goto retry;
save_errno = errno;
dbprintf(("%s: dgram_recv: recvfrom() failed: %s\n",
debug_prefix(NULL),
strerror(save_errno)));
errno = save_errno;
+ fcntl(sock, F_SETFL, flags);
return -1;
}
+
+ fcntl(sock, F_SETFL, flags);
+
dgram->len = size;
dgram->data[size] = '\0';
dgram->cur = dgram->data;
|