I know as fact that sprintf() is pure performance evil.  We need to eliminate
it everywhere possible in the server. This patch remove two calls to sprintf
for each connection.

This patch needs to be reworked to fit into inet_ntop.c.  Possibly  Resubmit
and I will review and commit it (unless someone else calls out a severe
problem that I don;t see).

Bill


diff -Naur apache_2.0a6/10xpatchlevel-4 apache_2.0a6/10xpatchlevel
--- apache_2.0a6/10xpatchlevel-4 Wed Sep 20 15:41:29 2000
+++ apache_2.0a6/10xpatchlevel Wed Sep 20 22:43:05 2000
@@ -2,4 +2,4 @@
 available from
  http://oss.sgi.com/projects/apache/

-10xpatchlevel=2.0a6-4
+10xpatchlevel=2.0a6-5
diff -Naur apache_2.0a6/src/include/httpd.h-4 apache_2.0a6/src/include/httpd.h
--- apache_2.0a6/src/include/httpd.h-4 Wed Sep 20 16:34:27 2000
+++ apache_2.0a6/src/include/httpd.h Wed Sep 20 22:43:21 2000
@@ -831,7 +831,9 @@
     /** remote address */
     struct sockaddr_in remote_addr;
     /** Client's IP address */
-    char *remote_ip;
+    char remote_ip[APR_INET_NTOA_LEN];
+    /** strlen(remote_ip) */
+    apr_size_t remote_ip_len;
     /** Client's DNS name, if known.  NULL if DNS hasn't been checked,
      *  "" if it has and no address was found.  N.B. Only access this though
      * get_remote_host() */
@@ -853,7 +855,9 @@
     /** How many times have we used it? */
     int keepalives;
     /** server IP address */
-    char *local_ip;
+    char local_ip[APR_INET_NTOA_LEN];
+    /** strlen(local_ip) */
+    apr_size_t local_ip_len;
     /** used for ap_get_server_name when UseCanonicalName is set to DNS
      *  (ignores setting of HostnameLookups) */
     char *local_host;
diff -Naur apache_2.0a6/src/lib/apr/include/apr_network_io.h-4
apache_2.0a6/src/lib/apr/include/apr_network_io.h
--- apache_2.0a6/src/lib/apr/include/apr_network_io.h-4 Sat Aug  5 23:07:09
2000
+++ apache_2.0a6/src/lib/apr/include/apr_network_io.h Wed Sep 20 22:43:38 2000
@@ -568,6 +568,19 @@
  */
 apr_status_t apr_socket_from_file(apr_socket_t **newsock, apr_file_t *file);

+#define APR_INET_NTOA_LEN 16
+/**
+ * Fast implementation of inet_ntoa().
+ * @param in Internet address to convert, in network order.
+ * @param buf Buffer of exactly APR_INET_NTOA_LEN bytes into which to
+ * format the address in dot notation.
+ * @param rlen If rlen is non-NULL, *rlen is set to the length of the
+ * formatted address.
+ * @return buf
+ * @deffunc char *apr_inet_ntoa(apr_in_addr in, char *buf, apr_size_t *rlen);
+ */
+APR_EXPORT(char *) apr_inet_ntoa(apr_in_addr in, char *buf, apr_size_t
*rlen);
+
 #ifdef __cplusplus
 }
 #endif
diff -Naur apache_2.0a6/src/lib/apr/network_io/beos/sockaddr.c-4
apache_2.0a6/src/lib/apr/network_io/beos/sockaddr.c
--- apache_2.0a6/src/lib/apr/network_io/beos/sockaddr.c-4 Tue Aug  1 22:26:26
2000
+++ apache_2.0a6/src/lib/apr/network_io/beos/sockaddr.c Wed Sep 20 22:43:52
2000
@@ -146,7 +146,8 @@
         return APR_EBADF;
     }

-    *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->local_addr->sin_addr));
+    *addr = apr_palloc(sock->cntxt, APR_INET_NTOA_LEN);
+    apr_inet_ntoa(sock->local_addr->sin_addr, *addr, NULL);
     return APR_SUCCESS;
 }

@@ -156,7 +157,8 @@
         return APR_EBADF;
     }

-    *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->remote_addr->sin_addr));
+    *addr = apr_palloc(sock->cntxt, APR_INET_NTOA_LEN);
+    apr_inet_ntoa(sock->remote_addr->sin_addr, *addr, NULL);
     return APR_SUCCESS;
 }

@@ -179,5 +181,55 @@

     *name = sock->remote_addr;
     return APR_SUCCESS;
