Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/unix
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2004-12-30 19:45:11 +0300
committerSimon Tatham <anakin@pobox.com>2004-12-30 19:45:11 +0300
commit6daf6faede46bd8aa3a39cbe59d34c987b2ea114 (patch)
tree2cc3ffe7c6bebeebc922c07e7f7317a8c346ca78 /unix
parent7573f3733f3ba896018dc7b1cdd2b3a51b450096 (diff)
Integrate unfix.org's IPv6 patches up to level 10, with rather a lot
of polishing to bring them to what I think should in principle be release quality. Unlike the unfix.org patches themselves, this checkin enables IPv6 by default; if you want to leave it out, you have to build with COMPAT=-DNO_IPV6. I have tested that this compiles on Visual C 7 (so the nightlies _should_ acquire IPv6 support without missing a beat), but since I don't have IPv6 set up myself I haven't actually tested that it _works_. It still seems to make correct IPv4 connections, but that's all I've been able to verify for myself. Further testing is needed. [originally from svn r5047] [this svn revision also touched putty-wishlist]
Diffstat (limited to 'unix')
-rw-r--r--unix/uxnet.c63
-rw-r--r--unix/uxplink.c1
2 files changed, 42 insertions, 22 deletions
diff --git a/unix/uxnet.c b/unix/uxnet.c
index 08fb4e17..f1ef98b0 100644
--- a/unix/uxnet.c
+++ b/unix/uxnet.c
@@ -69,7 +69,7 @@ struct SockAddr_tag {
* in this SockAddr structure.
*/
int family;
-#ifdef IPV6
+#ifndef NO_IPV6
struct addrinfo *ai; /* Address IPv6 style. */
#else
unsigned long address; /* Address IPv4 style. */
@@ -125,10 +125,10 @@ const char *error_string(int error)
return strerror(error);
}
-SockAddr sk_namelookup(const char *host, char **canonicalname)
+SockAddr sk_namelookup(const char *host, char **canonicalname, int address_family)
{
SockAddr ret = snew(struct SockAddr_tag);
-#ifdef IPV6
+#ifndef NO_IPV6
struct addrinfo hints;
int err;
#else
@@ -143,9 +143,9 @@ SockAddr sk_namelookup(const char *host, char **canonicalname)
*realhost = '\0';
ret->error = NULL;
-#ifdef IPV6
+#ifndef NO_IPV6
hints.ai_flags = AI_CANONNAME;
- hints.ai_family = AF_UNSPEC;
+ hints.ai_family = address_family;
hints.ai_socktype = 0;
hints.ai_protocol = 0;
hints.ai_addrlen = 0;
@@ -219,7 +219,7 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
strncpy(buf, addr->hostname, buflen);
buf[buflen-1] = '\0';
} else {
-#ifdef IPV6
+#ifndef NO_IPV6
if (getnameinfo(addr->ai->ai_addr, addr->ai->ai_addrlen, buf, buflen,
NULL, 0, NI_NUMERICHOST) != 0) {
buf[0] = '\0';
@@ -246,7 +246,7 @@ int sk_address_is_local(SockAddr addr)
if (addr->family == AF_UNSPEC)
return 0; /* we don't know; assume not */
else {
-#ifdef IPV6
+#ifndef NO_IPV6
if (addr->family == AF_INET)
return ipv4_is_loopback(
((struct sockaddr_in *)addr->ai->ai_addr)->sin_addr);
@@ -267,7 +267,7 @@ int sk_address_is_local(SockAddr addr)
int sk_addrtype(SockAddr addr)
{
return (addr->family == AF_INET ? ADDRTYPE_IPV4 :
-#ifdef IPV6
+#ifndef NO_IPV6
addr->family == AF_INET6 ? ADDRTYPE_IPV6 :
#endif
ADDRTYPE_NAME);
@@ -276,7 +276,7 @@ int sk_addrtype(SockAddr addr)
void sk_addrcopy(SockAddr addr, char *buf)
{
-#ifdef IPV6
+#ifndef NO_IPV6
if (addr->family == AF_INET)
memcpy(buf, &((struct sockaddr_in *)addr->ai->ai_addr)->sin_addr,
sizeof(struct in_addr));
@@ -297,7 +297,7 @@ void sk_addrcopy(SockAddr addr, char *buf)
void sk_addr_free(SockAddr addr)
{
-#ifdef IPV6
+#ifndef NO_IPV6
if (addr->ai != NULL)
freeaddrinfo(addr->ai);
#endif
@@ -381,7 +381,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
int nodelay, int keepalive, Plug plug)
{
int s;
-#ifdef IPV6
+#ifndef NO_IPV6
struct sockaddr_in6 a6;
#endif
struct sockaddr_in a;
@@ -448,7 +448,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
/* BSD IP stacks need sockaddr_in zeroed before filling in */
memset(&a,'\0',sizeof(struct sockaddr_in));
-#ifdef IPV6
+#ifndef NO_IPV6
memset(&a6,'\0',sizeof(struct sockaddr_in6));
#endif
@@ -459,7 +459,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
while (1) {
int retcode;
-#ifdef IPV6
+#ifndef NO_IPV6
if (addr->family == AF_INET6) {
/* XXX use getaddrinfo to get a local address? */
a6.sin6_family = AF_INET6;
@@ -501,7 +501,7 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
* Connect to remote address.
*/
switch(addr->family) {
-#ifdef IPV6
+#ifndef NO_IPV6
case AF_INET:
/* XXX would be better to have got getaddrinfo() to fill in the port. */
((struct sockaddr_in *)addr->ai->ai_addr)->sin_port =
@@ -564,13 +564,10 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
return (Socket) ret;
}
-Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
+Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, int address_family)
{
int s;
-#ifdef IPV6
-#if 0
- struct sockaddr_in6 a6;
-#endif
+#ifndef NO_IPV6
struct addrinfo hints, *ai;
char portstr[6];
#endif
@@ -598,9 +595,31 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
ret->listener = 1;
/*
+ * Translate address_family from platform-independent constants
+ * into local reality.
+ */
+ address_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :
+ address_family == ADDRTYPE_IPV6 ? AF_INET6 : AF_UNSPEC);
+
+#ifndef NO_IPV6
+ /* Let's default to IPv6.
+ * If the stack doesn't support IPv6, we will fall back to IPv4. */
+ if (address_family == AF_UNSPEC) address_family = AF_INET6;
+#else
+ /* No other choice, default to IPv4 */
+ if (address_family == AF_UNSPEC) address_family = AF_INET;
+#endif
+
+ /*
* Open socket.
*/
- s = socket(AF_INET, SOCK_STREAM, 0);
+ s = socket(address_family, SOCK_STREAM, 0);
+
+ /* If the host doesn't support IPv6 try fallback to IPv4. */
+ if (s < 0 && address_family == AF_INET6) {
+ address_family = AF_INET;
+ s = socket(address_family, SOCK_STREAM, 0);
+ }
ret->s = s;
if (s < 0) {
@@ -614,12 +633,12 @@ Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
/* BSD IP stacks need sockaddr_in zeroed before filling in */
memset(&a,'\0',sizeof(struct sockaddr_in));
-#ifdef IPV6
+#ifndef NO_IPV6
#if 0
memset(&a6,'\0',sizeof(struct sockaddr_in6));
#endif
hints.ai_flags = AI_NUMERICHOST;
- hints.ai_family = AF_UNSPEC;
+ hints.ai_family = address_family;
hints.ai_socktype = 0;
hints.ai_protocol = 0;
hints.ai_addrlen = 0;
diff --git a/unix/uxplink.c b/unix/uxplink.c
index 6f17b5a2..fdc0f666 100644
--- a/unix/uxplink.c
+++ b/unix/uxplink.c
@@ -227,6 +227,7 @@ static void usage(void)
printf(" -A -a enable / disable agent forwarding\n");
printf(" -t -T enable / disable pty allocation\n");
printf(" -1 -2 force use of particular protocol version\n");
+ printf(" -4 -6 force use of IPv4 or IPv6\n");
printf(" -C enable compression\n");
printf(" -i key private key file for authentication\n");
printf(" -s remote command is an SSH subsystem (SSH-2 only)\n");