3030
3131static const char * trace_channel = "proxy.ftp.conn" ;
3232
33+ static int set_conn_socket_opts (pool * p , conn_t * conn , int rcvbufsz ,
34+ int sndbufsz , struct tcp_keepalive * keepalive , int reuse_port ) {
35+ int res ;
36+
37+ #if PROFTPD_VERSION_NUMBER >= 0x0001030801
38+ res = pr_inet_set_socket_opts2 (p , conn , rcvbufsz , sndbufsz , keepalive ,
39+ reuse_port );
40+ #else
41+ res = pr_inet_set_socket_opts (p , conn , rcvbufsz , sndbufsz , keepalive );
42+
43+ /* Earlier versions of ProFTPD did not support setting the SO_REUSEPORT
44+ * socket option via pr_inet_set_socket_opts(), so we do it ourselves.
45+ *
46+ * For active data transfers, enabling SO_REUSEPORT can be very useful,
47+ * since the number/range of available source ports may be small.
48+ */
49+ # if defined(SO_REUSEPORT )
50+ if (setsockopt (conn -> listen_fd , SOL_SOCKET , SO_REUSEPORT ,
51+ (void * ) & reuse_port , sizeof (reuse_port )) < 0 ) {
52+ pr_log_writefile (proxy_logfd , MOD_PROXY_VERSION ,
53+ "error setting SO_REUSEPORT on fd %d: %s" , conn -> listen_fd ,
54+ strerror (errno ));
55+
56+ } else {
57+ pr_trace_msg (trace_channel , 8 ,
58+ "set socket fd %d reuseport = %d" , conn -> listen_fd , reuse_port );
59+ }
60+ # endif /* SO_REUSEPORT */
61+ #endif /* ProFTPD 1.3.8rc1 or later */
62+
63+ return res ;
64+ }
65+
3366conn_t * proxy_ftp_conn_accept (pool * p , conn_t * data_conn , conn_t * ctrl_conn ,
3467 int frontend_data ) {
3568 conn_t * conn ;
@@ -45,14 +78,14 @@ conn_t *proxy_ftp_conn_accept(pool *p, conn_t *data_conn, conn_t *ctrl_conn,
4578 reverse_dns = pr_netaddr_set_reverse_dns (ServerUseReverseDNS );
4679
4780 if (session .xfer .direction == PR_NETIO_IO_RD ) {
48- pr_inet_set_socket_opts (data_conn -> pool , data_conn ,
81+ set_conn_socket_opts (data_conn -> pool , data_conn ,
4982 (main_server -> tcp_rcvbuf_override ? main_server -> tcp_rcvbuf_len : 0 ), 0 ,
50- main_server -> tcp_keepalive );
83+ main_server -> tcp_keepalive , 0 );
5184
5285 } else {
53- pr_inet_set_socket_opts (data_conn -> pool , data_conn ,
86+ set_conn_socket_opts (data_conn -> pool , data_conn ,
5487 0 , (main_server -> tcp_sndbuf_override ? main_server -> tcp_sndbuf_len : 0 ),
55- main_server -> tcp_keepalive );
88+ main_server -> tcp_keepalive , 0 );
5689 }
5790
5891 if (frontend_data ) {
@@ -114,14 +147,14 @@ conn_t *proxy_ftp_conn_connect(pool *p, const pr_netaddr_t *bind_addr,
114147 reverse_dns = pr_netaddr_set_reverse_dns (ServerUseReverseDNS );
115148
116149 if (session .xfer .direction == PR_NETIO_IO_RD ) {
117- pr_inet_set_socket_opts (conn -> pool , conn ,
150+ set_conn_socket_opts (conn -> pool , conn ,
118151 (main_server -> tcp_rcvbuf_override ? main_server -> tcp_rcvbuf_len : 0 ), 0 ,
119- main_server -> tcp_keepalive );
152+ main_server -> tcp_keepalive , 1 );
120153
121154 } else {
122- pr_inet_set_socket_opts (conn -> pool , conn ,
155+ set_conn_socket_opts (conn -> pool , conn ,
123156 0 , (main_server -> tcp_sndbuf_override ? main_server -> tcp_sndbuf_len : 0 ),
124- main_server -> tcp_keepalive );
157+ main_server -> tcp_keepalive , 1 );
125158 }
126159
127160 pr_inet_set_proto_opts (session .pool , conn ,
0 commit comments