+}
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * Mike Abbott - [EMAIL PROTECTED]
+ * Accelerating Apache Project - http://oss.sgi.com/projects/apache/
+ *
+ * Fast implementation of inet_ntoa().  buf must be APR_INET_NTOA_LEN
+ * bytes.  Returns buf and, if rlen is non-null, sets *rlen to
+ * strlen(buf).
+ */
+APR_EXPORT(char *)
+apr_inet_ntoa(apr_in_addr in, char *buf, apr_size_t *rlen)
+{
+    int i;
+    char *bp;
+
+    /*
+     * This implementation is fast because it avoids sprintf(),
+     * division/modulo, and global static array lookups.
+     */
+
+    bp = buf;
+    for (i = 0; i < 4; i++) {
+        unsigned int o, n;
+
+ o = ((unsigned char *) &in)[i];
+ n = o;
+        if (n >= 200) {
+            *bp++ = '2';
+            n -= 200;
+ } else if (n >= 100) {
+            *bp++ = '1';
+            n -= 100;
+ }
+        if (o >= 10) {
+            int i;
+            for (i = 0; n >= 10; i++)
+                n -= 10;
+            *bp++ = i + '0';
+ }
+        *bp++ = n + '0';
+        *bp++ = '.';
+    }
+    *--bp = 0;
+    if (rlen)
+ *rlen = bp - buf;
+
+    return buf;
 }
 #endif
diff -Naur apache_2.0a6/src/lib/apr/network_io/unix/sockaddr.c-4
apache_2.0a6/src/lib/apr/network_io/unix/sockaddr.c
--- apache_2.0a6/src/lib/apr/network_io/unix/sockaddr.c-4 Tue Aug  1 22:26:29
2000
+++ apache_2.0a6/src/lib/apr/network_io/unix/sockaddr.c Wed Sep 20 22:44:15
2000
@@ -163,7 +163,8 @@
         }
     }

-    *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->local_addr->sin_addr));
+    *addr = apr_palloc(sock->cntxt, APR_INET_NTOA_LEN);
+    apr_inet_ntoa(sock->local_addr->sin_addr, *addr, NULL);
     return APR_SUCCESS;
 }

@@ -171,7 +172,8 @@

 apr_status_t apr_get_remote_ipaddr(char **addr, apr_socket_t *sock)
 {
-    *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->remote_addr->sin_addr));
+    *addr = apr_palloc(sock->cntxt, APR_INET_NTOA_LEN);
+    apr_inet_ntoa(sock->remote_addr->sin_addr, *addr, NULL);
     return APR_SUCCESS;
 }

@@ -200,3 +202,53 @@
     return APR_SUCCESS;
 }
 #endif
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * Mike Abbott - [EMAIL PROTECTED]
+ * Accelerating Apache Project - http://oss.sgi.com/projects/apache/
+ *
+ * Fast implementation of inet_ntoa().  buf must be APR_INET_NTOA_LEN
+ * bytes.  Returns buf and, if rlen is non-null, sets *rlen to
+ * strlen(buf).
+ */
+APR_EXPORT(char *)
+apr_inet_ntoa(apr_in_addr in, char *buf, apr_size_t *rlen)
+{
+    int i;
+    char *bp;
+
+    /*
+     * This implementation is fast because it avoids sprintf(),
+     * division/modulo, and global static array lookups.
+     */
+
+    bp = buf;
+    for (i = 0; i < 4; i++) {
+        unsigned int o, n;
+
+ o = ((unsigned char *) &in)[i];
+ n = o;
+        if (n >= 200) {
+            *bp++ = '2';
+            n -= 200;
+ } else if (n >= 100) {
+            *bp++ = '1';
+            n -= 100;
+ }
+        if (o >= 10) {
+            int i;
+            for (i = 0; n >= 10; i++)
+                n -= 10;
+            *bp++ = i + '0';
+ }
+        *bp++ = n + '0';
+        *bp++ = '.';
+    }
+    *--bp = 0;
+    if (rlen)
+ *rlen = bp - buf;
+
+    return buf;
+}
diff -Naur apache_2.0a6/src/lib/apr/network_io/win32/sockaddr.c-4
apache_2.0a6/src/lib/apr/network_io/win32/sockaddr.c
--- apache_2.0a6/src/lib/apr/network_io/win32/sockaddr.c-4 Tue Aug  1 22:26:31
2000
+++ apache_2.0a6/src/lib/apr/network_io/win32/sockaddr.c Wed Sep 20 22:44:28
2000
@@ -162,7 +162,8 @@
         }
     }

-    *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->local_addr->sin_addr));
+    *addr = apr_palloc(sock->cntxt, APR_INET_NTOA_LEN);
+    apr_inet_ntoa(sock->local_addr->sin_addr, *addr, NULL);
     return APR_SUCCESS;
 }

