You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by dr...@apache.org on 2006/06/23 14:20:59 UTC

svn commit: r416697 - in /apr/apr-util/trunk: include/apr_ssl.h include/private/apr_ssl_private.h ssl/apr_ssl_socket.c test/testssl.c

Author: dreid
Date: Fri Jun 23 05:20:59 2006
New Revision: 416697

URL: http://svn.apache.org/viewvc?rev=416697&view=rev
Log:
Add a function to change the requested poll events for an ssl socket
Change so we now track the pollset and simply store the pollfd structure
Refactor test so it's now more use

This now gets us to a point of having very basic functionality for ssl sockets.


Modified:
    apr/apr-util/trunk/include/apr_ssl.h
    apr/apr-util/trunk/include/private/apr_ssl_private.h
    apr/apr-util/trunk/ssl/apr_ssl_socket.c
    apr/apr-util/trunk/test/testssl.c

Modified: apr/apr-util/trunk/include/apr_ssl.h
URL: http://svn.apache.org/viewvc/apr/apr-util/trunk/include/apr_ssl.h?rev=416697&r1=416696&r2=416697&view=diff
==============================================================================
--- apr/apr-util/trunk/include/apr_ssl.h (original)
+++ apr/apr-util/trunk/include/apr_ssl.h Fri Jun 23 05:20:59 2006
@@ -226,14 +226,25 @@
                                                      apr_ssl_socket_t *);
 
 /**
- * @fn apr_status_t apr_pollset_remove_ssl_socket(apr_pollset_t *pollset,
-                                                  apr_ssl_socket_t *sock)
- * @brief remove an ssl socket from a pollset.
- * @param pollset The pollset to remove the socket from.
+ * @fn apr_status_t apr_pollset_remove_ssl_socket(apr_ssl_socket_t *sock)
+ * @brief Remove the ssl socket from it's pollset.
  * @param sock The ssl socket to remove.
  */
-APU_DECLARE(apr_status_t) apr_pollset_remove_ssl_socket(apr_pollset_t *,
-                                                        apr_ssl_socket_t *);
+APU_DECLARE(apr_status_t) apr_pollset_remove_ssl_socket(apr_ssl_socket_t *);
+
+/**
+ * @fn apr_status_t apr_ssl_socket_set_poll_events(apr_ssl_socket_t *sock,
+                                                   apr_int16_t events)
+ * @brief Set the required events for a socket.
+ * @note These will be used when apr_pollset_poll is next called for the
+ *       pollset the socket is currently attached to.
+ * @param sock The socket to set events for
+ * @param events The new events
+ * @return APR_SUCCESS if change made. Returns EINVAL if socket is not
+ *         attached to a pollset.
+ */
+APU_DECLARE(apr_status_t) apr_ssl_socket_set_poll_events(apr_ssl_socket_t *,
+                                                         apr_int16_t);
 
 /** @} */
 #ifdef __cplusplus

Modified: apr/apr-util/trunk/include/private/apr_ssl_private.h
URL: http://svn.apache.org/viewvc/apr/apr-util/trunk/include/private/apr_ssl_private.h?rev=416697&r1=416696&r2=416697&view=diff
==============================================================================
--- apr/apr-util/trunk/include/private/apr_ssl_private.h (original)
+++ apr/apr-util/trunk/include/private/apr_ssl_private.h Fri Jun 23 05:20:59 2006
@@ -46,6 +46,7 @@
     apr_pool_t        *pool;
     apr_socket_t      *plain;
     apr_ssl_factory_t *factory;
+    apr_pollset_t     *pollset;
     apr_pollfd_t      *poll;
     int                connected;
 

