IPv6 patch, any testers?
Chris Niekel <[email protected]>
| Newsgroups | gmane.network.sn |
|---|---|
| Message-ID | <[email protected]> |
Hi,
My ISP made the newsserver visible with ipv6. Since sn didn't talk ipv6
yet, I created a patch for it. If anyone is willing to test it, I'd
appreciate it. The patch is against version 0.3.6.
All changes are to the sock_get function in get.c
Greetings,
Chris Niekel
--
I've been down so long, if I'd cheer up, I'd still be depressed.
- Lisa Simpson, Moanin' Lisa Blues.
sn-ipv6patch
(text/plain, 3.1 KB)
--- orig/get.c
+++ mod/get.c
@@ -14,6 +14,7 @@
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/stat.h>
@@ -21,6 +22,8 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
+#include <arpa/inet.h>
+
#include <netinet/in.h>
#if 0
/* XXX */
@@ -146,6 +149,9 @@
static int sock_get (char *server, int port, unsigned long *addrp, int *reused)
{
int i, sd;
+ struct addrinfo *results, *save;
+ int r;
+ int fl;
for (i = 0; i < nsocks; i++)
if (port == socks[i].port)
@@ -159,42 +165,70 @@
socks[i] = socks[nsocks];
return (sd);
}
+ sd = -1;
/* XXX We could be passing a socket that isn't fully connected yet. */
-
*reused = 0;
- if ((sd = socket(AF_INET, SOCK_STREAM, 0)) > -1)
+
+ r = getaddrinfo(server, NULL, NULL, &results);
+ if (r != 0)
{
- struct hostent *hp;
+ perror("getaddrinfo");
+ return (-1);
+ }
+ save = results;
- if ((hp = gethostbyname(server)))
+ while (results)
+ {
+ if (results->ai_family == AF_INET)
{
- struct sockaddr_in sa;
- int fl;
-
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
- sa.sin_addr.s_addr = *(unsigned long *) (hp->h_addr_list[0]);
- *addrp = ntohl(sa.sin_addr.s_addr);
- fl = fcntl(sd, F_GETFL);
- fcntl(sd, F_SETFL, fl | O_NONBLOCK);
- i = connect(sd, (struct sockaddr *) &sa, sizeof (sa));
- if (i > -1 || EINPROGRESS == errno)
+ struct sockaddr_in* a = (struct sockaddr_in*) results->ai_addr;
+ a->sin_port = htons(port);
+ }
+ else
+ {
+ if (results->ai_family == AF_INET6)
{
- fcntl(sd, F_SETFL, fl);
- fcntl(sd, F_SETFD, 1);
- return (sd);
+ struct sockaddr_in6* a = (struct sockaddr_in6*)
+ results -> ai_addr;
+ a->sin6_port = htons(port);
}
else
- log("sock_get:connect to %s:%m?", server);
+ {
+ log("sock_get:unknown protocol %d for %s",
+ results->ai_family, server);
+ }
}
- else
- log("sock_get:resolve \"%s\"", server);
- close(sd);
+ sd = socket(results -> ai_family, results->ai_socktype,
+ results -> ai_protocol);
+ if (sd >= 0)
+ break;
+
+ results = results -> ai_next;
+ }
+ if (sd < 0)
+ {
+ log("sock_get:socket to %s:%m", server);
+ return -1;
+ }
+
+ fl = fcntl(sd, F_GETFL);
+ fcntl(sd, F_SETFL, fl | O_NONBLOCK);
+
+ r = connect(sd, (struct sockaddr *) (results->ai_addr),
+ results->ai_addrlen);
+ freeaddrinfo(save);
+ if (r == 0 | errno == EINPROGRESS)
+ {
+ fcntl(sd, F_SETFL, fl);
+ fcntl(sd, F_SETFD, 1);
+ return sd;
}
else
- log("sock_get:socket to %s:%m", server);
- return (-1);
+ {
+ log("sock_get:connect to %s:%m?", server);
+ return -1;
+ }
}
static void sock_put (int sd, char *server, unsigned long addr, int port)
signature.asc
(application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.3 (GNU/Linux) iD8DBQE/v2fwgQ3S2XWlk0sRAubOAJ0WbSpTZLAKo+/X7swGBjzf1n5g4QCfQ8Qt Em066V7HFKWOz1wjuQ6IB1M= =dFv0 -----END PGP SIGNATURE-----