update to fix leak in SSL code
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index bd3f172..7ab2297 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -46,6 +46,7 @@
 	PY_SSL_ERROR_WANT_CONNECT,
 	/* start of non ssl.h errorcodes */
 	PY_SSL_ERROR_EOF,         /* special case of SSL_ERROR_SYSCALL */
+        PY_SSL_ERROR_NO_SOCKET,   /* socket has been GC'd */
 	PY_SSL_ERROR_INVALID_ERROR_CODE
 };
 
@@ -111,7 +112,7 @@
 
 typedef struct {
 	PyObject_HEAD
-	PySocketSockObject *Socket;	/* Socket on which we're layered */
+	PyObject        *Socket;	/* weakref to socket on which we're layered */
 	SSL_CTX*	ctx;
 	SSL*		ssl;
 	X509*		peer_cert;
@@ -188,13 +189,15 @@
 		{
 			unsigned long e = ERR_get_error();
 			if (e == 0) {
-				if (ret == 0 || !obj->Socket) {
+                                PySocketSockObject *s
+                                  = (PySocketSockObject *) PyWeakref_GetObject(obj->Socket);
+				if (ret == 0 || (((PyObject *)s) == Py_None)) {
 				  p = PY_SSL_ERROR_EOF;
 				  errstr =
                                       "EOF occurred in violation of protocol";
 				} else if (ret == -1) {
 				  /* underlying BIO reported an I/O error */
-                                  return obj->Socket->errorhandler();
+                                  return s->errorhandler();
 				} else { /* possible? */
                                   p = PY_SSL_ERROR_SYSCALL;
                                   errstr = "Some I/O error occurred";
@@ -383,8 +386,7 @@
 		SSL_set_accept_state(self->ssl);
 	PySSL_END_ALLOW_THREADS
 
-	self->Socket = Sock;
-	Py_INCREF(self->Socket);
+	self->Socket = PyWeakref_NewRef((PyObject *) Sock, Py_None);
 	return self;
  fail:
 	if (errstr)
@@ -442,6 +444,14 @@
 	/* XXX If SSL_do_handshake() returns 0, it's also a failure. */
 	sockstate = 0;
 	do {
+                PySocketSockObject *sock
+                  = (PySocketSockObject *) PyWeakref_GetObject(self->Socket);
+                if (((PyObject*)sock) == Py_None) {
+                        _setSSLError("Underlying socket connection gone",
+                                     PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
+                        return NULL;
+                }
+
 		PySSL_BEGIN_ALLOW_THREADS
 		ret = SSL_do_handshake(self->ssl);
 		err = SSL_get_error(self->ssl, ret);
@@ -450,9 +460,9 @@
 			return NULL;
 		}
 		if (err == SSL_ERROR_WANT_READ) {
-			sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+			sockstate = check_socket_and_wait_for_timeout(sock, 0);
 		} else if (err == SSL_ERROR_WANT_WRITE) {
-			sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+			sockstate = check_socket_and_wait_for_timeout(sock, 1);
 		} else {
 			sockstate = SOCKET_OPERATION_OK;
 		}
@@ -1140,16 +1150,24 @@
 	int sockstate;
 	int err;
         int nonblocking;
+        PySocketSockObject *sock
+          = (PySocketSockObject *) PyWeakref_GetObject(self->Socket);
+
+        if (((PyObject*)sock) == Py_None) {
+                _setSSLError("Underlying socket connection gone",
+                             PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
+                return NULL;
+        }
 
 	if (!PyArg_ParseTuple(args, "y#:write", &data, &count))
 		return NULL;
 
         /* just in case the blocking state of the socket has been changed */
-	nonblocking = (self->Socket->sock_timeout >= 0.0);
+	nonblocking = (sock->sock_timeout >= 0.0);
         BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);
         BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);
 
-	sockstate = check_socket_and_wait_for_timeout(self->Socket, 1);
+	sockstate = check_socket_and_wait_for_timeout(sock, 1);
 	if (sockstate == SOCKET_HAS_TIMED_OUT) {
 		PyErr_SetString(PySSLErrorObject,
                                 "The write operation timed out");
@@ -1174,10 +1192,10 @@
 		}
 		if (err == SSL_ERROR_WANT_READ) {
 			sockstate =
-                            check_socket_and_wait_for_timeout(self->Socket, 0);
+                            check_socket_and_wait_for_timeout(sock, 0);
 		} else if (err == SSL_ERROR_WANT_WRITE) {
 			sockstate =
-                            check_socket_and_wait_for_timeout(self->Socket, 1);
+                            check_socket_and_wait_for_timeout(sock, 1);
 		} else {
 			sockstate = SOCKET_OPERATION_OK;
 		}
@@ -1233,10 +1251,17 @@
 	int sockstate;
 	int err;
         int nonblocking;
+        PySocketSockObject *sock
+          = (PySocketSockObject *) PyWeakref_GetObject(self->Socket);
+
+        if (((PyObject*)sock) == Py_None) {
+                _setSSLError("Underlying socket connection gone",
+                             PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
+                return NULL;
+        }
 
 	if (!PyArg_ParseTuple(args, "|Oi:read", &buf, &count))
 		return NULL;
-
         if ((buf == NULL) || (buf == Py_None)) {
 		if (!(buf = PyBytes_FromStringAndSize((char *) 0, len)))
 			return NULL;
@@ -1254,7 +1279,7 @@
 	}
 
         /* just in case the blocking state of the socket has been changed */
-	nonblocking = (self->Socket->sock_timeout >= 0.0);
+	nonblocking = (sock->sock_timeout >= 0.0);
         BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking);
         BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking);
 
@@ -1264,7 +1289,7 @@
 	PySSL_END_ALLOW_THREADS
 
 	if (!count) {
-		sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
+		sockstate = check_socket_and_wait_for_timeout(sock, 0);
 		if (sockstate == SOCKET_HAS_TIMED_OUT) {
 			PyErr_SetString(PySSLErrorObject,
 					"The read operation timed out");
@@ -1299,10 +1324,10 @@
 		}
 		if (err == SSL_ERROR_WANT_READ) {
 			sockstate =
-			  check_socket_and_wait_for_timeout(self->Socket, 0);
+			  check_socket_and_wait_for_timeout(sock, 0);
 		} else if (err == SSL_ERROR_WANT_WRITE) {
 			sockstate =
-			  check_socket_and_wait_for_timeout(self->Socket, 1);
+			  check_socket_and_wait_for_timeout(sock, 1);
 		} else if ((err == SSL_ERROR_ZERO_RETURN) &&
 			   (SSL_get_shutdown(self->ssl) ==
 			    SSL_RECEIVED_SHUTDOWN))