Modified: apr/apr-util/trunk/ssl/apr_ssl_socket.c
URL: http://svn.apache.org/viewvc/apr/apr-util/trunk/ssl/apr_ssl_socket.c?rev=416697&r1=416696&r2=416697&view=diff
==============================================================================
--- apr/apr-util/trunk/ssl/apr_ssl_socket.c (original)
+++ apr/apr-util/trunk/ssl/apr_ssl_socket.c Fri Jun 23 05:20:59 2006
@@ -167,34 +167,51 @@
                                                      apr_ssl_socket_t *sock)
 {
     apr_status_t rv;
-    if (sock->poll)
+    if (sock->pollset)
         /* socket is already in a pollset - return an error... */
         return EALREADY;
 
-    sock->poll = apr_pcalloc(sock->pool, sizeof(*sock->poll));
+    if (!sock->poll) {
+        sock->poll = apr_pcalloc(sock->pool, sizeof(*sock->poll));
 
-    sock->poll->desc_type = APR_POLL_SOCKET;
+        sock->poll->desc_type = APR_POLL_SOCKET;
+        sock->poll->desc.s = sock->plain;
+        sock->poll->client_data = sock;
+    }
     sock->poll->reqevents = APR_POLLIN | APR_POLLOUT;
-    sock->poll->desc.s = sock->plain;
-    sock->poll->client_data = sock->plain;
     rv = apr_pollset_add(pollset, sock->poll);
     if (rv != APR_SUCCESS)
         sock->poll = NULL;
+    sock->pollset = pollset;
     return rv;
 }
 
 
 
-APU_DECLARE(apr_status_t) apr_pollset_remove_ssl_socket(apr_pollset_t *pollset,
-                                                        apr_ssl_socket_t *sock)
+APU_DECLARE(apr_status_t) apr_pollset_remove_ssl_socket(apr_ssl_socket_t *sock)
+{
+    apr_status_t rv;
+    if (!sock->pollset)
+        return EINVAL;
+    rv = apr_pollset_remove(sock->pollset, sock->poll);
+    sock->pollset = NULL;
+    return rv;
+}
+
+APU_DECLARE(apr_status_t) apr_ssl_socket_set_poll_events(apr_ssl_socket_t *sock,
+                                                         apr_int16_t events)
 {
     apr_status_t rv;
     if (!sock->poll)
         return EINVAL;
-    rv = apr_pollset_remove(pollset, sock->poll);
-    sock->poll = NULL;
+    if ((rv = apr_pollset_remove(sock->pollset, sock->poll))
+         == APR_SUCCESS) {
+        sock->poll->reqevents = events;
+        rv = apr_pollset_add(sock->pollset, sock->poll);
+    }
     return rv;
 }
+
 
 #else /* ! APU_HAVE_SSL */
 

Modified: apr/apr-util/trunk/test/testssl.c
URL: http://svn.apache.org/viewvc/apr/apr-util/trunk/test/testssl.c?rev=416697&r1=416696&r2=416697&view=diff
==============================================================================
--- apr/apr-util/trunk/test/testssl.c (original)
+++ apr/apr-util/trunk/test/testssl.c Fri Jun 23 05:20:59 2006
@@ -46,13 +46,160 @@
 #include <stdlib.h>     /* for atexit(), malloc() */
 #include <string.h>
 
