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