Oops, forgot to attach the diff file. It is attached here: On Fri, 17 Oct 2003, Norman Tuttle wrote:
> This new patch for flood_socket_keepalive.c fixes some issues discovered > during opening and closing sockets. Predicated on the changes previously > made to the socket structure (reference my email with the 6 diffs), the > reopen_socket member, which has now been changed to "available", now takes > on an ordered enum of values. The keepalive_begin_conn() function has been > modified to properly handle error conditions and transitions, which can > occur between pages using ssl or no ssl, different hosts, or different > ports and require closure of the previous connection. > > Other changes: keepalive_end_conn() also contains logic to prevent certain > error conditions from crashing the function. The setting of the > socket's associated request, which was established in the patch mentioned > above, has been moved to the case where sockets are not being opened, > since otherwise the open_socket() or ssl_open_socket() function sets the > request. > > Please review the attached diff, which compares the latest > flood_socket_keepalive.c file with the version produced from the patch > creating the unified socket structure, which is named > flood_socket_keepalive_2.c > > -Norman Tuttle, Developer, OpenDemand Systems ([EMAIL PROTECTED]) > > > >
--- flood_socket_keepalive.c 2003-10-17 11:22:20.000000000 -0400 +++ flood_socket_keepalive_2.c 2003-10-15 19:06:44.000000000 -0400 @@ -76,18 +76,6 @@ ksock->ssl ? ssl_write_socket(ksock, req) : \ write_socket(ksock, req) -#define does_socket_need_reopen(ssl, ksock, req) \ - ((ssl!=ksock->ssl)||(req->parsed_uri->port!=ksock->port)|| \ - (strcasecmp(req->parsed_uri->hostname, ksock->hostname))) -/* case of either mismatch in ssl scheme, port, or hostname */ - -enum -{ - NOT_AVAILABLE, - AVAILABLE_OPEN, - AVAILABLE_CLOSED -}; - /** * Keep-alive implementation for socket_init. */ @@ -99,7 +87,7 @@ if (new_ksock == NULL) return APR_ENOMEM; new_ksock->socket = NULL; - new_ksock->available = AVAILABLE_CLOSED; + new_ksock->available = 1; new_ksock->wantresponse = 1; new_ksock->ssl = 0; @@ -112,55 +100,44 @@ */ apr_status_t keepalive_begin_conn(socket_t *sock, request_t *req, apr_pool_t *pool) { - apr_status_t status = APR_SUCCESS; flood_socket_t *ksock = (flood_socket_t *)sock; - int ssl = 0; /* new value for ssl, set up in next 10 lines */ - if (strcasecmp(req->parsed_uri->scheme, "https") == 0) - { - /* If we don't have SSL, error out. */ -#if FLOOD_HAS_OPENSSL - ssl = 1; -#else - return APR_ENOTIMPL; -#endif - } - /* If socket open, !ksock->socket is bogus state but don't close. */ - if ((ksock->available == AVAILABLE_OPEN)&&(ksock->socket)&& - ((does_socket_need_reopen(ssl, ksock, req))|| - /* above line includes test for compatible ssl, port, host, etc. */ - (check_socket(ksock) != APR_SUCCESS))) /* checks socket integrity */ - { /* first make sure it's closed! */ - ksock->ssl ? ssl_close_socket(ksock) : close_socket(ksock); - ksock->available = AVAILABLE_CLOSED; + if (!ksock->available && ksock->socket) { + apr_status_t e; + e = check_socket(ksock); + if (e != APR_SUCCESS) { + ksock->available = 1; + } } - ksock->ssl = ssl; - if ((ksock->available==AVAILABLE_CLOSED) || (!ksock->socket)) - { /* this logic handles above bogus condition. */ + if (ksock->available || ksock->socket == NULL) { + apr_status_t rv; + if (strcasecmp(req->parsed_uri->scheme, "https") == 0) { + /* If we don't have SSL, error out. */ #if FLOOD_HAS_OPENSSL - if (ssl) ssl_open_socket(ksock, req, &status); - else + ksock->ssl = 1; +#else + return APR_ENOTIMPL; #endif - open_socket(ksock, req, &status); - } - else /* Problem: keepalive introduces poss of begin_connect without socket/ - * request linkage through (ssl_)open_socket. Soln: In this case */ - { /* (available==AVAILABLE_OPEN), manually create the link here: */ - ksock->request = req; + } + else { + ksock->ssl = 0; + } + + /* The return types are not identical, so it can't be a ternary + * operation. */ + if (ksock->ssl) + ssl_open_socket(ksock, req, &rv); + else + open_socket(ksock, req, &rv); + + if (ksock->socket == NULL) + return rv; + + ksock->available = 0; /* we just opened it */ } - if (!ksock->socket) - { - ksock->available = AVAILABLE_CLOSED; /* Errors-reopen socket next time */ - if (status == APR_SUCCESS) - { /* There is still some error, although did not get returned in open. */ - status = APR_EGENERAL; /* opening null socket would be problematic. */ - } - } - if (status==APR_SUCCESS) ksock->available = NOT_AVAILABLE; /* socket now opened and IN USE */ - ksock->hostname = req->parsed_uri->hostname; - ksock->port = req->parsed_uri->port; + ksock->request = req; req->keepalive = 1; - return status; + return APR_SUCCESS; } /** @@ -591,12 +568,11 @@ { flood_socket_t *ksock = (flood_socket_t *)sock; - if (ksock && (ksock->socket) && (!resp || (resp->keepalive == 0))) - { /* This logic will leave the socket open if still keepalive. */ + if (resp->keepalive == 0) { ksock->ssl ? ssl_close_socket(ksock) : close_socket(ksock); - ksock->available = AVAILABLE_CLOSED; /* we just closed it */ + ksock->available = 1; /* we just closed it */ } - else ksock->available = AVAILABLE_OPEN; + return APR_SUCCESS; }