X-Git-Url: https://git.deb.at/w?a=blobdiff_plain;f=debian%2Fpatches%2F09_ipv6;fp=debian%2Fpatches%2F09_ipv6;h=6870768d86f1778b3c5c11ec12a2910edfac7622;hb=2ee4bc9605e8e54b9348a33dbac4f69afda46466;hp=0000000000000000000000000000000000000000;hpb=6b1f6251013f5cf018e37ec7e67fe629a7f34455;p=pkg%2Fnetris.git diff --git a/debian/patches/09_ipv6 b/debian/patches/09_ipv6 new file mode 100644 index 0000000..6870768 --- /dev/null +++ b/debian/patches/09_ipv6 @@ -0,0 +1,208 @@ +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 +Forwarded: no +Last-Updated: 2010-03-03 + +Index: netris-0.52/inet.c +=================================================================== +--- netris-0.52.orig/inet.c ++++ netris-0.52/inet.c +@@ -49,32 +49,60 @@ ExtFunc void InitNet(void) + + 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_INET6; ++ hints.ai_socktype = SOCK_STREAM; ++ hints.ai_flags = AI_PASSIVE; ++ ++ 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 @@ ExtFunc int WaitForConnection(char *port + (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 WaitForConnection(char *port + + 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_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;