From eugen@www.svzserv.kemerovo.su  Tue Apr  9 23:28:09 2002
Return-Path: <eugen@www.svzserv.kemerovo.su>
Received: from www.svzserv.kemerovo.su (www.svzserv.kemerovo.su [213.184.65.80])
	by hub.freebsd.org (Postfix) with ESMTP id 764E437B4D4
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  9 Apr 2002 23:26:55 -0700 (PDT)
Received: (from eugen@localhost)
	by www.svzserv.kemerovo.su (8.11.6/8.11.6) id g3A6Qcv49878;
	Wed, 10 Apr 2002 14:26:38 +0800 (KRAST)
	(envelope-from eugen)
Message-Id: <200204100626.g3A6Qcv49878@www.svzserv.kemerovo.su>
Date: Wed, 10 Apr 2002 14:26:38 +0800 (KRAST)
From: Eugene Grosbein <eugen@www.svzserv.kemerovo.su>
Reply-To: Eugene Grosbein <eugen@www.svzserv.kemerovo.su>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Stock ftpd does not reuse ports in passive mode and fails
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         36955
>Category:       bin
>Synopsis:       Stock ftpd does not reuse ports in passive mode and fails
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    yar
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Apr 09 23:30:01 PDT 2002
>Closed-Date:    Thu Aug 22 07:08:43 PDT 2002
>Last-Modified:  Thu Aug 22 07:08:43 PDT 2002
>Originator:     Eugene Grosbein
>Release:        FreeBSD 4.5-STABLE i386
>Organization:
Svyaz Service
>Environment:
Stock ftpd, passive mode transfers
		sysctl net.inet.ip.portrange.hi[first|last] range limited

>Description:
	I have limited net.inet.ip.portrange.hi[first|last] range
	to several hundred (600-700) of ports. If I try to download
	many thousands of small files through 100Mb ethernet connection
	using passive mode, it starts but quickly fails with diagnostics:

	<--- 425 
	Can't open passive connection: Can't assign requested address.
	
	I guess it's because it does not reuse ports of dedicated range.
	So one client can exhaust ports and passive mode transfers
	will be blocked for some time. There is no such problem with
	active mode but it's not suitable for some configurations.

>How-To-Repeat:
	See above.
>Fix:

	Perhaps, use SO_REUSEPORT option?
>Release-Note:
>Audit-Trail:

From: Maxim Konovalov <maxim@macomnet.ru>
To: Eugene Grosbein <eugen@www.svzserv.kemerovo.su>
Cc: bug-followup@freebsd.org
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode and
 fails
Date: Fri, 12 Apr 2002 13:14:43 +0400 (MSD)

 On 14:26+0800, Apr 10, 2002, Eugene Grosbein wrote:
 
 [...]
 > >Release:        FreeBSD 4.5-STABLE i386
 
 How old is it?
 
 > >Organization:
 > Svyaz Service
 > >Environment:
 > Stock ftpd, passive mode transfers
 > 		sysctl net.inet.ip.portrange.hi[first|last] range limited
 
 Could you please show sysctl net.inet.ip.portrange?
 
 [...]
 
 -- 
 Maxim Konovalov, MAcomnet, Internet Dept., system engineer
 phone: +7 (095) 796-9079, mailto:maxim@macomnet.ru
 

From: Eugene Grosbein <eugen@svzserv.kemerovo.su>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: Eugene Grosbein <eugen@www.svzserv.kemerovo.su>,
	bug-followup@freebsd.org
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode andfails
Date: Fri, 12 Apr 2002 17:17:54 +0800

 Maxim Konovalov wrote:
 
 > > >Release:        FreeBSD 4.5-STABLE i386
 > How old is it?
 
 1 March 2002
  
 > > >Organization:
 > > Svyaz Service
 > > >Environment:
 > > Stock ftpd, passive mode transfers
 > >               sysctl net.inet.ip.portrange.hi[first|last] range limited
 > 
 > Could you please show sysctl net.inet.ip.portrange?
 
 net.inet.ip.portrange.lowfirst: 1023
 net.inet.ip.portrange.lowlast: 600
 net.inet.ip.portrange.first: 1024
 net.inet.ip.portrange.last: 5000
 net.inet.ip.portrange.hifirst: 49152
 net.inet.ip.portrange.hilast: 49700
 
 These two last have been set from /etc/sysctl.conf
 
 Eugene Grosbein

