From c9c5ce23652db79f36925c1509a15ddf4f665422 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 10 May 2006 22:17:42 +0000 Subject: David McCreedy provided a fix for CURLINFO_LASTSOCKET that does extended checks on the to-be-returned socket to make sure it truly seems to be alive and well. For SSL connection it (only) uses OpenSSL functions. --- CHANGES | 5 +++++ RELEASE-NOTES | 1 + lib/getinfo.c | 18 +++++++++++++++++- lib/sslgen.c | 18 ++++++++++++++++++ lib/sslgen.h | 2 ++ lib/ssluse.c | 23 +++++++++++++++++++++++ lib/ssluse.h | 2 ++ 7 files changed, 68 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index c700e2f64..9f08a3036 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,11 @@ Changelog +Daniel (11 May 2006) +- David McCreedy provided a fix for CURLINFO_LASTSOCKET that does extended + checks on the to-be-returned socket to make sure it truly seems to be alive + and well. For SSL connection it (only) uses OpenSSL functions. + Daniel (10 May 2006) - Fixed DICT in two aspects: diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 3d42c7b8c..cebc62aaa 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -11,6 +11,7 @@ Curl and libcurl 7.15.4 This release includes the following changes: + o CURLINFO_LASTSOCKET returned sockets are now checked more before returned o curl-config got a --checkfor option to compare version numbers o line end conversions for FTP ASCII transfers o curl_multi_socket() API added (still mostly untested) diff --git a/lib/getinfo.c b/lib/getinfo.c index c7b4cfa4a..d74fbcf3c 100644 --- a/lib/getinfo.c +++ b/lib/getinfo.c @@ -75,6 +75,8 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) double *param_doublep=NULL; char **param_charp=NULL; struct curl_slist **param_slistp=NULL; + char buf; + va_start(arg, info); switch(info&CURLINFO_TYPEMASK) { @@ -197,9 +199,23 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) break; case CURLINFO_LASTSOCKET: if((data->state.lastconnect != -1) && - (data->state.connects[data->state.lastconnect] != NULL)) + (data->state.connects[data->state.lastconnect] != NULL)) { *param_longp = data->state.connects[data->state.lastconnect]-> sock[FIRSTSOCKET]; + /* we have a socket connected, let's determine if the server shut down */ + /* determine if ssl */ + if(data->state.connects[data->state.lastconnect]->protocol & PROT_SSL) { + /* use the SSL context */ + if (!Curl_ssl_check_cxn(data->state.connects[data->state.lastconnect])) + *param_longp = -1; /* FIN received */ + } + else { + /* use the socket */ + if(recv((int)data->state.connects[data->state.lastconnect]-> + sock[FIRSTSOCKET], (void*)&buf, 1, MSG_PEEK) == 0) + *param_longp = -1; /* FIN received */ + } + } else *param_longp = -1; break; diff --git a/lib/sslgen.c b/lib/sslgen.c index a4c941050..f8f8ec622 100644 --- a/lib/sslgen.c +++ b/lib/sslgen.c @@ -554,3 +554,21 @@ size_t Curl_ssl_version(char *buffer, size_t size) #endif /* USE_SSLEAY */ } + +/* + * This function tries to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +int Curl_ssl_check_cxn(struct connectdata *conn) +{ +#ifdef USE_SSLEAY + return Curl_ossl_check_cxn(conn); +#else + /* TODO: we lack implementation of this for GnuTLS */ + return -1; /* connection status unknown */ +#endif /* USE_SSLEAY */ +} diff --git a/lib/sslgen.h b/lib/sslgen.h index 6b63c3688..cd1b66390 100644 --- a/lib/sslgen.h +++ b/lib/sslgen.h @@ -67,6 +67,8 @@ struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data); size_t Curl_ssl_version(char *buffer, size_t size); +int Curl_ssl_check_cxn(struct connectdata *conn); + #if !defined(USE_SSL) && !defined(SSLGEN_C) /* set up blank macros for none-SSL builds */ #define Curl_ssl_close_all(x) diff --git a/lib/ssluse.c b/lib/ssluse.c index 503f7efe5..ab177009a 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -584,6 +584,29 @@ void Curl_ossl_cleanup(void) #endif } +/* + * This function uses SSL_peek to determine connection status. + * + * Return codes: + * 1 means the connection is still in place + * 0 means the connection has been closed + * -1 means the connection status is unknown + */ +int Curl_ossl_check_cxn(struct connectdata *conn) +{ + int rc; + char buf; + + rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1); + if (rc > 0) + return 1; /* connection still in place */ + + if (rc == 0) + return 0; /* connection has been closed */ + + return -1; /* connection status unknown */ +} + #endif /* USE_SSLEAY */ /* Selects an OpenSSL crypto engine diff --git a/lib/ssluse.h b/lib/ssluse.h index 1bbc2cc1c..5cc2f700e 100644 --- a/lib/ssluse.h +++ b/lib/ssluse.h @@ -64,4 +64,6 @@ ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */ size_t Curl_ossl_version(char *buffer, size_t size); +int Curl_ossl_check_cxn(struct connectdata *cxn); + #endif -- cgit v1.2.3