+struct sslTestCase {
+    char *host;
+    int port;
+    const char *request;
+    int result;
+} tests[] = {
+    { "svn.apache.org", 443, "GET / HTTP/1.0\n\n", 1 },
+    { NULL }
+};
+
+static apr_ssl_socket_t *createSocket(apr_ssl_factory_t *asf, 
+                                      apr_pollset_t *pollset,
+                                      apr_pool_t *pool, int blocking)
+{
+    apr_ssl_socket_t *sock;
+    apr_status_t rv;
+    printf("::Creating SSL socket\n");
+    rv = apr_ssl_socket_create(&sock, AF_INET, SOCK_STREAM, 0, asf, NULL);
+    if (rv != APR_SUCCESS) {
+        printf("\tFailed to create socket\n");
+        return NULL;
+    }
+    rv = apr_pollset_add_ssl_socket(pollset, sock);
+    if (rv != APR_SUCCESS) {
+        printf("\tFailed to add to pollset\n");
+        return NULL;
+    }
+    printf("\tOK\n");
+    return sock;
+}
+
+static apr_status_t connectSocket(apr_ssl_socket_t *sock,
+                                  const char *host, int port,
+                                  apr_pool_t *pool)
+{
+    apr_status_t rv;
+    apr_sockaddr_t *remoteSA;
+
+    printf("::Connecting socket\n");
+    rv = apr_sockaddr_info_get(&remoteSA, host, APR_UNSPEC, port, 0, pool);
+    if (rv != APR_SUCCESS) {
+        printf("\tFailed to get address for '%s', port %d\n", host, port);
+        return rv;
+    }
+    rv = apr_ssl_socket_connect(sock, remoteSA);
+    if (rv != APR_SUCCESS) {
+        printf("\tFailed to connect to '%s' port %d\n", host, port);
+        return rv;
+    }
+    printf("\tOK\n");
+    return rv;
+}
+
+static apr_status_t socketRead(apr_ssl_socket_t *sock,
+                               apr_pollset_t *pollset,
+                               char *buf, apr_size_t *len)
+{
+    int lrv;
+    const apr_pollfd_t *descs = NULL;
+    printf("::Reading from socket\n");
+    apr_status_t rv = apr_ssl_socket_set_poll_events(sock, APR_POLLIN);
+    if (rv != APR_SUCCESS) {
+        printf("\tUnable to change socket poll events!\n");
+        return rv;
+    }
+
+    rv = apr_pollset_poll(pollset, 30 * APR_USEC_PER_SEC, &lrv, &descs);
+    if (APR_STATUS_IS_TIMEUP(rv)) {
+        printf("\tTime up!\n");
+        return rv;
+    }
+
+    if (lrv != 1) {
+        printf("\tIncorrect return count, %d\n", lrv);
+        return rv;
+    }
+    if (descs[0].client_data != sock) {
+        printf("\tWrong socket returned?!\n");
+        return rv;
+    }
+    if ((descs[0].rtnevents & APR_POLLIN) == 0) {
+        printf("\tSocket wasn't ready? huh? req [%08x] vs rtn [%08x]\n",
+               descs[0].reqevents, descs[0].rtnevents);
+        return rv;
+    }
+    rv = apr_ssl_socket_recv(sock, buf, len);
+    if (rv == APR_SUCCESS)
+        printf("\tOK, read %d bytes\n", *len);
+    else
+        printf("\tFailed\n");
+    return rv;
+}
+
+static apr_status_t socketWrite(apr_ssl_socket_t *sock,
+                                apr_pollset_t *pollset,
+                                const char *buf, apr_size_t *len)
+{
+    int lrv;
+    const apr_pollfd_t *descs = NULL;
+    printf("::Writing to socket\n");
+    apr_status_t rv = apr_ssl_socket_set_poll_events(sock, APR_POLLOUT);
+    if (rv != APR_SUCCESS) {
+        printf("\tUnable to change socket poll events!\n");
+        return rv;
+    }
+
+    rv = apr_pollset_poll(pollset, 30 * APR_USEC_PER_SEC, &lrv, &descs);
+    if (APR_STATUS_IS_TIMEUP(rv)) {
+        printf("\tTime up!\n");
+        return rv;
+    }
+    if (lrv != 1) {
+        printf("\tIncorrect return count, %d\n", lrv);
+        return rv;
+    }
+    if (descs[0].client_data != sock) {
+        printf("\tWrong socket returned?!\n");
+        return rv;
+    }
+    if ((descs[0].rtnevents & APR_POLLOUT) == 0) {
+        printf("\tSocket wasn't ready? huh?\n");
+        return rv;
+    }
+    rv = apr_ssl_socket_send(sock, buf, len);
+    if (rv == APR_SUCCESS)
+        printf("\tOK, wrote %d bytes\n", *len);
+    else
+        printf("\tFailed\n");
+    return rv;
+}
+
+apr_status_t socketClose(apr_ssl_socket_t *sock, apr_pollset_t *pollset)
+{
+    apr_status_t rv;
+    printf("::Closing socket\n");
+    rv = apr_pollset_remove_ssl_socket(sock);
+    if (rv != APR_SUCCESS)
+        printf("\tUnable to remove socket from pollset?\n");
+    rv = apr_ssl_socket_close(sock);
+    if (rv != APR_SUCCESS)
+        printf("\tFailed to close SSL socket\n");
+    else
+        printf("\tOK\n");
+    return rv;
+}
+
+
 int main(int argc, const char * const * argv)
 {
     apr_pool_t *pool;
     apr_ssl_factory_t *asf = NULL;
-    apr_sockaddr_t *remoteSA;
     apr_status_t rv;
     apr_pollset_t *pollset;
+    struct sslTestCase *mytest;
 
 #ifdef APU_HAVE_SSL
 
@@ -71,51 +218,32 @@
         fprintf(stderr, "Unable to create client factory\n");
 
     } else {
-        apr_ssl_socket_t *sslSock;
-        fprintf(stdout, "Client factory created\n");
-        if (apr_ssl_socket_create(&sslSock, AF_INET, SOCK_STREAM, 0, asf, 
-                                  NULL) != APR_SUCCESS) {
-            printf("failed to create socket\n");
-        } else {
-            printf("created ssl socket\n");
+        int i;
+        for(i = 0; tests[i].host; i++) {
+            apr_ssl_socket_t *sslSock = createSocket(asf, pollset, pool, 0);
+            if (!sslSock)
+                continue;
 
-            rv = apr_sockaddr_info_get(&remoteSA, "svn.apache.org", 
-                                       APR_UNSPEC, 443, 0, pool);
+            rv = connectSocket(sslSock, tests[i].host, tests[i].port, pool);
             if (rv == APR_SUCCESS) {
-                apr_size_t len = 16;
-                char buffer[4096];
-
-                rv = apr_ssl_socket_connect(sslSock, remoteSA);
-                printf("Connect = %s\n", (rv == APR_SUCCESS ? "OK" : "Failed"));
-
-                rv = apr_pollset_add_ssl_socket(pollset, sslSock);
-                printf("Pollset add = %s\n", (rv == APR_SUCCESS ? "OK" : "Failed"));
-
-                printf("send: %s\n",
-                       (apr_ssl_socket_send(sslSock, "GET / HTTP/1.0\n\n", 
-                                            &len) == APR_SUCCESS ?
-                        "OK" : "Failed"));
-
-                len = 4096;
-                printf("recv: %s\n%s\n",
-                       (apr_ssl_socket_recv(sslSock, buffer, &len) == 
-                          APR_SUCCESS ? "OK" : "Failed"),
-                       buffer);
-                rv = apr_pollset_remove_ssl_socket(pollset, sslSock);
-                printf("Pollset remove = %s\n", (rv == APR_SUCCESS ? "OK" : "Failed"));
-
+                apr_size_t len = strlen(tests[i].request);
+                rv = socketWrite(sslSock, pollset, tests[i].request, &len);
+                if (rv == APR_SUCCESS) {
+                    char buffer[4096];
+                    len = 4096;
+                    rv = socketRead(sslSock, pollset, buffer, &len);
+                }
             }
-
-            printf("close = %s\n",
-                   (apr_ssl_socket_close(sslSock) == APR_SUCCESS ? 
-                    "OK" : "Failed"));
-
+            socketClose(sslSock, pollset);
         }
     }
 
+    apr_pollset_destroy(pollset);
     apr_pool_destroy(pool);
 
 #endif /* APU_HAVE_SSL */
 
     return 0;
 }
+
+