[ds6-devel] problem connecting to ipv6 sockets

Andreas Hofmann a.hofmann at fhbb.ch
Mon Jan 5 15:04:12 CET 2004


hi all,

i try to port some applications to ipv4/v6 and i try to do this as 
af-independent as possible. but i ran into problems by connecting to a ipv4/6 
daemon by connecting to it via a real ipv6 address. because i don't have a 
nameserver do do name-address lookups i used the local /etc/hosts file as 
follows:

----------------------
127.0.0.1                       localhost.fhbb.ch       localhost
fe80::20b:cdff:fef8:1c32        local6.fhbb.ch          local6
----------------------

i wrote two simple test applications to get on a clue for my problem. the one 
is a simple server that listens on port 20100 for ipv4 and ipv6 connections. 
the other is a simple clients which tries to establish a connection to that 
server and then receives a simple string from that server.

for testing i start the server on the same machine as the client. the eth0 
config of this machine is:
eth0      Protokoll:Ethernet  Hardware Adresse 00:0B:CD:F8:1C:32
          inet Adresse:10.1.93.108  Bcast:10.1.93.255  Maske:255.255.255.0
          inet6 Adresse: fe80::20b:cdff:fef8:1c32/64 
Gültigkeitsbereich:Verbindung
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:63004 errors:2786 dropped:0 overruns:0 frame:2
          TX packets:52194 errors:0 dropped:0 overruns:0 carrier:0
          Kollisionen:3073 Sendewarteschlangenlänge:100
          RX bytes:22941133 (21.8 Mb)  TX bytes:46248518 (44.1 Mb)
          Interrupt:20 Speicher:fc500000-fc510000

the client is started as follows: ip6client <host>

what i can not understand now is, that i can connect to the server by ipv4 
address 10.1.93.108. i can see then, that the server produces an ipv4 mapped 
ipv6 address (::ffff:10.1.93.108) and answers properly to the ipv4 client. i 
also can connect to the server by the ipv6 loopback address ::1 . but i can 
not connect neither by using the whole ipv6 address nor by the local6 entry 
in /etc/hosts.
summary:
ip6client localhost				---> works
ip6client 10.1.93.108				---> works
ip6client ::1					---> works !
ip6client local6					---> does not work
ip6client fe80::20b:cdff:fef8:1c32	---> does not work

the ipv6 config of my machines should work, because i can ping6 them from 
everywhere.

the sources of these two small apps are below. where is the mistake i made?
any ideas?

thanks in advance

andy.

p.s. : Linux version 2.4.21 / gcc version 3.2.2 / Mandrake Linux 9.1 3.2.2


------------------------IP6SERVER---------------------
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/resource.h>   /* getrusage() */
#include <sys/socket.h>	
#include <stdlib.h>         /* malloc(3) */

#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>


int main(int argc, char **argv){
	int 						sockfd,
							connfd,
							error;
	
	socklen_t					addrlen;
	
	struct sockaddr_storage		clientaddr;

	char						clienthost[100],
							clientservice[6];
													
	struct addrinfo				hints,
							*res,
							*ressave;
													
	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_PASSIVE;
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	sockfd = -1;
	
	error = getaddrinfo(NULL, "20100", &hints, &res);
	if(error){
		perror(gai_strerror(error));
		exit(-4);
	}
	else{
		ressave = res;
		while(res){
			sockfd=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
			if(!(sockfd < 0)){
				if(bind(sockfd, res->ai_addr, res->ai_addrlen) == 0){
					break;
				};
				close(sockfd);	
				sockfd = -1;
			}
			res = res->ai_next;
		};
		
		if(sockfd < 0){
			freeaddrinfo(ressave);
			fprintf(stderr, "socket error:: could not open socket\n");
			return -1;
		};
		listen(sockfd, 20);
		freeaddrinfo(ressave);
		
		for( ; ; ){					
			addrlen = sizeof(clientaddr);
			connfd = accept(sockfd, (struct sockaddr *) &clientaddr, &addrlen);
			
			if(connfd < 0){
				continue;
			};			
			getnameinfo((struct sockaddr *) &clientaddr, addrlen,
									clienthost, sizeof(clienthost), 
									clientservice, sizeof(clientservice), NI_NUMERICHOST);
			if(!(connfd < 0)){
				printf("Anfrage erhalten: Host=[%s] remote Port=[%s]\n",clienthost, 
clientservice);						
				char msg[200];
				sprintf(msg, "Hallo [%s], habe die Anfrage von deinem Port [%s] 
erhalten\n", 
							clienthost, clientservice);
				error = send(connfd, &msg, sizeof(msg), 0);
			};
		};
	};
  return 1;
};
------------------------------------------------------------

------------------------IP6CLIENT-----------------------
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>	
#include <stdlib.h>         /* malloc(3) */

#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>


int main(int argc, char **argv){
	int 						sockfd,
							connfd,
							error;
	
	int						addrlen;
	
	char						serverhost[1000],
							hostname[100];
	
	struct addrinfo				hints,
							*res,
							*ressave;

	strcpy(hostname, argv[1]);
	
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	error = getaddrinfo(hostname, "20100", &hints, &res);
	if(error < 0){
		fprintf(stderr, "getaddrinfo error:: [%s]\n", gai_strerror(error));
		exit(-4);
	}

	ressave = res;
	sockfd = -1;
	while(res){
		sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if(!(sockfd < 0)) {
			if(connect(sockfd, res->ai_addr, res->ai_addrlen)==0){
				printf("successfully connected::\n");
				break;
			};
			fprintf(stderr, "connect error:: [%s]\n", gai_strerror(errno));
			close(sockfd);	
			sockfd = -1;
		};
		res = res->ai_next;
	};

	freeaddrinfo(ressave);
	if(sockfd < 0){
		fprintf(stderr, "socket error:: could not open socket\n");
		return -1;
	};
	char buf[200];
	error = recv(sockfd, &buf, sizeof(buf), 0);
	if(error == -1){
		perror(gai_strerror(errno));
		exit(-4);	
	}
	printf("Meldung erhalten: %s\n", buf);
  return 1;
};

------------------------------------------------------------


More information about the ds6-devel mailing list