here is the patch that can do ftp proxy by IPv6. i can connect to IPv6 ftp server when this patch is applyed to modules/proxy/proxy_ftp.c in httpd-2.0.39.
please verify it and merge it if it is correct. regards, //shoichi sakane *** proxy_ftp-old.c Fri Jun 28 15:18:27 2002 --- proxy_ftp.c Fri Jun 28 15:05:26 2002 *************** *** 942,984 **** 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_setsocketopt(sock, APR_SO_RCVBUF, - conf->recv_buffer_size))) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); - } - #endif - - if (APR_SUCCESS != (rv = apr_setsocketopt(sock, APR_SO_REUSEADDR, one))) { - #ifndef _OSD_POSIX /* BS2000 has this option "always on" */ - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, - "proxy: FTP: error setting reuseaddr option: setsockopt(SO_REUSEADDR)"); - return HTTP_INTERNAL_SERVER_ERROR; - #endif /* _OSD_POSIX */ - } - - /* Set a timeout on the socket */ - if (conf->timeout_set == 1) { - apr_setsocketopt(sock, APR_SO_TIMEOUT, (int)conf->timeout); - } - else { - apr_setsocketopt(sock, - APR_SO_TIMEOUT, (int)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 --- 942,947 ---- *************** *** 994,1005 **** 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) ! */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: FTP: trying to connect to %pI (%s)...", connect_addr, connectname); --- 957,998 ---- int failed = 1; while (connect_addr) { ! 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_setsocketopt(sock, APR_SO_RCVBUF, ! conf->recv_buffer_size))) { ! ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, ! "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default"); ! } ! #endif ! ! if (APR_SUCCESS != (rv = apr_setsocketopt(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: setsockopt(SO_REUSEADDR)"); ! continue; ! #endif /* _OSD_POSIX */ ! } ! ! /* Set a timeout on the socket */ ! if (conf->timeout_set == 1) { ! apr_setsocketopt(sock, APR_SO_TIMEOUT, (int)conf->timeout); ! } ! else { ! apr_setsocketopt(sock, ! APR_SO_TIMEOUT, (int)r->server->timeout); ! } ! ! ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, ! "proxy: FTP: socket has been created"); ! ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: FTP: trying to connect to %pI (%s)...", connect_addr, connectname); *************** *** 1008,1013 **** --- 1001,1007 ---- /* 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,1288 **** "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) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: FTP: error creating EPSV socket"); return HTTP_INTERNAL_SERVER_ERROR; --- 1276,1282 ---- "proxy: FTP: EPSV contacting remote host on port %d", data_port); ! 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; *************** *** 1299,1305 **** /* 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); rv = apr_connect(data_sock, epsv_addr); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, --- 1293,1299 ---- /* 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, 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, *************** *** 1368,1374 **** "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) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: error creating PASV socket"); return HTTP_INTERNAL_SERVER_ERROR; --- 1362,1368 ---- "proxy: FTP: PASV contacting host %d.%d.%d.%d:%d", h3, h2, h1, h0, pasvport); ! 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; *************** *** 1383,1389 **** #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); rv = apr_connect(data_sock, pasv_addr); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server, --- 1377,1383 ---- #endif /* make the connection */ ! 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, *************** *** 1410,1416 **** 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) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "proxy: FTP: error creating local socket"); return HTTP_INTERNAL_SERVER_ERROR; --- 1404,1410 ---- apr_port_t local_port; unsigned int h0, h1, h2, h3, p0, p1; ! 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;