You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Marc Slemko <ma...@worldgate.com> on 1998/02/14 08:11:04 UTC

IPv6 support for Apache

ftp://ftp.inria.fr/network/ipv6/freebsd/New.tar.gz includes a modified
Apache 1.2.1.

under a licence of:

  This software is available with usual "research" terms
  with the aim of retain credits of the software.
  Permission to use, copy, modify and distribute this software for any
  purpose and without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies,
  and the name of INRIA, IMAG, or any contributor not be used in advertising
  or publicity pertaining to this material without the prior explicit
  permission. The software is provided "as is" without any
  warranties, support or liabilities of any kind.
  This software is derived from source code from
  "University of California at Berkeley" and
  "Digital Equipment Corporation" protected by copyrights.

(I think)

The changes included are below.  Don't seem backwards compatible, but
that isn't a big deal.  Not sure if the APIs are standardized enough
to make it worth considering for 1.3 (erm... or if anyone has 6bone 
connectivity anyway), but for 2.0.  Not overly complex, although
I would bet things are missing in a few places.

--- conf.h-orig	Mon Jun 30 19:38:13 1997
+++ conf.h-new	Sun Aug 17 09:48:45 1997
@@ -576,6 +577,9 @@
 #include <sys/ioctl.h>
 #ifndef MPE
 #include <arpa/inet.h>  /* for inet_ntoa */
+#define _ARPA_NAMESER_H_
+#define MAXDNAME	1025
+#include <resolv.h>  /* for RES_USE_INET6 */
 #endif
 #include <time.h>  /* for ctime */
 #include <signal.h>
--- http_conf_globals.h-orig	Sun Jun 29 12:08:35 1997
+++ http_conf_globals.h-new	Sun Aug 17 08:12:35 1997
@@ -62,7 +62,7 @@
 extern gid_t group_id_list[NGROUPS_MAX];
 #endif
 extern int max_requests_per_child;
-extern struct in_addr bind_address;
+extern struct in6_addr bind_address;
 extern listen_rec *listeners;
 extern int daemons_to_start;
 extern int daemons_min_free;
