mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 01:02:24 +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:
parent
8f458f7825
commit
d86e01e836
@ -204,6 +204,9 @@ void log_eventlog(void *handle, const char *event)
|
|||||||
fprintf(stderr, "%s\n", event);
|
fprintf(stderr, "%s\n", event);
|
||||||
fflush(stderr);
|
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 &&
|
if (ctx->cfg.logtype != LGTYP_PACKETS &&
|
||||||
ctx->cfg.logtype != LGTYP_SSHRAW)
|
ctx->cfg.logtype != LGTYP_SSHRAW)
|
||||||
return;
|
return;
|
||||||
|
@ -294,8 +294,7 @@ void console_provide_logctx(void *logctx)
|
|||||||
|
|
||||||
void logevent(void *frontend, const char *string)
|
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)
|
static void console_data_untrusted(HANDLE hout, const char *data, int len)
|
||||||
|
125
windows/winnet.c
125
windows/winnet.c
@ -115,7 +115,7 @@ static int cmpforsearch(void *av, void *bv)
|
|||||||
typedef rettype (WINAPI *t_##name) params; \
|
typedef rettype (WINAPI *t_##name) params; \
|
||||||
linkage t_##name p_##name
|
linkage t_##name p_##name
|
||||||
#define GET_WINSOCK_FUNCTION(module, 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,
|
DECL_WINSOCK_FUNCTION(NOTHING, int, WSAAsyncSelect,
|
||||||
(SOCKET, HWND, u_int, long));
|
(SOCKET, HWND, u_int, long));
|
||||||
@ -166,34 +166,84 @@ DECL_WINSOCK_FUNCTION(static, int, getnameinfo,
|
|||||||
(const struct sockaddr FAR * sa, socklen_t salen,
|
(const struct sockaddr FAR * sa, socklen_t salen,
|
||||||
char FAR * host, size_t hostlen, char FAR * serv,
|
char FAR * host, size_t hostlen, char FAR * serv,
|
||||||
size_t servlen, int flags));
|
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
|
#endif
|
||||||
|
|
||||||
static HMODULE winsock_module;
|
static HMODULE winsock_module = NULL;
|
||||||
|
static WSADATA wsadata;
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
static HMODULE wship6_module;
|
static HMODULE winsock2_module = NULL;
|
||||||
|
static HMODULE wship6_module = NULL;
|
||||||
#endif
|
#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)
|
void sk_init(void)
|
||||||
{
|
{
|
||||||
WORD winsock_ver;
|
winsock2_module = winsock_module = LoadLibrary("WS2_32.DLL");
|
||||||
WSADATA wsadata;
|
|
||||||
|
|
||||||
winsock_ver = MAKEWORD(2, 0);
|
|
||||||
winsock_module = LoadLibrary("WS2_32.DLL");
|
|
||||||
if (!winsock_module) {
|
if (!winsock_module) {
|
||||||
winsock_module = LoadLibrary("WSOCK32.DLL");
|
winsock_module = LoadLibrary("WSOCK32.DLL");
|
||||||
winsock_ver = MAKEWORD(1, 1);
|
|
||||||
}
|
}
|
||||||
if (!winsock_module)
|
if (!winsock_module)
|
||||||
fatalbox("Unable to load any WinSock library");
|
fatalbox("Unable to load any WinSock library");
|
||||||
|
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
wship6_module = LoadLibrary("wship6.dll");
|
/* Check if we have getaddrinfo in Winsock */
|
||||||
if (wship6_module) {
|
if (GetProcAddress(winsock_module, "getaddrinfo") != NULL) {
|
||||||
GET_WINSOCK_FUNCTION(wship6_module, getaddrinfo);
|
#ifdef NET_SETUP_DIAGNOSTICS
|
||||||
GET_WINSOCK_FUNCTION(wship6_module, freeaddrinfo);
|
logevent(NULL, "Native WinSock IPv6 support detected");
|
||||||
GET_WINSOCK_FUNCTION(wship6_module, getnameinfo);
|
#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
|
#endif
|
||||||
|
|
||||||
GET_WINSOCK_FUNCTION(winsock_module, WSAAsyncSelect);
|
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, recv);
|
||||||
GET_WINSOCK_FUNCTION(winsock_module, WSAIoctl);
|
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");
|
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);
|
sktree = newtree234(cmpfortree);
|
||||||
}
|
}
|
||||||
@ -367,6 +415,9 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
|
|||||||
*/
|
*/
|
||||||
if (p_getaddrinfo) {
|
if (p_getaddrinfo) {
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
|
#ifdef NET_SETUP_DIAGNOSTICS
|
||||||
|
logevent(NULL, "Using getaddrinfo() for resolving");
|
||||||
|
#endif
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_family = ret->family;
|
hints.ai_family = ret->family;
|
||||||
hints.ai_flags = AI_CANONNAME;
|
hints.ai_flags = AI_CANONNAME;
|
||||||
@ -376,6 +427,9 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifdef NET_SETUP_DIAGNOSTICS
|
||||||
|
logevent(NULL, "Using gethostbyname() for resolving");
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Otherwise use the IPv4-only gethostbyname...
|
* Otherwise use the IPv4-only gethostbyname...
|
||||||
* (NOTE: we don't use gethostbyname as a fallback!)
|
* (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 == WSAHOST_NOT_FOUND ? "Host does not exist" :
|
||||||
err == WSATRY_AGAIN ? "Host not found" :
|
err == WSATRY_AGAIN ? "Host not found" :
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
p_getaddrinfo ? "getaddrinfo: unknown error" :
|
p_getaddrinfo&&p_gai_strerror ? p_gai_strerror(err) :
|
||||||
#endif
|
#endif
|
||||||
"gethostbyname: unknown error");
|
"gethostbyname: unknown error");
|
||||||
} else {
|
} else {
|
||||||
@ -488,28 +542,11 @@ void sk_getaddr(SockAddr addr, char *buf, int buflen)
|
|||||||
{
|
{
|
||||||
#ifndef NO_IPV6
|
#ifndef NO_IPV6
|
||||||
if (addr->ai) {
|
if (addr->ai) {
|
||||||
/* Try to get the WSAAddressToStringA() function from wship6.dll */
|
if (p_WSAAddressToStringA) {
|
||||||
/* This way one doesn't need to have IPv6 dll's to use PuTTY and
|
p_WSAAddressToStringA(addr->ai->ai_addr, addr->ai->ai_addrlen,
|
||||||
* it will fallback to IPv4. */
|
NULL, buf, &buflen);
|
||||||
typedef int (CALLBACK * FADDRTOSTR) (LPSOCKADDR lpsaAddress,
|
} else
|
||||||
DWORD dwAddressLength,
|
strncpy(buf, "IPv6", buflen);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (addr->family == AF_INET) {
|
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_port = p_htons((short) sock->port);
|
||||||
a6.sin6_addr =
|
a6.sin6_addr =
|
||||||
((struct sockaddr_in6 *) sock->addr->ai->ai_addr)->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 {
|
} else {
|
||||||
a.sin_family = AF_INET;
|
a.sin_family = AF_INET;
|
||||||
a.sin_addr =
|
a.sin_addr =
|
||||||
|
Loading…
Reference in New Issue
Block a user