apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeff Trawick <trawi...@bellsouth.net>
Subject Re: OK...
Date Thu, 16 Nov 2000 15:47:50 GMT
"David Reid" <dreid@jetnet.co.uk> writes:

> OK, I've done some work on this but am getting an error now
> Could not connect: Can't assign requested address (49)

I have it working on Linux now...

Changes to your patch or to other code to get it to work:

  1) The existing apr_set_port() doesn't get along with the new 
     apr_connect().  When apr_connect() replaces the remote sockaddr,
     we lose the port set previously.

     For now, I added apr_set_sockaddr_port(), but I think we just
     need to change apr_set_port() to take a sockaddr instead of a
     socket and a local/remote flag.

  2) socket address-related vars weren't set up in apr_gethostbyname()
     when we created the sockaddr; I hit a segfault due to this

  3) I made a fix/tweak to get_local_addr() (not shown below; will be
     committed shortly); I don't *think* it was required but I may be
     confused 

New patch:

  (Setting the port in client.c is in a different order than in your
  patch due to my initial confusion about why the remote port was
  getting lost.)

Index: include/apr_network_io.h
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/include/apr_network_io.h,v
retrieving revision 1.71
diff -u -r1.71 apr_network_io.h
--- include/apr_network_io.h	2000/11/16 14:48:50	1.71
+++ include/apr_network_io.h	2000/11/16 15:42:14
@@ -265,7 +265,7 @@
  *                 APR assumes that the sockaddr_in in the apr_socket is 
  *                 completely filled out.
  */
-apr_status_t apr_connect(apr_socket_t *sock, const char *hostname);
+apr_status_t apr_connect(apr_socket_t *sock, apr_sockaddr_t *sa);
 
 /**
  * Get name of a machine we are currently connected to.
@@ -275,6 +275,9 @@
  */
 apr_status_t apr_get_hostname(char **name, apr_interface_e which, apr_socket_t *sock);
 
+apr_status_t apr_gethostbyname(apr_sockaddr_t **sa, const char *hostname,
+                               apr_pool_t *p);
+
 /**
  * Get name of the current machine
  * @param buf A buffer to store the hostname in.
@@ -434,6 +437,8 @@
  *      the port is already used, we won't find out about it here.
  */
 apr_status_t apr_set_port(apr_socket_t *sock, apr_interface_e which, apr_port_t port);
+
+apr_status_t apr_set_sockaddr_port(apr_sockaddr_t *sa, apr_port_t port);
 
 /**
  * Return the port associated with a socket.
Index: network_io/unix/sa_common.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sa_common.c,v
retrieving revision 1.6
diff -u -r1.6 sa_common.c
--- network_io/unix/sa_common.c	2000/11/16 14:48:49	1.6
+++ network_io/unix/sa_common.c	2000/11/16 15:42:15
@@ -78,6 +78,13 @@
     return APR_SUCCESS;
 }
 
+apr_status_t apr_set_sockaddr_port(apr_sockaddr_t *sa, apr_port_t port)
+{
+    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
+    sa->sa.sin.sin_port = htons(port);
+    return APR_SUCCESS;
+}
+
 apr_status_t apr_get_port(apr_port_t *port, apr_interface_e which, apr_socket_t *sock)
 {
     /* XXX IPv6: assumes sin_port and sin6_port at same offset */
@@ -171,3 +178,62 @@
     return APR_SUCCESS;
 }
 
+static void set_sockaddr_vars(apr_sockaddr_t *addr, int family)
+{
+    addr->sa.sin.sin_family = family;
+    addr->sa.sin.sin_family = family;
+
+    if (family == AF_INET) {
+        addr->sa_len = sizeof(struct sockaddr_in);
+        addr->addr_str_len = 16;
+        addr->ipaddr_ptr = &(addr->sa.sin.sin_addr);
+        addr->ipaddr_len = sizeof(struct in_addr);
+    }
+#if APR_HAVE_IPV6
+    else if (family == AF_INET6) {
+        addr->sa_len = sizeof(struct sockaddr_in6);
+        addr->addr_str_len = 46;
+        addr->ipaddr_ptr = &(addr->sa.sin6.sin6_addr);
+        addr->ipaddr_len = sizeof(struct in6_addr);
+    }
+#endif
+}
+
+apr_status_t apr_gethostbyname(apr_sockaddr_t **sa, const char *hostname, apr_pool_t *p)
+{
+    struct hostent *hp;
+
+    (*sa) = (apr_sockaddr_t *)apr_pcalloc(p, sizeof(apr_sockaddr_t));
+    if ((*sa) == NULL)
+        return APR_ENOMEM;
+    (*sa)->pool = p;
+    (*sa)->sa.sin.sin_family = AF_INET; /* we don't yet support IPv6 */
+    set_sockaddr_vars(*sa, (*sa)->sa.sin.sin_family);
+
+    if (hostname != NULL) {
+#ifndef GETHOSTBYNAME_HANDLES_NAS
+        if (*hostname >= '0' && *hostname <= '9' &&
+            strspn(hostname, "0123456789.") == strlen(hostname)) {
+            (*sa)->sa.sin.sin_addr.s_addr = inet_addr(hostname);
+            (*sa)->sa_len = sizeof(struct sockaddr_in);
+        }
+        else {
+#endif
+        hp = gethostbyname(hostname);
+
+        if (!hp)  {
+            return (h_errno + APR_OS_START_SYSERR);
+        }
+
+        memcpy((char *)&(*sa)->sa.sin.sin_addr, hp->h_addr_list[0],
+               hp->h_length);
+        (*sa)->sa_len = sizeof(struct sockaddr_in);
+        (*sa)->ipaddr_len = hp->h_length;
+
+#ifndef GETHOSTBYNAME_HANDLES_NAS
+        }
+#endif
+    }
+   (*sa)->hostname = apr_pstrdup(p, hostname);
+    return APR_SUCCESS;
+}
Index: network_io/unix/sockets.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
retrieving revision 1.56
diff -u -r1.56 sockets.c
--- network_io/unix/sockets.c	2000/11/16 14:48:49	1.56
+++ network_io/unix/sockets.c	2000/11/16 15:42:16
@@ -226,57 +226,35 @@
     return APR_SUCCESS;
 }
 
