@@ -159,7 +159,31 @@ module Sockaddr = struct
159159 Format. fprintf f " udp:%a:%d" Ipaddr. pp_for_uri addr port
160160end
161161
162- type socket_ty = [`Socket | `Close ]
162+ module Sockopt = struct
163+ type _ t = ..
164+
165+ type _ t + =
166+ | SO_DEBUG : bool t
167+ | SO_BROADCAST : bool t
168+ | SO_REUSEADDR : bool t
169+ | SO_KEEPALIVE : bool t
170+ | SO_DONTROUTE : bool t
171+ | SO_OOBINLINE : bool t
172+ | SO_ACCEPTCONN : bool t
173+ | TCP_NODELAY : bool t
174+ | IPV6_ONLY : bool t
175+ | SO_REUSEPORT : bool t
176+ | SO_SNDBUF : int t
177+ | SO_RCVBUF : int t
178+ | SO_TYPE : int t
179+ | SO_RCVLOWAT : int t
180+ | SO_SNDLOWAT : int t
181+ | SO_LINGER : int option t
182+ | SO_RCVTIMEO : float t
183+ | SO_SNDTIMEO : float t
184+ end
185+
186+ type socket_ty = [`Socket | `Close | `Sockopt ]
163187type 'a socket = ([> socket_ty ] as 'a ) r
164188
165189type 'tag stream_socket_ty = [`Stream | `Platform of 'tag | `Shutdown | socket_ty | Flow .source_ty | Flow .sink_ty ]
@@ -181,22 +205,34 @@ type 'a t = 'a r
181205 constraint 'a = [> [> `Generic ] ty ]
182206
183207module Pi = struct
208+ module type SOCKET = sig
209+ type t
210+ val setsockopt : t -> 'a Sockopt .t -> 'a -> unit
211+ val getsockopt : t -> 'a Sockopt .t -> 'a
212+ end
213+
214+ type (_, _, _) Resource.pi + =
215+ | Socket : ('t , (module SOCKET with type t = 't ), [> `Sockopt ]) Resource .pi
216+
184217 module type STREAM_SOCKET = sig
185218 type tag
186219 include Flow.Pi .SHUTDOWN
187220 include Flow.Pi .SOURCE with type t : = t
188221 include Flow.Pi .SINK with type t : = t
222+ include SOCKET with type t : = t
189223 val close : t -> unit
190224 end
191225
192226 let stream_socket (type t tag ) (module X : STREAM_SOCKET with type t = t and type tag = tag ) =
193227 Resource. handler @@
194228 H (Resource. Close , X. close) ::
229+ H (Socket , (module X )) ::
195230 Resource. bindings (Flow.Pi. two_way (module X ))
196231
197232 module type DATAGRAM_SOCKET = sig
198233 type tag
199234 include Flow.Pi .SHUTDOWN
235+ include SOCKET with type t : = t
200236 val send : t -> ?dst : Sockaddr .datagram -> Cstruct .t list -> unit
201237 val recv : t -> Cstruct .t -> Sockaddr .datagram * int
202238 val close : t -> unit
@@ -208,14 +244,15 @@ module Pi = struct
208244 let datagram_socket (type t tag ) (module X : DATAGRAM_SOCKET with type t = t and type tag = tag ) =
209245 Resource. handler @@
210246 Resource. bindings (Flow.Pi. shutdown (module X )) @ [
247+ H (Socket , (module X ));
211248 H (Datagram_socket , (module X ));
212249 H (Resource. Close , X. close)
213250 ]
214251
215252 module type LISTENING_SOCKET = sig
216253 type t
217254 type tag
218-
255+ include SOCKET with type t : = t
219256 val accept : t -> sw :Switch .t -> tag stream_socket_ty r * Sockaddr .stream
220257 val close : t -> unit
221258 val listening_addr : t -> Sockaddr .stream
@@ -227,6 +264,7 @@ module Pi = struct
227264 let listening_socket (type t tag ) (module X : LISTENING_SOCKET with type t = t and type tag = tag ) =
228265 Resource. handler [
229266 H (Resource. Close , X. close);
267+ H (Socket , (module X ));
230268 H (Listening_socket , (module X ))
231269 ]
232270
@@ -278,6 +316,14 @@ let accept_fork ~sw (t : [> 'a listening_socket_ty] r) ~on_error handle =
278316 )
279317 )
280318
319+ let setsockopt (Resource. T (t , ops )) opt v =
320+ let module X = (val (Resource. get ops Pi. Socket )) in
321+ X. setsockopt t opt v
322+
323+ let getsockopt (Resource. T (t , ops )) opt =
324+ let module X = (val (Resource. get ops Pi. Socket )) in
325+ X. getsockopt t opt
326+
281327let listening_addr (type tag ) (Resource. T (t , ops ) : [> tag listening_socket_ty ] r ) =
282328 let module X = (val (Resource. get ops Pi. Listening_socket )) in
283329 X. listening_addr t
0 commit comments