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