From: Maxim Konovalov <maxim@macomnet.ru>
To: Eugene Grosbein <eugen@svzserv.kemerovo.su>
Cc: bug-followup@freebsd.org
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode
 andfails
Date: Fri, 12 Apr 2002 15:03:54 +0400 (MSD)

 Eugene,
 
 The patch below solves the problem but I am not sure yet is it good
 idea or not..
 
 Index: ftpd.c
 ===================================================================
 RCS file: /home/ncvs/src/libexec/ftpd/ftpd.c,v
 retrieving revision 1.99
 diff -u -r1.99 ftpd.c
 --- ftpd.c	25 Feb 2002 16:39:34 -0000	1.99
 +++ ftpd.c	12 Apr 2002 10:53:00 -0000
 @@ -2415,7 +2415,7 @@
  void
  passive(void)
  {
 -	int len;
 +	int len, on;
  	char *p, *a;
 
  	if (pdata >= 0)		/* close old port if one set */
 @@ -2426,12 +2426,15 @@
  		perror_reply(425, "Can't open passive connection");
  		return;
  	}
 -
 +	on = 1;
 +	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR,
 +	    (char *)&on, sizeof(on)) < 0)
 +		syslog(LOG_ERR, "passive data connection setsockopt: %m");
  	(void) seteuid((uid_t)0);
 
  #ifdef IP_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET) {
 -	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
  					   : IP_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
 @@ -2441,7 +2444,7 @@
  #endif
  #ifdef IPV6_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET6) {
 -	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
  					   : IPV6_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
 
 %%%
 
 -- 
 Maxim Konovalov, MAcomnet, Internet Dept., system engineer
 phone: +7 (095) 796-9079, mailto:maxim@macomnet.ru
 

From: Eugene Grosbein <eugen@svzserv.kemerovo.su>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@freebsd.org
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive modeandfails
Date: Sat, 13 Apr 2002 11:56:34 +0800

 Maxim Konovalov wrote:
 
 > The patch below solves the problem but I am not sure yet is it good
 > idea or not..
 
 Why not? I've corrected it for -STABLE and it works.
 
 Eugene

From: Yar Tikhiy <yar@freebsd.org>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@freebsd.org,
	Eugene Grosbein <eugen@svzserv.kemerovo.su>
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode and fails
Date: Sun, 21 Jul 2002 16:59:45 +0400

 Setting SO_REUSEADDR on a listening socket is always a good idea.
 Plese refer to the following URL for a detailed explanation:
 http://www.kohala.com/start/torek.94dec31.txt
 
 BTW, I'd omit casting the "&on" parameter to setsockopt(2) to "char
 *" since now setsockopt(2) expects "void *" there.  In general, all
 that pointer casting in our ftpd is a real mess.  As a matter of
 fact, a pointer (or 0 as the null pointer) needs to be casted to a
 certain type only when passing it to a function without a prototype.
 And casting such a pointer to a wrong type is a really bad thing
 to do.
 
 -- 
 Yar

From: Yar Tikhiy <yar@comp.chem.msu.su>
To: Maxim Konovalov <maxim@macomnet.ru>
Cc: bug-followup@freebsd.org,
	Eugene Grosbein <eugen@svzserv.kemerovo.su>
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode and fails
Date: Sun, 21 Jul 2002 18:24:52 +0400

 One more note:  There's another spot in the code where passive data
 connections are opened, in the long_passive() function (EPSV.)
 
 -- 
 Yar

From: Maxim Konovalov <maxim@macomnet.ru>
To: Yar Tikhiy <yar@freebsd.org>
Cc: bug-followup@freebsd.org,
	Eugene Grosbein <eugen@svzserv.kemerovo.su>
Subject: Re: bin/36955: Stock ftpd does not reuse ports in passive mode and
 fails
Date: Mon, 22 Jul 2002 15:22:28 +0400 (MSD)

 Hi Yar,
 
 On 16:59+0400, Jul 21, 2002, Yar Tikhiy wrote:
 
 > Setting SO_REUSEADDR on a listening socket is always a good idea.
 > Plese refer to the following URL for a detailed explanation:
 > http://www.kohala.com/start/torek.94dec31.txt
 >
 > BTW, I'd omit casting the "&on" parameter to setsockopt(2) to "char
 > *" since now setsockopt(2) expects "void *" there.  In general, all
 > that pointer casting in our ftpd is a real mess.  As a matter of
 > fact, a pointer (or 0 as the null pointer) needs to be casted to a
 > certain type only when passing it to a function without a prototype.
 > And casting such a pointer to a wrong type is a really bad thing
 > to do.
 
 There is a comment in OpenBSD ftpd I was worrying about:
 
 void
 passive()
 {
 ...
         /*
          * XXX
          * At this point, it would be nice to have an algorithm that
          * inserted a growing delay in an attack scenario.  Such a thing
          * would look like continual passive sockets being opened, but
          * nothing serious being done with them.  They're not used to
          * move data; the entire attempt is just to use tcp FIN_WAIT
          * resources.
          */
         pdata = socket(AF_INET, SOCK_STREAM, 0);
 ...
 
 But AFAIU my patch does not make things worse. Here is a revised one:
 
 Index: ftpd.c
 ===================================================================
 RCS file: /home/ncvs/src/libexec/ftpd/ftpd.c,v
 retrieving revision 1.112
 diff -u -r1.112 ftpd.c
 --- ftpd.c	21 Jul 2002 12:06:56 -0000	1.112
 +++ ftpd.c	22 Jul 2002 10:34:23 -0000
 @@ -2470,7 +2470,7 @@
  void
  passive(void)
  {
 -	int len;
 +	int len, on;
  	char *p, *a;
 
  	if (pdata >= 0)		/* close old port if one set */
 @@ -2481,12 +2481,14 @@
  		perror_reply(425, "Can't open passive connection");
  		return;
  	}
 -
 +	on = 1;
 +	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
 +		syslog(LOG_ERR, "passive data connection setsockopt: %m");
  	(void) seteuid((uid_t)0);
 
  #ifdef IP_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET) {
 -	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
  					   : IP_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
 @@ -2496,7 +2498,7 @@
  #endif
  #ifdef IPV6_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET6) {
 -	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
  					   : IPV6_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
 @@ -2550,7 +2552,7 @@
  void
  long_passive(char *cmd, int pf)
  {
 -	int len;
 +	int len, on;
  	char *p, *a;
 
  	if (pdata >= 0)		/* close old port if one set */
 @@ -2588,6 +2590,9 @@
  		perror_reply(425, "Can't open passive connection");
  		return;
  	}
 +	on = 1;
 +	if (setsockopt(pdata, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
 +		syslog(LOG_ERR, "passive data connection setsockopt: %m");
 
  	(void) seteuid((uid_t)0);
 
 @@ -2597,7 +2602,7 @@
 
  #ifdef IP_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET) {
 -	    int on = restricted_data_ports ? IP_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IP_PORTRANGE_HIGH
  					   : IP_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE,
 @@ -2607,7 +2612,7 @@
  #endif
  #ifdef IPV6_PORTRANGE
  	if (ctrl_addr.su_family == AF_INET6) {
 -	    int on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
 +	    on = restricted_data_ports ? IPV6_PORTRANGE_HIGH
  					   : IPV6_PORTRANGE_DEFAULT;
 
  	    if (setsockopt(pdata, IPPROTO_IPV6, IPV6_PORTRANGE,
 
 %%%
 
 If it looks OK feel free to commit it. Thank you!
 
 P.S. I have already tested it on our production ftp server.
 
 -- 
 Maxim Konovalov, MAcomnet, Internet Dept., system engineer
 phone: +7 (095) 796-9079, mailto:maxim@macomnet.ru
 
State-Changed-From-To: open->patched 
State-Changed-By: yar 
State-Changed-When: Wed Jul 24 09:11:55 PDT 2002 
State-Changed-Why:  
Fixed in CURRENT, will be merged into STABLE in two weeks. 
Thanks! 


Responsible-Changed-From-To: freebsd-bugs->yar 
Responsible-Changed-By: yar 
Responsible-Changed-When: Wed Jul 24 09:11:55 PDT 2002 
Responsible-Changed-Why:  
MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=36955 
State-Changed-From-To: patched->feedback 
State-Changed-By: yar 
State-Changed-When: Thu Aug 8 06:54:08 PDT 2002 
State-Changed-Why:  
Now this bug is believed to be fixed in STABLE and CURRENT. 
Would you mind to test if it has gone for your configuration? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=36955 
State-Changed-From-To: feedback->closed 
State-Changed-By: yar 
State-Changed-When: Thu Aug 22 07:06:57 PDT 2002 
State-Changed-Why:  
The originator has acknowledged the problem had gone. 
Thanks, Eugene! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=36955 
>Unformatted:
