]> git.deb.at Git - pkg/netris.git/blobdiff - debian/patches/09_ipv6
Imported Debian patch 0.52-8
[pkg/netris.git] / debian / patches / 09_ipv6
diff --git a/debian/patches/09_ipv6 b/debian/patches/09_ipv6
new file mode 100644 (file)
index 0000000..6870768
--- /dev/null
@@ -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 <debian@gisladisker.se>
+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;