1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

After discussion with Jeroen Massar, here's a patch (mostly his)

which we think fixes the vista-ipv6 problem.

[originally from svn r7007]
This commit is contained in:
Simon Tatham 2006-12-23 09:04:27 +00:00
parent 8f458f7825
commit d86e01e836
3 changed files with 86 additions and 45 deletions

View File

@ -204,6 +204,9 @@ void log_eventlog(void *handle, const char *event)
fprintf(stderr, "%s\n", event);
fflush(stderr);
}
/* If we don't have a context yet (eg winnet.c init) then skip entirely */
if (!ctx)
return;
if (ctx->cfg.logtype != LGTYP_PACKETS &&
ctx->cfg.logtype != LGTYP_SSHRAW)
return;

View File

@ -294,8 +294,7 @@ void console_provide_logctx(void *logctx)
void logevent(void *frontend, const char *string)
{
if (console_logctx)
log_eventlog(console_logctx, string);
log_eventlog(console_logctx, string);
}
static void console_data_untrusted(HANDLE hout, const char *data, int len)

View File

@ -115,7 +115,7 @@ static int cmpforsearch(void *av, void *bv)
typedef rettype (WINAPI *t_##name) params; \
linkage t_##name p_##name
#define GET_WINSOCK_FUNCTION(module, name) \
p_##name = (t_##name) GetProcAddress(module, #name)
p_##name = module ? (t_##name) GetProcAddress(module, #name) : NULL
DECL_WINSOCK_FUNCTION(NOTHING, int, WSAAsyncSelect,
(SOCKET, HWND, u_int, long));
@ -166,34 +166,84 @@ DECL_WINSOCK_FUNCTION(static, int, getnameinfo,
(const struct sockaddr FAR * sa, socklen_t salen,
char FAR * host, size_t hostlen, char FAR * serv,
size_t servlen, int flags));
DECL_WINSOCK_FUNCTION(static, char *, gai_strerror, (int ecode));
DECL_WINSOCK_FUNCTION(static, int, WSAAddressToStringA,
(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFO,
LPTSTR, LPDWORD));
#endif
static HMODULE winsock_module;
static HMODULE winsock_module = NULL;
static WSADATA wsadata;
#ifndef NO_IPV6
static HMODULE wship6_module;
static HMODULE winsock2_module = NULL;
static HMODULE wship6_module = NULL;
#endif
int sk_startup(int hi, int lo)
{
WORD winsock_ver;
winsock_ver = MAKEWORD(hi, lo);
if (p_WSAStartup(winsock_ver, &wsadata)) {
return FALSE;
}
if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
return FALSE;
}
#ifdef NET_SETUP_DIAGNOSTICS
{
char buf[80];
sprintf(buf, "Using WinSock %d.%d", hi, lo);
logevent(NULL, buf);
}
#endif
return TRUE;
}
void sk_init(void)
{
WORD winsock_ver;
WSADATA wsadata;
winsock_ver = MAKEWORD(2, 0);
winsock_module = LoadLibrary("WS2_32.DLL");
winsock2_module = winsock_module = LoadLibrary("WS2_32.DLL");
if (!winsock_module) {
winsock_module = LoadLibrary("WSOCK32.DLL");
winsock_ver = MAKEWORD(1, 1);
}
if (!winsock_module)
fatalbox("Unable to load any WinSock library");
#ifndef NO_IPV6
wship6_module = LoadLibrary("wship6.dll");
if (wship6_module) {
GET_WINSOCK_FUNCTION(wship6_module, getaddrinfo);
GET_WINSOCK_FUNCTION(wship6_module, freeaddrinfo);
GET_WINSOCK_FUNCTION(wship6_module, getnameinfo);
/* Check if we have getaddrinfo in Winsock */
if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) {
#ifdef NET_SETUP_DIAGNOSTICS
logevent(NULL, "Native WinSock IPv6 support detected");
#endif
GET_WINSOCK_FUNCTION(winsock_module, getaddrinfo);
GET_WINSOCK_FUNCTION(winsock_module, freeaddrinfo);
GET_WINSOCK_FUNCTION(winsock_module, getnameinfo);
GET_WINSOCK_FUNCTION(winsock_module, gai_strerror);
} else {
/* Fall back to wship6.dll for Windows 2000 */
wship6_module = LoadLibrary("wship6.dll");
if (wship6_module) {
#ifdef NET_SETUP_DIAGNOSTICS
logevent(NULL, "WSH IPv6 support detected");
#endif
GET_WINSOCK_FUNCTION(wship6_module, getaddrinfo);
GET_WINSOCK_FUNCTION(wship6_module, freeaddrinfo);
GET_WINSOCK_FUNCTION(wship6_module, getnameinfo);
GET_WINSOCK_FUNCTION(wship6_module, gai_strerror);
} else {
#ifdef NET_SETUP_DIAGNOSTICS
logevent(NULL, "No IPv6 support detected");
#endif
}
}
GET_WINSOCK_FUNCTION(winsock2_module, WSAAddressToStringA);
#else
#ifdef NET_SETUP_DIAGNOSTICS
logevent(NULL, "PuTTY was built without IPv6 support");
#endif
#endif
GET_WINSOCK_FUNCTION(winsock_module, WSAAsyncSelect);
@ -223,14 +273,12 @@ void sk_init(void)
GET_WINSOCK_FUNCTION(winsock_module, recv);
GET_WINSOCK_FUNCTION(winsock_module, WSAIoctl);
if (p_WSAStartup(winsock_ver, &wsadata)) {
/* Try to get the best WinSock version we can get */
if (!sk_startup(2,2) &&
!sk_startup(2,0) &&
!sk_startup(1,1)) {
fatalbox("Unable to initialise WinSock");
}
if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
p_WSACleanup();
fatalbox("WinSock version is incompatible with %d.%d",
LOBYTE(winsock_ver), HIBYTE(winsock_ver));
}
sktree = newtree234(cmpfortree);
}
@ -367,6 +415,9 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
*/
if (p_getaddrinfo) {
struct addrinfo hints;
#ifdef NET_SETUP_DIAGNOSTICS
logevent(NULL, "Using getaddrinfo() for resolving");
#endif
memset(&hints, 0, sizeof(hints));
hints.ai_family = ret->family;
hints.ai_flags = AI_CANONNAME;
@ -376,6 +427,9 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
} else
#endif
{
#ifdef NET_SETUP_DIAGNOSTICS
logevent(NULL, "Using gethostbyname() for resolving");
#endif
/*
* Otherwise use the IPv4-only gethostbyname...
* (NOTE: we don't use gethostbyname as a fallback!)
@ -391,7 +445,7 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
err == WSAHOST_NOT_FOUND ? "Host does not exist" :
err == WSATRY_AGAIN ? "Host not found" :
#ifndef NO_IPV6
p_getaddrinfo ? "getaddrinfo: unknown error" :
p_getaddrinfo&&p_gai_strerror ? p_gai_strerror(err) :
#endif
"gethostbyname: unknown error");
} else {
@ -488,28 +542,11 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
{
#ifndef NO_IPV6
if (addr->ai) {
/* Try to get the WSAAddressToStringA() function from wship6.dll */
/* This way one doesn't need to have IPv6 dll's to use PuTTY and
* it will fallback to IPv4. */
typedef int (CALLBACK * FADDRTOSTR) (LPSOCKADDR lpsaAddress,
DWORD dwAddressLength,
LPWSAPROTOCOL_INFO lpProtocolInfo,
OUT LPTSTR lpszAddressString,
IN OUT LPDWORD lpdwAddressStringLength
);
FADDRTOSTR fAddrToStr = NULL;
HINSTANCE dllWS2 = LoadLibrary("ws2_32.dll");
if (dllWS2) {
fAddrToStr = (FADDRTOSTR)GetProcAddress(dllWS2,
"WSAAddressToStringA");
if (fAddrToStr) {
fAddrToStr(addr->ai->ai_addr, addr->ai->ai_addrlen,
NULL, buf, &buflen);
}
else strncpy(buf, "IPv6", buflen);
FreeLibrary(dllWS2);
}
if (p_WSAAddressToStringA) {
p_WSAAddressToStringA(addr->ai->ai_addr, addr->ai->ai_addrlen,
NULL, buf, &buflen);
} else
strncpy(buf, "IPv6", buflen);
} else
#endif
if (addr->family == AF_INET) {
@ -837,6 +874,8 @@ static DWORD try_connect(Actual_Socket sock)
a6.sin6_port = p_htons((short) sock->port);
a6.sin6_addr =
((struct sockaddr_in6 *) sock->addr->ai->ai_addr)->sin6_addr;
a6.sin6_flowinfo = ((struct sockaddr_in6 *) sock->addr->ai->ai_addr)->sin6_flowinfo;
a6.sin6_scope_id = ((struct sockaddr_in6 *) sock->addr->ai->ai_addr)->sin6_scope_id;
} else {
a.sin_family = AF_INET;
a.sin_addr =