PageRenderTime 50ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/d/phobos/std/socket.d

https://bitbucket.org/tbone/gdc-fixes
D | 1711 lines | 1129 code | 254 blank | 328 comment | 115 complexity | 6fdbfe914b3d196a11969e03b3bd51fd MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. // Written in the D programming language
  2. /*
  3. Copyright (C) 2004-2005 Christopher E. Miller
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not
  15. be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. socket.d 1.3
  19. Jan 2005
  20. Thanks to Benjamin Herr for his assistance.
  21. */
  22. /* NOTE: This file has been patched from the original DMD distribution to
  23. work with the GDC compiler.
  24. Modified by David Friedman, April 2005
  25. */
  26. /**
  27. * Notes: For Win32 systems, link with ws2_32.lib.
  28. * Example: See /dmd/samples/d/listener.d.
  29. * Authors: Christopher E. Miller
  30. * Macros:
  31. * WIKI=Phobos/StdSocket
  32. */
  33. module std.socket;
  34. private import std.string, std.stdint, std.c.string, std.c.stdlib;
  35. alias ptrdiff_t ssize_t;
  36. version(Unix)
  37. {
  38. version = BsdSockets;
  39. }
  40. version(Posix)
  41. {
  42. version = BsdSockets;
  43. }
  44. version (skyos) { /* nothging */ }
  45. else
  46. {
  47. version = have_getservbyport;
  48. version = have_getprotobynumber;
  49. }
  50. version(Win32)
  51. {
  52. pragma (lib, "wsock32.lib");
  53. private import std.c.windows.windows, std.c.windows.winsock;
  54. private alias std.c.windows.winsock.timeval _ctimeval;
  55. typedef SOCKET socket_t = INVALID_SOCKET;
  56. private const int _SOCKET_ERROR = SOCKET_ERROR;
  57. private int _lasterr()
  58. {
  59. return WSAGetLastError();
  60. }
  61. }
  62. else version(BsdSockets)
  63. {
  64. version (Unix)
  65. {
  66. version (FreeBSD)
  67. {
  68. // private import std.c.freebsd.socket;
  69. }
  70. private import std.c.unix.unix;
  71. private alias std.c.unix.unix.timeval _ctimeval;
  72. }
  73. typedef int32_t socket_t = -1;
  74. private const int _SOCKET_ERROR = -1;
  75. private int _lasterr()
  76. {
  77. return getErrno();
  78. }
  79. }
  80. else
  81. {
  82. static assert(0); // No socket support yet.
  83. }
  84. /// Base exception thrown from a Socket.
  85. class SocketException: Exception
  86. {
  87. int errorCode; /// Platform-specific error code.
  88. this(string msg, int err = 0)
  89. {
  90. errorCode = err;
  91. version(Unix)
  92. {
  93. if(errorCode > 0)
  94. {
  95. char[80] buf;
  96. auto cs = _d_gnu_cbridge_strerror(errorCode, buf.ptr, buf.length);
  97. //char* cs;
  98. /+version (linux)
  99. {
  100. cs = _d_gnu_cbridge_strerror(errorCode, buf.ptr, buf.length);
  101. }
  102. else version (OSX)
  103. {
  104. auto errs = _d_gnu_cbridge_strerror(errorCode, buf.ptr, buf.length);
  105. if (errs == 0)
  106. cs = buf.ptr;
  107. else
  108. {
  109. cs = "Unknown error";
  110. }
  111. }
  112. else version (FreeBSD)
  113. {
  114. auto errs = strerror_r(errorCode, buf.ptr, buf.length);
  115. if (errs == 0)
  116. cs = buf.ptr;
  117. else
  118. {
  119. cs = "Unknown error";
  120. }
  121. }
  122. else version (Solaris)
  123. {
  124. auto errs = strerror_r(errorCode, buf.ptr, buf.length);
  125. if (errs == 0)
  126. cs = buf.ptr;
  127. else
  128. {
  129. cs = "Unknown error";
  130. }
  131. }
  132. else
  133. {
  134. static assert(0);
  135. }+/
  136. auto len = strlen(cs);
  137. if(cs[len - 1] == '\n')
  138. len--;
  139. if(cs[len - 1] == '\r')
  140. len--;
  141. msg = msg ~ ": " ~ cs[0 .. len];
  142. }
  143. }
  144. super(msg);
  145. }
  146. }
  147. static this()
  148. {
  149. version(Win32)
  150. {
  151. WSADATA wd;
  152. // Winsock will still load if an older version is present.
  153. // The version is just a request.
  154. int val;
  155. val = WSAStartup(0x2020, &wd);
  156. if(val) // Request Winsock 2.2 for IPv6.
  157. throw new SocketException("Unable to initialize socket library", val);
  158. }
  159. }
  160. static ~this()
  161. {
  162. version(Win32)
  163. {
  164. WSACleanup();
  165. }
  166. }
  167. /**
  168. * The communication domain used to resolve an address.
  169. */
  170. enum AddressFamily: int
  171. {
  172. UNSPEC = AF_UNSPEC, ///
  173. UNIX = AF_UNIX, /// local communication
  174. INET = AF_INET, /// internet protocol version 4
  175. IPX = AF_IPX, /// novell IPX
  176. APPLETALK = AF_APPLETALK, /// appletalk
  177. INET6 = AF_INET6, // internet protocol version 6
  178. }
  179. /**
  180. * Communication semantics
  181. */
  182. enum SocketType: int
  183. {
  184. STREAM = SOCK_STREAM, /// sequenced, reliable, two-way communication-based byte streams
  185. DGRAM = SOCK_DGRAM, /// connectionless, unreliable datagrams with a fixed maximum length; data may be lost or arrive out of order
  186. RAW = SOCK_RAW, /// raw protocol access
  187. RDM = SOCK_RDM, /// reliably-delivered message datagrams
  188. SEQPACKET = SOCK_SEQPACKET, /// sequenced, reliable, two-way connection-based datagrams with a fixed maximum length
  189. }
  190. /**
  191. * Protocol
  192. */
  193. enum ProtocolType: int
  194. {
  195. IP = IPPROTO_IP, /// internet protocol version 4
  196. ICMP = IPPROTO_ICMP, /// internet control message protocol
  197. IGMP = IPPROTO_IGMP, /// internet group management protocol
  198. GGP = IPPROTO_GGP, /// gateway to gateway protocol
  199. TCP = IPPROTO_TCP, /// transmission control protocol
  200. PUP = IPPROTO_PUP, /// PARC universal packet protocol
  201. UDP = IPPROTO_UDP, /// user datagram protocol
  202. IDP = IPPROTO_IDP, /// Xerox NS protocol
  203. IPV6 = IPPROTO_IPV6, /// internet protocol version 6
  204. }
  205. /**
  206. * Protocol is a class for retrieving protocol information.
  207. */
  208. class Protocol
  209. {
  210. ProtocolType type; /// These members are populated when one of the following functions are called without failure:
  211. string name; /// ditto
  212. string[] aliases; /// ditto
  213. void populate(protoent* proto)
  214. {
  215. type = cast(ProtocolType)proto.p_proto;
  216. name = std.string.toString(proto.p_name).dup;
  217. int i;
  218. for(i = 0;; i++)
  219. {
  220. if(!proto.p_aliases[i])
  221. break;
  222. }
  223. if(i)
  224. {
  225. aliases = new string[i];
  226. for(i = 0; i != aliases.length; i++)
  227. {
  228. aliases[i] =
  229. std.string.toString(proto.p_aliases[i]).dup;
  230. }
  231. }
  232. else
  233. {
  234. aliases = null;
  235. }
  236. }
  237. /** Returns false on failure */
  238. bool getProtocolByName(string name)
  239. {
  240. protoent* proto;
  241. proto = getprotobyname(toStringz(name));
  242. if(!proto)
  243. return false;
  244. populate(proto);
  245. return true;
  246. }
  247. /** Returns false on failure */
  248. // Same as getprotobynumber().
  249. bool getProtocolByType(ProtocolType type)
  250. {
  251. version (have_getprotobynumber)
  252. {
  253. protoent* proto;
  254. proto = getprotobynumber(type);
  255. if(!proto)
  256. return false;
  257. populate(proto);
  258. return true;
  259. }
  260. else
  261. return false;
  262. }
  263. }
  264. unittest
  265. {
  266. Protocol proto = new Protocol;
  267. assert(proto.getProtocolByType(ProtocolType.TCP));
  268. printf("About protocol TCP:\n\tName: %.*s\n",
  269. cast(int) proto.name.length, proto.name.ptr);
  270. foreach(string s; proto.aliases)
  271. {
  272. printf("\tAlias: %.*s\n", cast(int) s.length, s.ptr);
  273. }
  274. }
  275. /**
  276. * Service is a class for retrieving service information.
  277. */
  278. class Service
  279. {
  280. /** These members are populated when one of the following functions are called without failure: */
  281. string name;
  282. string[] aliases; /// ditto
  283. ushort port; /// ditto
  284. string protocolName; /// ditto
  285. void populate(servent* serv)
  286. {
  287. name = std.string.toString(serv.s_name).dup;
  288. port = ntohs(cast(ushort)serv.s_port);
  289. protocolName = std.string.toString(serv.s_proto).dup;
  290. int i;
  291. for(i = 0;; i++)
  292. {
  293. if(!serv.s_aliases[i])
  294. break;
  295. }
  296. if(i)
  297. {
  298. aliases = new string[i];
  299. for(i = 0; i != aliases.length; i++)
  300. {
  301. aliases[i] =
  302. std.string.toString(serv.s_aliases[i]).dup;
  303. }
  304. }
  305. else
  306. {
  307. aliases = null;
  308. }
  309. }
  310. /**
  311. * If a protocol name is omitted, any protocol will be matched.
  312. * Returns: false on failure.
  313. */
  314. bool getServiceByName(string name, string protocolName)
  315. {
  316. servent* serv;
  317. serv = getservbyname(toStringz(name), toStringz(protocolName));
  318. if(!serv)
  319. return false;
  320. populate(serv);
  321. return true;
  322. }
  323. // Any protocol name will be matched.
  324. /// ditto
  325. bool getServiceByName(string name)
  326. {
  327. servent* serv;
  328. serv = getservbyname(toStringz(name), null);
  329. if(!serv)
  330. return false;
  331. populate(serv);
  332. return true;
  333. }
  334. /// ditto
  335. bool getServiceByPort(ushort port, string protocolName)
  336. {
  337. version (have_getservbyport)
  338. {
  339. servent* serv;
  340. serv = getservbyport(port, toStringz(protocolName));
  341. if(!serv)
  342. return false;
  343. populate(serv);
  344. return true;
  345. }
  346. else
  347. return false;
  348. }
  349. // Any protocol name will be matched.
  350. /// ditto
  351. bool getServiceByPort(ushort port)
  352. {
  353. version (have_getservbyport)
  354. {
  355. servent* serv;
  356. serv = getservbyport(port, null);
  357. if(!serv)
  358. return false;
  359. populate(serv);
  360. return true;
  361. }
  362. else
  363. return false;
  364. }
  365. }
  366. unittest
  367. {
  368. Service serv = new Service;
  369. if(serv.getServiceByName("epmap", "tcp"))
  370. {
  371. printf("About service epmap:\n\tService: %.*s\n\tPort: %d\n\tProtocol: %.*s\n",
  372. cast(int) serv.name.length, serv.name.ptr, serv.port,
  373. cast(int) serv.protocolName.length, serv.protocolName.ptr);
  374. foreach(char[] s; serv.aliases)
  375. {
  376. printf("\tAlias: %.*s\n", cast(int) s.length, s.ptr);
  377. }
  378. }
  379. else
  380. {
  381. printf("No service for epmap.\n");
  382. }
  383. }
  384. /**
  385. * Base exception thrown from an InternetHost.
  386. */
  387. class HostException: Exception
  388. {
  389. int errorCode; /// Platform-specific error code.
  390. this(string msg, int err = 0)
  391. {
  392. errorCode = err;
  393. super(msg);
  394. }
  395. }
  396. /**
  397. * InternetHost is a class for resolving IPv4 addresses.
  398. */
  399. class InternetHost
  400. {
  401. /** These members are populated when one of the following functions are called without failure: */
  402. string name;
  403. string[] aliases; /// ditto
  404. uint32_t[] addrList; /// ditto
  405. void validHostent(hostent* he)
  406. {
  407. if(he.h_addrtype != cast(int)AddressFamily.INET || he.h_length != 4)
  408. throw new HostException("Address family mismatch", _lasterr());
  409. }
  410. void populate(hostent* he)
  411. {
  412. int i;
  413. char* p;
  414. name = std.string.toString(he.h_name).dup;
  415. for(i = 0;; i++)
  416. {
  417. p = he.h_aliases[i];
  418. if(!p)
  419. break;
  420. }
  421. if(i)
  422. {
  423. aliases = new string[i];
  424. for(i = 0; i != aliases.length; i++)
  425. {
  426. aliases[i] =
  427. std.string.toString(he.h_aliases[i]).dup;
  428. }
  429. }
  430. else
  431. {
  432. aliases = null;
  433. }
  434. for(i = 0;; i++)
  435. {
  436. p = he.h_addr_list[i];
  437. if(!p)
  438. break;
  439. }
  440. if(i)
  441. {
  442. addrList = new uint32_t[i];
  443. for(i = 0; i != addrList.length; i++)
  444. {
  445. addrList[i] = ntohl(*(cast(uint32_t*)he.h_addr_list[i]));
  446. }
  447. }
  448. else
  449. {
  450. addrList = null;
  451. }
  452. }
  453. /**
  454. * Resolve host name. Returns false if unable to resolve.
  455. */
  456. bool getHostByName(string name)
  457. {
  458. hostent* he;
  459. synchronized(this.classinfo) he = gethostbyname(toStringz(name));
  460. if(!he)
  461. return false;
  462. validHostent(he);
  463. populate(he);
  464. return true;
  465. }
  466. /**
  467. * Resolve IPv4 address number. Returns false if unable to resolve.
  468. */
  469. bool getHostByAddr(uint addr)
  470. {
  471. uint x = htonl(addr);
  472. hostent* he;
  473. synchronized(this.classinfo) he = gethostbyaddr(&x, 4, cast(int)AddressFamily.INET);
  474. if(!he)
  475. return false;
  476. validHostent(he);
  477. populate(he);
  478. return true;
  479. }
  480. /**
  481. * Same as previous, but addr is an IPv4 address string in the
  482. * dotted-decimal form $(I a.b.c.d).
  483. * Returns false if unable to resolve.
  484. */
  485. bool getHostByAddr(string addr)
  486. {
  487. uint x = inet_addr(std.string.toStringz(addr));
  488. hostent* he;
  489. synchronized(this.classinfo) he = gethostbyaddr(&x, 4, cast(int)AddressFamily.INET);
  490. if(!he)
  491. return false;
  492. validHostent(he);
  493. populate(he);
  494. return true;
  495. }
  496. }
  497. unittest
  498. {
  499. InternetHost ih = new InternetHost;
  500. assert(ih.getHostByName("www.digitalmars.com"));
  501. printf("addrList.length = %d\n", ih.addrList.length);
  502. assert(ih.addrList.length);
  503. InternetAddress ia = new InternetAddress(ih.addrList[0], InternetAddress.PORT_ANY);
  504. char[] sia = ia.toAddrString();
  505. printf("IPaddress = %.*s\nname = %.*s\n", cast(int) sia.length, sia.ptr,
  506. cast(int) ih.name.length, ih.name.ptr);
  507. foreach(int i, string s; ih.aliases)
  508. {
  509. printf("aliases[%d] = %.*s\n", i, cast(int) s.length, s.ptr);
  510. }
  511. printf("---\n");
  512. assert(ih.getHostByAddr(ih.addrList[0]));
  513. printf("name = %.*s\n", cast(int) ih.name.length, ih.name.ptr);
  514. foreach(int i, string s; ih.aliases)
  515. {
  516. printf("aliases[%d] = %.*s\n", i, cast(int) s.length, s.ptr);
  517. }
  518. }
  519. /**
  520. * Base exception thrown from an Address.
  521. */
  522. class AddressException: Exception
  523. {
  524. this(string msg)
  525. {
  526. super(msg);
  527. }
  528. }
  529. /**
  530. * Address is an abstract class for representing a network addresses.
  531. */
  532. abstract class Address
  533. {
  534. protected sockaddr* name();
  535. protected int nameLen();
  536. AddressFamily addressFamily(); /// Family of this address.
  537. string toString(); /// Human readable string representing this address.
  538. }
  539. /**
  540. *
  541. */
  542. class UnknownAddress: Address
  543. {
  544. protected:
  545. sockaddr sa;
  546. sockaddr* name()
  547. {
  548. return &sa;
  549. }
  550. int nameLen()
  551. {
  552. return sa.sizeof;
  553. }
  554. public:
  555. AddressFamily addressFamily()
  556. {
  557. return cast(AddressFamily)sa.sa_family;
  558. }
  559. string toString()
  560. {
  561. return "Unknown";
  562. }
  563. }
  564. /**
  565. * InternetAddress is a class that represents an IPv4 (internet protocol version
  566. * 4) address and port.
  567. */
  568. class InternetAddress: Address
  569. {
  570. protected:
  571. sockaddr_in sin;
  572. sockaddr* name()
  573. {
  574. return cast(sockaddr*)&sin;
  575. }
  576. int nameLen()
  577. {
  578. return sin.sizeof;
  579. }
  580. this()
  581. {
  582. }
  583. public:
  584. const uint ADDR_ANY = INADDR_ANY; /// Any IPv4 address number.
  585. const uint ADDR_NONE = INADDR_NONE; /// An invalid IPv4 address number.
  586. const ushort PORT_ANY = 0; /// Any IPv4 port number.
  587. /// Overridden to return AddressFamily.INET.
  588. AddressFamily addressFamily()
  589. {
  590. return cast(AddressFamily)AddressFamily.INET;
  591. }
  592. /// Returns the IPv4 port number.
  593. ushort port()
  594. {
  595. return ntohs(sin.sin_port);
  596. }
  597. /// Returns the IPv4 address number.
  598. uint addr()
  599. {
  600. return ntohl(sin.sin_addr.s_addr);
  601. }
  602. /**
  603. * Params:
  604. * addr = an IPv4 address string in the dotted-decimal form a.b.c.d,
  605. * or a host name that will be resolved using an InternetHost
  606. * object.
  607. * port = may be PORT_ANY as stated below.
  608. */
  609. this(string addr, ushort port)
  610. {
  611. uint uiaddr = parse(addr);
  612. if(ADDR_NONE == uiaddr)
  613. {
  614. InternetHost ih = new InternetHost;
  615. if(!ih.getHostByName(addr))
  616. //throw new AddressException("Invalid internet address");
  617. throw new AddressException(
  618. "Unable to resolve host '" ~ addr ~ "'");
  619. uiaddr = ih.addrList[0];
  620. }
  621. sin.sin_family = AddressFamily.INET;
  622. sin.sin_addr.s_addr = htonl(uiaddr);
  623. sin.sin_port = htons(port);
  624. }
  625. /**
  626. * Construct a new Address. addr may be ADDR_ANY (default) and port may
  627. * be PORT_ANY, and the actual numbers may not be known until a connection
  628. * is made.
  629. */
  630. this(uint addr, ushort port)
  631. {
  632. sin.sin_family = AddressFamily.INET;
  633. sin.sin_addr.s_addr = htonl(addr);
  634. sin.sin_port = htons(port);
  635. }
  636. /// ditto
  637. this(ushort port)
  638. {
  639. sin.sin_family = AddressFamily.INET;
  640. sin.sin_addr.s_addr = 0; //any, "0.0.0.0"
  641. sin.sin_port = htons(port);
  642. }
  643. /// Human readable string representing the IPv4 address in dotted-decimal form.
  644. string toAddrString()
  645. {
  646. return std.string.toString(inet_ntoa(sin.sin_addr)).dup;
  647. }
  648. /// Human readable string representing the IPv4 port.
  649. string toPortString()
  650. {
  651. return std.string.toString(port());
  652. }
  653. /// Human readable string representing the IPv4 address and port in the form $(I a.b.c.d:e).
  654. string toString()
  655. {
  656. return toAddrString() ~ ":" ~ toPortString();
  657. }
  658. /**
  659. * Parse an IPv4 address string in the dotted-decimal form $(I a.b.c.d)
  660. * and return the number.
  661. * If the string is not a legitimate IPv4 address,
  662. * ADDR_NONE is returned.
  663. */
  664. static uint parse(string addr)
  665. {
  666. return ntohl(inet_addr(std.string.toStringz(addr)));
  667. }
  668. }
  669. unittest
  670. {
  671. InternetAddress ia = new InternetAddress("63.105.9.61", 80);
  672. assert(ia.toString() == "63.105.9.61:80");
  673. }
  674. /** */
  675. class SocketAcceptException: SocketException
  676. {
  677. this(string msg, int err = 0)
  678. {
  679. super(msg, err);
  680. }
  681. }
  682. /// How a socket is shutdown:
  683. enum SocketShutdown: int
  684. {
  685. RECEIVE = SD_RECEIVE, /// socket receives are disallowed
  686. SEND = SD_SEND, /// socket sends are disallowed
  687. BOTH = SD_BOTH, /// both RECEIVE and SEND
  688. }
  689. /// Flags may be OR'ed together:
  690. enum SocketFlags: int
  691. {
  692. NONE = 0, /// no flags specified
  693. OOB = MSG_OOB, /// out-of-band stream data
  694. PEEK = MSG_PEEK, /// peek at incoming data without removing it from the queue, only for receiving
  695. DONTROUTE = MSG_DONTROUTE, /// data should not be subject to routing; this flag may be ignored. Only for sending
  696. NOSIGNAL = MSG_NOSIGNAL, /// don't send SIGPIPE signal on socket write error and instead return EPIPE
  697. }
  698. /// Duration timeout value.
  699. extern(C) struct timeval
  700. {
  701. // D interface
  702. int seconds; /// Number of seconds.
  703. int microseconds; /// Number of additional microseconds.
  704. // C interface
  705. deprecated
  706. {
  707. alias seconds tv_sec;
  708. alias microseconds tv_usec;
  709. }
  710. }
  711. /// A collection of sockets for use with Socket.select.
  712. class SocketSet
  713. {
  714. private:
  715. uint maxsockets; /// max desired sockets, the fd_set might be capable of holding more
  716. fd_set set;
  717. version(Win32)
  718. {
  719. uint count()
  720. {
  721. return set.fd_count;
  722. }
  723. }
  724. else version(BsdSockets)
  725. {
  726. int maxfd;
  727. uint count;
  728. }
  729. public:
  730. /// Set the maximum amount of sockets that may be added.
  731. this(uint max)
  732. {
  733. maxsockets = max;
  734. reset();
  735. }
  736. /// Uses the default maximum for the system.
  737. this()
  738. {
  739. this(FD_SETSIZE);
  740. }
  741. /// Reset the SocketSet so that there are 0 Sockets in the collection.
  742. void reset()
  743. {
  744. FD_ZERO(&set);
  745. version(BsdSockets)
  746. {
  747. maxfd = -1;
  748. count = 0;
  749. }
  750. }
  751. void add(socket_t s)
  752. in
  753. {
  754. // Make sure too many sockets don't get added.
  755. assert(count < maxsockets);
  756. version(BsdSockets)
  757. {
  758. version(GNU)
  759. {
  760. // Tries to account for little and big endian..er needs work
  761. // assert((s/NFDBITS+1)*NFDBITS/8 <= nbytes);
  762. }
  763. else
  764. {
  765. assert(FDELT(s) < (FD_SETSIZE / NFDBITS));
  766. }
  767. }
  768. }
  769. body
  770. {
  771. FD_SET(s, &set);
  772. version(BsdSockets)
  773. {
  774. ++count;
  775. if(s > maxfd)
  776. maxfd = s;
  777. }
  778. }
  779. /// Add a Socket to the collection. Adding more than the maximum has dangerous side affects.
  780. void add(Socket s)
  781. {
  782. add(s.sock);
  783. }
  784. void remove(socket_t s)
  785. {
  786. FD_CLR(s, &set);
  787. version(BsdSockets)
  788. {
  789. --count;
  790. // note: adjusting maxfd would require scanning the set, not worth it
  791. }
  792. }
  793. /// Remove this Socket from the collection.
  794. void remove(Socket s)
  795. {
  796. remove(s.sock);
  797. }
  798. int isSet(socket_t s)
  799. {
  800. return FD_ISSET(s, &set);
  801. }
  802. /// Returns nonzero if this Socket is in the collection.
  803. int isSet(Socket s)
  804. {
  805. return isSet(s.sock);
  806. }
  807. /// Return maximum amount of sockets that can be added, like FD_SETSIZE.
  808. uint max()
  809. {
  810. return maxsockets;
  811. }
  812. fd_set* toFd_set()
  813. {
  814. return &set;
  815. }
  816. int selectn()
  817. {
  818. version(Win32)
  819. {
  820. return count;
  821. }
  822. else version(BsdSockets)
  823. {
  824. return maxfd + 1;
  825. }
  826. }
  827. }
  828. /// The level at which a socket option is defined:
  829. enum SocketOptionLevel: int
  830. {
  831. SOCKET = SOL_SOCKET, /// socket level
  832. IP = ProtocolType.IP, /// internet protocol version 4 level
  833. ICMP = ProtocolType.ICMP, ///
  834. IGMP = ProtocolType.IGMP, ///
  835. GGP = ProtocolType.GGP, ///
  836. TCP = ProtocolType.TCP, /// transmission control protocol level
  837. PUP = ProtocolType.PUP, ///
  838. UDP = ProtocolType.UDP, /// user datagram protocol level
  839. IDP = ProtocolType.IDP, ///
  840. IPV6 = ProtocolType.IPV6, /// internet protocol version 6 level
  841. }
  842. /// Linger information for use with SocketOption.LINGER.
  843. extern(C) struct linger
  844. {
  845. version (BsdSockets)
  846. version (GNU)
  847. {
  848. private alias std.c.unix.unix.linger __unix_linger;
  849. static assert(linger.sizeof == __unix_linger.sizeof);
  850. }
  851. // D interface
  852. version(Win32)
  853. {
  854. uint16_t on; /// Nonzero for on.
  855. uint16_t time; /// Linger time.
  856. }
  857. else version(BsdSockets)
  858. {
  859. version (GNU)
  860. {
  861. typeof(__unix_linger.l_onoff) on;
  862. typeof(__unix_linger.l_linger) time;
  863. }
  864. else
  865. {
  866. int32_t on;
  867. int32_t time;
  868. }
  869. }
  870. // C interface
  871. deprecated
  872. {
  873. alias on l_onoff;
  874. alias time l_linger;
  875. }
  876. }
  877. /// Specifies a socket option:
  878. enum SocketOption: int
  879. {
  880. DEBUG = SO_DEBUG, /// record debugging information
  881. BROADCAST = SO_BROADCAST, /// allow transmission of broadcast messages
  882. REUSEADDR = SO_REUSEADDR, /// allow local reuse of address
  883. LINGER = SO_LINGER, /// linger on close if unsent data is present
  884. OOBINLINE = SO_OOBINLINE, /// receive out-of-band data in band
  885. SNDBUF = SO_SNDBUF, /// send buffer size
  886. RCVBUF = SO_RCVBUF, /// receive buffer size
  887. DONTROUTE = SO_DONTROUTE, /// do not route
  888. // SocketOptionLevel.TCP:
  889. TCP_NODELAY = .TCP_NODELAY, /// disable the Nagle algorithm for send coalescing
  890. // SocketOptionLevel.IPV6:
  891. IPV6_UNICAST_HOPS = .IPV6_UNICAST_HOPS, ///
  892. IPV6_MULTICAST_IF = .IPV6_MULTICAST_IF, ///
  893. IPV6_MULTICAST_LOOP = .IPV6_MULTICAST_LOOP, ///
  894. IPV6_JOIN_GROUP = .IPV6_JOIN_GROUP, ///
  895. IPV6_LEAVE_GROUP = .IPV6_LEAVE_GROUP, ///
  896. }
  897. /**
  898. * Socket is a class that creates a network communication endpoint using the
  899. * Berkeley sockets interface.
  900. */
  901. class Socket
  902. {
  903. private:
  904. socket_t sock;
  905. AddressFamily _family;
  906. version(Win32)
  907. bool _blocking = false; /// Property to get or set whether the socket is blocking or nonblocking.
  908. // For use with accepting().
  909. protected this()
  910. {
  911. }
  912. public:
  913. /**
  914. * Create a blocking socket. If a single protocol type exists to support
  915. * this socket type within the address family, the ProtocolType may be
  916. * omitted.
  917. */
  918. this(AddressFamily af, SocketType type, ProtocolType protocol)
  919. {
  920. sock = cast(socket_t)socket(af, type, protocol);
  921. if(sock == socket_t.init)
  922. throw new SocketException("Unable to create socket", _lasterr());
  923. _family = af;
  924. }
  925. // A single protocol exists to support this socket type within the
  926. // protocol family, so the ProtocolType is assumed.
  927. /// ditto
  928. this(AddressFamily af, SocketType type)
  929. {
  930. this(af, type, cast(ProtocolType)0); // Pseudo protocol number.
  931. }
  932. /// ditto
  933. this(AddressFamily af, SocketType type, string protocolName)
  934. {
  935. protoent* proto;
  936. proto = getprotobyname(toStringz(protocolName));
  937. if(!proto)
  938. throw new SocketException("Unable to find the protocol", _lasterr());
  939. this(af, type, cast(ProtocolType)proto.p_proto);
  940. }
  941. ~this()
  942. {
  943. close();
  944. }
  945. /// Get underlying socket handle.
  946. socket_t handle()
  947. {
  948. return sock;
  949. }
  950. /**
  951. * Get/set socket's blocking flag.
  952. *
  953. * When a socket is blocking, calls to receive(), accept(), and send()
  954. * will block and wait for data/action.
  955. * A non-blocking socket will immediately return instead of blocking.
  956. */
  957. bool blocking()
  958. {
  959. version(Win32)
  960. {
  961. return _blocking;
  962. }
  963. else version(BsdSockets)
  964. {
  965. return !(fcntl(handle, F_GETFL, 0) & O_NONBLOCK);
  966. }
  967. }
  968. /// ditto
  969. void blocking(bool byes)
  970. {
  971. version(Win32)
  972. {
  973. uint num = !byes;
  974. if(_SOCKET_ERROR == ioctlsocket(sock, FIONBIO, &num))
  975. goto err;
  976. _blocking = byes;
  977. }
  978. else version(BsdSockets)
  979. {
  980. int x = fcntl(sock, F_GETFL, 0);
  981. if(-1 == x)
  982. goto err;
  983. if(byes)
  984. x &= ~O_NONBLOCK;
  985. else
  986. x |= O_NONBLOCK;
  987. if(-1 == fcntl(sock, F_SETFL, x))
  988. goto err;
  989. }
  990. return; // Success.
  991. err:
  992. throw new SocketException("Unable to set socket blocking", _lasterr());
  993. }
  994. /// Get the socket's address family.
  995. AddressFamily addressFamily() // getter
  996. {
  997. return _family;
  998. }
  999. /// Property that indicates if this is a valid, alive socket.
  1000. bool isAlive() // getter
  1001. {
  1002. int type;
  1003. socklen_t typesize = type.sizeof;
  1004. return !getsockopt(sock, SOL_SOCKET, SO_TYPE, cast(char*)&type, &typesize);
  1005. }
  1006. /// Associate a local address with this socket.
  1007. void bind(Address addr)
  1008. {
  1009. if(_SOCKET_ERROR == .bind(sock, addr.name(), addr.nameLen()))
  1010. throw new SocketException("Unable to bind socket", _lasterr());
  1011. }
  1012. /**
  1013. * Establish a connection. If the socket is blocking, connect waits for
  1014. * the connection to be made. If the socket is nonblocking, connect
  1015. * returns immediately and the connection attempt is still in progress.
  1016. */
  1017. void connect(Address to)
  1018. {
  1019. if(_SOCKET_ERROR == .connect(sock, to.name(), to.nameLen()))
  1020. {
  1021. int err;
  1022. err = _lasterr();
  1023. if(!blocking)
  1024. {
  1025. version(Win32)
  1026. {
  1027. if(WSAEWOULDBLOCK == err)
  1028. return;
  1029. }
  1030. else version(Unix) //posix
  1031. {
  1032. if(EINPROGRESS == err)
  1033. return;
  1034. }
  1035. else
  1036. {
  1037. static assert(0);
  1038. }
  1039. }
  1040. throw new SocketException("Unable to connect socket", err);
  1041. }
  1042. }
  1043. /**
  1044. * Listen for an incoming connection. bind must be called before you can
  1045. * listen. The backlog is a request of how many pending incoming
  1046. * connections are queued until accept'ed.
  1047. */
  1048. void listen(int backlog)
  1049. {
  1050. if(_SOCKET_ERROR == .listen(sock, backlog))
  1051. throw new SocketException("Unable to listen on socket", _lasterr());
  1052. }
  1053. /**
  1054. * Called by accept when a new Socket must be created for a new
  1055. * connection. To use a derived class, override this method and return an
  1056. * instance of your class. The returned Socket's handle must not be set;
  1057. * Socket has a protected constructor this() to use in this situation.
  1058. */
  1059. // Override to use a derived class.
  1060. // The returned socket's handle must not be set.
  1061. protected Socket accepting()
  1062. {
  1063. return new Socket;
  1064. }
  1065. /**
  1066. * Accept an incoming connection. If the socket is blocking, accept
  1067. * waits for a connection request. Throws SocketAcceptException if unable
  1068. * to accept. See accepting for use with derived classes.
  1069. */
  1070. Socket accept()
  1071. {
  1072. socket_t newsock;
  1073. //newsock = cast(socket_t).accept(sock, null, null); // DMD 0.101 error: found '(' when expecting ';' following 'statement
  1074. alias .accept topaccept;
  1075. newsock = cast(socket_t)topaccept(sock, null, null);
  1076. if(socket_t.init == newsock)
  1077. throw new SocketAcceptException("Unable to accept socket connection", _lasterr());
  1078. Socket newSocket;
  1079. try
  1080. {
  1081. newSocket = accepting();
  1082. assert(newSocket.sock == socket_t.init);
  1083. newSocket.sock = newsock;
  1084. version(Win32)
  1085. newSocket._blocking = _blocking; //inherits blocking mode
  1086. newSocket._family = _family; //same family
  1087. }
  1088. catch(Object o)
  1089. {
  1090. _close(newsock);
  1091. throw o;
  1092. }
  1093. return newSocket;
  1094. }
  1095. /// Disables sends and/or receives.
  1096. void shutdown(SocketShutdown how)
  1097. {
  1098. .shutdown(sock, cast(int)how);
  1099. }
  1100. private static void _close(socket_t sock)
  1101. {
  1102. version(Win32)
  1103. {
  1104. .closesocket(sock);
  1105. }
  1106. else version(BsdSockets)
  1107. {
  1108. .close(sock);
  1109. }
  1110. }
  1111. /**
  1112. * Immediately drop any connections and release socket resources.
  1113. * Calling shutdown before close is recommended for connection-oriented
  1114. * sockets. The Socket object is no longer usable after close.
  1115. */
  1116. //calling shutdown() before this is recommended
  1117. //for connection-oriented sockets
  1118. void close()
  1119. {
  1120. _close(sock);
  1121. sock = socket_t.init;
  1122. }
  1123. private Address newFamilyObject()
  1124. {
  1125. Address result;
  1126. switch(_family)
  1127. {
  1128. case cast(AddressFamily)AddressFamily.INET:
  1129. result = new InternetAddress;
  1130. break;
  1131. default:
  1132. result = new UnknownAddress;
  1133. }
  1134. return result;
  1135. }
  1136. /// Returns the local machine's host name. Idea from mango.
  1137. static string hostName() // getter
  1138. {
  1139. char[256] result; // Host names are limited to 255 chars.
  1140. if(_SOCKET_ERROR == .gethostname(result.ptr, result.length))
  1141. throw new SocketException("Unable to obtain host name", _lasterr());
  1142. return std.string.toString(cast(char*)result).dup;
  1143. }
  1144. /// Remote endpoint Address.
  1145. Address remoteAddress()
  1146. {
  1147. Address addr = newFamilyObject();
  1148. int nameLen = addr.nameLen();
  1149. if(_SOCKET_ERROR == .getpeername(sock, addr.name(), &nameLen))
  1150. throw new SocketException("Unable to obtain remote socket address", _lasterr());
  1151. assert(addr.addressFamily() == _family);
  1152. return addr;
  1153. }
  1154. /// Local endpoint Address.
  1155. Address localAddress()
  1156. {
  1157. Address addr = newFamilyObject();
  1158. int nameLen = addr.nameLen();
  1159. if(_SOCKET_ERROR == .getsockname(sock, addr.name(), &nameLen))
  1160. throw new SocketException("Unable to obtain local socket address", _lasterr());
  1161. assert(addr.addressFamily() == _family);
  1162. return addr;
  1163. }
  1164. /// Send or receive error code.
  1165. const int ERROR = _SOCKET_ERROR;
  1166. /**
  1167. * Send data on the connection. Returns the number of bytes actually
  1168. * sent, or ERROR on failure. If the socket is blocking and there is no
  1169. * buffer space left, send waits.
  1170. */
  1171. //returns number of bytes actually sent, or -1 on error
  1172. ssize_t send(void[] buf, SocketFlags flags)
  1173. {
  1174. flags |= SocketFlags.NOSIGNAL;
  1175. auto sent = .send(sock, buf.ptr, buf.length, cast(int)flags);
  1176. return sent;
  1177. }
  1178. /// ditto
  1179. ssize_t send(void[] buf)
  1180. {
  1181. return send(buf, SocketFlags.NOSIGNAL);
  1182. }
  1183. /**
  1184. * Send data to a specific destination Address. If the destination address is not specified, a connection must have been made and that address is used. If the socket is blocking and there is no buffer space left, sendTo waits.
  1185. */
  1186. ssize_t sendTo(void[] buf, SocketFlags flags, Address to)
  1187. {
  1188. flags |= SocketFlags.NOSIGNAL;
  1189. auto sent = .sendto(sock, buf.ptr, buf.length, cast(int)flags, to.name(), to.nameLen());
  1190. return sent;
  1191. }
  1192. /// ditto
  1193. ssize_t sendTo(void[] buf, Address to)
  1194. {
  1195. return sendTo(buf, SocketFlags.NONE, to);
  1196. }
  1197. //assumes you connect()ed
  1198. /// ditto
  1199. ssize_t sendTo(void[] buf, SocketFlags flags)
  1200. {
  1201. flags |= SocketFlags.NOSIGNAL;
  1202. auto sent = .sendto(sock, buf.ptr, buf.length, cast(int)flags, null, 0);
  1203. return sent;
  1204. }
  1205. //assumes you connect()ed
  1206. /// ditto
  1207. ssize_t sendTo(void[] buf)
  1208. {
  1209. return sendTo(buf, SocketFlags.NONE);
  1210. }
  1211. /**
  1212. * Receive data on the connection. Returns the number of bytes actually
  1213. * received, 0 if the remote side has closed the connection, or ERROR on
  1214. * failure. If the socket is blocking, receive waits until there is data
  1215. * to be received.
  1216. */
  1217. //returns number of bytes actually received, 0 on connection closure, or -1 on error
  1218. ssize_t receive(void[] buf, SocketFlags flags)
  1219. {
  1220. if(!buf.length) //return 0 and don't think the connection closed
  1221. return 0;
  1222. auto read = .recv(sock, buf.ptr, buf.length, cast(int)flags);
  1223. // if(!read) //connection closed
  1224. return read;
  1225. }
  1226. /// ditto
  1227. ssize_t receive(void[] buf)
  1228. {
  1229. return receive(buf, SocketFlags.NONE);
  1230. }
  1231. /**
  1232. * Receive data and get the remote endpoint Address.
  1233. * If the socket is blocking, receiveFrom waits until there is data to
  1234. * be received.
  1235. * Returns: the number of bytes actually received,
  1236. * 0 if the remote side has closed the connection, or ERROR on failure.
  1237. */
  1238. ssize_t receiveFrom(void[] buf, SocketFlags flags, out Address from)
  1239. {
  1240. if(!buf.length) //return 0 and don't think the connection closed
  1241. return 0;
  1242. from = newFamilyObject();
  1243. auto nameLen = from.nameLen();
  1244. auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int)flags, from.name(), &nameLen);
  1245. assert(from.addressFamily() == _family);
  1246. // if(!read) //connection closed
  1247. return read;
  1248. }
  1249. /// ditto
  1250. ssize_t receiveFrom(void[] buf, out Address from)
  1251. {
  1252. return receiveFrom(buf, SocketFlags.NONE, from);
  1253. }
  1254. //assumes you connect()ed
  1255. /// ditto
  1256. ssize_t receiveFrom(void[] buf, SocketFlags flags)
  1257. {
  1258. if(!buf.length) //return 0 and don't think the connection closed
  1259. return 0;
  1260. auto read = .recvfrom(sock, buf.ptr, buf.length, cast(int)flags, null, null);
  1261. // if(!read) //connection closed
  1262. return read;
  1263. }
  1264. //assumes you connect()ed
  1265. /// ditto
  1266. ssize_t receiveFrom(void[] buf)
  1267. {
  1268. return receiveFrom(buf, SocketFlags.NONE);
  1269. }
  1270. /// Get a socket option. Returns the number of bytes written to result.
  1271. //returns the length, in bytes, of the actual result - very different from getsockopt()
  1272. int getOption(SocketOptionLevel level, SocketOption option, void[] result)
  1273. {
  1274. socklen_t len = cast(socklen_t)result.length;
  1275. if(_SOCKET_ERROR == .getsockopt(sock, cast(int)level, cast(int)option, result.ptr, &len))
  1276. throw new SocketException("Unable to get socket option", _lasterr());
  1277. return len;
  1278. }
  1279. /// Common case of getting integer and boolean options.
  1280. int getOption(SocketOptionLevel level, SocketOption option, out int32_t result)
  1281. {
  1282. return getOption(level, option, (&result)[0 .. 1]);
  1283. }
  1284. /// Get the linger option.
  1285. int getOption(SocketOptionLevel level, SocketOption option, out linger result)
  1286. {
  1287. //return getOption(cast(SocketOptionLevel)SocketOptionLevel.SOCKET, SocketOption.LINGER, (&result)[0 .. 1]);
  1288. return getOption(level, option, (&result)[0 .. 1]);
  1289. }
  1290. // Set a socket option.
  1291. void setOption(SocketOptionLevel level, SocketOption option, void[] value)
  1292. {
  1293. if(_SOCKET_ERROR == .setsockopt(sock, cast(int)level, cast(int)option, value.ptr, cast(socklen_t)value.length))
  1294. throw new SocketException("Unable to set socket option", _lasterr());
  1295. }
  1296. /// Common case for setting integer and boolean options.
  1297. void setOption(SocketOptionLevel level, SocketOption option, int32_t value)
  1298. {
  1299. setOption(level, option, (&value)[0 .. 1]);
  1300. }
  1301. /// Set the linger option.
  1302. void setOption(SocketOptionLevel level, SocketOption option, linger value)
  1303. {
  1304. //setOption(cast(SocketOptionLevel)SocketOptionLevel.SOCKET, SocketOption.LINGER, (&value)[0 .. 1]);
  1305. setOption(level, option, (&value)[0 .. 1]);
  1306. }
  1307. /**
  1308. * Wait for a socket to change status. A wait timeout timeval or int microseconds may be specified; if a timeout is not specified or the timeval is null, the maximum timeout is used. The timeval timeout has an unspecified value when select returns. Returns the number of sockets with status changes, 0 on timeout, or -1 on interruption. If the return value is greater than 0, the SocketSets are updated to only contain the sockets having status changes. For a connecting socket, a write status change means the connection is established and it's able to send. For a listening socket, a read status change means there is an incoming connection request and it's able to accept.
  1309. */
  1310. //SocketSet's updated to include only those sockets which an event occured
  1311. //returns the number of events, 0 on timeout, or -1 on interruption
  1312. //for a connect()ing socket, writeability means connected
  1313. //for a listen()ing socket, readability means listening
  1314. //Winsock: possibly internally limited to 64 sockets per set
  1315. static int select(SocketSet checkRead, SocketSet checkWrite, SocketSet checkError, timeval* tv)
  1316. in
  1317. {
  1318. //make sure none of the SocketSet's are the same object
  1319. if(checkRead)
  1320. {
  1321. assert(checkRead !is checkWrite);
  1322. assert(checkRead !is checkError);
  1323. }
  1324. if(checkWrite)
  1325. {
  1326. assert(checkWrite !is checkError);
  1327. }
  1328. }
  1329. body
  1330. {
  1331. fd_set* fr, fw, fe;
  1332. int n = 0;
  1333. version(Win32)
  1334. {
  1335. // Windows has a problem with empty fd_set`s that aren't null.
  1336. fr = (checkRead && checkRead.count()) ? checkRead.toFd_set() : null;
  1337. fw = (checkWrite && checkWrite.count()) ? checkWrite.toFd_set() : null;
  1338. fe = (checkError && checkError.count()) ? checkError.toFd_set() : null;
  1339. }
  1340. else
  1341. {
  1342. if(checkRead)
  1343. {
  1344. fr = checkRead.toFd_set();
  1345. n = checkRead.selectn();
  1346. }
  1347. else
  1348. {
  1349. fr = null;
  1350. }
  1351. if(checkWrite)
  1352. {
  1353. fw = checkWrite.toFd_set();
  1354. int _n;
  1355. _n = checkWrite.selectn();
  1356. if(_n > n)
  1357. n = _n;
  1358. }
  1359. else
  1360. {
  1361. fw = null;
  1362. }
  1363. if(checkError)
  1364. {
  1365. fe = checkError.toFd_se

Large files files are truncated, but you can click here to view the full file