--- http_config.c-orig	Sun Jun 29 12:08:36 1997
+++ http_config.c-new	Sun Aug 17 08:29:53 1997
@@ -852,7 +852,7 @@
 static void get_addresses (pool *p, char *w, server_addr_rec ***paddr, unsigned port)
 {
     struct hostent *hep;
-    unsigned long my_addr;
+    struct in6_addr my_addr;
     server_addr_rec *sar;
     char *t;
     int i, is_an_ip_addr;
@@ -873,26 +873,20 @@
 
     is_an_ip_addr = 0;
     if (strcmp(w, "*") == 0) {
-	my_addr = htonl(INADDR_ANY);
+	my_addr = in6addr_any;
 	is_an_ip_addr = 1;
     } else if( strcmp(w, "_default_") == 0
-	    || strcmp(w, "255.255.255.255") == 0 ) {
-	my_addr = DEFAULT_VHOST_ADDR;
+	    || strcmp(w, "::") == 0 ) {
+	my_addr = in6addr_loopback;
 	is_an_ip_addr = 1;
-    } else if(
-#ifdef DGUX
-	    ( my_addr = inet_network(w) )
-#else
-	    ( my_addr = inet_addr(w) )
-#endif
-	    != INADDR_NONE ) {
+    } else if( inet_pton(AF_INET6, w, &my_addr) > 0 ) {
 	is_an_ip_addr = 1;
     }
     if( is_an_ip_addr ) {
 	sar = pcalloc( p, sizeof( server_addr_rec ) );
 	**paddr = sar;
 	*paddr = &sar->next;
-	sar->host_addr.s_addr = my_addr;
+	sar->host_addr = my_addr;
 	sar->host_port = port;
 	sar->virthost = pstrdup(p, w);
 	if (t != NULL) *t = ':';
@@ -901,7 +895,7 @@
 
     hep = gethostbyname(w);
 
-    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
+    if ((!hep) || (hep->h_addrtype != AF_INET6 || !hep->h_addr_list[0])) {
 	fprintf (stderr, "Cannot resolve host name %s --- ignoring!\n", w);
 	if (t != NULL) *t = ':';
 	return;
@@ -911,7 +905,7 @@
 	sar = pcalloc( p, sizeof( server_addr_rec ) );
 	**paddr = sar;
 	*paddr = &sar->next;
-	sar->host_addr = *(struct in_addr *)hep->h_addr_list[i];
+	sar->host_addr = *(struct in6_addr *)hep->h_addr_list[i];
 	sar->host_port = port;
 	sar->virthost = pstrdup(p, w);
     }
@@ -1042,7 +1036,7 @@
     scoreboard_fname = DEFAULT_SCOREBOARD;
     lock_fname = DEFAULT_LOCKFILE;
     max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
-    bind_address.s_addr = htonl(INADDR_ANY);
+    bind_address = in6addr_any;
     listeners = NULL;
 }
 
@@ -1063,10 +1057,8 @@
     s->keep_alive = 1;
     s->next = NULL;
     s->addrs = pcalloc(p, sizeof (server_addr_rec));
-    s->addrs->host_addr.s_addr = htonl (INADDR_ANY); /* NOT virtual host;
-					       * don't match any real network
-					       * interface.
-					       */
+    s->addrs->host_addr = in6addr_any;
+    /* NOT virtual host; don't match any real network interface. */
     s->addrs->host_port = 0; /* matches any port */
 
     s->module_config = create_server_config (p, s);
--- http_core.c-orig	Sat Jul  5 11:56:49 1997
+++ http_core.c-new	Sun Aug 17 08:43:33 1997
@@ -327,7 +327,7 @@
 const char *
 get_remote_host(conn_rec *conn, void *dir_config, int type)
 {
-    struct in_addr *iaddr;
+    struct in6_addr *iaddr;
     struct hostent *hptr;
 #ifdef MAXIMUM_DNS
     char **haddr;
@@ -345,8 +345,8 @@
 						SERVER_BUSY_DNS,
 						(request_rec*)NULL);
 #endif /* STATUS */
-	iaddr = &(conn->remote_addr.sin_addr);
-	hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
+	iaddr = &(conn->remote_addr.sin6_addr);
+	hptr = gethostbyaddr((char *)iaddr, sizeof(struct in6_addr), AF_INET6);
 	if (hptr != NULL)
 	{
 	    conn->remote_host = pstrdup(conn->pool, (void *)hptr->h_name);
@@ -360,7 +360,7 @@
 	    if (hptr)
 	    {
 		for(haddr=hptr->h_addr_list; *haddr; haddr++)
-		    if(((struct in_addr *)(*haddr))->s_addr == iaddr->s_addr)
+		    if(IN6_ARE_ADDR_EQUAL(*haddr, iaddr))
 			break;
 	    }
 	    if((!hptr) || (!(*haddr)))
@@ -1123,7 +1123,7 @@
 #endif
 
 const char *set_bind_address (cmd_parms *cmd, void *dummy, char *arg) {
-    bind_address.s_addr = get_virthost_addr (arg, NULL);
+    bind_address = *get_virthost_addr (arg, NULL);
     return NULL;
 }
 
@@ -1145,15 +1145,18 @@
 	ports = ips;
 
     new=pcalloc(cmd->pool, sizeof(listen_rec));
-    new->local_addr.sin_family = AF_INET;
+#ifdef SIN6_LEN
+    new->local_addr.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+    new->local_addr.sin6_family = AF_INET6;
     if (ports == ips) /* no address */
-	new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	new->local_addr.sin6_addr = in6addr_any;
     else
-	new->local_addr.sin_addr.s_addr = get_virthost_addr(ips, NULL);
+	new->local_addr.sin6_addr = *get_virthost_addr(ips, NULL);
     port=atoi(ports);
     if(!port)
 	return "Port must be numeric";
-    new->local_addr.sin_port = htons(port);
+    new->local_addr.sin6_port = htons(port);
     new->fd = -1;
     new->used = 0;
     new->next = listeners;
--- http_main.c-orig	Sun Jun 29 12:08:37 1997
+++ http_main.c-new	Sun Aug 17 09:55:15 1997
@@ -140,7 +140,7 @@
 char *scoreboard_fname;
 char *lock_fname;
 char *server_argv0;
-struct in_addr bind_address;
+struct in6_addr bind_address;
 listen_rec *listeners;
 int daemons_to_start;
 int daemons_min_free;
@@ -1464,7 +1464,7 @@
 pool *pconf;			/* Pool for config stuff */
 pool *ptrans;			/* Pool for per-transaction stuff */
 
-static server_rec *find_virtual_server (struct in_addr server_ip,
+static server_rec *find_virtual_server (struct in6_addr *server_ip,
 				unsigned port, server_rec *server)
 {
     server_rec *virt;
@@ -1475,11 +1475,11 @@
     for (virt = server->next; virt; virt = virt->next) {
 	for (sar = virt->addrs; sar; sar = sar->next) {
 	    if ((virt->is_virtual == 1) &&	/* VirtualHost */
-		(sar->host_addr.s_addr == htonl(INADDR_ANY) ||
-		sar->host_addr.s_addr == server_ip.s_addr) &&
+		(IN6_IS_ADDR_UNSPECIFIED(&sar->host_addr) ||
+		 IN6_ARE_ADDR_EQUAL(&sar->host_addr, server_ip)) &&
 		(sar->host_port == 0 || sar->host_port == port)) {
 		return virt;
-	    } else if ( sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
+	    } else if ( IN6_ARE_ADDR_EQUAL(&sar->host_addr, &in6addr_loopback)
 		&& (sar->host_port == 0 || sar->host_port == port)) {
 		/* this is so that you can build a server that is the
 		    "default" for any interface which isn't explicitly
@@ -1496,7 +1496,7 @@
 void default_server_hostnames(server_rec *s)
 {
     struct hostent *h;
-    struct in_addr *main_addr;
+    struct in6_addr *main_addr;
     int num_addr;
     char *def_hostname;
     int n;
@@ -1533,7 +1533,7 @@
     }
     main_addr = palloc( pconf, sizeof( *main_addr ) * num_addr );
     for (n = 0; n < num_addr; n++) {
-    	main_addr[n] = *(struct in_addr *)h->h_addr_list[n];
+    	main_addr[n] = *(struct in6_addr *)h->h_addr_list[n];
     }
 
     /* Then virtual hosts */
@@ -1543,10 +1543,10 @@
 	has_default_vhost_addr = 0;
 	for (n = 0; n < num_addr; n++) {
 	    for(sar = s->addrs; sar; sar = sar->next) {
-		if (sar->host_addr.s_addr == main_addr[n].s_addr &&
+		if (IN6_ARE_ADDR_EQUAL(&sar->host_addr, &main_addr[n]) &&
 		    s->port == mainport)
 		    s->is_virtual = 2;
-		if( sar->host_addr.s_addr == DEFAULT_VHOST_ADDR ) {
+		if( IN6_ARE_ADDR_EQUAL(&sar->host_addr, &in6addr_loopback )) {
 		    has_default_vhost_addr = 1;
 		}
 	    }
@@ -1571,15 +1571,18 @@
 	    } else {
 		if (s->addrs
 		    && (h = gethostbyaddr ((char *)&(s->addrs->host_addr),
-				   sizeof (struct in_addr), AF_INET))) {
+				   sizeof (struct in6_addr), AF_INET6))) {
 		    s->server_hostname = pstrdup (pconf, (char *)h->h_name);
 		} else {
 		    /* again, what can we do?  They didn't specify a
 			ServerName, and their DNS isn't working. -djg */
 		    if (s->addrs) {
+			char v[64]; /* for Paul Vixie */
+
 			fprintf(stderr, "Failed to resolve server name "
 			    "for %s (check DNS)\n",
-			    inet_ntoa(s->addrs->host_addr));
+			    inet_ntop(AF_INET6, &s->addrs->host_addr,
+				      v, sizeof(v)));
 		    }
 		    s->server_hostname = "bogus_host_without_reverse_dns";
 		}
@@ -1589,11 +1592,12 @@
 }
 
 conn_rec *new_connection (pool *p, server_rec *server, BUFF *inout,
-			  const struct sockaddr_in *remaddr,
-			  const struct sockaddr_in *saddr,
+			  const struct sockaddr_in6 *remaddr,
+			  const struct sockaddr_in6 *saddr,
 			  int child_num)
 {
     conn_rec *conn = (conn_rec *)pcalloc (p, sizeof(conn_rec));
+    char rname[64];
     
     /* Got a connection structure, so initialize what fields we can
      * (the rest are zeroed out by pcalloc).
@@ -1603,14 +1607,17 @@
     
     conn->pool = p;
     conn->local_addr = *saddr;
-    conn->server = find_virtual_server(saddr->sin_addr, ntohs(saddr->sin_port),
+    conn->server = find_virtual_server((struct in6_addr *)&saddr->sin6_addr,
+				       ntohs(saddr->sin6_port),
 				       server);
     conn->base_server = conn->server;
     conn->client = inout;
     
     conn->remote_addr = *remaddr;
     conn->remote_ip = pstrdup (conn->pool,
-			       inet_ntoa(conn->remote_addr.sin_addr));
+			       inet_ntop(AF_INET6,
+					 &conn->remote_addr.sin6_addr,
+					 rname, sizeof(rname)));
 
     return conn;
 }
@@ -1658,8 +1665,8 @@
 #else
     int clen;
 #endif
-    struct sockaddr sa_server;
-    struct sockaddr sa_client;
+    struct sockaddr_in6 sin_server;
+    struct sockaddr_in6 sin_client;
 
     csd = -1;
     dupped_csd = -1;
@@ -1776,8 +1783,8 @@
 	    deferred_die = 0;
 	    signal (SIGUSR1, (void (*)())deferred_die_handler);
             for (;;) {
-                clen = sizeof(sa_client);
-                csd  = accept(sd, &sa_client, &clen);
+                clen = sizeof(sin_client);
+                csd  = accept(sd, (struct sockaddr *)&sin_client, &clen);
 		if (csd >= 0 || errno != EINTR) break;
 		if (deferred_die) {
 		    /* we didn't get a socket, and we were told to die */
@@ -1821,8 +1828,8 @@
          * socket options, file descriptors, and read/write buffers.
          */
 
-	clen = sizeof(sa_server);
-	if (getsockname(csd, &sa_server, &clen) < 0) {
+	clen = sizeof(sin_server);
+	if (getsockname(csd, (struct sockaddr *)&sin_server, &clen) < 0) {
 	    log_unixerr("getsockname", NULL, NULL, server_conf);
 	    continue;
 	}
@@ -1844,8 +1851,7 @@
 	bpushfd(conn_io, csd, dupped_csd);
 
 	current_conn = new_connection (ptrans, server_conf, conn_io,
-				       (struct sockaddr_in *)&sa_client,
-				       (struct sockaddr_in *)&sa_server,
+				       &sin_client, &sin_server,
 				       child_num);
 
         /*
@@ -1971,12 +1977,12 @@
     return 0;
 }
 
-static int make_sock(pool *pconf, const struct sockaddr_in *server)
+static int make_sock(pool *pconf, const struct sockaddr_in6 *server)
 {
     int s;
     int one = 1;
 
-    if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
+    if ((s = socket(AF_INET6,SOCK_STREAM,IPPROTO_TCP)) == -1) {
         log_unixerr("socket", NULL, "Failed to get a socket, exiting child",
                     server_conf);
         exit(1);
@@ -2033,24 +2039,28 @@
 
 #ifdef MPE
 /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
-    if (ntohs(server->sin_port) < 1024) GETPRIVMODE();
+    if (ntohs(server->sin6_port) < 1024) GETPRIVMODE();
 #endif
-    if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in)) == -1)
+    if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in6)) == -1)
     {
+	char abuf[64];
+
         perror("bind");
 #ifdef MPE
-        if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+        if (ntohs(server->sin6_port) < 1024) GETUSERMODE();
 #endif
-	if (server->sin_addr.s_addr != htonl(INADDR_ANY))
+	if (!IN6_IS_ADDR_UNSPECIFIED(&server->sin6_addr))
 	    fprintf(stderr,"httpd: could not bind to address %s port %d\n",
-		    inet_ntoa(server->sin_addr), ntohs(server->sin_port));
+		    inet_ntop(AF_INET6, &server->sin6_addr,
+			      abuf, sizeof(abuf)),
+		    ntohs(server->sin6_port));
 	else
 	    fprintf(stderr,"httpd: could not bind to port %d\n",
-		    ntohs(server->sin_port));
+		    ntohs(server->sin6_port));
         exit(1);
     }
 #ifdef MPE
-    if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+    if (ntohs(server->sin6_port) < 1024) GETUSERMODE();
 #endif
     listen(s, 512);
     return s;
@@ -2111,7 +2121,7 @@
 
 void standalone_main(int argc, char **argv)
 {
-    struct sockaddr_in sa_server;
+    struct sockaddr_in6 sin_server;
     int saved_sd;
     int remaining_children_to_start;
 
@@ -2141,11 +2151,14 @@
 
 	if (listeners == NULL) {
 	    if (!is_graceful) {
-		memset ((char *)&sa_server, 0, sizeof (sa_server));
-		sa_server.sin_family = AF_INET;
-		sa_server.sin_addr = bind_address;
-		sa_server.sin_port = htons (server_conf->port);
-		sd = make_sock (pconf, &sa_server);
+		memset ((char *)&sin_server, 0, sizeof (sin_server));
+#ifdef SIN6_LEN
+		sin_server.sin6_len = sizeof(sin_server);
+#endif
+		sin_server.sin6_family = AF_INET6;
+		sin_server.sin6_addr = bind_address;
+		sin_server.sin6_port = htons (server_conf->port);
+		sd = make_sock (pconf, &sin_server);
 	    }
 	    else {
 		sd = saved_sd;
@@ -2336,6 +2349,9 @@
 {
     int c;
 
+    (void) res_init();
+    _res.options |= RES_USE_INET6;
+
 #ifdef AUX
     (void)set42sig();
 #endif
@@ -2405,7 +2421,7 @@
     else {
         conn_rec *conn;
 	request_rec *r;
-	struct sockaddr sa_server, sa_client;
+	struct sockaddr_in6 sin_server, sin_client;
 	BUFF *cio;
       
 	open_logs(server_conf, pconf);
@@ -2430,21 +2446,23 @@
       }
 #endif
 
-	c = sizeof(sa_client);
-	if ((getpeername(fileno(stdin), &sa_client, &c)) < 0)
+	c = sizeof(sin_client);
+	if ((getpeername(fileno(stdin),
+			 (struct sockaddr *)&sin_client, &c)) < 0)
 	{
 /* get peername will fail if the input isn't a socket */
 	    perror("getpeername");
-	    memset(&sa_client, '\0', sizeof(sa_client));
+	    memset(&sin_client, '\0', sizeof(sin_client));
 	}
 
-	c = sizeof(sa_server);
-	if(getsockname(fileno(stdin), &sa_server, &c) < 0) {
+	c = sizeof(sin_server);
+	if(getsockname(fileno(stdin),
+		       (struct sockaddr *)&sin_server, &c) < 0) {
 	    perror("getsockname");
 	    fprintf(stderr, "Error getting local address\n");
 	    exit(1);
 	}
-	server_conf->port =ntohs(((struct sockaddr_in *)&sa_server)->sin_port);
+	server_conf->port =ntohs(sin_server.sin6_port);
 	cio = bcreate(ptrans, B_RDWR);
 #ifdef MPE
 /* HP MPE 5.5 inetd only passes the incoming socket as stdin (fd 0), whereas
@@ -2459,8 +2477,7 @@
 #endif
 	cio->fd_in = fileno(stdin);
 	conn = new_connection (ptrans, server_conf, cio,
-			       (struct sockaddr_in *)&sa_client,
-			       (struct sockaddr_in *)&sa_server,-1);
+			       &sin_client, &sin_server,-1);
 	r = read_request (conn);
 	if (r) process_request (r); /* else premature EOF (ignore) */
 
--- http_protocol.c-orig	Tue Jul  1 00:50:29 1997
+++ http_protocol.c-new	Sun Aug 17 09:07:59 1997
@@ -574,20 +574,17 @@
   if (!strcasecmp(host, r->server->server_hostname)) {
     return (uri + r->hostlen);
   }
-  else if (!strcmp(host, inet_ntoa(r->connection->local_addr.sin_addr))) {
-    return (uri + r->hostlen);
-  }
 
-  /* Now things get a bit trickier - check the IP address(es) of the host */
-  /* they gave, see if it matches ours.                                   */
+  /* Now things get a bit trickier - check the IPv6 address(es) of the host */
+  /* they gave, see if it matches ours.                                     */
   else {
     struct hostent *hp;
     int n;
 
     if ((hp = gethostbyname(host))) {
       for (n = 0; hp->h_addr_list[n] != NULL; n++) {
-	if (r->connection->local_addr.sin_addr.s_addr ==
-	    (((struct in_addr *)(hp->h_addr_list[n]))->s_addr)) {
+	if (IN6_ARE_ADDR_EQUAL(&r->connection->local_addr.sin6_addr,
+			       (struct in6_addr *)(hp->h_addr_list[n]))) {
 	  return (uri + r->hostlen);
 	}
       }
--- httpd.h-orig	Sat Jul  5 20:04:22 1997
+++ httpd.h-new	Sun Aug 17 08:35:22 1997
@@ -75,12 +75,14 @@
 #endif
 
 /* Root of server */
+#ifndef DOCUMENT_LOCATION
 #ifdef __EMX__
 /* Set default for OS/2 file system */ 
 #define DOCUMENT_LOCATION "/os2httpd/docs"
 #else
 #define DOCUMENT_LOCATION "/usr/local/etc/httpd/htdocs"
 #endif
+#endif
 
 /* Max. number of dynamically loaded modules */
 #define DYNAMIC_MODULE_LIMIT 64
@@ -152,13 +154,19 @@
 #endif
 
 /* The name of the document config file */
+#ifndef RESOURCE_CONFIG_FILE
 #define RESOURCE_CONFIG_FILE "conf/srm.conf"
+#endif
 
 /* The name of the MIME types file */
+#ifndef TYPES_CONFIG_FILE
 #define TYPES_CONFIG_FILE "conf/mime.types"
+#endif
 
 /* The name of the access file */
+#ifndef ACCESS_CONFIG_FILE
 #define ACCESS_CONFIG_FILE "conf/access.conf"
+#endif
 
 /* Whether we should enable rfc1413 identity checking */
 #define DEFAULT_RFC1413 0
@@ -547,8 +555,8 @@
   
   /* Who is the client? */
   
-  struct sockaddr_in local_addr; /* local address */
-  struct sockaddr_in remote_addr;/* remote address */
+  struct sockaddr_in6 local_addr; /* local address */
+  struct sockaddr_in6 remote_addr;/* remote address */
   char *remote_ip;		/* Client's IP address */
   char *remote_host;		/* Client's DNS name, if known.
                                  * NULL if DNS hasn't been checked,
@@ -571,15 +579,14 @@
 
 /* Per-vhost config... */
 
-/* The address 255.255.255.255, when used as a virtualhost address,
+/* The address ::1 (loopback), when used as a virtualhost address,
  * will become the "default" server when the ip doesn't match other vhosts.
  */
-#define DEFAULT_VHOST_ADDR 0xfffffffful
 
 typedef struct server_addr_rec server_addr_rec;
 struct server_addr_rec {
     server_addr_rec *next;
-    struct in_addr host_addr;	/* The bound address, for this server */
+    struct in6_addr host_addr;	/* The bound address, for this server */
     unsigned short host_port;	/* The bound port, for this server */   
     char *virthost;		/* The name given in <VirtualHost> */
 };
@@ -635,7 +642,7 @@
 /* These are more like real hosts than virtual hosts */
 struct listen_rec {
     listen_rec *next;
-    struct sockaddr_in local_addr; /* local IP address and port */
+    struct sockaddr_in6 local_addr; /* local IP address and port */
     int fd;
     int used;	/* Only used during restart */
 /* more stuff here, like which protocol is bound to the port */
@@ -712,7 +719,7 @@
 void chdir_file(const char *file);
      
 char *get_local_host(pool *);
-unsigned long get_virthost_addr (const char *hostname, unsigned short *port);
+struct in6_addr *get_virthost_addr (const char *hostname, unsigned short *port);
 
 extern time_t restart_time;
 
--- mod_rewrite.c-orig	Thu Jun 26 20:26:30 1997
+++ mod_rewrite.c-new	Sun Aug 17 09:58:34 1997
@@ -3052,6 +3052,7 @@
 **  special DNS lookup functions
 **
 */
+/* This implies the canonical (ie shortest) address textual form is used ?! */
 
 static int is_this_our_host(request_rec *r, char *testhost)
 {
@@ -3063,6 +3064,7 @@
     char *name;
     int i, j;
     server_addr_rec *sar;
+    char hname[64];
 
     /* we can check:
        r->
@@ -3071,20 +3073,22 @@
        r->server->
             int is_virtual            0=main, 1=ip-virtual, 2=non-ip-virtual
             char *server_hostname     used on compare to r->hostname
-            inet_ntoa(r->connection->local_addr.sin_addr)
+            inet_ntop(AF_INET6, &r->connection->local_addr.sin6_addr, ...)
                                       used on compare to r->hostname
             unsigned short port       for redirects
             char *path                name of ServerPath
             int pathlen               len of ServerPath
             char *names               Wildcarded names for ServerAlias servers 
        r->server->addrs->
-            struct in_addr host_addr  The bound address, for this server
+            struct in6_addr host_addr The bound address, for this server
             short host_port           The bound port, for this server 
             char *virthost            The name given in <VirtualHost> 
     */
 
     ourhostname = r->server->server_hostname;
-    ourhostip   = inet_ntoa(r->connection->local_addr.sin_addr);
+    ourhostip   = (char *)inet_ntop(AF_INET6,
+				    &r->connection->local_addr.sin6_addr,
+				    hname, sizeof(hname));
 
     /* just a simple common case */
     if (strcmp(testhost, ourhostname) == 0 ||
@@ -3095,7 +3099,7 @@
     if (!r->server->is_virtual) {
         /* main servers */
 
-        /* check for the alternative IP addresses */
+        /* check for the alternative IPv6 addresses */
         if ((cppHNLour = resolv_ipaddr_list(r, ourhostname)) == NULL)
             return NO;
         if ((cppHNLtest = resolv_ipaddr_list(r, testhost)) == NULL)
@@ -3132,6 +3136,7 @@
     return NO;
 }
 
+#ifdef notneeded
 static int isaddr(char *host)
 {
     char *cp;
@@ -3142,9 +3147,9 @@
         return NO;
     if (*host == '\0')
         return NO;
-    /* Make sure it has only digits and dots. */
+    /* Make sure it has only hexdigits, dots and colons. */
     for (cp = host; *cp; cp++) {
-        if (!isdigit(*cp) && *cp != '.')
+        if (!isxdigit(*cp) && *cp != '.' && *cp != ':')
             return NO;
     }
     /* If it has a trailing dot, 
@@ -3153,6 +3158,7 @@
        return NO;
     return YES;
 }
+#endif
 
 static char **resolv_ipaddr_list(request_rec *r, char *name)
 {
@@ -3160,17 +3166,20 @@
     struct hostent *hep;
     int i;
 
-    if (isaddr(name)) 
-        hep = gethostbyaddr(name, sizeof(struct in_addr), AF_INET);
-    else
-        hep = gethostbyname(name);
+    hep = gethostbyname(name);
     if (hep == NULL)
         return NULL;
     for (i = 0; hep->h_addr_list[i]; i++)
         ;
     cppHNL = (char **)palloc(r->pool, sizeof(char *)*(i+1));
-    for (i = 0; hep->h_addr_list[i]; i++)
-        cppHNL[i] = pstrdup(r->pool, inet_ntoa(*((struct in_addr *)(hep->h_addr_list[i]))) );
+    for (i = 0; hep->h_addr_list[i]; i++) {
+	struct in6_addr *addr;
+	char name[64];
+
+	addr = (struct in6_addr *)(hep->h_addr_list[i]);
+        cppHNL[i] = pstrdup(r->pool,
+			    inet_ntop(AF_INET6, addr, name, sizeof(name)));
+    }
     cppHNL[i] = NULL;
     return cppHNL;
 }
--- rfc1413.c-orig	Thu May 29 12:29:12 1997
+++ rfc1413.c-new	Sun Aug 17 09:21:45 1997
@@ -102,10 +102,10 @@
 /* bind_connect - bind both ends of a socket */
 
 static int
-get_rfc1413(int sock, const struct sockaddr_in *our_sin,
-	  const struct sockaddr_in *rmt_sin, char user[256], server_rec *srv)
+get_rfc1413(int sock, const struct sockaddr_in6 *our_sin,
+	  const struct sockaddr_in6 *rmt_sin, char user[256], server_rec *srv)
 {
-    struct sockaddr_in rmt_query_sin, our_query_sin;
+    struct sockaddr_in6 rmt_query_sin, our_query_sin;
     unsigned int rmt_port, our_port;
     int i;
     char *cp;
@@ -121,12 +121,12 @@
      */
 
     our_query_sin = *our_sin;
-    our_query_sin.sin_port = htons(ANY_PORT);
+    our_query_sin.sin6_port = htons(ANY_PORT);
     rmt_query_sin = *rmt_sin;
-    rmt_query_sin.sin_port = htons(RFC1413_PORT);
+    rmt_query_sin.sin6_port = htons(RFC1413_PORT);
 
     if (bind(sock, (struct sockaddr *)&our_query_sin,
-	     sizeof(struct sockaddr_in)) < 0)
+	     sizeof(struct sockaddr_in6)) < 0)
     {
 	log_unixerr("bind", NULL, "rfc1413: Error binding to local port", srv);
 	return -1;
@@ -137,12 +137,12 @@
  * the service
  */
     if (connect(sock, (struct sockaddr *)&rmt_query_sin,
-		sizeof(struct sockaddr_in)) < 0)
+		sizeof(struct sockaddr_in6)) < 0)
 	return -1;
 
 /* send the data */
-    ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
-	    ntohs(our_sin->sin_port));
+    ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n",
+		ntohs(rmt_sin->sin6_port), ntohs(our_sin->sin6_port));
     do i = write(sock, buffer, strlen(buffer));
     while (i == -1 && errno == EINTR);
     if (i == -1)
@@ -167,8 +167,8 @@
     buffer[i] = '\0';
 /* RFC1413_USERLEN = 512 */
     if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
-	       user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
-	|| ntohs(our_sin->sin_port) != our_port) return -1;
+	       user) != 3 || ntohs(rmt_sin->sin6_port) != rmt_port
+	|| ntohs(our_sin->sin6_port) != our_port) return -1;
 
     /*
      * Strip trailing carriage return. It is part of the
@@ -197,7 +197,7 @@
 
     result = FROM_UNKNOWN;
 
-    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
     if (sock < 0)
     {
 	log_unixerr("socket", NULL, "rfc1413: error creating socket", srv);
--- util.c-orig	Thu Jun 26 19:47:47 1997
+++ util.c-new	Sun Aug 17 09:14:03 1997
@@ -1114,27 +1114,27 @@
 
 #if 0
 int get_portnum(int sd) {
-    struct sockaddr addr;
+    struct sockaddr_in6 addr;
     int len;
 
-    len = sizeof(struct sockaddr);
-    if(getsockname(sd,&addr,&len) < 0)
+    len = sizeof(struct sockaddr_in6);
+    if(getsockname(sd,(struct sockaddr *)&addr,&len) < 0)
         return -1;
-    return ntohs(((struct sockaddr_in *)&addr)->sin_port);
+    return ntohs(addr.sin6_port);
 }
 
-struct in_addr get_local_addr(int sd) {
-    struct sockaddr addr;
+struct in6_addr *get_local_addr(int sd) {
+    static struct sockaddr_in6 addr;
     int len;
 
-    len = sizeof(struct sockaddr);
-    if(getsockname(sd,&addr,&len) < 0) {
+    len = sizeof(struct sockaddr_in6);
+    if(getsockname(sd,(struct sockaddr *)&addr,&len) < 0) {
 	perror ("getsockname");
         fprintf (stderr, "Can't get local host address!\n");
 	exit(1);
     }
          
-    return ((struct sockaddr_in *)&addr)->sin_addr;
+    return &(addr.sin6_addr);
 }
 #endif
 
@@ -1142,9 +1142,9 @@
  * Parses a host of the form <address>[:port]
  * :port is permitted if 'port' is not NULL
  */
-unsigned long get_virthost_addr (const char *w, unsigned short *ports) {
+struct in6_addr *get_virthost_addr (const char *w, unsigned short *ports) {
     struct hostent *hep;
-    unsigned long my_addr;
+    static struct in6_addr my_addr;
     char *p;
 
     p = strchr(w, ':');
@@ -1158,23 +1158,19 @@
     if (strcmp(w, "*") == 0)
     {
 	if (p != NULL) *p = ':';
-	return htonl(INADDR_ANY);
+	my_addr = in6addr_any;
+	return &my_addr;
     }
 	
-#ifdef DGUX
-    my_addr = inet_network(w);
-#else
-    my_addr = inet_addr(w);
-#endif
-    if (my_addr != INADDR_NONE)
+    if (inet_pton(AF_INET6, w, &my_addr) > 0)
     {
 	if (p != NULL) *p = ':';
-	return my_addr;
+	return &my_addr;
     }
 
     hep = gethostbyname(w);
 	    
-    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
+    if ((!hep) || (hep->h_addrtype != AF_INET6 || !hep->h_addr_list[0])) {
 	fprintf (stderr, "Cannot resolve host name %s --- exiting!\n", w);
 	exit(1);
     }
@@ -1188,7 +1184,8 @@
 	    
     if (p != NULL) *p = ':';
 
-    return ((struct in_addr *)(hep->h_addr))->s_addr;
+    my_addr = *((struct in6_addr *)(hep->h_addr));
+    return &my_addr;
 }
 
 
--- util_script.c-orig	Thu Jun 26 20:28:56 1997
+++ util_script.c-new	Sun Aug 17 09:17:59 1997
@@ -201,7 +201,7 @@
     table_set (e, "SERVER_ADMIN", s->server_admin); /* Apache */
     table_set (e, "SCRIPT_FILENAME", r->filename); /* Apache */
     
-    ap_snprintf(port, sizeof(port), "%d", ntohs(c->remote_addr.sin_port));
+    ap_snprintf(port, sizeof(port), "%d", ntohs(c->remote_addr.sin6_port));
     table_set (e, "REMOTE_PORT", port);            /* Apache */
 
     if (c->user) table_set(e, "REMOTE_USER", c->user);


Re: IPv6 support for Apache

Posted by Marc Slemko <ma...@worldgate.com>.
On Sun, 15 Feb 1998, Ben Laurie wrote:

> Marc Slemko wrote:
> > 
> > ftp://ftp.inria.fr/network/ipv6/freebsd/New.tar.gz includes a modified
> > Apache 1.2.1.
> > 
> > under a licence of:
> > 
> >   This software is available with usual "research" terms
> >   with the aim of retain credits of the software.
> >   Permission to use, copy, modify and distribute this software for any
> >   purpose and without fee is hereby granted, provided that the above
> >   copyright notice and this permission notice appear in all copies,
> >   and the name of INRIA, IMAG, or any contributor not be used in advertising
> >   or publicity pertaining to this material without the prior explicit
> >   permission. The software is provided "as is" without any
> >   warranties, support or liabilities of any kind.
> >   This software is derived from source code from
> >   "University of California at Berkeley" and
> >   "Digital Equipment Corporation" protected by copyrights.
> > 
> > (I think)
> 
> So is this another one we have to whine about licensing to?

No, they include the Apache license I think but they don't even include
Apache, just patches, so there isn't really any problem.


Re: IPv6 support for Apache

Posted by Ben Laurie <be...@algroup.co.uk>.
Marc Slemko wrote:
> 
> ftp://ftp.inria.fr/network/ipv6/freebsd/New.tar.gz includes a modified
> Apache 1.2.1.
> 
> under a licence of:
> 
>   This software is available with usual "research" terms
>   with the aim of retain credits of the software.
>   Permission to use, copy, modify and distribute this software for any
>   purpose and without fee is hereby granted, provided that the above
>   copyright notice and this permission notice appear in all copies,
>   and the name of INRIA, IMAG, or any contributor not be used in advertising
>   or publicity pertaining to this material without the prior explicit
>   permission. The software is provided "as is" without any
>   warranties, support or liabilities of any kind.
>   This software is derived from source code from
>   "University of California at Berkeley" and
>   "Digital Equipment Corporation" protected by copyrights.
> 
> (I think)

So is this another one we have to whine about licensing to?

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686|Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |Apache-SSL author
A.L. Digital Ltd,     |http://www.algroup.co.uk/Apache-SSL
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache