You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by jo...@apache.org on 2005/09/09 10:21:22 UTC

svn commit: r279729 - in /apr/apr/branches/1.2.x: CHANGES network_io/unix/sockets.c test/testsock.c

Author: jorton
Date: Fri Sep  9 01:21:17 2005
New Revision: 279729

URL: http://svn.apache.org/viewcvs?rev=279729&view=rev
Log:
Merge r279727 from trunk:

Fix apr_socket_addr_get(APR_REMOTE) after a non-blocking connect():

* network_io/unix/sockets.c (alloc_socket): Set remote_addr_unknown.
(apr_socket_accept): Clear remote_addr_unknown.  
(apr_socket_connect): Clear remote_addr_unknown and set remote_addr
iff the passed-in address was not the inaddr_any address.

* test/testsock.c (test_get_addr): New test.

PR: 32737

Modified:
    apr/apr/branches/1.2.x/CHANGES
    apr/apr/branches/1.2.x/network_io/unix/sockets.c
    apr/apr/branches/1.2.x/test/testsock.c

Modified: apr/apr/branches/1.2.x/CHANGES
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/CHANGES?rev=279729&r1=279728&r2=279729&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/CHANGES (original)
+++ apr/apr/branches/1.2.x/CHANGES Fri Sep  9 01:21:17 2005
@@ -1,5 +1,8 @@
 Changes for APR 1.2.2
 
+  *) Fix apr_socket_addr_get(,APR_REMOTE,) after a non-blocking
+     connection is completed.  PR 32737.  [Joe Orton]
+
   *) Fix apr_file_gets() and apr_file_read() to catch write failures
      when flushing pending writes for a buffered file.  [Joe Orton]
 

Modified: apr/apr/branches/1.2.x/network_io/unix/sockets.c
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/network_io/unix/sockets.c?rev=279729&r1=279728&r2=279729&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/network_io/unix/sockets.c (original)
+++ apr/apr/branches/1.2.x/network_io/unix/sockets.c Fri Sep  9 01:21:17 2005
@@ -66,6 +66,7 @@
     (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->pool,
                                                         sizeof(apr_sockaddr_t));
     (*new)->remote_addr->pool = p;
+    (*new)->remote_addr_unknown = 1;
 #ifndef WAITIO_USES_POLL
     /* Create a pollset with room for one descriptor. */
     /* ### check return codes */
@@ -197,6 +198,8 @@
     }
 #endif
 
+    (*new)->remote_addr_unknown = 0;
+
     *(*new)->local_addr = *sock->local_addr;
 
     /* The above assignment just overwrote the pool entry. Setting the local_addr 
@@ -289,7 +292,16 @@
         return errno;
     }
 
-    sock->remote_addr = sa;
+    if (memcmp(sa->ipaddr_ptr, generic_inaddr_any, sa->ipaddr_len)) {
+        /* A real remote address was passed in.  If the unspecified
+         * address was used, the actual remote addr will have to be
+         * determined using getpeername() if required. */
+        /* ### this should probably be a structure copy + fixup as per
+         * _accept()'s handling of local_addr */
+        sock->remote_addr = sa;
+        sock->remote_addr_unknown = 0;
+    }
+
     if (sock->local_addr->port == 0) {
         /* connect() got us an ephemeral port */
         sock->local_port_unknown = 1;

Modified: apr/apr/branches/1.2.x/test/testsock.c
URL: http://svn.apache.org/viewcvs/apr/apr/branches/1.2.x/test/testsock.c?rev=279729&r1=279728&r2=279729&view=diff
==============================================================================
--- apr/apr/branches/1.2.x/test/testsock.c (original)
+++ apr/apr/branches/1.2.x/test/testsock.c Fri Sep  9 01:21:17 2005
@@ -22,6 +22,7 @@
 #include "apr_general.h"
 #include "apr_lib.h"
 #include "apr_strings.h"
+#include "apr_poll.h"
 
 static void launch_child(abts_case *tc, apr_proc_t *proc, const char *arg1, apr_pool_t *p)
 {
@@ -203,6 +204,64 @@
     APR_ASSERT_SUCCESS(tc, "Problem closing socket", rv);
 }
 
+static void test_get_addr(abts_case *tc, void *data)
+{
+    apr_status_t rv;
+    apr_socket_t *ld, *sd, *cd;
+    apr_sockaddr_t *sa, *ca;
+    char a[128], b[128];
+
+    ld = setup_socket(tc);
+
+    APR_ASSERT_SUCCESS(tc,
+                       "get local address of bound socket",
+                       apr_socket_addr_get(&sa, APR_LOCAL, ld));
+
+    rv = apr_socket_create(&cd, sa->family, SOCK_STREAM,
+                           APR_PROTO_TCP, p);
+    APR_ASSERT_SUCCESS(tc, "create client socket", rv);
+
+    APR_ASSERT_SUCCESS(tc, "enable non-block mode",
+                       apr_socket_opt_set(cd, APR_SO_NONBLOCK, 1));
+    
+    /* initiate connection */
+    apr_socket_connect(cd, sa);
+
+    APR_ASSERT_SUCCESS(tc, "accept connection",
+                       apr_socket_accept(&sd, ld, p));
+    
+    {
+        /* wait for writability */
+        apr_pollfd_t pfd;
+        int n;
+
+        pfd.p = p;
+        pfd.desc_type = APR_POLL_SOCKET;
+        pfd.reqevents = APR_POLLOUT|APR_POLLHUP;
+        pfd.desc.s = cd;
+        pfd.client_data = NULL;
+
+        APR_ASSERT_SUCCESS(tc, "poll for connect completion",
+                           apr_poll(&pfd, 1, &n, 5 * APR_USEC_PER_SEC));
+
+    }
+
+    APR_ASSERT_SUCCESS(tc, "get local address of server socket",
+                       apr_socket_addr_get(&sa, APR_LOCAL, sd));
+
+    APR_ASSERT_SUCCESS(tc, "get remote address of client socket",
+                       apr_socket_addr_get(&ca, APR_REMOTE, cd));
+    
+    apr_snprintf(a, sizeof a, "%pI", sa);
+    apr_snprintf(b, sizeof b, "%pI", ca);
+
+    ABTS_STR_EQUAL(tc, a, b);
+                       
+    apr_socket_close(cd);
+    apr_socket_close(sd);
+    apr_socket_close(ld);
+}
+
 abts_suite *testsock(abts_suite *suite)
 {
     suite = ADD_SUITE(suite)
@@ -212,6 +271,7 @@
     abts_run_test(suite, test_send, NULL);
     abts_run_test(suite, test_recv, NULL);
     abts_run_test(suite, test_timeout, NULL);
+    abts_run_test(suite, test_get_addr, NULL);
 
     return suite;
 }