[Ttssh2-commit] [4335] ・IPv6対応

Back to archive index

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(&section);
             ConnectionInfo* info = 0 <= index && index < countof(list) ? (ConnectionInfo*) list[index] : NULL;
@@ -590,6 +651,10 @@
             table.put(url, info);
             ::LeaveCriticalSection(&section);
             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"



Ttssh2-commit メーリングリストの案内
Back to archive index