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