Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #1239: socket.patch

File socket.patch, 23.4 kB (added by elite01, 12 years ago)
  • tango/net/InternetAddress.d

    old new  
    1212 
    1313module tango.net.InternetAddress; 
    1414 
    15 private import tango.net.Socket
     15private import tango.net.Socket : IPv4Address
    1616 
    17 /******************************************************************************* 
     17public alias IPv4Address InternetAddress; 
    1818 
    19  
    20 *******************************************************************************/ 
    21  
    22 class InternetAddress : IPv4Address 
    23 { 
    24         /*********************************************************************** 
    25  
    26                 useful for Datagrams 
    27  
    28         ***********************************************************************/ 
    29  
    30         this(){} 
    31  
    32         /*********************************************************************** 
    33  
    34                 -port- can be PORT_ANY 
    35                 -addr- is an IP address or host name 
    36  
    37         ***********************************************************************/ 
    38  
    39         this (char[] addr, int port = PORT_ANY) 
    40         { 
    41                 foreach (int i, char c; addr) 
    42                          if (c is ':') 
    43                             { 
    44                             port = parse (addr [i+1 .. $]); 
    45                             addr = addr [0 .. i]; 
    46                             break; 
    47                             } 
    48  
    49                 super (addr, cast(ushort) port); 
    50         } 
    51  
    52         /*********************************************************************** 
    53  
    54  
    55         ***********************************************************************/ 
    56  
    57         this (uint addr, ushort port) 
    58         { 
    59                 super (addr, port); 
    60         } 
    61  
    62  
    63         /*********************************************************************** 
    64  
    65  
    66         ***********************************************************************/ 
    67  
    68         this (ushort port) 
    69         { 
    70                 super (port); 
    71         } 
    72  
    73         /********************************************************************** 
    74  
    75         **********************************************************************/ 
    76  
    77         private static int parse (char[] s) 
    78         {        
    79                 int number; 
    80  
    81                 foreach (c; s) 
    82                          number = number * 10 + (c - '0'); 
    83  
    84                 return number; 
    85         } 
    86 } 
  • tango/net/SocketConduit.d

    old new  
    5858 
    5959        ***********************************************************************/ 
    6060 
     61        this (Address addr, bool connect = false) 
     62        { 
     63                this (addr.addressFamily, SocketType.STREAM, ProtocolType.TCP, true); 
     64                if(connect) this.connect(addr); 
     65        } 
     66 
     67        /*********************************************************************** 
     68         
     69                Create an Internet Socket with the provided characteristics 
     70 
     71        ***********************************************************************/ 
     72 
    6173        this (AddressFamily family, SocketType type, ProtocolType protocol) 
    6274        { 
    6375                this (family, type, protocol, true); 
  • tango/net/ServerSocket.d

    old new  
    5050 
    5151        ***********************************************************************/ 
    5252 
    53         this (InternetAddress addr, int backlog=32, bool reuse=false) 
     53        this (Address addr, int backlog=32, bool reuse=false) 
    5454        { 
    55                 socket_ = new Socket (AddressFamily.INET, SocketType.STREAM, ProtocolType.IP); 
     55                socket_ = new Socket (addr.addressFamily, SocketType.STREAM, ProtocolType.TCP); 
    5656                socket_.setAddressReuse(reuse).bind(addr).listen(backlog); 
    5757        } 
    5858 
  • tango/net/Socket.d

    old new  
    6464 
    6565private import  tango.time.Time; 
    6666 
     67private import  tango.stdc.stringz; 
     68 
    6769private import  tango.sys.Common; 
    6870 
    6971private import  tango.core.Exception; 
    7072 
     73private import  Integer = tango.text.convert.Integer; 
    7174 
     75version(Win32) 
     76{ 
     77        private import tango.sys.SharedLib; 
     78} 
     79 
    7280/******************************************************************************* 
    7381 
    7482 
    7583*******************************************************************************/ 
    7684 
    77 version=Tango; 
    78 version (Tango) 
    79 { 
    80         private char[] toString (char[] tmp, int i) 
    81         { 
    82                 int j = tmp.length; 
    83                 do { 
    84                    tmp[--j] = cast(char)(i % 10 + '0'); 
    85                    } while (i /= 10); 
    86  
    87                 return tmp [j .. $]; 
    88         } 
    89 } 
    90  
    9185version (linux) 
    9286         version = BsdSockets; 
    9387 
     
    160154                hostent* gethostbyname(char* name); 
    161155                hostent* gethostbyaddr(void* addr, int len, int type); 
    162156                int WSAGetLastError(); 
     157                 
     158                // those are dynamcally loaded to support older windows versions: 
     159                int function(char* node, char* service, addrinfo* hints, addrinfo** res) getaddrinfo; 
     160                void function(addrinfo *res) freeaddrinfo; 
     161                int function(sockaddr* sa, int salen, char* host, int hostlen, char* serv, int servlen, int flags) getnameinfo; 
     162                char* function(int errcode) gai_strerrorW; 
    163163                } 
     164                 
     165        char* gai_strerror(int errcode) { 
     166                return gai_strerrorA(errcode); // TODO: possibly gai_strerrorW? 
     167        } 
    164168 
    165169        static this() 
    166170        { 
    167171                WSADATA wd; 
    168172                if (WSAStartup (0x0101, &wd)) 
    169173                    throw new SocketException("Unable to initialize socket library"); 
     174                 
     175                //Stdout("Loading IPv6 support").newline; 
     176                //Stdout("Trying Ws2_32.dll (Windows XP or newer)...").newline; 
     177                auto lib = SharedLib.load("Ws2_32.dll"); 
     178                getnameinfo = cast(typeof(getnameinfo))lib.getSymbolNoThrow("getnameinfo"); 
     179                if(!getnameinfo) { 
     180                        lib.unload(); 
     181                        lib = SharedLib.load("Wship6.dll"); 
     182                        //Stdout("Trying Wship6.dll (Windows 2000 with IPv6 technology preview)...").newline; 
     183                } 
     184                getnameinfo = cast(typeof(getnameinfo))lib.getSymbolNoThrow("getnameinfo"); 
     185                if(!getnameinfo) { 
     186                       //Stdout("No IPv6 support at all :("); 
     187                       lib.unload(); 
     188                } 
     189                getaddrinfo = cast(typeof(getaddrinfo))lib.getSymbol("getaddrinfo"); 
     190                freeaddrinfo = cast(typeof(freaddrinfo))lib.getSymbol("getaddrinfo"); 
     191                gai_strerrorW = cast(typeof(gai_strerror))lib.getSymbol("gai_strerrorW"); 
    170192        } 
    171193 
    172194 
     
    214236                char* inet_ntoa(uint ina); 
    215237                hostent* gethostbyname(char* name); 
    216238                hostent* gethostbyaddr(void* addr, int len, int type); 
     239                int getaddrinfo(char* node, char* service, addrinfo* hints, addrinfo** res); 
     240                void freeaddrinfo(addrinfo *res); 
     241                int getnameinfo(sockaddr* sa, int salen, char* host, int hostlen, char* serv, int servlen, int flags); 
     242                char* gai_strerror(int errcode); 
    217243                } 
    218244        } 
    219245 
     
    254280} 
    255281 
    256282 
     283struct addrinfo { 
     284       int       ai_flags; 
     285       int       ai_family; 
     286       int       ai_socktype; 
     287       int       ai_protocol; 
     288       uint      ai_addrlen; 
     289       sockaddr* ai_addr; 
     290       char*     ai_canonname; 
     291       addrinfo* ai_next; 
     292} 
     293 
     294 
    257295struct hostent 
    258296{ 
    259297        char* h_name; 
     
    446484                TCP =     6, 
    447485                UDP =     17, 
    448486        } 
     487         
     488        enum AIFlags: int 
     489        { 
     490                PASSIVE = 0, // :TODO: 
     491                ADDRCONFIG = 0, // :TODO: 
     492        } 
    449493} 
    450494else version (darwin) 
    451495{ 
     
    506550                TCP =     6,  // appears to be correct 
    507551                UDP =     17, // appears to be correct 
    508552        } 
     553         
     554        enum AIFlags: int 
     555        { 
     556                PASSIVE = 0, // :TODO: 
     557                ADDRCONFIG = 0, // :TODO: 
     558        } 
    509559} 
    510560else version (freebsd) 
    511561{ 
     
    560610                TCP =     6,  // appears to be correct 
    561611                UDP =     17, // appears to be correct 
    562612        } 
     613         
     614        enum AIFlags: int 
     615        { 
     616                PASSIVE = 0, // :TODO: 
     617                ADDRCONFIG = 0, // :TODO: 
     618        } 
    563619} 
    564620else version (linux) 
    565621{ 
     
    624680                TCP =     6,  // appears to be correct 
    625681                UDP =     17, // appears to be correct 
    626682        } 
     683         
     684        enum AIFlags: int 
     685        { 
     686                PASSIVE = 0x0001, // :TODO: 
     687                ADDRCONFIG = 0x0020, 
     688        } 
    627689} // end versioning 
    628690 
    629691/*********************************************************************** 
     
    700762                INET =       2, 
    701763                IPX =        6, 
    702764                APPLETALK =  16, 
    703                 //INET6 =      ? // Need Windows XP ? 
     765                INET6 =      23 // Need Windows XP ? 
    704766        } 
    705767} 
    706768else version(BsdSockets) 
     
    714776                        INET =       2, 
    715777                        IPX =        23, 
    716778                        APPLETALK =  16, 
    717                         //INET6 =      10, 
     779                        INET6 =      10, 
    718780                } 
    719781        } 
    720782        else version (freebsd) 
     
    726788                        INET =       2, 
    727789                        IPX =        23, 
    728790                        APPLETALK =  16, 
    729                         //INET6 =      28, 
     791                        INET6 =      28, 
    730792                } 
    731793        }     
    732794        else version (linux) 
     
    738800                        INET =       2, 
    739801                        IPX =        4, 
    740802                        APPLETALK =  5, 
    741                         //INET6 =      10, 
     803                        INET6 =      10, 
    742804                } 
    743805        } // end version 
    744806} 
     
    921983                return this; 
    922984        } 
    923985 
    924  
    925986        /*********************************************************************** 
    926987 
    927988 
     
    11311192                        case AddressFamily.INET: 
    11321193                                result = new IPv4Address; 
    11331194                                break; 
     1195                         
     1196                        case AddressFamily.INET6: 
     1197                                result = new IPv6Address; 
     1198                                break; 
    11341199 
    11351200                        default: 
    11361201                                result = new UnknownAddress; 
     
    11841249                if(SOCKET_ERROR == .getpeername (sock, addr.name(), &nameLen)) 
    11851250                   exception ("Unable to obtain remote socket address: "); 
    11861251                assert (addr.addressFamily() == family); 
     1252                if(auto addr6 = cast(IPv6Address)addr) { 
     1253                        // check and decode IPv4 mapped addresses 
     1254                        if(addr6.sin.sin6_addr[0..12] == [cast(ubyte)0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]) { 
     1255                                auto addr4 = new IPv4Address(); 
     1256                                (cast(ubyte*)(&addr4.sin.sin_addr))[0..4] = addr6.sin.sin6_addr[12..16]; 
     1257                                addr4.sin.sin_port = addr6.sin.sin_port; 
     1258                                addr = addr4; 
     1259                        } 
     1260                } 
    11871261                return addr; 
    11881262        } 
    11891263 
     
    14691543 
    14701544 
    14711545 
     1546 
    14721547/******************************************************************************* 
    14731548 
    14741549 
     
    14781553{ 
    14791554        protected sockaddr* name(); 
    14801555        protected int nameLen(); 
    1481         AddressFamily addressFamily(); 
    1482         char[] toString(); 
    1483  
     1556         
    14841557        /*********************************************************************** 
    14851558 
    14861559                Tango: added this common function 
     
    14911564        { 
    14921565                throw new AddressException (msg); 
    14931566        } 
     1567         
     1568        static Address create(sockaddr* sa) { 
     1569                switch(sa.sa_family) { 
     1570                case AddressFamily.INET: 
     1571                    return new IPv4Address(sa); 
     1572                case AddressFamily.INET6: 
     1573                    return new IPv6Address(sa); 
     1574                default: 
     1575                    return null; 
     1576                } 
     1577        } 
    14941578 
     1579        public: 
     1580         
     1581        static Address resolve(char[] host, char[] service = null, AddressFamily af = AddressFamily.UNSPEC, AIFlags flags = cast(AIFlags)0) { 
     1582            return resolveAll(host, service, af, flags)[0]; 
     1583        } 
     1584         
     1585        static Address resolve(char[] host, ushort port, AddressFamily af = AddressFamily.UNSPEC, AIFlags flags = cast(AIFlags)0) { 
     1586            return resolveAll(host, port, af, flags)[0]; 
     1587        } 
     1588         
     1589        /*********************************************************************** 
     1590 
     1591 
     1592        ***********************************************************************/ 
     1593         
     1594        static Address[] resolveAll(char[] host, char[] service = null, AddressFamily af = AddressFamily.UNSPEC, AIFlags flags = cast(AIFlags)0) { 
     1595                Address[] retVal; 
     1596                version(Win32) { 
     1597                        if(!getaddrinfo) { // *old* windows, let's fall back to NetHost 
     1598                                uint port = cast(uint)Integer.toInt(service); 
     1599                                if(flags & AIFlags.PASSIVE && host is null) { 
     1600                                        return [new IPv4Address(0, port)]; 
     1601                                } 
     1602                                auto nh = new NetHost; 
     1603                                if(!nh.getHostByName(host)) { 
     1604                                        throw new AddressException("couldn't resolve " ~ host); 
     1605                                } 
     1606                                retVal.length = nh.addrList.length; 
     1607                                foreach(i, addr; nh.addrList) { 
     1608                                        retVal[i] = new IPv4Address(addr, port); 
     1609                                } 
     1610                                return retVal; 
     1611                        } 
     1612                } 
     1613                addrinfo* info; 
     1614                addrinfo hints; 
     1615                hints.ai_flags = flags; 
     1616                hints.ai_family = flags & AIFlags.PASSIVE && af == AddressFamily.UNSPEC ? AddressFamily.INET6 : af; 
     1617                hints.ai_socktype = SocketType.STREAM; 
     1618                int error = getaddrinfo(toStringz(host), service.length == 0 ? null : toStringz(service), &hints, &info); 
     1619                if(error != 0) { 
     1620                        throw new AddressException(fromStringz(gai_strerror(error))); 
     1621                } 
     1622                retVal.length = 16; 
     1623                retVal.length = 0; 
     1624                while(info) { 
     1625                        if(auto addr = create(info.ai_addr)) { 
     1626                                retVal ~= addr; 
     1627                        } 
     1628                        info = info.ai_next; 
     1629                } 
     1630                freeaddrinfo(info); 
     1631                return retVal; 
     1632        } 
     1633         
     1634        /*********************************************************************** 
     1635 
     1636 
     1637        ***********************************************************************/ 
     1638         
     1639        static Address[] resolveAll(char host[], ushort port, AddressFamily af = AddressFamily.UNSPEC, AIFlags flags = cast(AIFlags)0) { 
     1640                char[16] buf; 
     1641                return resolveAll(host, Integer.itoa(buf, port), af, flags); 
     1642        } 
     1643         
     1644        /*********************************************************************** 
     1645 
     1646 
     1647        ***********************************************************************/ 
     1648         
     1649        static Address passive(char[] service, AddressFamily af = AddressFamily.UNSPEC, AIFlags flags = cast(AIFlags)0) { 
     1650                return resolve(null, service, af, flags | AIFlags.PASSIVE); 
     1651        } 
     1652         
     1653        /*********************************************************************** 
     1654 
     1655 
     1656        ***********************************************************************/ 
     1657         
     1658        static Address passive(ushort port, AddressFamily af = AddressFamily.UNSPEC, AIFlags flags = cast(AIFlags)0) { 
     1659                return resolve(null, port, af, flags | AIFlags.PASSIVE); 
     1660        } 
     1661         
     1662        /*********************************************************************** 
     1663 
     1664 
     1665        ***********************************************************************/ 
     1666 
     1667        char[] toAddrString() 
     1668        { 
     1669                char[1025] host = void; 
     1670                getnameinfo(name, nameLen, host.ptr, host.length, null, 0, 1 /* NUMERIC */); 
     1671                return fromStringz(host.ptr); 
     1672        } 
     1673 
     1674        /*********************************************************************** 
     1675 
     1676 
     1677        ***********************************************************************/ 
     1678 
     1679        char[] toPortString() 
     1680        { 
     1681                char[32] service = void; 
     1682                getnameinfo(name, nameLen, null, 0, service.ptr, service.length, 0); 
     1683                foreach(i, c; service) { 
     1684                        if(c == '\0') { 
     1685                                return service[0..i].dup; 
     1686                        } 
     1687                } 
     1688        } 
     1689         
     1690 
     1691        /*********************************************************************** 
     1692 
     1693 
     1694        ***********************************************************************/ 
     1695 
     1696        char[] toString() 
     1697        { 
     1698                return toAddrString ~ ":" ~ toPortString; 
     1699        } 
     1700         
     1701         
     1702        /*********************************************************************** 
     1703 
     1704 
     1705        ***********************************************************************/ 
     1706 
     1707        AddressFamily addressFamily() 
     1708        { 
     1709                return cast(AddressFamily)name.sa_family; 
     1710        } 
     1711 
    14951712} 
    14961713 
    1497  
    14981714/******************************************************************************* 
    14991715 
    15001716 
     
    15861802                int i; 
    15871803                char* p; 
    15881804 
    1589                 name = .toString(he.h_name); 
     1805                name = fromStringz(he.h_name); 
    15901806 
    15911807                for(i = 0;; i++) 
    15921808                { 
     
    16001816                        aliases = new char[][i]; 
    16011817                        for(i = 0; i != aliases.length; i++) 
    16021818                        { 
    1603                                 aliases[i] = .toString(he.h_aliases[i]); 
     1819                                aliases[i] = fromStringz(he.h_aliases[i]); 
    16041820                        } 
    16051821                } 
    16061822                else 
     
    17751991        { 
    17761992                return sin.sizeof; 
    17771993        } 
     1994         
     1995        this(sockaddr* addr) 
     1996        { 
     1997                sin = *(cast(sockaddr_in*)addr); 
     1998        } 
    17781999 
    17792000 
    17802001        public: 
     
    18432064                        if(!ih.getHostByName(addr)) 
    18442065                          { 
    18452066                          char[16] tmp = void; 
    1846                           exception ("Unable to resolve "~addr~":"~.toString(tmp, port)); 
     2067                          exception ("Unable to resolve "~addr~":"~Integer.itoa(tmp, port)); 
    18472068                          } 
    18482069                        uiaddr = ih.addrList[0]; 
    18492070                } 
     
    18932114 
    18942115        char[] toPortString() 
    18952116        { 
    1896                 return .toString (_port, port()); 
     2117                return Integer.itoa (_port, port()); 
    18972118        } 
    18982119 
    18992120 
     
    19382159 
    19392160*******************************************************************************/ 
    19402161 
     2162class IPv6Address : Address 
     2163{ 
     2164        protected: 
     2165         
     2166        this() { 
     2167        } 
     2168 
     2169        /*********************************************************************** 
     2170         
     2171 
     2172        ***********************************************************************/ 
     2173 
     2174        struct sockaddr_in6 
     2175        { 
     2176                ushort sin_family; 
     2177                ushort sin_port; 
     2178                 
     2179                uint sin6_flowinfo; 
     2180                ubyte[16] sin6_addr; 
     2181                uint sin6_scope_id; 
     2182        } 
     2183         
     2184        sockaddr_in6 sin; 
     2185 
     2186        this(sockaddr* sa) { 
     2187                sin = *cast(sockaddr_in6*)sa; 
     2188        } 
     2189         
     2190        /*********************************************************************** 
     2191 
     2192 
     2193        ***********************************************************************/ 
     2194 
     2195        sockaddr* name() 
     2196        { 
     2197                return cast(sockaddr*)&sin; 
     2198        } 
     2199 
     2200 
     2201        /*********************************************************************** 
     2202 
     2203 
     2204        ***********************************************************************/ 
     2205 
     2206        int nameLen() 
     2207        { 
     2208                return sin.sizeof; 
     2209        } 
     2210 
     2211 
     2212        public: 
     2213 
     2214        const uint ADDR_ANY = 0; 
     2215        const uint ADDR_NONE = cast(uint)-1; 
     2216        const ushort PORT_ANY = 0; 
     2217 
     2218 
     2219        /*********************************************************************** 
     2220 
     2221 
     2222        ***********************************************************************/ 
     2223 
     2224        ushort port() 
     2225        { 
     2226                return ntohs(sin.sin_port); 
     2227        } 
     2228 
     2229 
     2230        /*********************************************************************** 
     2231 
     2232                -port- can be PORT_ANY 
     2233                -addr- is an IP address or host name 
     2234 
     2235        ***********************************************************************/ 
     2236 
     2237        this(char[] addr, int port = PORT_ANY) 
     2238        { 
     2239                version(Win32) { 
     2240                        if(!getaddrinfo) exception("This platform does not support IPv6."); 
     2241                } 
     2242                addrinfo* info; 
     2243                addrinfo hints; 
     2244                hints.ai_family = AddressFamily.INET6; 
     2245                int error = getaddrinfo((addr ~ '\0').ptr, null, &hints, &info); 
     2246                if(error != 0) { 
     2247                        exception(fromStringz(gai_strerror(error))); 
     2248                } 
     2249                sin = *cast(sockaddr_in6*)(info.ai_addr); 
     2250                sin.sin_port = htons(port); 
     2251        } 
     2252         
     2253         
     2254        /*********************************************************************** 
     2255 
     2256                -service- can be a port number or service name 
     2257                -addr- is an IP address or host name 
     2258 
     2259        ***********************************************************************/ 
     2260 
     2261        this(char[] addr, char[] service) 
     2262        { 
     2263                version(Win32) { 
     2264                        if(!getaddrinfo) exception("This platform does not support IPv6."); 
     2265                } 
     2266                addrinfo* info; 
     2267                addrinfo hints; 
     2268                hints.ai_family = AddressFamily.INET6; 
     2269                int error = getaddrinfo((addr ~ '\0').ptr, (service ~ '\0').ptr, &hints, &info); 
     2270                if(error != 0) { 
     2271                        exception(fromStringz(gai_strerror(error))); 
     2272                } 
     2273                sin = *cast(sockaddr_in6*)(info.ai_addr); 
     2274        } 
     2275 
     2276 
     2277        ubyte[] addr() 
     2278        { 
     2279                return sin.sin6_addr; 
     2280        } 
     2281 
     2282 
     2283        /*********************************************************************** 
     2284 
     2285 
     2286        ***********************************************************************/ 
     2287 
     2288        char[] toString() 
     2289        { 
     2290                return "[" ~ toAddrString ~ "]:" ~ toPortString; 
     2291        } 
     2292} 
     2293 
     2294/******************************************************************************* 
     2295 
     2296 
     2297*******************************************************************************/ 
     2298 
    19412299//a set of sockets for Socket.select() 
    19422300class SocketSet 
    19432301{