From 9cf303e9bcd84001e4abdde4e8cd73c773b39d80 Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Wed, 17 Jul 2002 17:55:59 +0000 Subject: [PATCH] Get proxy ftp to work over IPv6. Submitted by: Shoichi Sakane Reviewed and modified slightly by: Jeff Trawick git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@96100 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 2 + modules/proxy/proxy_ftp.c | 89 ++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/CHANGES b/CHANGES index 6ff75683bc..661ce4252d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ Changes with Apache 2.0.40 + *) Get proxy ftp to work over IPv6. [Shoichi Sakane ] + *) Look for OpenSSL libraries in /usr/lib64. [Peter Poeml ] *) Update SuSE layout. [Peter Poeml ] diff --git a/modules/proxy/proxy_ftp.c b/modules/proxy/proxy_ftp.c index 5ae5b28a51..a306056c46 100644 --- a/modules/proxy/proxy_ftp.c +++ b/modules/proxy/proxy_ftp.c @@ -942,43 +942,6 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, connectname, NULL)); } - - if ((rv = apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error creating socket"); - return HTTP_INTERNAL_SERVER_ERROR; - } - -#if !defined(TPF) && !defined(BEOS) - if (conf->recv_buffer_size > 0 - && (rv = apr_socket_opt_set(sock, APR_SO_RCVBUF, - conf->recv_buffer_size))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "apr_socket_opt_set(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } -#endif - - if ((rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, one)) - != APR_SUCCESS) { -#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error setting reuseaddr option: apr_socket_opt_set(SO_REUSEADDR)"); - return HTTP_INTERNAL_SERVER_ERROR; -#endif /* _OSD_POSIX */ - } - - /* Set a timeout on the socket */ - if (conf->timeout_set == 1) { - apr_socket_timeout_set(sock, conf->timeout); - } - else { - apr_socket_timeout_set(sock, r->server->timeout); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: socket has been created"); - - /* * At this point we have a list of one or more IP addresses of the * machine to connect to. If configured, reorder this list so that the @@ -994,20 +957,48 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, int failed = 1; while (connect_addr) { - /* FIXME: @@@: We created an APR_INET socket. Now there may be - * IPv6 (AF_INET6) DNS addresses in the list... IMO the socket - * should be created with the correct family in the first place. - * (either do it in this loop, or make at least two attempts - * with the AF_INET and AF_INET6 elements in the list) - */ + if ((rv = apr_socket_create(&sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error creating socket"); + continue; + } + +#if !defined(TPF) && !defined(BEOS) + if (conf->recv_buffer_size > 0 + && (rv = apr_socket_opt_set(sock, APR_SO_RCVBUF, + conf->recv_buffer_size))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "apr_socket_opt_set(APR_SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); + } +#endif + + if (APR_SUCCESS != (rv = apr_socket_opt_set(sock, APR_SO_REUSEADDR, one))) { + apr_socket_close(sock); +#ifndef _OSD_POSIX /* BS2000 has this option "always on" */ + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "proxy: FTP: error setting reuseaddr option: apr_socket_opt_set(APR_SO_REUSEADDR)"); + continue; +#endif /* _OSD_POSIX */ + } + + /* Set a timeout on the socket */ + if (conf->timeout_set == 1) { + apr_socket_timeout_set(sock, conf->timeout); + } + else { + apr_socket_timeout_set(sock, r->server->timeout); + } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, - "proxy: FTP: trying to connect to %pI (%s)...", connect_addr, connectname); + "proxy: FTP: fam %d socket created, trying to connect to %pI (%s)...", + connect_addr->family, connect_addr, connectname); /* make the connection out of the socket */ rv = apr_connect(sock, connect_addr); /* if an error occurred, loop round and try again */ if (rv != APR_SUCCESS) { + apr_socket_close(sock); ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, "proxy: FTP: attempt to connect to %pI (%s) failed", connect_addr, connectname); connect_addr = connect_addr->next; @@ -1282,7 +1273,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, "proxy: FTP: EPSV contacting remote host on port %d", data_port); - if ((rv = apr_socket_create(&data_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { + if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: FTP: error creating EPSV socket"); return HTTP_INTERNAL_SERVER_ERROR; @@ -1300,7 +1291,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, /* make the connection */ apr_socket_addr_get(&data_addr, APR_REMOTE, sock); apr_sockaddr_ip_get(&data_ip, data_addr); - apr_sockaddr_info_get(&epsv_addr, data_ip, APR_INET, data_port, 0, p); + apr_sockaddr_info_get(&epsv_addr, data_ip, connect_addr->family, data_port, 0, p); rv = apr_connect(data_sock, epsv_addr); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, @@ -1369,7 +1360,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, "proxy: FTP: PASV contacting host %d.%d.%d.%d:%d", h3, h2, h1, h0, pasvport); - if ((rv = apr_socket_create(&data_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { + if ((rv = apr_socket_create(&data_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: error creating PASV socket"); return HTTP_INTERNAL_SERVER_ERROR; @@ -1385,7 +1376,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, #endif /* make the connection */ - apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), APR_INET, pasvport, 0, p); + apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), connect_addr->family, pasvport, 0, p); rv = apr_connect(data_sock, pasv_addr); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, @@ -1412,7 +1403,7 @@ int ap_proxy_ftp_handler(request_rec *r, proxy_server_conf *conf, apr_port_t local_port; unsigned int h0, h1, h2, h3, p0, p1; - if ((rv = apr_socket_create(&local_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) { + if ((rv = apr_socket_create(&local_sock, connect_addr->family, SOCK_STREAM, r->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: FTP: error creating local socket"); return HTTP_INTERNAL_SERVER_ERROR; -- 2.50.1