-apr_status_t apr_connect(apr_socket_t *sock, const char *hostname)
+apr_status_t apr_connect(apr_socket_t *sock, apr_sockaddr_t *sa)
 {
-    struct hostent *hp;
-
     if ((sock->socketdes < 0) || (!sock->remote_addr)) {
         return APR_ENOTSOCK;
     }
-    if (hostname != NULL) {
-#ifndef GETHOSTBYNAME_HANDLES_NAS
-        if (*hostname >= '0' && *hostname <= '9' &&
-            strspn(hostname, "0123456789.") == strlen(hostname)) {
-            sock->remote_addr->sa.sin.sin_addr.s_addr = inet_addr(hostname);
-        }
-        else {
-#endif
-        hp = gethostbyname(hostname);
-
-        if (!hp)  {
-            return (h_errno + APR_OS_START_SYSERR);
-        }
-
-        /* XXX IPv6: move name resolution out of this function */
-        memcpy((char *)&sock->remote_addr->sa.sin.sin_addr, hp->h_addr_list[0],

-               hp->h_length);
-
-#ifndef GETHOSTBYNAME_HANDLES_NAS
-        }
-#endif
-    }
 
-    if ((connect(sock->socketdes, 
-                 (const struct sockaddr *)&sock->remote_addr->sa.sin,
-                 sock->remote_addr->sa_len) < 0) &&
+    if ((connect(sock->socketdes,
+                 (const struct sockaddr *)&sa->sa.sin,
+                 sa->sa_len) < 0) &&
         (errno != EINPROGRESS)) {
         return errno;
     }
     else {
-        /* XXX IPv6 */
+        sock->remote_addr = sa;
+        /* XXX IPv6 assumes sin_port and sin6_port at same offset */
         if (sock->local_addr->sa.sin.sin_port == 0) {
             /* connect() got us an ephemeral port */
             sock->local_port_unknown = 1;
         }
-        /* XXX IPv6 */
-        if (sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
+        /* XXX IPv6 to be handled better later... */
+        if (sock->local_addr->sa.sin.sin_family == AF_INET6 ||
+            sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
             /* not bound to specific local interface; connect() had to assign
              * one for the socket
              */
             sock->local_interface_unknown = 1;
         }
 #ifndef HAVE_POLL
-	sock->connected=1;
+        sock->connected=1;
 #endif
         return APR_SUCCESS;
     }
Index: test/client.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/test/client.c,v
retrieving revision 1.17
diff -u -r1.17 client.c
--- test/client.c	2000/11/09 15:01:35	1.17
+++ test/client.c	2000/11/16 15:42:16
@@ -73,6 +73,7 @@
     char *dest = "127.0.0.1";
     apr_port_t local_port, remote_port;
     apr_interval_time_t read_timeout = -1;
+    apr_sockaddr_t *destsa;
 
     setbuf(stdout, NULL);
     if (argc > 1) {
@@ -115,8 +116,17 @@
         fprintf(stdout, "OK\n");
     }
 
+    fprintf(stdout,"\tClient:  Making socket address...............");
+    if (apr_gethostbyname(&destsa, dest, context) != APR_SUCCESS){
+        apr_close_socket(sock);
+        fprintf(stdout, "Failed!\n");
+        fprintf(stdout, "Couldn't create a socket address structure for %s\n", dest);
+        exit(-1);
+    }
+    fprintf(stdout,"OK\n");
+
     fprintf(stdout, "\tClient:  Setting port for socket.......");
-    if (apr_set_port(sock, APR_REMOTE, 8021) != APR_SUCCESS) {
+    if (apr_set_sockaddr_port(destsa, 8021) != APR_SUCCESS) {
         apr_close_socket(sock);
         fprintf(stderr, "Couldn't set the port correctly\n");
         exit(-1);
@@ -125,7 +135,7 @@
 
     fprintf(stdout, "\tClient:  Connecting to socket.......");
 
-    stat = apr_connect(sock, dest);
+    stat = apr_connect(sock, destsa);
 
     if (stat != APR_SUCCESS) {
         apr_close_socket(sock);

-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Mime
View raw message