@@ -170,7 +171,8 @@

 apr_status_t apr_get_remote_ipaddr(char **addr, apr_socket_t *sock)
 {
-    *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->remote_addr->sin_addr));
+    *addr = apr_palloc(sock->cntxt, APR_INET_NTOA_LEN);
+    apr_inet_ntoa(sock->remote_addr->sin_addr, *addr, NULL);
     return APR_SUCCESS;
 }

@@ -195,4 +197,54 @@
 {
     *name = sock->remote_addr;
     return APR_SUCCESS;
+}
+
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All rights reserved.
+ *
+ * Mike Abbott - [EMAIL PROTECTED]
+ * Accelerating Apache Project - http://oss.sgi.com/projects/apache/
+ *
+ * Fast implementation of inet_ntoa().  buf must be APR_INET_NTOA_LEN
+ * bytes.  Returns buf and, if rlen is non-null, sets *rlen to
+ * strlen(buf).
+ */
+APR_EXPORT(char *)
+apr_inet_ntoa(apr_in_addr in, char *buf, apr_size_t *rlen)
+{
+    int i;
+    char *bp;
+
+    /*
+     * This implementation is fast because it avoids sprintf(),
+     * division/modulo, and global static array lookups.
+     */
+
+    bp = buf;
+    for (i = 0; i < 4; i++) {
+        unsigned int o, n;
+
+ o = ((unsigned char *) &in)[i];
+ n = o;
+        if (n >= 200) {
+            *bp++ = '2';
+            n -= 200;
+ } else if (n >= 100) {
+            *bp++ = '1';
+            n -= 100;
+ }
+        if (o >= 10) {
+            int i;
+            for (i = 0; n >= 10; i++)
+                n -= 10;
+            *bp++ = i + '0';
+ }
+        *bp++ = n + '0';
+        *bp++ = '.';
+    }
+    *--bp = 0;
+    if (rlen)
+ *rlen = bp - buf;
+
+    return buf;
 }
diff -Naur apache_2.0a6/src/main/http_connection.c-4
apache_2.0a6/src/main/http_connection.c
--- apache_2.0a6/src/main/http_connection.c-4 Sat Aug  5 23:07:34 2000
+++ apache_2.0a6/src/main/http_connection.c Wed Sep 20 22:44:41 2000
@@ -264,14 +264,14 @@

     conn->pool = p;
     conn->local_addr = *saddr;
-    conn->local_ip = apr_pstrdup(conn->pool,
-    inet_ntoa(conn->local_addr.sin_addr));
+    apr_inet_ntoa(conn->local_addr.sin_addr, conn->local_ip,
+      &conn->local_ip_len);
     conn->base_server = server;
     conn->client = inout;

     conn->remote_addr = *remaddr;
-    conn->remote_ip = apr_pstrdup(conn->pool,
-         inet_ntoa(conn->remote_addr.sin_addr));
+    apr_inet_ntoa(conn->remote_addr.sin_addr, conn->remote_ip,
+      &conn->remote_ip_len);

     conn->id = id;

diff -Naur apache_2.0a6/src/main/http_vhost.c-4
apache_2.0a6/src/main/http_vhost.c
--- apache_2.0a6/src/main/http_vhost.c-4 Sat Aug  5 23:07:35 2000
+++ apache_2.0a6/src/main/http_vhost.c Wed Sep 20 22:44:55 2000
@@ -618,6 +618,8 @@
       s->server_hostname = apr_pstrdup(p, (char *) h->h_name);
   }
   else {
+      char nbuf[APR_INET_NTOA_LEN];
+
       /* again, what can we do?  They didn't specify a
          ServerName, and their DNS isn't working. -djg */
       ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
@@ -624,7 +626,7 @@
        "Failed to resolve server name "
        "for %s (check DNS) -- or specify an explicit "
        "ServerName",
-       inet_ntoa(s->addrs->host_addr));
+       apr_inet_ntoa(s->addrs->host_addr, nbuf, NULL));
       s->server_hostname =
    apr_pstrdup(p, "bogus_host_without_reverse_dns");
   }
diff -Naur apache_2.0a6/src/modules/standard/mod_log_config.c-4
apache_2.0a6/src/modules/standard/mod_log_config.c
--- apache_2.0a6/src/modules/standard/mod_log_config.c-4 Wed Sep 20 16:35:00
2000
+++ apache_2.0a6/src/modules/standard/mod_log_config.c Wed Sep 20 22:45:08
2000
@@ -296,11 +296,13 @@

 static const char *log_remote_address(request_rec *r, char *a, apr_size_t
*rlen)
 {
+    *rlen = r->connection->remote_ip_len;
     return r->connection->remote_ip;
 }

 static const char *log_local_address(request_rec *r, char *a, apr_size_t
*rlen)
 {
+    *rlen = r->connection->local_ip_len;
     return r->connection->local_ip;
 }




Reply via email to