Subject: Re: port-i386/37533: Client can not connect to any address with ipv6 address
To: None <port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: Phan Nam <metallica2507@yahoo.com>
List: netbsd-bugs
Date: 12/17/2007 17:40:02
The following reply was made to PR port-i386/37533; it has been noted by GNATS.

From: Phan Nam <metallica2507@yahoo.com>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-i386/37533: Client can not connect to any address with ipv6 address
Date: Mon, 17 Dec 2007 07:51:30 -0800 (PST)

 --0-1486253397-1197906690=:74497
 Content-Type: text/plain; charset=iso-8859-1
 Content-Transfer-Encoding: 8bit
 
 Dear Arnaud Degroote
 
 First of all, I really thank for you help. And now I can use IPv4-mapping address to send and receive datagram packet with AF_INET6 socket.
 
 I also try to use AF_INET6 socket to connect AF_INET6 server, the system throws an error "Network is unreachable". I also try this test on Linux, and I see it can connect to AF_INET6 server. What happens to this test?
 
 Maybe, this test needs to configure correctly, would you please helping me configure or test system with OS NetBSD.
 
 And here is my codes
 
 /*
 ** server.c -- a stream socket server demo
 */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/wait.h>
 #include <signal.h>
 
 #define MYPORT 3490 // the port users will be connecting to
 #define BACKLOG 10 // how many pending connections queue will hold
 void sigchld_handler(int s)
 {
     while(waitpid(-1, NULL, WNOHANG) > 0);
 }
 int main(void)
 {
     int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
     struct sockaddr_in6 my_addr; // my address information
     struct sockaddr_in6 *my_addrP = (struct sockaddr_in6*)&my_addr;
     struct sockaddr_in6 their_addr; // connector’s address information
     socklen_t sin_size;
     char caddr[16];
     int i=0;
     struct sigaction sa;
     int yes=1;
     int len = 28;
 
     if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
         perror("socket");
         exit(1);
     }
     
     if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
         perror("setsockopt");
         exit(1);
     }
     memset(&caddr, 0, 16);
     for(i=0; i< 16; i++)
         caddr[i] = 0;
 
     my_addrP->sin6_family = AF_INET6; // host byte order
     my_addrP->sin6_port = htons(MYPORT); // short, network byte order
     memcpy((void *)&(my_addrP->sin6_addr), caddr, 16 );
     if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)) == -1) {
         perror("bind");
         exit(1);
     }
     if (listen(sockfd, BACKLOG) == -1) {
         perror("listen");
         exit(1);
     }
     sa.sa_handler = sigchld_handler; // reap all dead processes
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_RESTART;
     if (sigaction(SIGCHLD, &sa, NULL) == -1) {
     perror("sigaction");
     exit(1);
     }
     while(1) { // main accept() loop
         sin_size = sizeof(struct sockaddr_in6);
         if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
             perror("accept");
             continue;
         }
         memcpy(caddr, (void *)&(their_addr.sin6_addr), 16 );
         printf("server: got connection from: ");
         for (i=0;i < 16; i++)
             printf(" %d", caddr[i]);
             printf("\n");
         if (!fork()) { // this is the child process
             close(sockfd); // child doesn’t need the listener
             if (send(new_fd, "Hello, world!\n", 14, 0) == -1)
             perror("send");
             close(new_fd);
             exit(0);
         }
         close(new_fd); // parent doesn’t need this
     }
     return 0;
 }
 
 And here is client's code
 
 /*
 ** client.c -- a stream socket client demo
 */
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <netdb.h>
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #define PORT 3490 // the port client will be connecting to
 #define MAXDATASIZE 100 // max number of bytes we can get at once
 int main(int argc, char *argv[])
 {
     int sockfd, numbytes;
     char buf[MAXDATASIZE];
     struct hostent *he;
     struct sockaddr_in6 their_addr; // connector’s address information
     char caddr[16];
     int i=0;
 
     if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
         perror("socket");
         exit(1);
     }
 
     memset(&caddr, 0, 16);
     their_addr.sin6_family = AF_INET6; // host byte order
     their_addr.sin6_port = htons(PORT); // short, network byte order
     
     for (i =0; i<16; i++)
         caddr[i] = 0;
     memcpy((void *)&(their_addr.sin6_addr), caddr, sizeof(struct in6_addr) );
     
     if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr_in6)) == -1) {
         perror("connect");
         exit(1);
     }
 
 
     if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
         perror("recv");
         exit(1);
     }
     buf[numbytes] = '\0';
     printf("Received: %s",buf);
     close(sockfd);
     return 0;
 }
 
 
 Please help me check.
 
 Thanks
 
 Best regards
 Nam Phan
 
 
 
 Arnaud Degroote <degroote@netbsd.org> wrote: The following reply was made to PR port-i386/37533; it has been noted by GNATS.
 
 From: Arnaud Degroote 
 To: gnats-bugs@NetBSD.org
 Cc: port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,
  netbsd-bugs@netbsd.org, metallica2507@yahoo.com
 Subject: Re: port-i386/37533: Client can not connect to any address with ipv6 address
 Date: Thu, 13 Dec 2007 21:07:28 +0100
 
  The quick solution is to to unset the sysctl net.inet6.ip6.v6only using
  sysctl -w net.inet6.ip6.v6only=0
  
  Note that this behaviour is not enabled because it has security impact
  (see for example
  ftp://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2006-016.txt.asc).
  
  I think the best thing to do is probably to use a AF_INET6 socket to
  connect to your AF_INET6 server. 
  
  Another note on your code, you may use IN6ADDR_ANY_INIT or in6addr_any
  (depending the context) to let your server binding on any available
  iface.
  
  I hope it will help.
  
  Regards,
  -- 
  Arnaud Degroote
  degroote@netbsd.org
  
 
 
        
 ---------------------------------
 Looking for last minute shopping deals?  Find them fast with Yahoo! Search.
 --0-1486253397-1197906690=:74497
 Content-Type: text/html; charset=iso-8859-1
 Content-Transfer-Encoding: 8bit
 
 Dear Arnaud Degroote<br><br>First of all, I really thank for you help. And now I can use IPv4-mapping address to send and receive datagram packet with AF_INET6 socket.<br><br>I also try to use AF_INET6 socket to connect AF_INET6 server, the system throws an error <span style="font-weight: bold;">"Network is unreachable"</span>. I also try this test on Linux, and I see it can connect to AF_INET6 server. What happens to this test?<br><br>Maybe, this test needs to configure correctly, would you please helping me configure or test system with OS NetBSD.<br><br>And here is my codes<br><br>/*<br>** server.c -- a stream socket server demo<br>*/<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;errno.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;sys/types.h&gt;<br>#include &lt;sys/socket.h&gt;<br>#include &lt;netinet/in.h&gt;<br>#include &lt;arpa/inet.h&gt;<br>#include &lt;sys/wait.h&gt;<br>#include
  &lt;signal.h&gt;<br><br>#define MYPORT 3490 // the port users will be connecting to<br>#define BACKLOG 10 // how many pending connections queue will hold<br>void sigchld_handler(int s)<br>{<br>&nbsp;&nbsp;&nbsp; while(waitpid(-1, NULL, WNOHANG) &gt; 0);<br>}<br>int main(void)<br>{<br>&nbsp;&nbsp;&nbsp; int sockfd, new_fd; // listen on sock_fd, new connection on new_fd<br>&nbsp;&nbsp;&nbsp; struct sockaddr_in6 my_addr; // my address information<br>&nbsp;&nbsp;&nbsp; struct sockaddr_in6 *my_addrP = (struct sockaddr_in6*)&amp;my_addr;<br>&nbsp;&nbsp;&nbsp; struct sockaddr_in6 their_addr; // connector’s address information<br>&nbsp;&nbsp;&nbsp; socklen_t sin_size;<br>&nbsp;&nbsp;&nbsp; char caddr[16];<br>&nbsp;&nbsp;&nbsp; int i=0;<br>&nbsp;&nbsp;&nbsp; struct sigaction sa;<br>&nbsp;&nbsp;&nbsp; int yes=1;<br>&nbsp;&nbsp;&nbsp; int len = 28;<br><br>&nbsp;&nbsp;&nbsp; if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  perror("socket");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&amp;yes,sizeof(int)) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("setsockopt");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; memset(&amp;caddr, 0, 16);<br>&nbsp;&nbsp;&nbsp; for(i=0; i&lt; 16; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; caddr[i] = 0;<br><br>&nbsp;&nbsp;&nbsp; my_addrP-&gt;sin6_family = AF_INET6; // host byte order<br>&nbsp;&nbsp;&nbsp; my_addrP-&gt;sin6_port = htons(MYPORT); // short, network byte order<br>&nbsp;&nbsp;&nbsp; memcpy((void *)&amp;(my_addrP-&gt;sin6_addr), caddr, 16 );<br>&nbsp;&nbsp;&nbsp; if (bind(sockfd, (struct sockaddr *)&amp;my_addr, sizeof(struct sockaddr_in6)) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  perror("bind");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if (listen(sockfd, BACKLOG) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("listen");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; sa.sa_handler = sigchld_handler; // reap all dead processes<br>&nbsp;&nbsp;&nbsp; sigemptyset(&amp;sa.sa_mask);<br>&nbsp;&nbsp;&nbsp; sa.sa_flags = SA_RESTART;<br>&nbsp;&nbsp;&nbsp; if (sigaction(SIGCHLD, &amp;sa, NULL) == -1) {<br>&nbsp;&nbsp;&nbsp; perror("sigaction");<br>&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; while(1) { // main accept() loop<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sin_size = sizeof(struct sockaddr_in6);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((new_fd = accept(sockfd, (struct sockaddr *)&amp;their_addr, &amp;sin_size)) == -1)
  {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("accept");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy(caddr, (void *)&amp;(their_addr.sin6_addr), 16 );<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("server: got connection from: ");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i=0;i &lt; 16; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(" %d", caddr[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!fork()) { // this is the child process<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close(sockfd); // child doesn’t need the listener<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (send(new_fd, "Hello, world!\n", 14, 0) ==
  -1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("send");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close(new_fd);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close(new_fd); // parent doesn’t need this<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br>And here is client's code<br><br>/*<br>** client.c -- a stream socket client demo<br>*/<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;errno.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;netdb.h&gt;<br>#include &lt;sys/types.h&gt;<br>#include &lt;netinet/in.h&gt;<br>#include &lt;sys/socket.h&gt;<br>#define PORT 3490 // the port client will be connecting to<br>#define MAXDATASIZE 100 // max number of bytes we can get at once<br>int main(int argc, char
  *argv[])<br>{<br>&nbsp;&nbsp;&nbsp; int sockfd, numbytes;<br>&nbsp;&nbsp;&nbsp; char buf[MAXDATASIZE];<br>&nbsp;&nbsp;&nbsp; struct hostent *he;<br>&nbsp;&nbsp;&nbsp; struct sockaddr_in6 their_addr; // connector’s address information<br>&nbsp;&nbsp;&nbsp; char caddr[16];<br>&nbsp;&nbsp;&nbsp; int i=0;<br><br>&nbsp;&nbsp;&nbsp; if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("socket");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; memset(&amp;caddr, 0, 16);<br>&nbsp;&nbsp;&nbsp; their_addr.sin6_family = AF_INET6; // host byte order<br>&nbsp;&nbsp;&nbsp; their_addr.sin6_port = htons(PORT); // short, network byte order<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; for (i =0; i&lt;16; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; caddr[i] = 0;<br>&nbsp;&nbsp;&nbsp; memcpy((void *)&amp;(their_addr.sin6_addr), caddr, sizeof(struct in6_addr)
  );<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if (connect(sockfd, (struct sockaddr *)&amp;their_addr, sizeof(struct sockaddr_in6)) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("connect");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br><br><br>&nbsp;&nbsp;&nbsp; if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("recv");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; buf[numbytes] = '\0';<br>&nbsp;&nbsp;&nbsp; printf("Received: %s",buf);<br>&nbsp;&nbsp;&nbsp; close(sockfd);<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br><br>Please help me check.<br><br>Thanks<br><br>Best regards<br>Nam Phan<br><br><br><br><b><i>Arnaud Degroote &lt;degroote@netbsd.org&gt;</i></b> wrote:<blockquote class="replbq" style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px;"> The following reply was made
  to PR port-i386/37533; it has been noted by GNATS.<br><br>From: Arnaud Degroote <degroote@netbsd.org><br>To: gnats-bugs@NetBSD.org<br>Cc: port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,<br> netbsd-bugs@netbsd.org, metallica2507@yahoo.com<br>Subject: Re: port-i386/37533: Client can not connect to any address with ipv6 address<br>Date: Thu, 13 Dec 2007 21:07:28 +0100<br><br> The quick solution is to to unset the sysctl net.inet6.ip6.v6only using<br> sysctl -w net.inet6.ip6.v6only=0<br> <br> Note that this behaviour is not enabled because it has security impact<br> (see for example<br> ftp://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2006-016.txt.asc).<br> <br> I think the best thing to do is probably to use a AF_INET6 socket to<br> connect to your AF_INET6 server. <br> <br> Another note on your code, you may use IN6ADDR_ANY_INIT or in6addr_any<br> (depending the context) to let your server binding on any available<br> iface.<br> <br> I hope it will
  help.<br> <br> Regards,<br> -- <br> Arnaud Degroote<br> degroote@netbsd.org<br> <br></degroote@netbsd.org></blockquote><br><p>&#32;
       <hr size=1>Looking for last minute shopping deals? <a href="http://us.rd.yahoo.com/evt=51734/*http://tools.search.yahoo.com/newsearch/category.php?category=shopping"> 
 Find them fast with Yahoo! Search.</a>
 --0-1486253397-1197906690=:74497--