svnno****@sourc*****
svnno****@sourc*****
2011年 2月 24日 (木) 17:59:02 JST
Revision: 4335 http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=4335 Author: doda Date: 2011-02-24 17:59:02 +0900 (Thu, 24 Feb 2011) Log Message: ----------- ・IPv6対応 ・ダミーのアドレス情報を返す事によって、Proxy使用時はローカル側で名前解決を行わないようにした Modified Paths: -------------- trunk/TTProxy/ProxyWSockHook.h trunk/TTProxy/TTProxy.h trunk/TTProxy/TTProxy.vcproj -------------- next part -------------- Modified: trunk/TTProxy/ProxyWSockHook.h =================================================================== --- trunk/TTProxy/ProxyWSockHook.h 2011-02-24 03:38:07 UTC (rev 4334) +++ trunk/TTProxy/ProxyWSockHook.h 2011-02-24 08:59:02 UTC (rev 4335) @@ -49,7 +49,11 @@ private: struct DUMMYHOSTENT { struct hostent entry; + struct addrinfo ainfo[2]; in_addr addr; + struct in6_addr addr6; + struct sockaddr_in saddr; + struct sockaddr_in6 saddr6; char* addrlist[2]; char* alias; char hostname[1]; @@ -467,6 +471,7 @@ String realhost; unsigned short realport; in_addr addr; + struct in6_addr addr6; char* buffer; DWORD time; ConnectionInfo(ProxyInfo& proxy, String realhost):proxy(proxy), realhost(realhost), buffer(NULL) { @@ -475,8 +480,21 @@ delete[] buffer; } void fillBuffer(char* buffer, int bufferLength) { + fillBuffer(buffer, bufferLength, "ssh"); + } + void fillBuffer(char* buffer, int bufferLength, const char *portname) { + struct servent *sv; + int portnum = 0; + if (sv = getservbyname(portname, "tcp")) { + portnum = sv->s_port; + } + else { + portnum = atoi(portname); + } + memset(buffer, 0, bufferLength); DUMMYHOSTENT* dst = (DUMMYHOSTENT*) buffer; dst->addr = addr; + dst->addr6 = addr6; dst->addrlist[0] = (char*) &dst->addr; dst->addrlist[1] = NULL; dst->entry.h_addr_list = dst->addrlist; @@ -485,6 +503,35 @@ dst->entry.h_addrtype = AF_INET; dst->entry.h_length = sizeof (in_addr); dst->entry.h_name = dst->hostname; + + dst->saddr6.sin6_family = AF_INET6; + dst->saddr6.sin6_port = htons(portnum); + dst->saddr6.sin6_flowinfo = 0; + dst->saddr6.sin6_addr = dst->addr6; + dst->saddr6.sin6_scope_id = 0; + + dst->saddr.sin_family = AF_INET; + dst->saddr.sin_port = htons(portnum); + dst->saddr.sin_addr = dst->addr; + + dst->ainfo[0].ai_flags = 0; + dst->ainfo[0].ai_family = PF_INET6; + dst->ainfo[0].ai_socktype = SOCK_STREAM; + dst->ainfo[0].ai_protocol = IPPROTO_TCP; + dst->ainfo[0].ai_addrlen = sizeof(sockaddr_in6); + dst->ainfo[0].ai_canonname = NULL; + dst->ainfo[0].ai_addr = (struct sockaddr *)(&dst->saddr6); + dst->ainfo[0].ai_next = &dst->ainfo[1]; + + dst->ainfo[1].ai_flags = 0; + dst->ainfo[1].ai_family = PF_INET; + dst->ainfo[1].ai_socktype = SOCK_STREAM; + dst->ainfo[1].ai_protocol = IPPROTO_TCP; + dst->ainfo[1].ai_addrlen = sizeof(sockaddr_in); + dst->ainfo[1].ai_canonname = NULL; + dst->ainfo[1].ai_addr = (struct sockaddr *)(&dst->saddr); + dst->ainfo[1].ai_next = NULL; + strcpy_s(dst->hostname, bufferLength - sizeof (DUMMYHOSTENT), realhost); } }; @@ -539,6 +586,20 @@ return NULL; return get(addr.S_un.S_un_b.s_b4 - 1); } + ConnectionInfo* get(in6_addr addr) { + int i; + for (i=0; i<10; i++) { + if (addr.s6_addr[i] != 0) + return NULL; + } + if (addr.s6_addr[10] != 0xff || addr.s6_addr[11] != 0xff) + return NULL; + for (i=12; i<15; i++) { + if (addr.s6_addr[i] != 0) + return NULL; + } + return get(addr.s6_addr[15] - 1); + } ConnectionInfo* get(int index) { ::EnterCriticalSection(§ion); ConnectionInfo* info = 0 <= index && index < countof(list) ? (ConnectionInfo*) list[index] : NULL; @@ -590,6 +651,10 @@ table.put(url, info); ::LeaveCriticalSection(§ion); info->addr.s_addr = htonl(i + 1); + memset(info->addr6.s6_addr, 0, 16); + info->addr6.s6_addr[10] = 0xff; + info->addr6.s6_addr[11] = 0xff; + info->addr6.s6_addr[15] = i + 1; info->time = ::GetTickCount(); return info; @@ -1670,7 +1735,7 @@ Hooker::hook(module, (FARPROC) HOOKEDAPI_##APINAME, (FARPROC) instance().ORIG_##APINAME); #define LOADAPI(APINAME) \ - (FARPROC&) ORIG_##APINAME = ::GetProcAddress(wsock32, #APINAME); + (FARPROC&) ORIG_##APINAME = ::GetProcAddress(ws2_32, #APINAME); #define SETUP_HOOKAPI(APINAME) \ Hooker::setup((FARPROC) instance().ORIG_##APINAME, (FARPROC) HOOKEDAPI_##APINAME); @@ -1686,6 +1751,17 @@ holder = info; } } + else if (name->sa_family == AF_INET6) { + struct sockaddr_in6* in6 = (struct sockaddr_in6*) name; + info = connectioninfolist.get(in6->sin6_addr); + if (info == NULL && defaultProxy.type != ProxyInfo::TYPE_NONE) { + DWORD bufflen = 64; + char* buff = new char[64]; + WSAAddressToString((struct sockaddr*)name, sizeof(struct sockaddr_in6), NULL, buff, &bufflen); + info = new ConnectionInfo(defaultProxy, buff); + holder = info; + } + } if (info != NULL) { if (info->proxy.type == ProxyInfo::TYPE_NONE_FORCE) { info = NULL; @@ -1695,15 +1771,26 @@ hostname = info->realhost; }else{ info->realport = ntohs(((struct sockaddr_in*) name)->sin_port); - ((struct sockaddr_in*) name)->sin_port = htons(info->proxy.getPort()); + if (name->sa_family == AF_INET) { + ((struct sockaddr_in*) name)->sin_port = htons(info->proxy.getPort()); + } else { // AF_INET6 + ((struct sockaddr_in6*) name)->sin6_port = htons(info->proxy.getPort()); + } hostname = info->proxy.host; } - struct hostent* entry = ORIG_gethostbyname(hostname); - if (entry == NULL) { + struct addrinfo hints, *res; + memset(&hints, 0, sizeof hints); + hints.ai_family = name->sa_family; + if (getaddrinfo(hostname, NULL, &hints, &res) != 0) { WSASetLastError(WSAECONNREFUSED); return SOCKET_ERROR; } - memcpy(&((struct sockaddr_in*) name)->sin_addr, entry->h_addr_list[0], entry->h_length); + if (name->sa_family == AF_INET) { + memcpy(&((struct sockaddr_in*) name)->sin_addr, &((struct sockaddr_in*)res->ai_addr)->sin_addr, sizeof(struct in_addr)); + } else { // AF_INET6 + memcpy(&((struct sockaddr_in6*) name)->sin6_addr, &((struct sockaddr_in6*)res->ai_addr)->sin6_addr, sizeof(struct in6_addr)); + } + freeaddrinfo(res); } } int result = ORIG_connect(s, name, namelen); @@ -1937,6 +2024,45 @@ return handle; } + DECLARE_HOOKAPI(HANDLE, WSAAsyncGetAddrInfo, (HWND window, UINT message, const char* hostname, const char* portname, struct addrinfo* hints, struct addrinfo** res), (window, message, hostname, portname, hints, res)) { + ConnectionInfo* info = connectioninfolist.find(hostname); + if (info == NULL || info->proxy.type == ProxyInfo::TYPE_NONE_FORCE) { + return ORIG_WSAAsyncGetAddrInfo(window, message, hostname, portname, hints, res); + } + if (info->proxy.type == ProxyInfo::TYPE_SSL + || info->proxy.type == ProxyInfo::TYPE_HTTP_SSL + || info->proxy.type == ProxyInfo::TYPE_TELNET_SSL + || info->proxy.type == ProxyInfo::TYPE_SOCKS4_SSL + || info->proxy.type == ProxyInfo::TYPE_SOCKS5_SSL) { + if (!SSLSocket::isEnabled()) { + ::WSASetLastError(WSAHOST_NOT_FOUND); + return NULL; + } + } + HANDLE handle = connectioninfolist.getTask(info); + int bufferLength = sizeof (DUMMYHOSTENT) + strlen(hostname) + 1; + info->buffer = new char[bufferLength]; + info->fillBuffer(info->buffer, bufferLength, portname); + DUMMYHOSTENT* d = (DUMMYHOSTENT*)info->buffer; + *res = d->ainfo; + if (aicount < 256) { + ailist[aicount++] = d->ainfo; + } + ::PostMessage(window, message, (WPARAM) handle, MAKELPARAM(0, 0)); + return handle; + } + + DECLARE_HOOKAPI(void, freeaddrinfo, (struct addrinfo* ai), (ai)) { + int i; + for (i=0; i<aicount; i++) { + if (ailist[i] == ai) { + return; + } + } + ORIG_freeaddrinfo(ai); + return; + } + DECLARE_HOOKAPI(int, WSAAsyncSelect, (SOCKET s, HWND window, UINT message, long event), (s, window, message, event)) { asyncselectinfo.put(s, window, message, event); return ORIG_WSAAsyncSelect(s, window, message, event); @@ -1993,12 +2119,16 @@ HWND owner; HMODULE resource_module; AsyncSelectInfoTable asyncselectinfo; + struct addrinfo* ailist[256]; + int aicount; - ProxyWSockHook():shower(NULL), owner(NULL), resource_module(GetInstanceHandle()), timeout(0) { - HMODULE wsock32 = ::GetModuleHandle("wsock32.dll"); + ProxyWSockHook():shower(NULL), owner(NULL), resource_module(GetInstanceHandle()), timeout(0), aicount(0) { + HMODULE ws2_32 = ::GetModuleHandle("ws2_32.dll"); LOADAPI(connect) LOADAPI(gethostbyname) LOADAPI(WSAAsyncGetHostByName) + LOADAPI(WSAAsyncGetAddrInfo) + LOADAPI(freeaddrinfo) LOADAPI(WSAAsyncSelect) LOADAPI(WSACancelAsyncRequest) LOADAPI(send) @@ -2134,6 +2264,8 @@ SETUP_HOOKAPI(connect) SETUP_HOOKAPI(gethostbyname) SETUP_HOOKAPI(WSAAsyncGetHostByName) + SETUP_HOOKAPI(WSAAsyncGetAddrInfo) + SETUP_HOOKAPI(freeaddrinfo) SETUP_HOOKAPI(WSAAsyncSelect) SETUP_HOOKAPI(WSACancelAsyncRequest) SETUP_HOOKAPI(send) @@ -2146,6 +2278,8 @@ INSTALL_HOOKAPI(connect) INSTALL_HOOKAPI(gethostbyname) INSTALL_HOOKAPI(WSAAsyncGetHostByName) + INSTALL_HOOKAPI(WSAAsyncGetAddrInfo) + INSTALL_HOOKAPI(freeaddrinfo) INSTALL_HOOKAPI(WSAAsyncSelect) INSTALL_HOOKAPI(WSACancelAsyncRequest) INSTALL_HOOKAPI(send) @@ -2159,6 +2293,8 @@ UNINSTALL_HOOKAPI(connect) UNINSTALL_HOOKAPI(gethostbyname) UNINSTALL_HOOKAPI(WSAAsyncGetHostByName) + UNINSTALL_HOOKAPI(WSAAsyncGetAddrInfo) + UNINSTALL_HOOKAPI(freeaddrinfo) UNINSTALL_HOOKAPI(WSAAsyncSelect) UNINSTALL_HOOKAPI(WSACancelAsyncRequest) UNINSTALL_HOOKAPI(send) @@ -2170,7 +2306,7 @@ static String generateURL() { return instance().defaultProxy.generateURL(); } - static String parseURL(const char* url, BOOL prefix) { + static String parseURL(const char* url, BOOL prefix) { ProxyInfo proxy; String realhost = ProxyInfo::parse(url, proxy); if (realhost != NULL) { Modified: trunk/TTProxy/TTProxy.h =================================================================== --- trunk/TTProxy/TTProxy.h 2011-02-24 03:38:07 UTC (rev 4334) +++ trunk/TTProxy/TTProxy.h 2011-02-24 08:59:02 UTC (rev 4335) @@ -190,6 +190,8 @@ } (FARPROC&) *hooks->Pconnect = ProxyWSockHook::hook_connect((FARPROC) *hooks->Pconnect); (FARPROC&) *hooks->PWSAAsyncGetHostByName = ProxyWSockHook::hook_WSAAsyncGetHostByName((FARPROC) *hooks->PWSAAsyncGetHostByName); + (FARPROC&) *hooks->PWSAAsyncGetAddrInfo = ProxyWSockHook::hook_WSAAsyncGetAddrInfo((FARPROC) *hooks->PWSAAsyncGetAddrInfo); + (FARPROC&) *hooks->Pfreeaddrinfo = ProxyWSockHook::hook_freeaddrinfo((FARPROC) *hooks->Pfreeaddrinfo); (FARPROC&) *hooks->PWSAAsyncSelect = ProxyWSockHook::hook_WSAAsyncSelect((FARPROC) *hooks->PWSAAsyncSelect); (FARPROC&) *hooks->PWSACancelAsyncRequest = ProxyWSockHook::hook_WSACancelAsyncRequest((FARPROC) *hooks->PWSACancelAsyncRequest); } @@ -198,6 +200,8 @@ // unhook functions ProxyWSockHook::unhook_connect((FARPROC) *hooks->Pconnect); ProxyWSockHook::unhook_WSAAsyncGetHostByName((FARPROC) *hooks->PWSAAsyncGetHostByName); + ProxyWSockHook::unhook_WSAAsyncGetAddrInfo((FARPROC) *hooks->PWSAAsyncGetAddrInfo); + ProxyWSockHook::unhook_freeaddrinfo((FARPROC) *hooks->Pfreeaddrinfo); ProxyWSockHook::unhook_WSAAsyncSelect((FARPROC) *hooks->PWSAAsyncSelect); ProxyWSockHook::unhook_WSACancelAsyncRequest((FARPROC) *hooks->PWSACancelAsyncRequest); } Modified: trunk/TTProxy/TTProxy.vcproj =================================================================== --- trunk/TTProxy/TTProxy.vcproj 2011-02-24 03:38:07 UTC (rev 4334) +++ trunk/TTProxy/TTProxy.vcproj 2011-02-24 08:59:02 UTC (rev 4335) @@ -77,7 +77,7 @@ <Tool Name="VCLinkerTool" IgnoreImportLibrary="true" - AdditionalDependencies="wsock32.lib ttpcmn.lib" + AdditionalDependencies="ws2_32.lib ttpcmn.lib" OutputFile="Release/TTXProxy.dll" LinkIncremental="1" SuppressStartupBanner="true" @@ -180,7 +180,7 @@ <Tool Name="VCLinkerTool" IgnoreImportLibrary="true" - AdditionalDependencies="wsock32.lib ttpcmn.lib" + AdditionalDependencies="ws2_32.lib ttpcmn.lib" OutputFile="Debug/TTXProxy.dll" LinkIncremental="2" SuppressStartupBanner="true"