NetBSD Problem Report #37533
From martin@duskware.de Thu Dec 13 13:37:07 2007
Return-Path: <martin@duskware.de>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by narn.NetBSD.org (Postfix) with ESMTP id 849DE63B935
for <gnats-bugs@gnats.netbsd.org>; Thu, 13 Dec 2007 13:37:07 +0000 (UTC)
Message-Id: <20071213123521.D5AA563B8FF@narn.NetBSD.org>
Date: Thu, 13 Dec 2007 12:35:21 +0000 (UTC)
From: metallica2507@yahoo.com
Reply-To: metallica2507@yahoo.com
To: netbsd-bugs-owner@NetBSD.org
Subject: Client can not connect to any address with ipv6 address
X-Send-Pr-Version: www-1.0
>Number: 37533
>Category: port-i386
>Synopsis: Client can not connect to any address with ipv6 address
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: port-i386-maintainer
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Dec 13 13:40:00 +0000 2007
>Closed-Date: Sun Feb 25 16:59:56 +0000 2018
>Last-Modified: Sun Feb 25 16:59:56 +0000 2018
>Originator: Nam Phan
>Release: NetBSD netbsd 3.1.1 NetBSD 3.1.1
>Organization:
Global Cybersoft Ltd
>Environment:
NetBSD netbsd 3.1.1 NetBSD 3.1.1 (GENERIC) #0: Sun Jul 1 08:48:35 PDT 2007 builds@wb42:/home/builds/ab/netbsd-3-1-1-RELEASE/i386/200707010939Z-obj/home/builds/ab/netbsd-3-1-1-RELEASE/src/sys/arch/i386/compile/GENERIC i386
>Description:
Hi staff
I have an issue which I think this error is due to OS NetBSD.
I have written a small application to create socket and send/receive data package between server and client. In this application, I use IPv6 address to create socket.
I have run server and client in two consoles on my computer which has OS NetBSD, I saw the error like that "Network is unreachable".
I also run this application on another computer that has OS Linux, the application can send and receive data successfully.
Maybe, I configured wrongly on the computer or OS NetBSD doesn't support.
Please help me fix this issue.
And here is my application
/*
* SERVER
*/
#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;
}
/*
* CLIENT
*/
#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_in their_addr;
char caddr[16];
int i=0;
if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // get the host info
herror("gethostbyname");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
//their_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(PORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct*/
if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr_in)) == -1) {
perror("connect");
exit(1);
}
/*if (connect(sockfd, (struct sockaddr *)&their_addr4, sizeof(struct sockaddr_in)) == -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;
}
Thanks and best regards
Nam Phan
>How-To-Repeat:
We use gcc compiler to compile application
Run them in two console
The bug always appears when client connects to server.
>Fix:
I really don't know
>Release-Note:
>Audit-Trail:
From: Arnaud Degroote <degroote@netbsd.org>
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
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 <stdio.h><br>#include <stdlib.h><br>#include <unistd.h><br>#include <errno.h><br>#include <string.h><br>#include <sys/types.h><br>#include <sys/socket.h><br>#include <netinet/in.h><br>#include <arpa/inet.h><br>#include <sys/wait.h><br>#include
<signal.h><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> while(waitpid(-1, NULL, WNOHANG) > 0);<br>}<br>int main(void)<br>{<br> int sockfd, new_fd; // listen on sock_fd, new connection on new_fd<br> struct sockaddr_in6 my_addr; // my address information<br> struct sockaddr_in6 *my_addrP = (struct sockaddr_in6*)&my_addr;<br> struct sockaddr_in6 their_addr; // connector’s address information<br> socklen_t sin_size;<br> char caddr[16];<br> int i=0;<br> struct sigaction sa;<br> int yes=1;<br> int len = 28;<br><br> if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {<br>
perror("socket");<br> exit(1);<br> }<br> <br> if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {<br> perror("setsockopt");<br> exit(1);<br> }<br> memset(&caddr, 0, 16);<br> for(i=0; i< 16; i++)<br> caddr[i] = 0;<br><br> my_addrP->sin6_family = AF_INET6; // host byte order<br> my_addrP->sin6_port = htons(MYPORT); // short, network byte order<br> memcpy((void *)&(my_addrP->sin6_addr), caddr, 16 );<br> if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)) == -1) {<br>
perror("bind");<br> exit(1);<br> }<br> if (listen(sockfd, BACKLOG) == -1) {<br> perror("listen");<br> exit(1);<br> }<br> sa.sa_handler = sigchld_handler; // reap all dead processes<br> sigemptyset(&sa.sa_mask);<br> sa.sa_flags = SA_RESTART;<br> if (sigaction(SIGCHLD, &sa, NULL) == -1) {<br> perror("sigaction");<br> exit(1);<br> }<br> while(1) { // main accept() loop<br> sin_size = sizeof(struct sockaddr_in6);<br> if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
{<br> perror("accept");<br> continue;<br> }<br> memcpy(caddr, (void *)&(their_addr.sin6_addr), 16 );<br> printf("server: got connection from: ");<br> for (i=0;i < 16; i++)<br> printf(" %d", caddr[i]);<br> printf("\n");<br> if (!fork()) { // this is the child process<br> close(sockfd); // child doesn’t need the listener<br> if (send(new_fd, "Hello, world!\n", 14, 0) ==
-1)<br> perror("send");<br> close(new_fd);<br> exit(0);<br> }<br> close(new_fd); // parent doesn’t need this<br> }<br> return 0;<br>}<br><br>And here is client's code<br><br>/*<br>** client.c -- a stream socket client demo<br>*/<br>#include <stdio.h><br>#include <stdlib.h><br>#include <unistd.h><br>#include <errno.h><br>#include <string.h><br>#include <netdb.h><br>#include <sys/types.h><br>#include <netinet/in.h><br>#include <sys/socket.h><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> int sockfd, numbytes;<br> char buf[MAXDATASIZE];<br> struct hostent *he;<br> struct sockaddr_in6 their_addr; // connector’s address information<br> char caddr[16];<br> int i=0;<br><br> if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {<br> perror("socket");<br> exit(1);<br> }<br><br> memset(&caddr, 0, 16);<br> their_addr.sin6_family = AF_INET6; // host byte order<br> their_addr.sin6_port = htons(PORT); // short, network byte order<br> <br> for (i =0; i<16; i++)<br> caddr[i] = 0;<br> memcpy((void *)&(their_addr.sin6_addr), caddr, sizeof(struct in6_addr)
);<br> <br> if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr_in6)) == -1) {<br> perror("connect");<br> exit(1);<br> }<br><br><br> if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {<br> perror("recv");<br> exit(1);<br> }<br> buf[numbytes] = '\0';<br> printf("Received: %s",buf);<br> close(sockfd);<br> return 0;<br>}<br><br><br>Please help me check.<br><br>Thanks<br><br>Best regards<br>Nam Phan<br><br><br><br>Arnaud Degroote <degroote@netbsd.org> 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> 
<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--
From: Arnaud Degroote <degroote@netbsd.org>
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: Mon, 17 Dec 2007 20:27:19 +0100
I've checked your new code. It is correct behaviour that you can't connect
with your client. If Linux lets you to do it, Linux must be fixed. RFC
2373 part 2.5.2 says the following :
The unspecified address must not be used as the destination address
of IPv6 packets or in IPv6 Routing Headers.
What you need to do is the same thing that for ipv4. You need to know
one of the adress of the host you want to join (localhost here). For
that purpose, you need to call getaddrinfo and look for AF_INET6 adress
(man getaddrinfo has some nice examples). With this adress, you can
connect to your server.
I hope it will help you.
Regards,
--
Arnaud Degroote
degroote@netbsd.org
State-Changed-From-To: open->closed
State-Changed-By: maxv@NetBSD.org
State-Changed-When: Sun, 25 Feb 2018 16:59:56 +0000
State-Changed-Why:
Close this PR. As said in the last answer, this behavior is intentional.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.