Hi,
the following patch was posted from Rogier Wolff, but the Mailing List
Daemon refused to accept it. We are crrently fixing the posting problem,
and here is his posting.
Volker
---------- Forwarded message ----------
Date: Fri, 10 Dec 1999 14:09:30 +0100 (MET)
From: Rogier Wolff
To: proxy-suite-owner@suse.com
Subject: failure notice (fwd)
Hi,
When the data port for connections to the server is specified as 41000
- 41999, there will always be a data connection between realserver:20
and proxyserver:41000, as the ftp-proxy always uses the lowest
possible port. Some ftp-servers don't seem to like this. They end up
refusing to build a dataconnection half of the time. (i.e. first
request works, second request doesn't, and so forth).
I observed this on an old Red Hat system, probably still running a 2.0
kernel (just checked: Yes, its 2.0.32). Now you know why this system
should really be behind the firewall.
Anyway, I've modified the ftp-proxy to start looking for a free port
at a random position in the range. This reduces the problem from
occurring 50% of the time to 0.05% of the time. (range is 1000
entries). This is acceptable, as the retry will simply work.
Roger.
diff -ur proxy-suite-1.7.orig/common/com-misc.c proxy-suite-1.7/common/com-misc.c
--- proxy-suite-1.7.orig/common/com-misc.c Fri Oct 22 11:29:01 1999
+++ proxy-suite-1.7/common/com-misc.c Fri Dec 10 12:47:11 1999
@@ -643,6 +643,17 @@
#endif
}
+int misc_rand (int lrng, int urng)
+{
+ struct timeval t;
+
+ if (lrng == urng) return lrng;
+
+ gettimeofday (&t, NULL);
+ srand (t.tv_usec);
+ return (lrng + (rand () % (urng - lrng + 1)));
+}
+
/* ------------------------------------------------------------
* $Log: com-misc.c,v $
diff -ur proxy-suite-1.7.orig/common/com-socket.c proxy-suite-1.7/common/com-socket.c
--- proxy-suite-1.7.orig/common/com-socket.c Fri Oct 22 11:29:01 1999
+++ proxy-suite-1.7/common/com-socket.c Fri Dec 10 12:49:21 1999
@@ -1163,6 +1163,7 @@
{
struct sockaddr_in saddr;
int sock;
+ int i;
u_int16_t port;
if (phls == NULL || ctyp == NULL) /* Sanity check */
@@ -1181,17 +1182,22 @@
saddr.sin_addr.s_addr = htonl(addr);
saddr.sin_family = AF_INET;
+
/*
** Bind the socket, taking care of a given port range.
** Note: this function covers also lrng = urng = 0 ...
+ **
+ ** Note: To prevent problems with reuseing portnos too quickly
+ ** we start at a random point inside the range.
*/
- for (port = lrng; port <= urng; port++) {
+ for (i=0,port = misc_rand (lrng, urng);i < (urng-lrng); i++,port++) {
saddr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &saddr,
sizeof(saddr)) == 0)
break;
if (errno != EADDRINUSE)
- port = urng + 1;
+ i = urng-lrng + 1;
+ if (port >= urng) port = lrng;
}
if (port > urng) { /* nothing found? */
close(sock);
--
** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
"I didn't say it was your fault. I said I was going to blame it on you."