[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Patch to make Netris IPv6-enabled



package netris
tags 561977 + patch
thanks

I submit an NMU-formed difference file that adds capability
to Netris for using IPv6 as well as IPv4. It is a Quilt patch
that implements this capability.

-- 
Mats Erik Andersson, fil. dr
<debian@gisladisker.se>

Abbonerar på: debian-mentors, debian-devel-games, debian-perl, debian-ipv6
diff -u netris-0.52/debian/changelog netris-0.52/debian/changelog
--- netris-0.52/debian/changelog
+++ netris-0.52/debian/changelog
@@ -1,3 +1,11 @@
+netris (0.52-7.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Implement support for IPv6:
+    - debian/patches/09_inet.c-ipv6
+
+ -- Mats Erik Andersson <mats.andersson@gisladisker.se>  Wed, 03 Mar 2010 11:33:17 +0100
+
 netris (0.52-7) unstable; urgency=low
 
   * The "once every release" release.
diff -u netris-0.52/debian/patches/series netris-0.52/debian/patches/series
--- netris-0.52/debian/patches/series
+++ netris-0.52/debian/patches/series
@@ -8,0 +9 @@
+09_inet.c-ipv6
only in patch2:
unchanged:
--- netris-0.52.orig/debian/patches/09_inet.c-ipv6
+++ netris-0.52/debian/patches/09_inet.c-ipv6
@@ -0,0 +1,205 @@
+Description: Implement capability for IPv6.
+ Migration to 'getaddrinfo()' and 'struct sockaddr_storage'
+ make both address families AF_INET and AF_INET6 viable.
+ .
+ The preferred form of a port is as a string value in getaddrinfo(),
+ so named ports are no possible, alongside numerical ports.
+ .
+ The goto statement is left because the previous code enforced
+ a similar construct. It should really be removed.
+Author: Mats Erik Andersson <debian@gisladisker.se>
+Forwarded: no
+Last-Updated: 2010-03-03
+--- netris-0.52/inet.c.debian
++++ netris-0.52/inet.c
+@@ -49,32 +49,60 @@
+ 
+ ExtFunc int WaitForConnection(char *portStr)
+ {
+-	struct sockaddr_in addr;
+-	struct hostent *host;
+-	int sockListen;
++	struct sockaddr_storage addr;
++	struct sockaddr_in *sa4 = (struct sockaddr_in *) &addr;
++	struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &addr;
++	struct hostent *host = NULL;
++	struct addrinfo hints, *ai, *aiptr;
++	char portStrDef[12];
++	int sockListen, status;
+ 	socklen_t addrLen;
+-	short port;
+ 	int val1;
+ 	struct linger val2;
+ 
+-	if (portStr)
+-		port = atoi(portStr);	/* XXX Error checking */
+-	else
+-		port = DEFAULT_PORT;
+-	memset(&addr, 0, sizeof(addr));
+-	addr.sin_family = AF_INET;
+-	addr.sin_addr.s_addr = htonl(INADDR_ANY);
+-	addr.sin_port = htons(port);
+-	sockListen = socket(AF_INET, SOCK_STREAM, 0);
+-	if (sockListen < 0)
++	if (!portStr || !strlen(portStr)) {
++		snprintf(portStrDef, sizeof(portStrDef), "%u", DEFAULT_PORT);
++		portStr = portStrDef;
++	}
++	/* XXX Error checking of port string. */
++
++	memset(&hints, 0, sizeof(hints));
++	hints.ai_family = AF_UNSPEC;
++	hints.ai_socktype = SOCK_STREAM;
++	hints.ai_flags = AI_PASSIVE | AI_V4MAPPED | AI_ADDRCONFIG;
++
++	if ( (status = getaddrinfo(NULL, portStr, &hints, &ai)) ) {
++		fprintf(stderr, "getaddrinfo() failed: %s\n",
++				gai_strerror(status));
++		die("getaddrinfo");
++	}
++
++	for (aiptr = ai; aiptr; aiptr = aiptr->ai_next) {
++		if ( (sockListen = socket(aiptr->ai_family,
++						aiptr->ai_socktype,
++						aiptr->ai_protocol))
++				< 0 )
++			continue;
++
++		val1 = 1;
++		setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR,
++				(void *)&val1, sizeof(val1));
++		val1 = 0;
++		setsockopt(sockListen, IPPROTO_IPV6, IPV6_V6ONLY,
++				(void *)&val1, sizeof(val1));
++
++		if ( bind(sockListen, aiptr->ai_addr, aiptr->ai_addrlen)
++				== 0 )
++			if ( listen(sockListen, 1) >= 0 )
++				break;
++
++		close(sockListen);
++	}
++
++	freeaddrinfo(ai);
++	if (aiptr == NULL)
+ 		die("socket");
+-	val1 = 1;
+-	setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR,
+-			(void *)&val1, sizeof(val1));
+-	if (bind(sockListen, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+-		die("bind");
+-	if (listen(sockListen, 1) < 0)
+-		die("listen");
++
+ 	addrLen = sizeof(addr);
+ 	sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen);
+ 	if (sock < 0)
+@@ -86,13 +114,18 @@
+ 			(void *)&val2, sizeof(val2));
+ 	netGen.fd = sock;
+ 	strcpy(opponentHost, "???");
+-	if (addr.sin_family == AF_INET) {
+-		host = gethostbyaddr((void *)&addr.sin_addr,
+-				sizeof(struct in_addr), AF_INET);
+-		if (host) {
+-			strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
+-			opponentHost[sizeof(opponentHost)-1] = 0;
+-		}
++	switch (addr.ss_family) {
++		case AF_INET6:
++			host = gethostbyaddr((void *)&sa6->sin6_addr,
++				sizeof(struct in6_addr), addr.ss_family);
++			break;
++		case AF_INET:
++			host = gethostbyaddr((void *)&sa4->sin_addr,
++				sizeof(struct in_addr), addr.ss_family);
++	}
++	if (host) {
++		strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
++		opponentHost[sizeof(opponentHost)-1] = 0;
+ 	}
+ 	AddEventGen(&netGen);
+ 	isServer = 1;
+@@ -101,36 +134,54 @@
+ 
+ ExtFunc int InitiateConnection(char *hostStr, char *portStr)
+ {
+-	struct sockaddr_in addr;
+-	struct hostent *host;
+-	short port;
+-	int mySock;
+-
+-	if (portStr)
+-		port = atoi(portStr);	/* XXX Error checking */
+-	else
+-		port = DEFAULT_PORT;
+-	host = gethostbyname(hostStr);
+-	if (!host)
+-		die("gethostbyname");
+-	assert(host->h_addrtype == AF_INET);
+-	strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
+-	opponentHost[sizeof(opponentHost)-1] = 0;
+- again:
+-	memset(&addr, 0, sizeof(addr));
+-	addr.sin_family = host->h_addrtype;
+-	memcpy(&addr.sin_addr, host->h_addr, host->h_length);
+-	addr.sin_port = htons(port);
+-	mySock = socket(AF_INET, SOCK_STREAM, 0);
+-	if (mySock < 0)
+-		die("socket");
+-	if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+-		if (errno != ECONNREFUSED)
+-			die("connect");
++	struct addrinfo hints, *ai, *aiptr;
++	char portStrDef[12];
++	int mySock, status;
++
++	if (!portStr || !strlen(portStr)) {
++		snprintf(portStrDef, sizeof(portStrDef), "%u", DEFAULT_PORT);
++		portStr = portStrDef;
++	}
++	/* XXX Error checking of port string. */
++
++	memset(&hints, 0, sizeof(hints));
++	hints.ai_family = AF_UNSPEC;
++	hints.ai_socktype = SOCK_STREAM;
++	hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME;
++
++	if ( (status = getaddrinfo(hostStr, portStr, &hints, &ai)) ) {
++		fprintf(stderr, "getaddrinfo() failed: %s\n",
++				gai_strerror(status));
++		die("getaddrinfo");
++	}
++
++	for (aiptr = ai; aiptr; aiptr = aiptr->ai_next) {
++again:
++		if ( (mySock = socket(aiptr->ai_family, aiptr->ai_socktype,
++						aiptr->ai_protocol))
++				< 0 )
++			continue;
++		while ( (status = connect(mySock, aiptr->ai_addr,
++						aiptr->ai_addrlen)) < 0
++				&& errno == ECONNREFUSED ) {
++			close(mySock);
++			sleep(1);
++			goto again;
++		}
++		if (status >= 0)			
++			break;
++		/* Failure to connect. */
+ 		close(mySock);
+-		sleep(1);
+-		goto again;
+ 	}
++
++	if (aiptr == NULL) {
++		freeaddrinfo(ai);
++		die("socket/connect");
++	}
++
++	strncpy(opponentHost, aiptr->ai_canonname, sizeof(opponentHost)-1);
++	opponentHost[sizeof(opponentHost)-1] = 0;
++	freeaddrinfo(ai);
+ 	netGen.fd = sock = mySock;
+ 	AddEventGen(&netGen);
+ 	return 0;

Attachment: signature.asc
Description: Digital signature


Reply to: