1 /******************************************************************************
2 
3     Transparent Linux IP sockets interface wrapper.
4 
5     Copyright:
6         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
7         All rights reserved.
8 
9     License:
10         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
11         Alternatively, this file may be distributed under the terms of the Tango
12         3-Clause BSD License (see LICENSE_BSD.txt for details).
13 
14  ******************************************************************************/
15 
16 module ocean.sys.socket.model.ISocket;
17 
18 import ocean.meta.types.Qualifiers;
19 import ocean.stdc.posix.sys.socket;
20 import ocean.io.device.Conduit: ISelectable;
21 import ocean.io.device.IODevice: IODevice;
22 import ocean.sys.socket.InetAddress;
23 import core.sys.posix.netinet.in_: AF_INET, AF_INET6, IPPROTO_TCP;
24 import core.sys.posix.sys.types: ssize_t;
25 import core.sys.posix.unistd: close;
26 
27 // FIXME: somehow the import above doesn't result in this symbol being
28 // identifiable in this module. Re-defining it locally.
29 // Perhaps this is a symptom of a circular import?
30 enum : uint
31 {
32     MSG_NOSIGNAL    = 0x4000
33 }
34 
35 /******************************************************************************
36 
37     Flags supported by .accept4() and the socket accept() methods.
38 
39  ******************************************************************************/
40 
41 public enum SocketFlags
42 {
43     None,
44     SOCK_NONBLOCK = .SOCK_NONBLOCK,
45     SOCK_CLOEXEC  = .SOCK_CLOEXEC
46 }
47 
48 /******************************************************************************
49 
50     Abstract socket class
51 
52  ******************************************************************************/
53 
54 public abstract class ISocket : IODevice
55 {
56     import ocean.sys.CloseOnExec;
57 
58     /**************************************************************************
59 
60         Flags supported by accept4().
61 
62      **************************************************************************/
63 
64     protected alias .SocketFlags SocketFlags;
65 
66     /**************************************************************************
67 
68         File descriptor. Set by socket()/accept() and reset by close() and
69         clear(). Should be modified otherwise only in special situations.
70 
71      **************************************************************************/
72 
73     public int fd = -1;
74 
75     /**************************************************************************
76 
77         If true, the destructor will call close().
78         Enabled by socket()/accept() on success, disabled by close() and
79         socket()/accept() on failure. Should be modified otherwise only in
80         special situations.
81 
82      **************************************************************************/
83 
84     public bool close_in_destructor = false;
85 
86     /**************************************************************************
87 
88         If true, send() and therefore write() are requested not to send SIGPIPE
89         on errors when this socket is stream oriented (e.g. TCP) and the other
90         end breaks the connection.
91 
92      **************************************************************************/
93 
94     public bool suppress_sigpipe = true;
95 
96     /**************************************************************************
97 
98         Address struct (sin_addr/sin6_addr) length.
99 
100      **************************************************************************/
101 
102     public socklen_t in_addrlen;
103 
104     /**************************************************************************
105 
106         Constructor.
107 
108         Params:
109             in_addrlen = address struct length
110 
111      **************************************************************************/
112 
113     protected this ( socklen_t in_addrlen )
114     {
115         this.in_addrlen = in_addrlen;
116     }
117 
118     /**************************************************************************
119 
120         Destructor. Calls close() if indicated by close_in_destructor.
121 
122      **************************************************************************/
123 
124     ~this ( )
125     {
126         if (this.close_in_destructor)
127         {
128             this.close();
129         }
130     }
131 
132     /**************************************************************************
133 
134         Required by ISelectable.
135 
136         Returns:
137             the socket file descriptor.
138 
139      **************************************************************************/
140 
141     public Handle fileHandle ( )
142     {
143         return cast (Handle) this.fd;
144     }
145 
146     /**************************************************************************
147 
148         Calls getsockopt(SOL_SOCKET, SO_ERROR) to obtain the current error code
149         for this socket.
150 
151         Returns:
152             the current error code for this socket, which can be 0, or 0 if an
153             error code could not be obtained for this socket.
154 
155      **************************************************************************/
156 
157     public int error ( )
158     {
159         return this.error(this);
160     }
161 
162     /**************************************************************************
163 
164         Calls getsockopt(SOL_SOCKET, SO_ERROR) to obtain the current error code
165         for the socket referred to by fd.
166 
167         Returns:
168             the current error code for this socket, which can be 0, or 0 if an
169             error code could not be obtained for fd.
170 
171      **************************************************************************/
172 
173     public static int error ( ISelectable socket )
174     {
175         int errnum;
176 
177         socklen_t n = errnum.sizeof;
178 
179         return !.getsockopt(socket.fileHandle, SOL_SOCKET, SO_ERROR, &errnum, &n)? errnum : 0;
180     }
181 
182     /**************************************************************************
183 
184         Creates a socket endpoint for communication and sets this.fd to the
185         corresponding file descriptor.
186 
187         Params:
188             domain = The desired socket domain.
189                 The domain argument specifies a communication domain; this sel-
190                 ects the protocol family which will be used for communication.
191                 These families are defined in <sys/socket.h>. The currently
192                 understood formats include
193 
194                 Name                Purpose                          Man page
195                 AF_UNIX, AF_LOCAL   Local communication              unix(7)
196                 AF_INET             IPv4 Internet protocols          ip(7)
197                 AF_INET6            IPv6 Internet protocols          ipv6(7)
198                 AF_IPX              IPX - Novell protocols
199                 AF_NETLINK          Kernel user interface device     netlink(7)
200                 AF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)
201                 AF_AX25             Amateur radio AX.25 protocol
202                 AF_ATMPVC           Access to raw ATM PVCs
203                 AF_APPLETALK        AppleTalk                        ddp(7)
204                 AF_PACKET           Low level packet interface       packet(7)
205 
206             type = desired socket type, which specifies the communication
207                 semantics.  Supported types are
208 
209                 SOCK_STREAM     Provides sequenced, reliable,  two-way,  connec‐
210                                 tion-based  byte  streams.   An out-of-band data
211                                 transmission mechanism may be supported.
212 
213                 SOCK_DGRAM      Supports datagrams - connectionless,  unreliable
214                                 messages of a fixed maximum length.
215 
216                 SOCK_SEQPACKET  Provides  a sequenced, reliable, two-way connec‐
217                                 tion-based data transmission path for  datagrams
218                                 of  fixed maximum length; a consumer is required
219                                 to read an entire packet with each input  system
220                                 call.
221 
222                 SOCK_RAW        Provides raw network protocol access.
223 
224                 Some  socket  types may not be implemented by all protocol fami‐
225                 lies;  for  example,  SOCK_SEQPACKET  is  not  implemented   for
226                 AF_INET (IPv4).
227 
228                 Since  Linux  2.6.27, the type argument serves a second purpose:
229                 in addition to specifying a socket type, it may include the bit‐
230                 wise  OR  of any of the following values, to modify the behavior
231                 of socket():
232 
233                 SOCK_NONBLOCK   Set the O_NONBLOCK file status flag on  the  new
234                                 open  file  description.   Using this flag saves
235                                 extra calls to  fcntl(2)  to  achieve  the  same
236                                 result.
237 
238                 SOCK_CLOEXEC    Set  the  close-on-exec (FD_CLOEXEC) flag on the
239                                 new file descriptor.  See the description of the
240                                 O_CLOEXEC  flag  in open(2) for reasons why this
241                                 may be useful.
242 
243             protocol = desired protocol or 0 to use the default protocol for the
244                 specified type (e.g. TCP for `type == SOCK_STREAM` or UDP for
245                 `type == SOCK_DGRAM`).
246 
247                 The protocol specifies a particular protocol to be used with the
248                 socket.   Normally  only  a  single protocol exists to support a
249                 particular socket type within a given protocol family, in  which
250                 case  protocol  can  be specified as 0.  However, it is possible
251                 that many protocols may exist, in which case a particular proto‐
252                 col  must  be  specified in this manner.  The protocol number to
253                 use is specific to the “communication domain” in which  communi‐
254                 cation  is  to take place; see protocols(5).  See getprotoent(3)
255                 on how to map protocol name strings to protocol numbers.
256 
257                 Sockets of type SOCK_STREAM are full-duplex byte streams,  simi‐
258                 lar to pipes.  They do not preserve record boundaries.  A stream
259                 socket must be in a connected state before any data may be  sent
260                 or  received  on  it.  A connection to another socket is created
261                 with a connect(2) call.  Once connected, data may be transferred
262                 using  read(2) and write(2) calls or some variant of the send(2)
263                 and recv(2) calls.  When a session has been completed a close(2)
264                 may  be  performed.  Out-of-band data may also be transmitted as
265                 described in send(2) and received as described in recv(2).
266 
267 
268         Returns:
269             the socket file descriptor on success or -1 on failure. On failure
270             errno is set appropriately and this.fd is -1.
271 
272         Errors:
273             EACCES Permission  to  create  a socket of the specified type and/or
274                    protocol is denied.
275 
276             EAFNOSUPPORT
277                    The implementation does not  support  the  specified  address
278                    family.
279 
280             EINVAL Unknown protocol, or protocol family not available.
281 
282             EINVAL Invalid flags in type.
283 
284             EMFILE Process file table overflow.
285 
286             ENFILE The  system  limit on the total number of open files has been
287                    reached.
288 
289             ENOBUFS or ENOMEM
290                    Insufficient memory is available.  The socket cannot be  cre‐
291                    ated until sufficient resources are freed.
292 
293             EPROTONOSUPPORT
294                    The  protocol type or the specified protocol is not supported
295                    within this domain.
296 
297             Other errors may be generated by the underlying protocol modules.
298 
299      **************************************************************************/
300 
301     public int socket ( int domain, int type, int protocol = 0 )
302     {
303         this.fd = .socket(
304             domain, setCloExec(type, SocketFlags.SOCK_CLOEXEC), protocol
305         );
306 
307         this.close_in_destructor = (this.fd >= 0);
308 
309         return this.fd;
310     }
311 
312     /**************************************************************************
313 
314         Assigns a local address to this socket. This socket needs to have been
315         created by socket().
316 
317         Note: This generic wrapper should be used only in special situations,
318         the subclass variants for a particular address family are preferred.
319 
320         Params:
321             local_address = local internet address, expected to point to a sin_addr
322                       or sin6_addr instance, depending on the IP version of this
323                       instance
324 
325         Returns:
326             0 on success or -1 on failure. On failure errno is set
327             appropriately.
328 
329         Errors:
330             EACCES The address is protected, and the user is not the superuser.
331 
332             EADDRINUSE
333                    The given address is already in use.
334 
335             EBADF  sockfd is not a valid descriptor.
336 
337             EINVAL The socket is already bound to an address.
338 
339             ENOTSOCK
340                    The file descriptor is a descriptor for a file, not a socket.
341 
342      **************************************************************************/
343 
344     public int bind ( sockaddr* local_address )
345     {
346         return .bind(this.fd, local_address, this.in_addrlen);
347     }
348 
349     /**************************************************************************
350 
351         Accepts a connection from a listening socket and sets this.fd to the
352         accepted socket file descriptor.
353 
354         Note: This generic wrapper should be used only in special situations,
355         the subclass variants for a particular address family are preferred.
356 
357         The  accept()  system  call  is  used with connection-based socket types
358         (SOCK_STREAM, SOCK_SEQPACKET).  It extracts the first connection request
359         on  the  queue  of pending connections for the listening socket, creates
360         a new connected socket, and returns a new file descriptor  referring  to
361         that socket.  The newly  created socket  is not in the listening  state.
362         The original socket is unaffected by this call.
363 
364         If  no  pending  connections are present on the queue, and the socket is
365         not marked as nonblocking, accept() blocks the caller until a connection
366         is  present.  If the socket is marked nonblocking and no pending connec‐
367         tions are present on the queue, accept() fails with the error EAGAIN  or
368         EWOULDBLOCK.
369 
370         In order to be notified of incoming connections on a socket, you can use
371         select(2) or poll(2).  A readable event will be  delivered  when  a  new
372         connection  is  attempted and you may then call accept() to get a socket
373         for that connection.  Alternatively, you can set the socket  to  deliver
374         SIGIO when activity occurs on a socket; see socket(7) for details.
375 
376         Params:
377             listening_socket   = the file descriptor of the listening socket to
378                              accept the new connection from
379             remote_address = filled in with the address of the peer socket, as
380                              known to the communications layer; expected to
381                              point to a sin_addr or sin6_addr instance,
382                              depending on the IP version of this instance
383             addrlen        = actual address struct length output, initialised to
384                              this.in_addrlen; returning a different value
385                              indicates socket family mixup
386 
387             flags =
388                 The following  values  can be bitwise ORed in flags:
389 
390                 SOCK_NONBLOCK   Set the O_NONBLOCK file status flag on  the  new
391                                 open  file  description.   Using this flag saves
392                                 extra calls to  fcntl(2)  to  achieve  the  same
393                                 result.
394 
395                 SOCK_CLOEXEC    Set  the  close-on-exec (FD_CLOEXEC) flag on the
396                                 new file descriptor.  See the description of the
397                                 O_CLOEXEC  flag  in open(2) for reasons why this
398                                 may be useful.
399 
400         Returns:
401             the file descriptor of the accepted socket on success or -1 on
402             failure. On failure errno is set appropriately.
403 
404         Errors:
405             EAGAIN or EWOULDBLOCK
406                    The  socket  is  marked  nonblocking  and  no connections are
407                    present to be accepted.
408 
409             EBADF  The descriptor is invalid.
410 
411             ECONNABORTED
412                    A connection has been aborted.
413 
414             EFAULT The  addr  argument  is  not  in  a writable part of the user
415                    address space.
416 
417             EINTR  The system call was interrupted by a signal that  was  caught
418                    before a valid connection arrived; see signal(7).
419 
420             EINVAL Socket  is  not  listening  for  connections,  or  addrlen is
421                    invalid (e.g., is negative).
422 
423             EINVAL invalid value in flags.
424 
425             EMFILE The per-process limit  of  open  file  descriptors  has  been
426                    reached.
427 
428             ENFILE The  system  limit on the total number of open files has been
429                    reached.
430 
431             ENOBUFS, ENOMEM
432                    Not enough free memory.  This often  means  that  the  memory
433                    allocation is limited by the socket buffer limits, not by the
434                    system memory.
435 
436             ENOTSOCK
437                    The descriptor references a file, not a socket.
438 
439             EOPNOTSUPP
440                    The referenced socket is not of type SOCK_STREAM.
441 
442             EPROTO Protocol error.
443 
444             In addition, Linux accept() may fail if:
445 
446             EPERM  Firewall rules forbid connection.
447 
448             In addition, network errors for the new socket and  as  defined  for
449             the  protocol  may  be  returned.   Various Linux kernels can return
450             other  errors  such  as  ENOSR,  ESOCKTNOSUPPORT,   EPROTONOSUPPORT,
451             ETIMEDOUT.  The value ERESTARTSYS may be seen during a trace.
452 
453      **************************************************************************/
454 
455     public int accept ( ISelectable listening_socket,
456                         sockaddr* remote_address, out socklen_t addrlen,
457                         SocketFlags flags = SocketFlags.None )
458     {
459         addrlen = this.in_addrlen;
460 
461         this.fd = .accept4(
462             listening_socket.fileHandle, remote_address, &addrlen,
463             setCloExec(flags, SocketFlags.SOCK_CLOEXEC)
464         );
465 
466         this.close_in_destructor = (this.fd >= 0);
467 
468         return this.fd;
469     }
470 
471     /**************************************************************************
472 
473         Accepts a connection from a listening socket and sets this.fd to the
474         accepted socket file descriptor.
475 
476         See description above for further information.
477 
478         Params:
479             listening_socket = the listening socket to accept the new connection
480                                from
481             flags            = socket flags, see description above
482 
483         Returns:
484             the file descriptor of the accepted socket on success or -1 on
485             failure. On failure errno is set appropriately.
486 
487      **************************************************************************/
488 
489     public int accept ( ISelectable listening_socket, SocketFlags flags = SocketFlags.None )
490     {
491         this.fd = .accept4(
492             listening_socket.fileHandle, null, null,
493             setCloExec(flags, SocketFlags.SOCK_CLOEXEC)
494         );
495 
496         this.close_in_destructor = (this.fd >= 0);
497 
498         return this.fd;
499     }
500 
501     /**************************************************************************
502 
503         Accepts a connection from a listening socket and sets this.fd to the
504         accepted socket file descriptor.
505 
506         See description above for further information.
507 
508         Params:
509             listening_socket = the listening socket to accept the new connection
510                                from
511             nonblocking      = true: make the accepted socket nonblocking,
512                                false: leave it blocking
513 
514         Returns:
515             the file descriptor of the accepted socket on success or -1 on
516             failure. On failure errno is set appropriately.
517 
518      **************************************************************************/
519 
520     public int accept ( ISelectable listening_socket, bool nonblocking )
521     {
522         static immutable SocketFlags[2] flags = [SocketFlags.None, SocketFlags.SOCK_NONBLOCK];
523 
524         return this.accept(listening_socket, flags[nonblocking]);
525     }
526 
527     /**************************************************************************
528 
529         Connects this socket the specified address and port.
530 
531         Note: This generic wrapper should be used only in special situations,
532         the subclass variants for a particular address family are preferred.
533 
534         If  this socket is of type SOCK_DGRAM  then the  address  is the one  to
535         which datagrams are sent by default, and the  only  address  from  which
536         datagrams  are  received.   If  the  socket  is  of  type SOCK_STREAM or
537         SOCK_SEQPACKET, this call attempts to make a connection  to  the  socket
538         that is bound to the address specified by addr.
539 
540         Generally,  connection-based protocol sockets may successfully connect()
541         only once; connectionless protocol sockets may  use  connect()  multiple
542         times  to change their association.  Connectionless sockets may dissolve
543         the association by connecting to an address with the sa_family member of
544         sockaddr set to AF_UNSPEC (supported on Linux since kernel 2.2).
545 
546         Params:
547             remote_address = remote internet address, expected to point to a sin_addr
548                       or sin6_addr instance, depending on the IP version of this
549                       instance
550 
551         Returns:
552             0 on success or -1 on failure. On error failure is set
553             appropriately.
554 
555         Errors:
556             The  following  are  general socket errors only.  There may be other
557             domain-specific error codes.
558 
559             EACCES For Unix domain sockets, which are  identified  by  pathname:
560                    Write permission is denied on the socket file, or search per‐
561                    mission is denied for one of the directories in the path pre‐
562                    fix.  (See also path_resolution(7).)
563 
564             EACCES, EPERM
565                    The user tried to connect to a broadcast address without hav‐
566                    ing the socket  broadcast  flag  enabled  or  the  connection
567                    request failed because of a local firewall rule.
568 
569             EADDRINUSE
570                    Local address is already in use.
571 
572             EAFNOSUPPORT
573                   The passed address didn't have the correct address family in
574                   its sa_family field.
575 
576             EAGAIN No more free local ports or insufficient entries in the rout‐
577                    ing    cache.    For   AF_INET   see   the   description   of
578                    /proc/sys/net/ipv4/ip_local_port_range ip(7) for  information
579                    on how to increase the number of local ports.
580 
581             EALREADY
582                    The  socket  is nonblocking and a previous connection attempt
583                    has not yet been completed.
584 
585             EBADF  The file descriptor is not a valid index  in  the  descriptor
586                    table.
587 
588             ECONNREFUSED
589                    No-one listening on the remote address.
590 
591             EFAULT The  socket  structure  address is outside the user's address
592                    space.
593 
594             EINPROGRESS
595                    The socket is nonblocking and the connection cannot  be  com‐
596                    pleted  immediately.   It is possible to select(2) or poll(2)
597                    for completion by selecting the socket  for  writing.   After
598                    select(2)  indicates  writability,  use getsockopt(2) to read
599                    the SO_ERROR option at level SOL_SOCKET to determine  whether
600                    connect() completed successfully (SO_ERROR is zero) or unsuc‐
601                    cessfully (SO_ERROR is one of the usual  error  codes  listed
602                    here, explaining the reason for the failure).
603 
604             EINTR  The  system call was interrupted by a signal that was caught;
605                    see signal(7).
606 
607             EISCONN
608                    The socket is already connected.
609 
610             ENETUNREACH
611                    Network is unreachable.
612 
613             ENOTSOCK
614                    The file descriptor is not associated with a socket.
615 
616             ETIMEDOUT
617                    Timeout while attempting connection.  The server may  be  too
618                    busy to accept new connections.  Note that for IP sockets the
619                    timeout may be very long when syncookies are enabled  on  the
620                    server.
621 
622      **************************************************************************/
623 
624     public int connect ( sockaddr* remote_address )
625     {
626         return .connect(this.fd, remote_address, this.in_addrlen);
627     }
628 
629     /**************************************************************************
630 
631         listen() marks this socket as a passive socket, that is, as a socket
632         that will be used to accept incoming connection requests using
633         accept().
634 
635         Params:
636             backlog =
637                 The backlog argument defines the maximum  length  to  which  the
638                 queue  of pending connections for sockfd may grow.  If a connec‐
639                 tion request arrives when the queue  is  full,  the  client  may
640                 receive  an  error with an indication of ECONNREFUSED or, if the
641                 underlying protocol supports retransmission, the request may  be
642                 ignored so that a later reattempt at connection succeeds.
643 
644         Returns:
645             0 on success or -1 on failure. On failure errno is set
646             appropriately.
647 
648         Errors:
649             EADDRINUSE
650                    Another socket is already listening on the same port.
651 
652             EBADF  The argument sockfd is not a valid descriptor.
653 
654             ENOTSOCK
655                    The argument sockfd is not a socket.
656 
657             EOPNOTSUPP
658                    The socket is not of a type that  supports  the  listen()
659                    operation.
660 
661 
662      **************************************************************************/
663 
664     public int listen ( int backlog )
665     {
666         return .listen(this.fd, backlog);
667     }
668 
669     /**************************************************************************
670 
671         The shutdown() call causes all or part of a full-duplex connection on
672         the socket to be shut down.
673 
674         Params:
675             how =
676                 - SHUT_RD: further receptions will be disallowed,
677                 - SHUT_WR: further transmissions will be disallowed,
678                 - SHUT_RDWR: further receptions and transmissions will be disal‐
679                   lowed.
680         Returns:
681             0 on success or -1 on failure. On failure errno is set
682             appropriately.
683 
684         Errors:
685             EBADF  The argument sockfd is not a valid descriptor.
686 
687             ENOTSOCK
688                    The argument sockfd is not a socket.
689 
690             ENOTCONN
691                    The specified socket is not connected.
692 
693      **************************************************************************/
694 
695     public int shutdown ( int how = SHUT_RDWR )
696     {
697         return .shutdown(this.fd, how);
698     }
699 
700     /**************************************************************************
701 
702         Obtains the value of a socket option, writing the value data to dst.
703 
704         Note: The actual value data type and length depends on the particular
705         option. If the returned value is above dst.length, dst contains the
706         first bytes of the truncated value. If the returned value is below
707         dst.length on success, it indicates the number of bytes in dst written
708         to.
709 
710         Params:
711             level   = socket option level
712             optname = socket option name
713             dst     = value destination buffer
714 
715         Returns:
716             the actual value length on success or -1 on failure.
717             On failure errno is set appropriately.
718 
719         Errors:
720             EBADF  The argument sockfd is not a valid descriptor.
721 
722             EFAULT dst is not in a valid part of the process address space.
723 
724             ENOPROTOOPT
725                    The option is unknown at the level indicated.
726 
727             ENOTSOCK
728                    The argument sockfd is a file, not a socket.
729 
730      **************************************************************************/
731 
732     public ssize_t getsockopt ( int level, int optname, void[] dst )
733     {
734         socklen_t result_len = cast(socklen_t)dst.length;
735 
736         int r = .getsockopt(this.fd, level, optname, dst.ptr, &result_len);
737 
738         return cast(uint)(r ? r : result_len);
739     }
740 
741     /**************************************************************************
742 
743         Calls getsockopt() to obtain the value of a socket option.
744 
745         Notes:
746             - The actual value data type T depends on the particular option. If
747               the returned value differs from val.sizeof on success, the wrong
748               type was used and val contains most likely junk.
749             - T = bool is internally substituted by int and therefore suitable
750               for flag options.
751 
752         Params:
753             level   = socket option level
754             optname = socket option name
755             val     = value output
756 
757         Returns:
758             the actual value length on success or -1 on failure.
759             On failure errno is set appropriately.
760 
761      **************************************************************************/
762 
763     public ssize_t getsockoptVal ( T ) ( int level, int optname, out T val )
764     {
765         static if (is (T == bool))
766         {
767             int dst;
768 
769             scope (success) val = !!dst;
770         }
771         else
772         {
773             alias val dst;
774         }
775 
776         return this.getsockopt(level, optname, (cast (void*) &dst)[0 .. dst.sizeof]);
777     }
778 
779     /**************************************************************************
780 
781         Sets the value of a socket option, using the value data in src.
782         The actual value data type and length depends on the particular option.
783 
784         Params:
785             level   = socket option level
786             optname = socket option name
787             src     = value source buffer
788 
789         Returns:
790             0 on success or -1 on failure.
791             On failure errno is set appropriately.
792 
793         Errors:
794             EBADF - The argument sockfd is not a valid descriptor.
795 
796             EFAULT - src is not in a valid part of the process address space.
797 
798             EINVAL - src.length does not match the expected value length.
799 
800             ENOPROTOOPT - The option is unknown at the level indicated.
801 
802             ENOTSOCK - The argument sockfd is a file, not a socket.
803 
804      **************************************************************************/
805 
806     public int setsockopt ( int level, int optname, const(void)[] src )
807     {
808         return .setsockopt(this.fd, level, optname, src.ptr, cast(uint)src.length);
809     }
810 
811     /**************************************************************************
812 
813         Calls setsockopt() to sets the value of a socket option to val.
814 
815         Notes:
816             - The actual value data type T depends on the particular option.
817               Failure with EINVAL indicates that a type of the wrong size was
818               used.
819             - T = bool is internally substituted by int and therefore suitable
820               for flag options.
821 
822         Params:
823             level   = socket option level
824             optname = socket option name
825             val     = option value
826 
827         Returns:
828             0 on success or -1 on failure.
829             On failure errno is set appropriately.
830 
831      **************************************************************************/
832 
833     public int setsockoptVal ( T ) ( int level, int optname, T val )
834     {
835         static if (is (T == bool))
836         {
837             int src = val;
838         }
839         else
840         {
841             alias val src;
842         }
843 
844         return this.setsockopt(level, optname, (cast (void*) &src)[0 .. src.sizeof]);
845     }
846 
847     /**************************************************************************
848 
849         Calls send() to send as many src bytes as possible.
850 
851         Note: May raise ESIGPIPE on errors when this socket is stream oriented
852         (e.g. TCP), the other end breaks the connection and
853         this.suppress_sigpipe is false.
854 
855         Params:
856             src = data to send
857 
858         Returns:
859             the number of src bytes sent on success or -1 on failure.
860             On failure errno is set appropriately.
861 
862      **************************************************************************/
863 
864     override public ssize_t write ( const(void)[] src )
865     {
866         return this.send(src, 0);
867     }
868 
869     /**************************************************************************
870 
871         Sends as many src bytes as possible to the remote.
872 
873         Note: May raise ESIGPIPE on errors when this socket is stream oriented
874         (e.g. TCP), the other end breaks the connection flags does not contain
875         MSG_NOSIGNAL. If  this.suppress_sigpipe is true, MSG_NOSIGNAL will be
876         set in flags automatically.
877 
878         Params:
879             src   = data to send
880             flags =  the bitwise OR of zero or more of the following flags:
881 
882                 MSG_CONFIRM (Since Linux 2.3.15)
883                        Tell  the  link layer that forward progress happened: you
884                        got a successful reply from the other side.  If the  link
885                        layer  doesn't  get  this  it  will regularly reprobe the
886                        neighbor (e.g.,  via  a  unicast  ARP).   Only  valid  on
887                        SOCK_DGRAM and SOCK_RAW sockets and currently only imple‐
888                        mented for IPv4 and IPv6.  See arp(7) for details.
889 
890                 MSG_DONTROUTE
891                        Don't use a gateway to send out the packet, only send  to
892                        hosts  on  directly  connected networks.  This is usually
893                        used only by diagnostic or  routing  programs.   This  is
894                        only  defined  for  protocol  families that route; packet
895                        sockets don't.
896 
897                 MSG_DONTWAIT (since Linux 2.2)
898                        Enables nonblocking operation;  if  the  operation  would
899                        block,  EAGAIN  or EWOULDBLOCK is returned (this can also
900                        be enabled using the O_NONBLOCK  flag  with  the  F_SETFL
901                        fcntl(2)).
902 
903                 MSG_EOR (since Linux 2.2)
904                        Terminates  a  record  (when this notion is supported, as
905                        for sockets of type SOCK_SEQPACKET).
906 
907                 MSG_MORE (Since Linux 2.4.4)
908                        The caller has more data to send.  This flag is used with
909                        TCP  sockets  to  obtain  the same effect as the TCP_CORK
910                        socket option (see tcp(7)), with the difference that this
911                        flag can be set on a per-call basis.
912 
913                        Since  Linux  2.6,  this  flag  is also supported for UDP
914                        sockets, and informs the kernel to  package  all  of  the
915                        data sent in calls with this flag set into a single data‐
916                        gram which is only transmitted when a call  is  performed
917                        that  does not specify this flag.  (See also the UDP_CORK
918                        socket option described in udp(7).)
919 
920                 MSG_NOSIGNAL (since Linux 2.2)
921                        Requests not to send SIGPIPE on errors on stream oriented
922                        sockets  when  the  other end breaks the connection.  The
923                        EPIPE error is still returned.
924 
925                 MSG_OOB
926                        Sends out-of-band  data  on  sockets  that  support  this
927                        notion (e.g., of type SOCK_STREAM); the underlying proto‐
928                        col must also support out-of-band data.
929 
930         Returns:
931             the number of src bytes sent on success or -1 on failure.
932             On failure errno is set appropriately.
933 
934         Errors:
935             These are some standard errors generated by the socket layer.  Addi‐
936             tional errors may be generated and returned from the underlying pro‐
937             tocol modules; see their respective manual pages.
938 
939             EACCES (For Unix domain sockets, which are identified  by  pathname)
940                    Write permission is denied on the destination socket file, or
941                    search permission is denied for one of  the  directories  the
942                    path prefix.  (See path_resolution(7).)
943 
944             EAGAIN or EWOULDBLOCK
945                    The  socket is marked nonblocking and the requested operation
946                    would block.  POSIX.1-2001 allows either error to be returned
947                    for  this  case, and does not require these constants to have
948                    the same value, so a portable application  should  check  for
949                    both possibilities.
950 
951             EBADF  An invalid descriptor was specified.
952 
953             ECONNRESET
954                    Connection reset by peer.
955 
956             EDESTADDRREQ
957                    The  socket  is  not  connection-mode, and no peer address is
958                    set.
959 
960             EFAULT An invalid user space address was specified for an argument.
961 
962             EINTR  A signal occurred before any data was transmitted;  see  sig‐
963                    nal(7).
964 
965             EINVAL Invalid argument passed.
966 
967             EISCONN
968                    The connection-mode socket was connected already but a recip‐
969                    ient was specified.  (Now either this error is  returned,  or
970                    the recipient specification is ignored.)
971 
972             EMSGSIZE
973                    The socket type requires that message be sent atomically, and
974                    the size of the message to be sent made this impossible.
975 
976             ENOBUFS
977                    The output queue for a network interface was full.  This gen‐
978                    erally  indicates that the interface has stopped sending, but
979                    may be caused by transient congestion.  (Normally, this  does
980                    not occur in Linux.  Packets are just silently dropped when a
981                    device queue overflows.)
982 
983             ENOMEM No memory available.
984 
985             ENOTCONN
986                    The socket is not connected, and no target has been given.
987 
988             ENOTSOCK
989                    The argument sockfd is not a socket.
990 
991             EOPNOTSUPP
992                    Some bit in the  flags  argument  is  inappropriate  for  the
993                    socket type.
994 
995             EPIPE  The  local  end  has  been shut down on a connection oriented
996                    socket.  In this case the process will also receive a SIGPIPE
997                    unless MSG_NOSIGNAL is set.
998 
999      **************************************************************************/
1000 
1001     public ssize_t send ( const(void)[] src, int flags )
1002     {
1003         return .send(this.fd, src.ptr, src.length,
1004                      this.suppress_sigpipe? flags | MSG_NOSIGNAL : flags);
1005     }
1006 
1007     /**************************************************************************
1008 
1009         Receives dst.length bytes from the remote but at most as possible with
1010         one attempt.
1011 
1012 
1013         Params:
1014             dst   = buffer to receive data in
1015             flags =  the bitwise OR of zero or more of the following flags:
1016 
1017                 MSG_CMSG_CLOEXEC (recvmsg() only; since Linux 2.6.23)
1018                        Set  the  close-on-exec  flag  for  the  file  descriptor
1019                        received via a Unix  domain  file  descriptor  using  the
1020                        SCM_RIGHTS  operation  (described in unix(7)).  This flag
1021                        is useful for the same reasons as the O_CLOEXEC  flag  of
1022                        open(2).
1023 
1024                 MSG_DONTWAIT (since Linux 2.2)
1025                        Enables  nonblocking  operation;  if  the operation would
1026                        block, the call fails with the error  EAGAIN  or  EWOULD‐
1027                        BLOCK (this can also be enabled using the O_NONBLOCK flag
1028                        with the F_SETFL fcntl(2)).
1029                 MSG_OOB
1030                        This flag requests receipt of out-of-band data that would
1031                        not be received in the normal data stream.   Some  proto‐
1032                        cols  place expedited data at the head of the normal data
1033                        queue, and thus this flag cannot be used with such proto‐
1034                        cols.
1035 
1036                 MSG_PEEK
1037                        This  flag  causes  the  receive operation to return data
1038                        from the beginning of the receive queue without  removing
1039                        that  data  from  the  queue.  Thus, a subsequent receive
1040                        call will return the same data.
1041 
1042                 MSG_TRUNC (since Linux 2.2)
1043                        For  raw  (AF_PACKET),  Internet  datagram  (since  Linux
1044                        2.4.27/2.6.8),  and netlink (since Linux 2.6.22) sockets:
1045                        return the real length of the packet  or  datagram,  even
1046                        when  it  was  longer than the passed buffer.  Not imple‐
1047                        mented for Unix domain (unix(7)) sockets.
1048 
1049                        For use with Internet stream sockets, see tcp(7).
1050 
1051                 MSG_WAITALL (since Linux 2.2)
1052                        This flag requests that the  operation  block  until  the
1053                        full  request  is satisfied.  However, the call may still
1054                        return less data than requested if a signal is caught, an
1055                        error  or  disconnect  occurs,  or  the  next  data to be
1056                        received is of a different type than that returned.
1057                 MSG_EOR
1058                        indicates  end-of-record;  the  data returned completed a
1059                        record (generally used with  sockets  of  type  SOCK_SEQ‐
1060                        PACKET).
1061 
1062                 MSG_TRUNC
1063                        indicates  that  the  trailing  portion of a datagram was
1064                        discarded because the datagram was larger than the buffer
1065                        supplied.
1066 
1067                 MSG_CTRUNC
1068                        indicates  that  some  control data were discarded due to
1069                        lack of space in the buffer for ancillary data.
1070 
1071                 MSG_OOB
1072                        is returned to indicate  that  expedited  or  out-of-band
1073                        data were received.
1074 
1075                 MSG_ERRQUEUE
1076                        indicates that no data was received but an extended error
1077                        from the socket error queue.
1078 
1079         Returns:
1080             the number of bytes received on success or -1 on failure.
1081             On failure errno is set appropriately.
1082 
1083         Errors:
1084 
1085             EAGAIN or EWOULDBLOCK
1086                    The socket is marked nonblocking and  the  receive  operation
1087                    would  block, or a receive timeout had been set and the time‐
1088                    out expired before data was  received.   POSIX.1-2001  allows
1089                    either  error  to  be  returned  for  this case, and does not
1090                    require these constants to have the same value, so a portable
1091                    application should check for both possibilities.
1092 
1093             EBADF  The argument sockfd is an invalid descriptor.
1094 
1095             ECONNREFUSED
1096                    A  remote host refused to allow the network connection (typi‐
1097                    cally because it is not running the requested service).
1098 
1099             EFAULT The receive buffer pointer(s)  point  outside  the  process's
1100                    address space.
1101 
1102             EINTR  The  receive  was  interrupted by delivery of a signal before
1103                    any data were available; see signal(7).
1104 
1105             EINVAL Invalid argument passed.
1106 
1107             ENOMEM Could not allocate memory for recvmsg().
1108 
1109             ENOTCONN
1110                    The socket is associated with a connection-oriented  protocol
1111                    and has not been connected (see connect(2) and accept(2)).
1112 
1113             ENOTSOCK
1114                    The argument sockfd does not refer to a socket.
1115 
1116      **************************************************************************/
1117 
1118     public ssize_t recv ( void[] dst, int flags )
1119     {
1120         return .recv(this.fd, dst.ptr, dst.length, flags);
1121     }
1122 
1123     /**************************************************************************
1124 
1125         Obtains the local socket address.
1126 
1127         Note: This generic wrapper should be used only in special situations,
1128         the subclass variants for a particular address family are preferred.
1129 
1130         getsockname() returns the current address to which this socket is bound,
1131         in the buffer pointed to by local_address. The addrlen argument is
1132         initialized to this.in_addrlen which indicates the amount of space
1133         pointed to by addr. On return it contains the actual size of the name
1134         returned (in bytes). The name is truncated if the buffer provided is
1135         too small; in this case, addrlen will return a value greater than
1136         this.in_addrlen.
1137 
1138         Params:
1139             local_address = filled in with the address of the local socket, as
1140                              known to the communications layer; expected to
1141                              point to a sin_addr or sin6_addr instance,
1142                              depending on the IP version of this instance
1143             addrlen        = actual address struct length output, initialised to
1144                              this.in_addrlen; returning a different value
1145                              indicates socket family mixup
1146 
1147         Returns:
1148             0 success or -1 on failure. On failure errno is set appropriately.
1149 
1150         Errors:
1151             EBADF this.fd is not a valid descriptor.
1152 
1153             EFAULT local_address points to memory not in a valid part of the
1154                 process address space.
1155 
1156             EINVAL addrlen is invalid (e.g., is negative).
1157 
1158             ENOBUFS
1159                 Insufficient resources were available in the system to perform
1160                 the operation.
1161 
1162             ENOTSOCK
1163                 this.fd is a file, not a socket.
1164 
1165      **************************************************************************/
1166 
1167     public int getsockname ( sockaddr* local_address, out socklen_t addrlen )
1168     {
1169         addrlen = this.in_addrlen;
1170 
1171         return .getsockname(this.fd, local_address, &addrlen);
1172     }
1173 
1174     /**************************************************************************
1175 
1176         Obtains the remote socket address.
1177 
1178         Note: This generic wrapper should be used only in special situations,
1179         the subclass variants for a particular address family are preferred.
1180 
1181         getpeername() returns the address of the peer connected to this socket,
1182         in the buffer pointed to by remote_address. The addrlen argument is
1183         initialized to this.in_addrlen which indicates the amount of space
1184         pointed to by addr. On return it contains the actual size of the name
1185         returned (in bytes). The name is truncated if the buffer provided is
1186         too small; in this case, addrlen will return a value greater than
1187         this.in_addrlen.
1188 
1189         Params:
1190             remote_address = filled in with the address of the remote socket, as
1191                              known to the communications layer; expected to
1192                              point to a sin_addr or sin6_addr instance,
1193                              depending on the IP version of this instance
1194             addrlen        = actual address struct length output, initialised to
1195                              this.in_addrlen; returning a different value
1196                              indicates socket family mixup
1197 
1198         Returns:
1199             0 success or -1 on failure. On failure errno is set appropriately.
1200 
1201         Errors:
1202             EBADF this.fd is not a valid descriptor.
1203 
1204             EFAULT remote_address points to memory not in a valid part of the
1205                 process address space.
1206 
1207             EINVAL addrlen is invalid (e.g., is negative).
1208 
1209             ENOBUFS
1210                 Insufficient resources were available in the system to perform
1211                 the operation.
1212 
1213             ENOTCONN
1214                 The socket is not connected.
1215 
1216             ENOTSOCK
1217                 this.fd is a file, not a socket.
1218 
1219      **************************************************************************/
1220 
1221     public int getpeername ( sockaddr* remote_address, out socklen_t addrlen )
1222     {
1223         addrlen = this.in_addrlen;
1224 
1225         return .getpeername(this.fd, remote_address, &addrlen);
1226     }
1227 
1228     /**************************************************************************
1229 
1230         Closes the socket and resets the file descriptor, address and port.
1231 
1232         Returns:
1233             0 success or -1 on failure. On failure errno is set appropriately.
1234 
1235         Errors:
1236             EBADF  fd isn't a valid open file descriptor.
1237 
1238             EINTR  The close() call was interrupted by a signal; see signal(7).
1239 
1240             EIO    An I/O error occurred.
1241 
1242      **************************************************************************/
1243 
1244     public int close ( )
1245     {
1246         scope (exit) this.clear();
1247 
1248         return .close(this.fd);
1249     }
1250 
1251     /**************************************************************************
1252 
1253         Resets the file descriptor, address and port.
1254         Called from close(), should be called otherwise only in special
1255         situations.
1256 
1257      **************************************************************************/
1258 
1259     public void clear ( )
1260     {
1261         this.fd                  = -1;
1262         this.close_in_destructor = false;
1263     }
1264 
1265 
1266     /**************************************************************************
1267 
1268         Formats information about the socket into the provided buffer.
1269 
1270         Params:
1271             buf      = buffer to format into
1272             io_error = true if an I/O error has been reported
1273 
1274      **************************************************************************/
1275 
1276     abstract public void formatInfo ( ref char[] buf, bool io_error );
1277 }
1278 
1279 // TODO: Replace with import ocean.stdc.posix.sys.socket: accept4
1280 
1281 extern (C) private int accept4(int sockfd, sockaddr* addr, socklen_t* addrlen,
1282                                SocketFlags flags = SocketFlags.None);