From: Bill Stoddard Date: Thu, 29 Jan 2004 03:20:14 +0000 (+0000) Subject: Win32: Port Win32DisableAcceptEx from 2.1 X-Git-Tag: 2.0.49~185 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1892d88af6158862c4a95b5fc2ed1c338ae4bc62;p=thirdparty%2Fapache%2Fhttpd.git Win32: Port Win32DisableAcceptEx from 2.1 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@102441 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index e7a6f356715..dda7e01d9f8 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,11 @@ Changes with Apache 2.0.49 + *) Win32: Add Win32DisableAcceptEx directive. This Windows + NT/2000/CP directive is useful to work around bugs in some + third party layered service providers like virus scanners, + VPN and firewall products, that do not properly handle + WinSock 2 APIs. Use this directive if your server is issuing + AcceptEx failed messages. + [Allan Edwards, Bill Rowe, Bill Stoddard, Jeff Trawick] *) Make REMOTE_PORT variable available in mod_rewrite. PR 25772. [André Malo] diff --git a/STATUS b/STATUS index a9487049030..049679fad87 100644 --- a/STATUS +++ b/STATUS @@ -1,5 +1,5 @@ APACHE 2.0 STATUS: -*-text-*- -Last modified at [$Date: 2004/01/28 22:35:54 $] +Last modified at [$Date: 2004/01/29 03:20:14 $] Release: @@ -113,15 +113,6 @@ PATCHES TO BACKPORT FROM 2.1 http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/proxy/proxy_http.c?r1=1.176&r2=1.177 +1: stoddard, nd - * Win32: Port Win32DisableAcceptEx directive. This fix enables using - Winsock 1.1 accept() call in place of Winsock 2.0 AcceptEx() to work - around bugs in third party layered service providers (e.g. virus - scanners) that do not properly handle various Winsock 2 APIs. - http://cvs.apache.org/viewcvs.cgi/httpd-2.0/server/mpm/winnt/child.c?r1=1.19&r2=1.20 - http://cvs.apache.org/viewcvs.cgi/httpd-2.0/server/mpm/winnt/mpm_winnt.c?r1=1.301&r2=1.302 - http://cvs.apache.org/viewcvs.cgi/httpd-2.0/server/mpm/winnt/mpm_winnt.h?r1=1.42&r2=1.43 - +1: stoddard, trawick (with subsequent change to messages), ake - * If large file support is enabled, allow any file that is greater than AP_MAX_SENDFILE to be split into multiple buckets. This allows Apache to send files that are greater than 2gig. Otherwise we run into diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index c230f731b46..bf07dfb5dff 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -709,11 +709,11 @@ static void worker_main(long thread_num) ap_update_child_status_from_indexes(0, thread_num, SERVER_READY, NULL); /* Grab a connection off the network */ - if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - context = win9x_get_connection(context); + if (use_acceptex) { + context = winnt_get_connection(context); } else { - context = winnt_get_connection(context); + context = win9x_get_connection(context); } if (!context) { /* Time for the thread to exit */ @@ -741,6 +741,16 @@ static void worker_main(long thread_num) context->accept_socket = INVALID_SOCKET; ap_lingering_close(c); } + else if (!use_acceptex) { + /* If the socket is disconnected but we are not using acceptex, + * we cannot reuse the socket. Disconnected sockets are removed + * from the apr_socket_t struct by apr_sendfile() to prevent the + * socket descriptor from being inadvertently closed by a call + * to apr_socket_close(), so close it directly. + */ + closesocket(context->accept_socket); + context->accept_socket = INVALID_SOCKET; + } } else { /* ap_run_create_connection closes the socket on failure */ @@ -777,7 +787,7 @@ static void cleanup_thread(HANDLE *handles, int *thread_cnt, int thread_to_clean static void create_listener_thread() { int tid; - if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + if (!use_acceptex) { _beginthreadex(NULL, 0, (LPTHREAD_START_ROUTINE) win9x_accept, NULL, 0, &tid); } else { @@ -1015,7 +1025,7 @@ void child_main(apr_pool_t *pconf) } /* Shutdown the worker threads */ - if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { + if (!use_acceptex) { for (i = 0; i < threads_created; i++) { add_job(INVALID_SOCKET); } @@ -1073,8 +1083,8 @@ void child_main(apr_pool_t *pconf) CloseHandle(allowed_globals.jobsemaphore); apr_thread_mutex_destroy(allowed_globals.jobmutex); - if (osver.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { - apr_thread_mutex_destroy(qlock); + if (use_acceptex) { + apr_thread_mutex_destroy(qlock); CloseHandle(qwait_event); } diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 64566614bbc..4d775a828f1 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -103,6 +103,7 @@ static DWORD parent_pid; DWORD my_pid; int ap_threads_per_child = 0; +int use_acceptex = 1; static int thread_limit = DEFAULT_THREAD_LIMIT; static int first_thread_limit = 0; static int changed_limit_at_restart; @@ -217,6 +218,19 @@ static const char *set_thread_limit (cmd_parms *cmd, void *dummy, const char *ar } return NULL; } +static const char *set_disable_acceptex(cmd_parms *cmd, void *dummy, char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + if (use_acceptex) { + use_acceptex = 0; + ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, + "Disabled use of AcceptEx() WinSock2 API"); + } + return NULL; +} static const command_rec winnt_cmds[] = { LISTEN_COMMANDS, @@ -224,6 +238,8 @@ AP_INIT_TAKE1("ThreadsPerChild", set_threads_per_child, NULL, RSRC_CONF, "Number of threads each child creates" ), AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF, "Maximum worker threads in a server for this run of Apache"), +AP_INIT_NO_ARGS("Win32DisableAcceptEx", set_disable_acceptex, NULL, RSRC_CONF, + "Disable use of the high performance AcceptEx WinSock2 API to work around buggy VPN or Firewall software"), { NULL } }; diff --git a/server/mpm/winnt/mpm_winnt.h b/server/mpm/winnt/mpm_winnt.h index 01a7c0204cb..0444638a626 100644 --- a/server/mpm/winnt/mpm_winnt.h +++ b/server/mpm/winnt/mpm_winnt.h @@ -100,7 +100,7 @@ void mpm_nt_eventlog_stderr_open(char *display_name, apr_pool_t *p); void mpm_nt_eventlog_stderr_flush(void); /* From winnt.c: */ - +extern int use_acceptex; extern OSVERSIONINFO osver; extern void clean_child_exit(int);