sig
  module Address :
    sig
      module Unix :
        sig
          type t = [ `Unix of string ]
          val create : string -> Unix_syscalls.Socket.Address.Unix.t
          val to_string : Unix_syscalls.Socket.Address.Unix.t -> string
          val compare :
            Unix_syscalls.Socket.Address.Unix.t ->
            Unix_syscalls.Socket.Address.Unix.t -> int
          val t_of_sexp :
            Sexplib.Sexp.t -> Unix_syscalls.Socket.Address.Unix.t
          val __t_of_sexp__ :
            Sexplib.Sexp.t -> Unix_syscalls.Socket.Address.Unix.t
          val sexp_of_t :
            Unix_syscalls.Socket.Address.Unix.t -> Sexplib.Sexp.t
          val bin_t :
            Unix_syscalls.Socket.Address.Unix.t
            Core.Std.Bin_prot.Type_class.t
          val bin_read_t :
            Unix_syscalls.Socket.Address.Unix.t Core.Std.Bin_prot.Read.reader
          val __bin_read_t__ :
            (int -> Unix_syscalls.Socket.Address.Unix.t)
            Core.Std.Bin_prot.Read.reader
          val bin_reader_t :
            Unix_syscalls.Socket.Address.Unix.t
            Core.Std.Bin_prot.Type_class.reader
          val bin_size_t :
            Unix_syscalls.Socket.Address.Unix.t Core.Std.Bin_prot.Size.sizer
          val bin_write_t :
            Unix_syscalls.Socket.Address.Unix.t
            Core.Std.Bin_prot.Write.writer
          val bin_writer_t :
            Unix_syscalls.Socket.Address.Unix.t
            Core.Std.Bin_prot.Type_class.writer
        end
      module Inet :
        sig
          type t = [ `Inet of Unix_syscalls.Inet_addr.t * int ]
          val create :
            Unix_syscalls.Inet_addr.t ->
            port:int -> Unix_syscalls.Socket.Address.Inet.t
          val create_bind_any :
            port:int -> Unix_syscalls.Socket.Address.Inet.t
          val addr :
            Unix_syscalls.Socket.Address.Inet.t -> Unix_syscalls.Inet_addr.t
          val port : Unix_syscalls.Socket.Address.Inet.t -> int
          val to_string : Unix_syscalls.Socket.Address.Inet.t -> string
          val compare :
            Unix_syscalls.Socket.Address.Inet.t ->
            Unix_syscalls.Socket.Address.Inet.t -> int
          val t_of_sexp :
            Sexplib.Sexp.t -> Unix_syscalls.Socket.Address.Inet.t
          val __t_of_sexp__ :
            Sexplib.Sexp.t -> Unix_syscalls.Socket.Address.Inet.t
          val sexp_of_t :
            Unix_syscalls.Socket.Address.Inet.t -> Sexplib.Sexp.t
          val bin_t :
            Unix_syscalls.Socket.Address.Inet.t
            Core.Std.Bin_prot.Type_class.t
          val bin_read_t :
            Unix_syscalls.Socket.Address.Inet.t Core.Std.Bin_prot.Read.reader
          val __bin_read_t__ :
            (int -> Unix_syscalls.Socket.Address.Inet.t)
            Core.Std.Bin_prot.Read.reader
          val bin_reader_t :
            Unix_syscalls.Socket.Address.Inet.t
            Core.Std.Bin_prot.Type_class.reader
          val bin_size_t :
            Unix_syscalls.Socket.Address.Inet.t Core.Std.Bin_prot.Size.sizer
          val bin_write_t :
            Unix_syscalls.Socket.Address.Inet.t
            Core.Std.Bin_prot.Write.writer
          val bin_writer_t :
            Unix_syscalls.Socket.Address.Inet.t
            Core.Std.Bin_prot.Type_class.writer
        end
      type t = [ `Inet of Unix_syscalls.Inet_addr.t * int | `Unix of string ]
      val to_string : [< Unix_syscalls.Socket.Address.t ] -> string
      val to_sockaddr :
        [< Unix_syscalls.Socket.Address.t ] -> Core.Std.Unix.sockaddr
      val t_of_sexp : Sexplib.Sexp.t -> Unix_syscalls.Socket.Address.t
      val __t_of_sexp__ : Sexplib.Sexp.t -> Unix_syscalls.Socket.Address.t
      val sexp_of_t : Unix_syscalls.Socket.Address.t -> Sexplib.Sexp.t
      val bin_t :
        Unix_syscalls.Socket.Address.t Core.Std.Bin_prot.Type_class.t
      val bin_read_t :
        Unix_syscalls.Socket.Address.t Core.Std.Bin_prot.Read.reader
      val __bin_read_t__ :
        (int -> Unix_syscalls.Socket.Address.t) Core.Std.Bin_prot.Read.reader
      val bin_reader_t :
        Unix_syscalls.Socket.Address.t Core.Std.Bin_prot.Type_class.reader
      val bin_size_t :
        Unix_syscalls.Socket.Address.t Core.Std.Bin_prot.Size.sizer
      val bin_write_t :
        Unix_syscalls.Socket.Address.t Core.Std.Bin_prot.Write.writer
      val bin_writer_t :
        Unix_syscalls.Socket.Address.t Core.Std.Bin_prot.Type_class.writer
    end
  module Family :
    sig
      type 'a t constraint 'a = [< Unix_syscalls.Socket.Address.t ]
      val unix :
        Unix_syscalls.Socket.Address.Unix.t Unix_syscalls.Socket.Family.t
      val inet :
        Unix_syscalls.Socket.Address.Inet.t Unix_syscalls.Socket.Family.t
      val to_string :
        [< Unix_syscalls.Socket.Address.t ] Unix_syscalls.Socket.Family.t ->
        string
    end
  type ('a, 'b) t
    constraint 'a = [< `Active | `Bound | `Passive | `Unconnected ]
    constraint 'b = [< Unix_syscalls.Socket.Address.t ]
  module Type :
    sig
      type 'a t constraint 'a = [< Unix_syscalls.Socket.Address.t ]
      val tcp :
        Unix_syscalls.Socket.Address.Inet.t Unix_syscalls.Socket.Type.t
      val udp :
        Unix_syscalls.Socket.Address.Inet.t Unix_syscalls.Socket.Type.t
      val unix :
        Unix_syscalls.Socket.Address.Unix.t Unix_syscalls.Socket.Type.t
      val unix_dgram :
        Unix_syscalls.Socket.Address.Unix.t Unix_syscalls.Socket.Type.t
    end
  val create :
    ([< Unix_syscalls.Socket.Address.t ] as 'a) Unix_syscalls.Socket.Type.t ->
    ([ `Unconnected ], 'a) Unix_syscalls.Socket.t
  val connect :
    ([ `Unconnected ], [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t ->
    '-> ([ `Active ], 'a) Unix_syscalls.Socket.t Import.Deferred.t
  val connect_interruptible :
    ([ `Unconnected ], [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t ->
    '->
    interrupt:unit Import.Deferred.t ->
    [ `Interrupted | `Ok of ([ `Active ], 'a) Unix_syscalls.Socket.t ]
    Import.Deferred.t
  val bind :
    ([ `Unconnected ], [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t ->
    '-> ([ `Bound ], 'a) Unix_syscalls.Socket.t Import.Deferred.t
  val listen :
    ?max_pending_connections:int ->
    ([ `Bound ], [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t -> ([ `Passive ], 'a) Unix_syscalls.Socket.t
  val accept :
    ([ `Passive ], [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t ->
    [ `Ok of ([ `Active ], 'a) Unix_syscalls.Socket.t * '| `Socket_closed ]
    Import.Deferred.t
  val accept_interruptible :
    ([ `Passive ], [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t ->
    interrupt:unit Import.Deferred.t ->
    [ `Interrupted
    | `Ok of ([ `Active ], 'a) Unix_syscalls.Socket.t * 'a
    | `Socket_closed ] Import.Deferred.t
  val shutdown :
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ])
    Unix_syscalls.Socket.t -> [ `Both | `Receive | `Send ] -> unit
  val fd :
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ])
    Unix_syscalls.Socket.t -> Fd.t
  val of_fd :
    Fd.t ->
    ([< Unix_syscalls.Socket.Address.t ] as 'a) Unix_syscalls.Socket.Type.t ->
    ([< `Active | `Bound | `Passive | `Unconnected ], 'a)
    Unix_syscalls.Socket.t
  val getsockname :
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t -> 'a
  val getpeername :
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t -> 'a
  module Opt :
    sig
      type 'a t
      val debug : bool Unix_syscalls.Socket.Opt.t
      val broadcast : bool Unix_syscalls.Socket.Opt.t
      val reuseaddr : bool Unix_syscalls.Socket.Opt.t
      val keepalive : bool Unix_syscalls.Socket.Opt.t
      val dontroute : bool Unix_syscalls.Socket.Opt.t
      val oobinline : bool Unix_syscalls.Socket.Opt.t
      val acceptconn : bool Unix_syscalls.Socket.Opt.t
      val nodelay : bool Unix_syscalls.Socket.Opt.t
      val sndbuf : int Unix_syscalls.Socket.Opt.t
      val rcvbuf : int Unix_syscalls.Socket.Opt.t
      val error : int Unix_syscalls.Socket.Opt.t
      val typ : int Unix_syscalls.Socket.Opt.t
      val rcvlowat : int Unix_syscalls.Socket.Opt.t
      val sndlowat : int Unix_syscalls.Socket.Opt.t
      val linger : int option Unix_syscalls.Socket.Opt.t
      val rcvtimeo : float Unix_syscalls.Socket.Opt.t
      val sndtimeo : float Unix_syscalls.Socket.Opt.t
      val mcast_loop : bool Unix_syscalls.Socket.Opt.t
      val mcast_ttl : int Unix_syscalls.Socket.Opt.t
      val to_string : 'Unix_syscalls.Socket.Opt.t -> string
    end
  val getopt :
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ])
    Unix_syscalls.Socket.t -> 'Unix_syscalls.Socket.Opt.t -> 'c
  val setopt :
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ])
    Unix_syscalls.Socket.t -> 'Unix_syscalls.Socket.Opt.t -> '-> unit
  val mcast_join :
    ?ifname:string ->
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t -> '-> unit
  val mcast_leave :
    ?ifname:string ->
    ([< `Active | `Bound | `Passive | `Unconnected ],
     [< Unix_syscalls.Socket.Address.t ] as 'a)
    Unix_syscalls.Socket.t -> '-> unit
  val sexp_of_t :
    (([< `Active | `Bound | `Passive | `Unconnected ] as 'a) ->
     Sexplib.Sexp.t) ->
    (([< Unix_syscalls.Socket.Address.t ] as 'b) -> Sexplib.Sexp.t) ->
    ('a, 'b) Unix_syscalls.Socket.t -> Sexplib.Sexp.t
end