$NetBSD: patch-ae,v 1.3 2000/12/01 03:15:34 itojun Exp $

PATCH_SITES+=	http://apps.v6.linux.or.jp/pub/Linux/IPv6-2/canna/
PATCHFILES+=	Canna35b2-v6-20000602.diff.gz
PATCH_DIST_STRIP=	-p1
(copied here for as the above patch does not apply cleanly

diff -ru lib/RKC/Imakefile lib/RKC/Imakefile
--- lib/RKC/Imakefile	Tue Oct 22 21:26:34 1996
+++ lib/RKC/Imakefile	Fri Jun  2 15:11:31 2000
@@ -11,7 +11,7 @@
          LINTLIBS = ../RK/llib-lRK.ln
          INCLUDES = -I$(CANNAROOT)/include
 
-           DEFINES = $(SIGNAL_DEFINES) $(RKC_DEFINES) $(ENGINE_DEFS)
+           DEFINES = $(SIGNAL_DEFINES) $(RKC_DEFINES) $(ENGINE_DEFS) $(INET6_DEFS)
 
            HEADER = rkc.h rkcw.h
              OBJS = rkc.o convert.o wconvert.o wutil.o
diff -ru lib/RKC/wconvert.c lib/RKC/wconvert.c
--- lib/RKC/wconvert.c	Wed Nov 27 16:22:30 1996
+++ lib/RKC/wconvert.c	Fri Jun  2 15:01:34 2000
@@ -368,13 +368,46 @@
 int number ;
 char *hostname ;
 {
+#ifdef INET6
+    struct addrinfo hints, *res0, *res;
+    struct servent *sp ;
+    char servbuf[NI_MAXSERV];
+#else
     struct sockaddr_in inaddr;	    /* INET socket address. */
     unsigned long hostinetaddr;     /* result of inet_addr of arpa addr */
     struct hostent *host_ptr, workhostbuf ;
     struct servent *sp ;
     int addrlen ;		 
     char *h_addr_ptr;
+#endif
 
+#ifdef INET6
+    sp = getservbyname( IR_SERVICE_NAME, "tcp");
+    sprintf(servbuf, "%u", (sp ? ntohs(sp->s_port) : IR_DEFAULT_PORT) + number);
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    if ( getaddrinfo( hostname, servbuf, &hints, &res0 ) ){
+	errno = EINVAL;
+	return( -1 );
+    }
+    for( res = res0 ; res ; res = res->ai_next ){
+	if( res->ai_family != PF_INET && res->ai_family != PF_INET6 )
+	    continue;
+	if( (ServerFD = socket( res->ai_family, res->ai_socktype, res->ai_protocol )) < 0 )
+	    continue;
+	errno = 0;
+	if( connect( ServerFD, res->ai_addr, res->ai_addrlen ) ){
+#ifdef nodef
+	    perror("connect");
+#endif
+	    close( ServerFD ) ;
+	    ServerFD = -1;
+	    continue;
+	}
+    }
+    freeaddrinfo( res0 );
+#else /* INET6 / !INET6 */
     /* 󥿡ͥåȥɥᥤ³롣 */
     if( (host_ptr = gethostbyname( hostname ) )
 	                                 == (struct hostent *)NULL) {
@@ -423,8 +456,10 @@
 	perror("connect") ;
 #endif
 	close( ServerFD ) ;
+	ServerFD = -1;
 	return( -1 ) ;
     }
+#endif /* !INET6 */
     return( ServerFD ) ;
 }
 #endif
diff -ru server/Imakefile server/Imakefile
--- server/Imakefile	Wed Nov 27 16:25:24 1996
+++ server/Imakefile	Fri Jun  2 14:52:47 2000
@@ -5,12 +5,12 @@
      INSTUGIDFLAGS = -m 6555 $(cannaOwnerGroup)
 #ifdef __EMX__
          INSTFLAGS = $(INSTUGIDFLAGS)
-   LOCAL_LIBRARIES = $(CANNAROOT)/lib/RK/RK.a
+   LOCAL_LIBRARIES = $(CANNAROOT)/lib/RK/RK.a $(INET6_LIBS)
 #else
          INSTFLAGS = -s $(INSTUGIDFLAGS)
-   LOCAL_LIBRARIES = $(CANNAROOT)/lib/RK/libRK.a
+   LOCAL_LIBRARIES = $(CANNAROOT)/lib/RK/libRK.a $(INET6_LIBS)
 #endif
-           DEFINES = $(CANNASERVER_DEFINES)
+           DEFINES = $(CANNASERVER_DEFINES) $(INET6_DEFS)
           INCLUDES = -I$(CANNAROOT)/include
 
             IRSRCS = $(SRCS) $(HEADER)
diff -ru server/connection.c server/connection.c
--- server/connection.c	Wed Nov 27 16:26:10 1996
+++ server/connection.c	Fri Dec  1 11:52:10 2000
@@ -133,2 +133,63 @@
 #ifdef USE_INET_SOCKET  /* ɣΣţԥɥᥤκ */
+#ifdef INET6
+static int open_inet6_socket ()
+{
+  extern int PortNumberPlus;
+  struct sockaddr_in6 in6sock;
+  struct servent *sp;
+  int retry, request;
+  
+  /* /etc/servicesݡֹ */
+  if( (sp = getservbyname(IR_SERVICE_NAME ,"tcp")) == NULL )
+  {
+    ir_debug( Dmsg(5,"Warning: Port number not find on '/etc/services'.\n");)
+    ir_debug( Dmsg(5,"         Use %d as default.\n", IR_DEFAULT_PORT);)
+  }
+  
+  if ((request = socket (AF_INET6, SOCK_STREAM, 0)) < 0)
+  {
+    ir_debug( Dmsg(5,"Warning: INET socket for server failed.\n");)
+  }
+  else
+  {
+#ifdef SO_REUSEADDR
+    {
+      int one = 1;
+      setsockopt(request, SOL_SOCKET, SO_REUSEADDR,
+		 (char *)&one, sizeof(int));
+    }
+#endif
+    bzero ((char *)&in6sock, sizeof (in6sock));
+    in6sock.sin6_family = AF_INET6;
+    in6sock.sin6_port =
+    (sp ? ntohs(sp->s_port) : IR_DEFAULT_PORT) + PortNumberPlus;
+    
+    ir_debug( Dmsg(5, "ݡֹ:[%d]\n",htons(in6sock.sin6_port));)
+    
+    in6sock.sin6_port = htons(in6sock.sin6_port);
+    in6sock.sin6_addr = in6addr_any;
+    
+    retry = 0;
+    while ( bind(request, (struct sockaddr *)&in6sock, sizeof(in6sock)) < 0 ) 
+    { 
+      ir_debug( Dmsg(5, "bind ȥ饤[%d]\n",retry);)	
+      if (++retry == 5){
+	ir_debug( Dmsg(5,"Warning: Server could not bind.\n");)
+	close(request);
+	request = -1; /* bind   */
+	break;
+      }
+      sleep (1);
+    }
+    if( retry != 5 ) {
+      if (listen (request, 5)){
+	ir_debug( Dmsg(5,"Warning: Server could not listen.\n");)
+	close(request); 
+	request = -1; /* listen   */
+      }
+    }
+  }
+  return request;
+}
+#endif
 static int open_inet_socket ()
@@ -200,2 +261,5 @@
   int request;
+#if defined(USE_INET_SOCKET) && defined(INET6)
+  int inet6_ok = 0;
+#endif
   
@@ -222,2 +286,14 @@
 #ifdef USE_INET_SOCKET  /* ɣΣţԥɥᥤ */    
+#ifdef INET6
+  if ((request = open_inet6_socket ()) != -1)
+  {
+    inet6_ok++;
+    WellKnownConnections |= (1L << request);
+    ir_debug( Dmsg(3,"INET6 domain socket is created\n"); )
+  }
+  else
+  {
+    ir_debug( Dmsg(5,"Warning: INET6 domain not created.\n");)
+  }
+#endif
   if ((request = open_inet_socket ()) != -1)
@@ -229,3 +305,9 @@
     ir_debug( Dmsg(5,"Warning: INET domain not created.\n");)
+#ifdef INET6
+    if ( !inet6_ok ){
+      return 0; /* ˼ */
+    }
+#else
     return 0; /* ˼ */
+#endif
   }
@@ -609,6 +691,11 @@
 {
+#ifdef INET6
+    struct sockaddr_storage from;
+#else
     struct sockaddr_in	from;
     struct hostent	*hp;
-    char		buf[MAXDATA], *inet_ntoa();
-    int 		fromlen = sizeof( struct sockaddr_in ) ;
+    char		*inet_ntoa();
+#endif
+    char		buf[MAXDATA];
+    int 		fromlen = sizeof(from);
 
@@ -622,2 +709,15 @@
 
+#ifdef INET6
+#ifdef AF_UNIX
+    if (from.ss_family != AF_UNIX)
+#else
+    if (from.ss_family != AF_LOCAL)
+#endif
+    {
+	if (getnameinfo((struct sockaddr *)&from, fromlen, buf, sizeof(buf),
+	    NULL, 0, 0) != 0) {
+	    strcpy(buf, "invalid");
+	}
+    }
+#else
     if( from.sin_family == AF_INET ) {
@@ -630,3 +730,5 @@
 	    strncpy( buf, inet_ntoa( from.sin_addr ), MAXDATA-1 ) ;
-    } else {
+    }
+#endif
+    else {
         client->hostaddr = IR_UNIX_ADDRESS;
