aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES5
-rw-r--r--RELEASE-NOTES1
-rw-r--r--lib/getinfo.c18
-rw-r--r--lib/sslgen.c18
-rw-r--r--lib/sslgen.h2
-rw-r--r--lib/ssluse.c23
-rw-r--r--lib/ssluse.h2
7 files changed, 68 insertions, 1 deletions
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