00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 module mango.io.Socket;
00070
00071 private import mango.utils.Text;
00072
00073 private import mango.base.System;
00074
00075 private import mango.io.Resource,
00076 mango.io.Exception;
00077
00078 private import mango.io.model.IBuffer;
00079
00080
00081
00082
00083
00084
00085 version(linux)
00086 {
00087 version = BsdSockets;
00088 }
00089
00090 version(Win32)
00091 {
00092 typedef uint socket_t = ~0;
00093 }
00094 else version(BsdSockets)
00095 {
00096 typedef int socket_t = -1;
00097 }
00098 else
00099 {
00100 static assert(0);
00101 }
00102
00103 private:
00104
00105 const socket_t INVALID_SOCKET = socket_t.init;
00106 const int SOCKET_ERROR = -1;
00107
00108
00109
00110
00111
00112
00113
00114
00115 static this()
00116 {
00117 version(Win32)
00118 {
00119 WSADATA wd;
00120 if(WSAStartup(0x0101, &wd))
00121 throw new SocketException("Unable to initialize socket library.");
00122 }
00123 }
00124
00125
00126 static ~this()
00127 {
00128 Socket.cancelAll (true);
00129 version(Win32)
00130 {
00131 WSACleanup();
00132 }
00133 }
00134
00135
00136
00137 private import std.stdint;
00138
00139
00140
00141
00142
00143
00144
00145 version(Win32)
00146 {
00147 import std.c.windows.windows;
00148
00149
00150
00151 extern(Windows)
00152 {
00153 const int WSADESCRIPTION_LEN = 256;
00154 const int WSASYS_STATUS_LEN = 128;
00155
00156 struct WSADATA
00157 {
00158 WORD wVersion;
00159 WORD wHighVersion;
00160 char szDescription[WSADESCRIPTION_LEN+1];
00161 char szSystemStatus[WSASYS_STATUS_LEN+1];
00162 ushort iMaxSockets;
00163 ushort iMaxUdpDg;
00164 char* lpVendorInfo;
00165 }
00166 alias WSADATA* LPWSADATA;
00167
00168
00169 const int IOCPARM_MASK = 0x7f;
00170 const int IOC_IN = cast(int)0x80000000;
00171 const int FIONBIO = IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126;
00172 const int SOL_SOCKET = 0xFFFF;
00173 const int SO_TYPE = 0x1008;
00174
00175
00176 int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
00177 int WSACleanup();
00178 socket_t socket(int af, int type, int protocol);
00179 int ioctlsocket(socket_t s, int cmd, uint* argp);
00180 int getsockopt(socket_t s, int level, int optname, char* optval, int* optlen);
00181 uint inet_addr(char* cp);
00182 int bind(socket_t s, sockaddr* name, int namelen);
00183 int connect(socket_t s, sockaddr* name, int namelen);
00184 int listen(socket_t s, int backlog);
00185 socket_t accept(socket_t s, sockaddr* addr, int* addrlen);
00186 int closesocket(socket_t s);
00187 int shutdown(socket_t s, int how);
00188 int getpeername(socket_t s, sockaddr* name, int* namelen);
00189 int getsockname(socket_t s, sockaddr* name, int* namelen);
00190 int send(socket_t s, void* buf, int len, int flags);
00191 int sendto(socket_t s, void* buf, int len, int flags, sockaddr* to, int tolen);
00192 int recv(socket_t s, void* buf, int len, int flags);
00193 int recvfrom(socket_t s, void* buf, int len, int flags, sockaddr* from, int* fromlen);
00194 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
00195
00196 int getsockopt(socket_t s, int level, int optname, void* optval, int* optlen);
00197 int setsockopt(socket_t s, int level, int optname, void* optval, int optlen);
00198 int gethostname(void* namebuffer, int buflen);
00199 char* inet_ntoa(uint ina);
00200 hostent* gethostbyname(char* name);
00201 hostent* gethostbyaddr(void* addr, int len, int type);
00202
00203
00204 const int WSAEWOULDBLOCK = 10035;
00205 const int WSAEINTR = 10004;
00206
00207 int WSAGetLastError();
00208 }
00209 }
00210 else version(BsdSockets)
00211 {
00212 extern(C)
00213 {
00214 const int F_GETFL = 3;
00215 const int F_SETFL = 4;
00216 const int O_NONBLOCK = 0x4000;
00217 const int SOL_SOCKET = 0xFFFF;
00218 const int SO_TYPE = 0x1008;
00219
00220
00221 socket_t socket(int af, int type, int protocol);
00222 int fcntl(socket_t s, int f, ...);
00223 int getsockopt(socket_t s, int level, int optname, char* optval, int* optlen);
00224 uint inet_addr(char* cp);
00225 int bind(socket_t s, sockaddr* name, int namelen);
00226 int connect(socket_t s, sockaddr* name, int namelen);
00227 int listen(socket_t s, int backlog);
00228 socket_t accept(socket_t s, sockaddr* addr, int* addrlen);
00229 int close(socket_t s);
00230 int shutdown(socket_t s, int how);
00231 int getpeername(socket_t s, sockaddr* name, int* namelen);
00232 int getsockname(socket_t s, sockaddr* name, int* namelen);
00233 int send(socket_t s, void* buf, int len, int flags);
00234 int sendto(socket_t s, void* buf, int len, int flags, sockaddr* to, int tolen);
00235 int recv(socket_t s, void* buf, int len, int flags);
00236 int recvfrom(socket_t s, void* buf, int len, int flags, sockaddr* from, int* fromlen);
00237 int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* errorfds, timeval* timeout);
00238 int getsockopt(socket_t s, int level, int optname, void* optval, int* optlen);
00239 int setsockopt(socket_t s, int level, int optname, void* optval, int optlen);
00240 int gethostname(void* namebuffer, int buflen);
00241 char* inet_ntoa(uint ina);
00242 hostent* gethostbyname(char* name);
00243 hostent* gethostbyaddr(void* addr, int len, int type);
00244
00245
00246 const int EINTR = 4;
00247 version(linux)
00248 {
00249 const int EINPROGRESS = 115;
00250
00251
00252 import std.c.linux.linux;
00253 }
00254 else
00255 {
00256 static assert(0);
00257 }
00258 }
00259 }
00260
00261 /+
00262 #ifdef INCLUDE_ALL_FOR_DOXYGEN
00263 +/
00264
00265
00266
00267
00268
00269
00270
00271 struct timeval
00272 {
00273 int tv_sec;
00274 int tv_usec;
00275 }
00276
00277
00278
00279 struct fd_set
00280 {
00281 }
00282
00283
00284 struct sockaddr
00285 {
00286 ushort sa_family;
00287 char[14] sa_data = [0];
00288 }
00289
00290
00291 struct hostent
00292 {
00293 char* h_name;
00294 char** h_aliases;
00295 version(Win32)
00296 {
00297 short h_addrtype;
00298 short h_length;
00299 }
00300 else version(BsdSockets)
00301 {
00302 int h_addrtype;
00303 int h_length;
00304 }
00305 char** h_addr_list;
00306
00307
00308 char* h_addr()
00309 {
00310 return h_addr_list[0];
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321 version(BigEndian)
00322 {
00323 uint16_t htons(uint16_t x)
00324 {
00325 return x;
00326 }
00327
00328
00329 uint32_t htonl(uint32_t x)
00330 {
00331 return x;
00332 }
00333 }
00334 else version(LittleEndian)
00335 {
00336 import std.intrinsic;
00337
00338
00339 uint16_t htons(uint16_t x)
00340 {
00341 return (x >> 8) | (x << 8);
00342 }
00343
00344
00345 uint32_t htonl(uint32_t x)
00346 {
00347 return bswap(x);
00348 }
00349 }
00350 else
00351 {
00352 static assert(0);
00353 }
00354
00355
00356 uint16_t ntohs(uint16_t x)
00357 {
00358 return htons(x);
00359 }
00360
00361
00362 uint32_t ntohl(uint32_t x)
00363 {
00364 return htonl(x);
00365 }
00366
00367 /+
00368 #endif
00369 +/
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 public:
00380
00381
00382
00383
00384
00385
00386
00387 class HostException: IOException
00388 {
00389 this(char[] msg)
00390 {
00391 super(msg);
00392 }
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 class SocketException: IOException
00402 {
00403 this(char[] msg)
00404 {
00405 super(msg);
00406 }
00407 }
00408
00409
00410
00411
00412
00413
00414
00415 class AddressException: SocketException
00416 {
00417 this(char[] msg)
00418 {
00419 super(msg);
00420 }
00421 }
00422
00423
00424
00425
00426
00427
00428
00429 class SocketAcceptException: SocketException
00430 {
00431 this(char[] msg)
00432 {
00433 super(msg);
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443 static int lastError ()
00444 {
00445 version (Win32)
00446 {
00447 return WSAGetLastError();
00448 }
00449 version (linux)
00450 {
00451 return getErrno();
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462 class Socket : Resource
00463 {
00464 private:
00465 socket_t sock;
00466 Socket.AddressFamily _family;
00467 static bool cancelled;
00468
00469 version(Win32)
00470 bit _blocking = false;
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 protected this(socket_t sock)
00481 {
00482
00483 set (sock);
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493 protected void set (socket_t sock)
00494 {
00495 this.sock = sock;
00496
00497
00498 acquire();
00499 }
00500
00501
00502
00503
00504
00505
00506
00507 protected void reset ()
00508 {
00509 this.sock = INVALID_SOCKET;
00510 }
00511
00512
00513 public:
00514
00515
00516
00517
00518
00519
00520
00521 static bool isCancelled ()
00522 {
00523 return cancelled;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532 static void cancelAll (bool cancel)
00533 {
00534 cancelled = cancel;
00535 version (TraceLinux)
00536 {
00537 printf ("socket cancel status now set\n");
00538 }
00539 }
00540
00541
00542
00543
00544
00545
00546
00547 /+
00548 #ifdef INCLUDE_ALL_FOR_DOXYGEN
00549 +/
00550
00551 version (Win32)
00552 {
00553
00554
00555
00556
00557
00558 enum Option: int
00559 {
00560
00561 SO_DEBUG = 0x1,
00562
00563
00564 SO_BROADCAST = 0x20,
00565 SO_REUSEADDR = 0x4,
00566 SO_LINGER = 0x80,
00567 SO_DONTLINGER = ~(SO_LINGER),
00568 SO_OOBINLINE = 0x100,
00569 SO_SNDBUF = 0x1001,
00570 SO_RCVBUF = 0x1002,
00571 SO_ERROR = 0x1007,
00572
00573 SO_ACCEPTCONN = 0x2,
00574 SO_KEEPALIVE = 0x8,
00575 SO_DONTROUTE = 0x10,
00576 SO_TYPE = 0x1008,
00577
00578
00579 IP_MULTICAST_LOOP = 0x4,
00580 IP_ADD_MEMBERSHIP = 0x5,
00581 IP_DROP_MEMBERSHIP = 0x6,
00582 }
00583
00584
00585
00586
00587
00588
00589 union linger
00590 {
00591 struct {
00592 ushort l_onoff;
00593 ushort l_linger;
00594 };
00595 ushort[2] array;
00596 }
00597
00598
00599
00600
00601
00602
00603 enum OptionLevel
00604 {
00605 SOCKET = 0xFFFF,
00606 IP = 0,
00607 TCP = 6,
00608 UDP = 17,
00609 }
00610 }
00611
00612 version (BsdSockets)
00613 {
00614
00615
00616
00617
00618
00619
00620
00621 enum Option: int
00622 {
00623
00624 SO_DEBUG = 1,
00625 SO_BROADCAST = 6,
00626 SO_REUSEADDR = 2,
00627 SO_LINGER = 13,
00628 SO_DONTLINGER = ~(SO_LINGER),
00629 SO_OOBINLINE = 10,
00630 SO_SNDBUF = 7,
00631 SO_RCVBUF = 8,
00632 SO_ERROR = 4,
00633
00634 SO_ACCEPTCONN = 30,
00635 SO_KEEPALIVE = 9,
00636 SO_DONTROUTE = 5,
00637 SO_TYPE = 3,
00638
00639
00640 IP_MULTICAST_LOOP = 34,
00641 IP_ADD_MEMBERSHIP = 35,
00642 IP_DROP_MEMBERSHIP = 36,
00643 }
00644
00645
00646
00647
00648
00649
00650 union linger
00651 {
00652 struct {
00653 int l_onoff;
00654 int l_linger;
00655 };
00656 int[2] array;
00657 }
00658
00659
00660
00661
00662
00663
00664 enum OptionLevel
00665 {
00666 SOCKET = 1,
00667 IP = 0,
00668 TCP = 6,
00669 UDP = 17,
00670 }
00671 }
00672
00673
00674
00675
00676
00677
00678 enum Shutdown: int
00679 {
00680 RECEIVE = 0,
00681 SEND = 1,
00682 BOTH = 2,
00683 }
00684
00685
00686
00687
00688
00689
00690 enum Flags: int
00691 {
00692 NONE = 0,
00693 OOB = 0x1,
00694 PEEK = 0x02,
00695 DONTROUTE = 0x04,
00696 }
00697
00698
00699
00700
00701
00702
00703 enum Type: int
00704 {
00705 STREAM = 1,
00706 DGRAM = 2,
00707 RAW = 3,
00708 RDM = 4,
00709 SEQPACKET = 5,
00710 }
00711
00712
00713
00714
00715
00716
00717
00718 enum Protocol: int
00719 {
00720 IP = 0,
00721 ICMP = 1,
00722 IGMP = 2,
00723 GGP = 3,
00724 TCP = 6,
00725 PUP = 12,
00726 UDP = 17,
00727 IDP = 22,
00728 ND = 77,
00729 RAW = 255,
00730 MAX = 256,
00731 }
00732
00733
00734
00735
00736
00737
00738
00739 version(Win32)
00740 {
00741 enum AddressFamily: int
00742 {
00743 UNSPEC = 0,
00744 UNIX = 1,
00745 INET = 2,
00746 IPX = 6,
00747 APPLETALK = 16,
00748
00749 }
00750 }
00751 else version(BsdSockets)
00752 {
00753 enum AddressFamily: int
00754 {
00755 UNSPEC = 0,
00756 UNIX = 1,
00757 INET = 2,
00758 IPX = 4,
00759 APPLETALK = 5,
00760
00761 }
00762 }
00763
00764 /+
00765 #endif
00766 +/
00767
00768
00769
00770
00771
00772
00773
00774 this (Socket.AddressFamily af, Socket.Type type, Socket.Protocol protocol)
00775 {
00776 create (af, type, protocol);
00777
00778
00779 acquire();
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789 protected void create (Socket.AddressFamily af, Socket.Type type, Socket.Protocol protocol)
00790 {
00791 sock = socket (af, type, protocol);
00792 if(sock == sock.init)
00793 exception("Unable to create socket: ");
00794 _family = af;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804 socket_t handle()
00805 {
00806 return sock;
00807 }
00808
00809
00810
00811
00812
00813
00814
00815 override char[] toString()
00816 {
00817 return "Socket";
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827 bit blocking()
00828 {
00829 version(Win32)
00830 {
00831 return _blocking;
00832 }
00833 else version(BsdSockets)
00834 {
00835 return !(fcntl(handle, F_GETFL, 0) & O_NONBLOCK);
00836 }
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846 void blocking(bit byes)
00847 {
00848 version(Win32)
00849 {
00850 uint num = !byes;
00851 if(SOCKET_ERROR == ioctlsocket(sock, FIONBIO, &num))
00852 goto err;
00853 _blocking = byes;
00854 }
00855 else version(BsdSockets)
00856 {
00857 int x = fcntl(handle, F_GETFL, 0);
00858 if(byes)
00859 x &= ~O_NONBLOCK;
00860 else
00861 x |= O_NONBLOCK;
00862 if(SOCKET_ERROR == fcntl(sock, F_SETFL, x))
00863 goto err;
00864 }
00865 return;
00866
00867 err:
00868 exception("Unable to set socket blocking: ");
00869 }
00870
00871
00872
00873
00874
00875
00876
00877 AddressFamily addressFamily()
00878 {
00879 return _family;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888 bit isAlive()
00889 {
00890 int type, typesize = type.sizeof;
00891 return getsockopt (sock, SOL_SOCKET, SO_TYPE, cast(char*) &type, &typesize) != SOCKET_ERROR;
00892 }
00893
00894
00895
00896
00897
00898
00899
00900 void bind(Address addr)
00901 {
00902 if(SOCKET_ERROR == .bind (sock, addr.name(), addr.nameLen()))
00903 exception ("Unable to bind socket: ");
00904 }
00905
00906
00907
00908
00909
00910
00911
00912 void connect(Address to)
00913 {
00914 if(SOCKET_ERROR == .connect (sock, to.name(), to.nameLen()))
00915 {
00916 if(!blocking)
00917 {
00918 version(Win32)
00919 {
00920 if(WSAEWOULDBLOCK == WSAGetLastError())
00921 return;
00922 }
00923 else version(linux)
00924 {
00925 if(EINPROGRESS == getErrno())
00926 return;
00927 }
00928 else
00929 {
00930 static assert(0);
00931 }
00932 }
00933 exception ("Unable to connect socket: ");
00934 }
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944 void listen(int backlog)
00945 {
00946 if(SOCKET_ERROR == .listen (sock, backlog))
00947 exception ("Unable to listen on socket: ");
00948 }
00949
00950
00951
00952
00953
00954
00955
00956 protected Socket createSocket (socket_t handle)
00957 {
00958 return new Socket (handle);
00959 }
00960
00961
00962
00963
00964
00965
00966 Socket accept()
00967 {
00968 socket_t newsock = .accept (sock, null, null);
00969 if(INVALID_SOCKET == newsock)
00970
00971
00972 {
00973 return null;
00974
00975 }
00976
00977
00978 Socket newSocket = createSocket (newsock);
00979
00980 version(Win32)
00981 newSocket._blocking = _blocking;
00982 newSocket._family = _family;
00983 return newSocket;
00984 }
00985
00986
00987
00988
00989
00990
00991
00992 void shutdown()
00993 {
00994 .shutdown (sock, cast(int) Shutdown.BOTH);
00995 }
00996
00997
00998
00999
01000
01001
01002 void shutdown(Socket.Shutdown how)
01003 {
01004 .shutdown (sock, cast(int)how);
01005 }
01006
01007
01008
01009
01010
01011
01012
01013
01014 void setLingerPeriod (int period)
01015 {
01016 linger l;
01017
01018 l.l_onoff = 1;
01019 l.l_linger = period;
01020
01021 setOption (OptionLevel.SOCKET, Option.SO_LINGER, l.array);
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 void setAddressReuse (bool enabled)
01033 {
01034 int[1] x = enabled;
01035 setOption (OptionLevel.SOCKET, Option.SO_REUSEADDR, x);
01036 }
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 bool setGroup (InternetAddress address, Socket.Option option)
01049 {
01050 struct ip_mreq
01051 {
01052 uint imr_multiaddr;
01053 uint imr_interface;
01054 };
01055
01056 ip_mreq mrq;
01057
01058 mrq.imr_interface = 0;
01059 mrq.imr_multiaddr = address.sin.sin_addr;
01060 return .setsockopt(handle(), OptionLevel.IP, option, &mrq, mrq.sizeof) != SOCKET_ERROR;
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 override void closure ()
01074 {
01075 version (TraceLinux)
01076 {
01077 printf ("closing socket handle ...\n");
01078 }
01079 version(Win32)
01080 {
01081 .closesocket (sock);
01082 }
01083 else version(BsdSockets)
01084 {
01085 .close (sock);
01086 }
01087 sock = sock.init;
01088 version (TraceLinux)
01089 {
01090 printf ("socket handle closed\n");
01091 }
01092 }
01093
01094
01095
01096
01097
01098
01099
01100 private Address newFamilyObject ()
01101 {
01102 Address result;
01103 switch(_family)
01104 {
01105 case AddressFamily.INET:
01106 result = new InternetAddress;
01107 break;
01108
01109 default:
01110 result = new UnknownAddress;
01111 }
01112 return result;
01113 }
01114
01115
01116
01117
01118
01119
01120
01121
01122 static char[] hostName ()
01123 {
01124 char[64] name;
01125
01126 if(SOCKET_ERROR == .gethostname (name, name.length))
01127 exception ("Unable to obtain host name: ");
01128 return name [0 .. std.string.strlen(name)].dup;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138 static uint hostAddress ()
01139 {
01140 InternetHost ih = new InternetHost;
01141
01142 char[] hostname = hostName();
01143 ih.getHostByName (hostname);
01144 assert (ih.addrList.length);
01145 return ih.addrList[0];
01146 }
01147
01148
01149
01150
01151
01152
01153
01154 Address remoteAddress ()
01155 {
01156 Address addr = newFamilyObject ();
01157 int nameLen = addr.nameLen ();
01158 if(SOCKET_ERROR == .getpeername (sock, addr.name(), &nameLen))
01159 exception ("Unable to obtain remote socket address: ");
01160 assert (addr.addressFamily() == _family);
01161 return addr;
01162 }
01163
01164
01165
01166
01167
01168
01169
01170 Address localAddress ()
01171 {
01172 Address addr = newFamilyObject ();
01173 int nameLen = addr.nameLen();
01174 if(SOCKET_ERROR == .getsockname (sock, addr.name(), &nameLen))
01175 exception ("Unable to obtain local socket address: ");
01176 assert (addr.addressFamily() == _family);
01177 return addr;
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187 int send (void[] buf, Socket.Flags flags = Socket.Flags.NONE)
01188 {
01189 int sent = .send (sock, buf, buf.length, cast(int)flags);
01190 return sent;
01191 }
01192
01193
01194
01195
01196
01197
01198
01199
01200 int sendTo (void[] buf, Socket.Flags flags, Address to)
01201 {
01202 int sent = .sendto (sock, buf, buf.length, cast(int)flags, to.name(), to.nameLen());
01203 return sent;
01204 }
01205
01206
01207
01208
01209
01210
01211
01212
01213 int sendTo (void[] buf, Address to)
01214 {
01215 return sendTo (buf, Socket.Flags.NONE, to);
01216 }
01217
01218
01219
01220
01221
01222
01223
01224
01225 int sendTo (void[] buf, Socket.Flags flags = Socket.Flags.NONE)
01226 {
01227 int sent = .sendto (sock, buf, buf.length, cast(int)flags, null, 0);
01228 return sent;
01229 }
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239 int receive (void[] buf, Socket.Flags flags = Socket.Flags.NONE)
01240 {
01241 if(!buf.length)
01242 return 0;
01243 int read = .recv(sock, buf, buf.length, cast(int)flags);
01244 if (read == SOCKET_ERROR)
01245 exception ("Failed while receiving socket data: ");
01246
01247 return read;
01248 }
01249
01250
01251
01252
01253
01254
01255
01256
01257 int receiveFrom (void[] buf, Socket.Flags flags, out Address from)
01258 {
01259 if(!buf.length)
01260 return 0;
01261 version (TraceLinux)
01262 {
01263 printf ("executing recvFrom() \n");
01264 }
01265 from = newFamilyObject ();
01266 int nameLen = from.nameLen ();
01267 int read = .recvfrom (sock, buf, buf.length, cast(int)flags, from.name(), &nameLen);
01268 version (TraceLinux)
01269 {
01270 printf ("recvFrom returns %d\n", read);
01271 }
01272 if (read == SOCKET_ERROR)
01273 exception ("Failed while receiving socket data: ");
01274
01275 assert (from.addressFamily() == _family);
01276
01277 return read;
01278 }
01279
01280
01281
01282
01283
01284
01285
01286
01287 int receiveFrom (void[] buf, out Address from)
01288 {
01289 return receiveFrom (buf, Socket.Flags.NONE, from);
01290 }
01291
01292
01293
01294
01295
01296
01297
01298
01299 int receiveFrom (void[] buf, Socket.Flags flags)
01300 {
01301 if(!buf.length)
01302 return 0;
01303 int read = .recvfrom (sock, buf, buf.length, cast(int)flags, null, null);
01304 if (read == SOCKET_ERROR)
01305 exception ("Failed while receiving socket data: ");
01306
01307 return read;
01308 }
01309
01310
01311
01312
01313
01314
01315
01316
01317 int receiveFrom (void[] buf)
01318 {
01319 return receiveFrom (buf, Socket.Flags.NONE);
01320 }
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330 int getOption (Socket.OptionLevel level, Socket.Option option, void[] result)
01331 {
01332 int len = result.length;
01333 if(SOCKET_ERROR == .getsockopt (sock, cast(int)level, cast(int)option, result, &len))
01334 exception ("Unable to get socket option: ");
01335 return len;
01336 }
01337
01338
01339
01340
01341
01342
01343
01344 void setOption (Socket.OptionLevel level, Socket.Option option, void[] value)
01345 {
01346 if(SOCKET_ERROR == .setsockopt (sock, cast(int)level, cast(int)option, value, value.length))
01347 exception ("Unable to set socket option: ");
01348 }
01349
01350
01351
01352
01353
01354
01355
01356
01357 protected static void exception (char[] msg)
01358 {
01359 msg ~= System.error (lastError);
01360 throw new SocketException (msg);
01361 }
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 static int select (SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, timeval* tv)
01379 in
01380 {
01381
01382 if(checkRead)
01383 {
01384 assert(checkRead !== checkWrite);
01385 assert(checkRead !== checkError);
01386 }
01387 if(checkWrite)
01388 {
01389 assert(checkWrite !== checkError);
01390 }
01391 }
01392 body
01393 {
01394 fd_set* fr, fw, fe;
01395
01396 version(Win32)
01397 {
01398
01399 fr = (checkRead && checkRead.count()) ? checkRead.toFd_set() : null;
01400 fw = (checkWrite && checkWrite.count()) ? checkWrite.toFd_set() : null;
01401 fe = (checkError && checkError.count()) ? checkError.toFd_set() : null;
01402 }
01403 else
01404 {
01405 fr = checkRead ? checkRead.toFd_set() : null;
01406 fw = checkWrite ? checkWrite.toFd_set() : null;
01407 fe = checkError ? checkError.toFd_set() : null;
01408 }
01409
01410 int result;
01411
01412
01413 while ((result = .select (socket_t.max - 1, fr, fw, fe, tv)) == -1)
01414 version(Win32)
01415 {
01416 if(WSAGetLastError() != WSAEINTR)
01417 break;
01418 }
01419 else version(linux)
01420 {
01421 if(getErrno() != EINTR)
01422 break;
01423 }
01424 else
01425 {
01426 static assert(0);
01427 }
01428
01429
01430
01431
01432
01433
01434 return result;
01435 }
01436
01437
01438
01439
01440
01441
01442
01443 static int select (SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, int microseconds)
01444 {
01445 timeval tv;
01446 tv.tv_sec = 0;
01447 tv.tv_usec = microseconds;
01448 return select (checkRead, checkWrite, checkError, &tv);
01449 }
01450
01451
01452
01453
01454
01455
01456
01457
01458 static int select (SocketSet checkRead, SocketSet checkWrite, SocketSet checkError)
01459 {
01460 return select (checkRead, checkWrite, checkError, null);
01461 }
01462
01463
01464
01465
01466
01467
01468
01469 /+
01470 bit poll (events)
01471 {
01472 int WSAEventSelect(socket_t s, WSAEVENT hEventObject, int lNetworkEvents);
01473 int poll(pollfd* fds, int nfds, int timeout);
01474 }
01475 +/
01476
01477
01478 }
01479
01480
01481
01482
01483
01484
01485
01486
01487 abstract class Address
01488 {
01489 protected sockaddr* name();
01490 protected int nameLen();
01491 Socket.AddressFamily addressFamily();
01492 char[] toString();
01493 }
01494
01495
01496
01497
01498
01499
01500
01501 class UnknownAddress: Address
01502 {
01503 protected:
01504 sockaddr sa;
01505
01506
01507
01508
01509
01510
01511
01512 sockaddr* name()
01513 {
01514 return &sa;
01515 }
01516
01517
01518
01519
01520
01521
01522
01523 int nameLen()
01524 {
01525 return sa.sizeof;
01526 }
01527
01528
01529 public:
01530
01531
01532
01533
01534
01535 Socket.AddressFamily addressFamily()
01536 {
01537 return cast(Socket.AddressFamily)sa.sa_family;
01538 }
01539
01540
01541
01542
01543
01544
01545
01546 char[] toString()
01547 {
01548 return "Unknown";
01549 }
01550 }
01551
01552
01553
01554
01555
01556
01557
01558 class InternetHost
01559 {
01560 char[] name;
01561 char[][] aliases;
01562 uint[] addrList;
01563
01564
01565
01566
01567
01568
01569
01570 protected void validHostent(hostent* he)
01571 {
01572 if(he.h_addrtype != cast(int)Socket.AddressFamily.INET || he.h_length != 4)
01573 throw new HostException("Address family mismatch.");
01574 }
01575
01576
01577
01578
01579
01580
01581
01582 void populate(hostent* he)
01583 {
01584 int i;
01585 char* p;
01586
01587 name = std.string.toString(he.h_name);
01588
01589 for(i = 0;; i++)
01590 {
01591 p = he.h_aliases[i];
01592 if(!p)
01593 break;
01594 }
01595
01596 if(i)
01597 {
01598 aliases = new char[][i];
01599 for(i = 0; i != aliases.length; i++)
01600 {
01601 aliases[i] = std.string.toString(he.h_aliases[i]);
01602 }
01603 }
01604 else
01605 {
01606 aliases = null;
01607 }
01608
01609 for(i = 0;; i++)
01610 {
01611 p = he.h_addr_list[i];
01612 if(!p)
01613 break;
01614 }
01615
01616 if(i)
01617 {
01618 addrList = new uint[i];
01619 for(i = 0; i != addrList.length; i++)
01620 {
01621 addrList[i] = ntohl(*(cast(uint*)he.h_addr_list[i]));
01622 }
01623 }
01624 else
01625 {
01626 addrList = null;
01627 }
01628 }
01629
01630
01631
01632
01633
01634
01635
01636 bit getHostByName(char[] name)
01637 {
01638 hostent* he = gethostbyname(std.string.toStringz(name));
01639 if(!he)
01640 return false;
01641 validHostent(he);
01642 populate(he);
01643 return true;
01644 }
01645
01646
01647
01648
01649
01650
01651
01652 bit getHostByAddr(uint addr)
01653 {
01654 uint x = htonl(addr);
01655 hostent* he = gethostbyaddr(&x, 4, cast(int)Socket.AddressFamily.INET);
01656 if(!he)
01657 return false;
01658 validHostent(he);
01659 populate(he);
01660 return true;
01661 }
01662
01663
01664
01665
01666
01667
01668
01669
01670 bit getHostByAddr(char[] addr)
01671 {
01672 uint x = inet_addr(std.string.toStringz(addr));
01673 hostent* he = gethostbyaddr(&x, 4, cast(int)Socket.AddressFamily.INET);
01674 if(!he)
01675 return false;
01676 validHostent(he);
01677 populate(he);
01678 return true;
01679 }
01680 }
01681
01682
01683 unittest
01684 {
01685 InternetHost ih = new InternetHost;
01686 assert(ih.addrList.length);
01687 InternetAddress ia = new InternetAddress(ih.addrList[0], InternetAddress.PORT_ANY);
01688 printf("IP address = %.*s\nname = %.*s\n", ia.toAddrString(), ih.name);
01689 foreach(int i, char[] s; ih.aliases)
01690 {
01691 printf("aliases[%d] = %.*s\n", i, s);
01692 }
01693
01694 printf("---\n");
01695
01696 assert(ih.getHostByAddr(ih.addrList[0]));
01697 printf("name = %.*s\n", ih.name);
01698 foreach(int i, char[] s; ih.aliases)
01699 {
01700 printf("aliases[%d] = %.*s\n", i, s);
01701 }
01702 }
01703
01704
01705
01706
01707
01708
01709
01710 class InternetAddress: Address
01711 {
01712 /+
01713 #ifdef INCLUDE_ALL_FOR_DOXYGEN
01714 +/
01715 protected:
01716
01717
01718
01719
01720
01721 struct sockaddr_in
01722 {
01723 ushort sin_family = cast(ushort)Socket.AddressFamily.INET;
01724 ushort sin_port;
01725 uint sin_addr;
01726 char[8] sin_zero = [0];
01727 }
01728 /+
01729 #endif
01730 +/
01731
01732 sockaddr_in sin;
01733
01734
01735
01736
01737
01738
01739
01740 sockaddr* name()
01741 {
01742 return cast(sockaddr*)&sin;
01743 }
01744
01745
01746
01747
01748
01749
01750
01751 int nameLen()
01752 {
01753 return sin.sizeof;
01754 }
01755
01756
01757
01758
01759
01760
01761
01762 this()
01763 {
01764 }
01765
01766
01767 public:
01768 const uint ADDR_ANY = 0;
01769 const uint ADDR_NONE = cast(int)-1;
01770 const ushort PORT_ANY = 0;
01771
01772
01773
01774
01775
01776
01777
01778 Socket.AddressFamily addressFamily()
01779 {
01780 return Socket.AddressFamily.INET;
01781 }
01782
01783
01784
01785
01786
01787
01788
01789 ushort port()
01790 {
01791 return ntohs(sin.sin_port);
01792 }
01793
01794
01795
01796
01797
01798
01799
01800 uint addr()
01801 {
01802 return ntohl(sin.sin_addr);
01803 }
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813 this(char[] addr, ushort port = PORT_ANY)
01814 {
01815 uint uiaddr = parse(addr);
01816 if(ADDR_NONE == uiaddr)
01817 {
01818 InternetHost ih = new InternetHost;
01819 if(!ih.getHostByName(addr))
01820 throw new AddressException("Invalid internet address '"~addr~"'");
01821 uiaddr = ih.addrList[0];
01822 }
01823 sin.sin_addr = htonl(uiaddr);
01824 sin.sin_port = htons(port);
01825 }
01826
01827
01828
01829
01830
01831
01832
01833 this(uint addr, ushort port)
01834 {
01835 sin.sin_addr = htonl(addr);
01836 sin.sin_port = htons(port);
01837 }
01838
01839
01840
01841
01842
01843
01844
01845 this(ushort port)
01846 {
01847 sin.sin_addr = 0;
01848 sin.sin_port = htons(port);
01849 }
01850
01851
01852
01853
01854
01855
01856
01857 char[] toAddrString()
01858 {
01859 return std.string.toString(inet_ntoa(sin.sin_addr)).dup;
01860 }
01861
01862
01863
01864
01865
01866
01867
01868 char[] toPortString()
01869 {
01870 return std.string.toString(port());
01871 }
01872
01873
01874
01875
01876
01877
01878
01879 char[] toString()
01880 {
01881 return toAddrString() ~ ":" ~ toPortString();
01882 }
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892 static uint parse(char[] addr)
01893 {
01894 return ntohl(inet_addr(std.string.toStringz(addr)));
01895 }
01896 }
01897
01898
01899 unittest
01900 {
01901 InternetAddress ia = new InternetAddress("63.105.9.61", 80);
01902 assert(ia.toString() == "63.105.9.61:80");
01903 }
01904
01905
01906
01907
01908
01909
01910
01911
01912 class SocketSet
01913 {
01914 private:
01915 uint nbytes;
01916 byte* buf;
01917
01918
01919 version(Win32)
01920 {
01921 uint count()
01922 {
01923 return *(cast(uint*)buf);
01924 }
01925
01926
01927 void count(int setter)
01928 {
01929 *(cast(uint*)buf) = setter;
01930 }
01931
01932
01933 socket_t* first()
01934 {
01935 return cast(socket_t*)(buf + uint.sizeof);
01936 }
01937 }
01938 else version(linux)
01939 {
01940 import std.intrinsic;
01941
01942
01943 uint nfdbits;
01944
01945
01946 uint fdelt(socket_t s)
01947 {
01948 return cast(uint)s / nfdbits;
01949 }
01950
01951
01952 uint fdmask(socket_t s)
01953 {
01954 return 1 << cast(uint)s % nfdbits;
01955 }
01956
01957
01958 uint* first()
01959 {
01960 return cast(uint*)buf;
01961 }
01962 }
01963
01964
01965 public:
01966
01967
01968
01969
01970
01971 this(uint max)
01972 {
01973 version(Win32)
01974 {
01975 nbytes = max * socket_t.sizeof;
01976 buf = new byte[nbytes + uint.sizeof];
01977 count = 0;
01978 }
01979 else version(linux)
01980 {
01981 if(max <= 32)
01982 nbytes = 32 * uint.sizeof;
01983 else
01984 nbytes = max * uint.sizeof;
01985 buf = new byte[nbytes];
01986 nfdbits = nbytes * 8;
01987
01988 }
01989 else
01990 {
01991 static assert(0);
01992 }
01993 }
01994
01995
01996
01997
01998
01999
02000
02001 this()
02002 {
02003 version(Win32)
02004 {
02005 this(64);
02006 }
02007 else version(linux)
02008 {
02009 this(32);
02010 }
02011 else
02012 {
02013 static assert(0);
02014 }
02015 }
02016
02017
02018
02019
02020
02021
02022
02023 void reset()
02024 {
02025 version(Win32)
02026 {
02027 count = 0;
02028 }
02029 else version(linux)
02030 {
02031 buf[0 .. nbytes] = 0;
02032 }
02033 else
02034 {
02035 static assert(0);
02036 }
02037 }
02038
02039
02040
02041
02042
02043
02044
02045 void add(socket_t s)
02046 in
02047 {
02048 version(Win32)
02049 {
02050 assert(count < max);
02051 }
02052 }
02053 body
02054 {
02055 version(Win32)
02056 {
02057 uint c = count;
02058 first[c] = s;
02059 count = c + 1;
02060 }
02061 else version(linux)
02062 {
02063 bts(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits);
02064 }
02065 else
02066 {
02067 static assert(0);
02068 }
02069 }
02070
02071
02072
02073
02074
02075
02076
02077 void add(Socket s)
02078 {
02079 add(s.sock);
02080 }
02081
02082
02083
02084
02085
02086
02087
02088 void remove(socket_t s)
02089 {
02090 version(Win32)
02091 {
02092 uint c = count;
02093 socket_t* start = first;
02094 socket_t* stop = start + c;
02095
02096 for(; start != stop; start++)
02097 {
02098 if(*start == s)
02099 goto found;
02100 }
02101 return;
02102
02103 found:
02104 for(++start; start != stop; start++)
02105 {
02106 *(start - 1) = *start;
02107 }
02108
02109 count = c - 1;
02110 }
02111 else version(linux)
02112 {
02113 btr(cast(uint*)&first[fdelt(s)], cast(uint)s % nfdbits);
02114 }
02115 else
02116 {
02117 static assert(0);
02118 }
02119 }
02120
02121
02122
02123
02124
02125
02126
02127 void remove(Socket s)
02128 {
02129 remove(s.sock);
02130 }
02131
02132
02133
02134
02135
02136
02137
02138 int isSet(socket_t s)
02139 {
02140 version(Win32)
02141 {
02142 socket_t* start = first;
02143 socket_t* stop = start + count;
02144
02145 for(; start != stop; start++)
02146 {
02147 if(*start == s)
02148 return true;
02149 }
02150 return false;
02151 }
02152 else version(linux)
02153 {
02154
02155 int index = cast(uint)s % nfdbits;
02156 return (cast(uint*)&first[fdelt(s)])[index / (uint.sizeof*8)] & (1 << (index & ((uint.sizeof*8) - 1)));
02157 }
02158 else
02159 {
02160 static assert(0);
02161 }
02162 }
02163
02164
02165
02166
02167
02168
02169
02170 int isSet(Socket s)
02171 {
02172 return isSet(s.sock);
02173 }
02174
02175
02176
02177
02178
02179
02180
02181
02182 uint max()
02183 {
02184 return nbytes / socket_t.sizeof;
02185 }
02186
02187
02188
02189
02190
02191
02192
02193 fd_set* toFd_set()
02194 {
02195 return cast(fd_set*)buf;
02196 }
02197 }
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211 interface IListener
02212 {
02213
02214
02215
02216
02217
02218
02219
02220 void cancel ();
02221 }
02222
02223
02224
02225
02226
02227
02228 interface ISocketReader
02229 {
02230
02231
02232
02233
02234
02235
02236
02237 int read (IBuffer buffer);
02238 }
02239
02240
02241