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