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