Skip to content

Commit f043f61

Browse files
committed
add support for setting/getting socket options
1 parent 7695d22 commit f043f61

File tree

15 files changed

+421
-4
lines changed

15 files changed

+421
-4
lines changed

lib_eio/mock/flow.ml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,52 @@ module Mock_flow = struct
108108
done;
109109
traceln "%s: closed" t.label
110110

111+
let setsockopt : type a. t -> a Eio.Net.Sockopt.t -> a -> unit = fun t opt v ->
112+
let opt_desc = match opt with
113+
| Eio.Net.Sockopt.SO_DEBUG -> Fmt.str "SO_DEBUG = %b" v
114+
| Eio.Net.Sockopt.SO_BROADCAST -> Fmt.str "SO_BROADCAST = %b" v
115+
| Eio.Net.Sockopt.SO_REUSEADDR -> Fmt.str "SO_REUSEADDR = %b" v
116+
| Eio.Net.Sockopt.SO_KEEPALIVE -> Fmt.str "SO_KEEPALIVE = %b" v
117+
| Eio.Net.Sockopt.SO_DONTROUTE -> Fmt.str "SO_DONTROUTE = %b" v
118+
| Eio.Net.Sockopt.SO_OOBINLINE -> Fmt.str "SO_OOBINLINE = %b" v
119+
| Eio.Net.Sockopt.SO_ACCEPTCONN -> Fmt.str "SO_ACCEPTCONN = %b" v
120+
| Eio.Net.Sockopt.TCP_NODELAY -> Fmt.str "TCP_NODELAY = %b" v
121+
| Eio.Net.Sockopt.IPV6_ONLY -> Fmt.str "IPV6_ONLY = %b" v
122+
| Eio.Net.Sockopt.SO_REUSEPORT -> Fmt.str "SO_REUSEPORT = %b" v
123+
| Eio.Net.Sockopt.SO_SNDBUF -> Fmt.str "SO_SNDBUF = %d" v
124+
| Eio.Net.Sockopt.SO_RCVBUF -> Fmt.str "SO_RCVBUF = %d" v
125+
| Eio.Net.Sockopt.SO_TYPE -> Fmt.str "SO_TYPE = %d" v
126+
| Eio.Net.Sockopt.SO_RCVLOWAT -> Fmt.str "SO_RCVLOWAT = %d" v
127+
| Eio.Net.Sockopt.SO_SNDLOWAT -> Fmt.str "SO_SNDLOWAT = %d" v
128+
| Eio.Net.Sockopt.SO_LINGER -> Fmt.str "SO_LINGER = %s" (match v with None -> "None" | Some n -> string_of_int n)
129+
| Eio.Net.Sockopt.SO_RCVTIMEO -> Fmt.str "SO_RCVTIMEO = %f" v
130+
| Eio.Net.Sockopt.SO_SNDTIMEO -> Fmt.str "SO_SNDTIMEO = %f" v
131+
| _ -> "unknown"
132+
in
133+
traceln "%s: setsockopt %s (mock)" t.label opt_desc
134+
135+
let getsockopt : type a. t -> a Eio.Net.Sockopt.t -> a = fun t opt ->
136+
match opt with
137+
| Eio.Net.Sockopt.SO_DEBUG -> traceln "%s: getsockopt SO_DEBUG = false" t.label; false
138+
| Eio.Net.Sockopt.SO_BROADCAST -> traceln "%s: getsockopt SO_BROADCAST = false" t.label; false
139+
| Eio.Net.Sockopt.SO_REUSEADDR -> traceln "%s: getsockopt SO_REUSEADDR = false" t.label; false
140+
| Eio.Net.Sockopt.SO_KEEPALIVE -> traceln "%s: getsockopt SO_KEEPALIVE = false" t.label; false
141+
| Eio.Net.Sockopt.SO_DONTROUTE -> traceln "%s: getsockopt SO_DONTROUTE = false" t.label; false
142+
| Eio.Net.Sockopt.SO_OOBINLINE -> traceln "%s: getsockopt SO_OOBINLINE = false" t.label; false
143+
| Eio.Net.Sockopt.SO_ACCEPTCONN -> traceln "%s: getsockopt SO_ACCEPTCONN = false" t.label; false
144+
| Eio.Net.Sockopt.TCP_NODELAY -> traceln "%s: getsockopt TCP_NODELAY = false" t.label; false
145+
| Eio.Net.Sockopt.IPV6_ONLY -> traceln "%s: getsockopt IPV6_ONLY = false" t.label; false
146+
| Eio.Net.Sockopt.SO_REUSEPORT -> traceln "%s: getsockopt SO_REUSEPORT = false" t.label; false
147+
| Eio.Net.Sockopt.SO_SNDBUF -> traceln "%s: getsockopt SO_SNDBUF = 0" t.label; 0
148+
| Eio.Net.Sockopt.SO_RCVBUF -> traceln "%s: getsockopt SO_RCVBUF = 0" t.label; 0
149+
| Eio.Net.Sockopt.SO_TYPE -> traceln "%s: getsockopt SO_TYPE = 0" t.label; 0
150+
| Eio.Net.Sockopt.SO_RCVLOWAT -> traceln "%s: getsockopt SO_RCVLOWAT = 0" t.label; 0
151+
| Eio.Net.Sockopt.SO_SNDLOWAT -> traceln "%s: getsockopt SO_SNDLOWAT = 0" t.label; 0
152+
| Eio.Net.Sockopt.SO_LINGER -> traceln "%s: getsockopt SO_LINGER = None" t.label; None
153+
| Eio.Net.Sockopt.SO_RCVTIMEO -> traceln "%s: getsockopt SO_RCVTIMEO = 0.0" t.label; 0.0
154+
| Eio.Net.Sockopt.SO_SNDTIMEO -> traceln "%s: getsockopt SO_SNDTIMEO = 0.0" t.label; 0.0
155+
| _ -> raise (Failure "Mock getsockopt not implemented")
156+
111157
let make ?(pp=pp_default) label =
112158
{
113159
pp;

lib_eio/mock/net.ml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ module Listening_socket = struct
9999
label : string;
100100
listening_addr : Eio.Net.Sockaddr.stream;
101101
on_accept : (Flow.t * Eio.Net.Sockaddr.stream) Handler.t;
102+
(* TODO: avsm persist sockopts? *)
102103
}
103104

104105
type tag = [`Generic]
@@ -123,6 +124,52 @@ module Listening_socket = struct
123124

124125
let listening_addr { listening_addr; _ } = listening_addr
125126

127+
let setsockopt : type a. t -> a Eio.Net.Sockopt.t -> a -> unit = fun t opt v ->
128+
let opt_desc = match opt with
129+
| Eio.Net.Sockopt.SO_DEBUG -> Fmt.str "SO_DEBUG = %b" v
130+
| Eio.Net.Sockopt.SO_BROADCAST -> Fmt.str "SO_BROADCAST = %b" v
131+
| Eio.Net.Sockopt.SO_REUSEADDR -> Fmt.str "SO_REUSEADDR = %b" v
132+
| Eio.Net.Sockopt.SO_KEEPALIVE -> Fmt.str "SO_KEEPALIVE = %b" v
133+
| Eio.Net.Sockopt.SO_DONTROUTE -> Fmt.str "SO_DONTROUTE = %b" v
134+
| Eio.Net.Sockopt.SO_OOBINLINE -> Fmt.str "SO_OOBINLINE = %b" v
135+
| Eio.Net.Sockopt.SO_ACCEPTCONN -> Fmt.str "SO_ACCEPTCONN = %b" v
136+
| Eio.Net.Sockopt.TCP_NODELAY -> Fmt.str "TCP_NODELAY = %b" v
137+
| Eio.Net.Sockopt.IPV6_ONLY -> Fmt.str "IPV6_ONLY = %b" v
138+
| Eio.Net.Sockopt.SO_REUSEPORT -> Fmt.str "SO_REUSEPORT = %b" v
139+
| Eio.Net.Sockopt.SO_SNDBUF -> Fmt.str "SO_SNDBUF = %d" v
140+
| Eio.Net.Sockopt.SO_RCVBUF -> Fmt.str "SO_RCVBUF = %d" v
141+
| Eio.Net.Sockopt.SO_TYPE -> Fmt.str "SO_TYPE = %d" v
142+
| Eio.Net.Sockopt.SO_RCVLOWAT -> Fmt.str "SO_RCVLOWAT = %d" v
143+
| Eio.Net.Sockopt.SO_SNDLOWAT -> Fmt.str "SO_SNDLOWAT = %d" v
144+
| Eio.Net.Sockopt.SO_LINGER -> Fmt.str "SO_LINGER = %s" (match v with None -> "None" | Some n -> string_of_int n)
145+
| Eio.Net.Sockopt.SO_RCVTIMEO -> Fmt.str "SO_RCVTIMEO = %f" v
146+
| Eio.Net.Sockopt.SO_SNDTIMEO -> Fmt.str "SO_SNDTIMEO = %f" v
147+
| _ -> "unknown"
148+
in
149+
traceln "%s: setsockopt %s" t.label opt_desc
150+
151+
let getsockopt : type a. t -> a Eio.Net.Sockopt.t -> a = fun t opt ->
152+
match opt with
153+
| Eio.Net.Sockopt.SO_DEBUG -> traceln "%s: getsockopt SO_DEBUG = false" t.label; false
154+
| Eio.Net.Sockopt.SO_BROADCAST -> traceln "%s: getsockopt SO_BROADCAST = false" t.label; false
155+
| Eio.Net.Sockopt.SO_REUSEADDR -> traceln "%s: getsockopt SO_REUSEADDR = false" t.label; false
156+
| Eio.Net.Sockopt.SO_KEEPALIVE -> traceln "%s: getsockopt SO_KEEPALIVE = false" t.label; false
157+
| Eio.Net.Sockopt.SO_DONTROUTE -> traceln "%s: getsockopt SO_DONTROUTE = false" t.label; false
158+
| Eio.Net.Sockopt.SO_OOBINLINE -> traceln "%s: getsockopt SO_OOBINLINE = false" t.label; false
159+
| Eio.Net.Sockopt.SO_ACCEPTCONN -> traceln "%s: getsockopt SO_ACCEPTCONN = false" t.label; false
160+
| Eio.Net.Sockopt.TCP_NODELAY -> traceln "%s: getsockopt TCP_NODELAY = false" t.label; false
161+
| Eio.Net.Sockopt.IPV6_ONLY -> traceln "%s: getsockopt IPV6_ONLY = false" t.label; false
162+
| Eio.Net.Sockopt.SO_REUSEPORT -> traceln "%s: getsockopt SO_REUSEPORT = false" t.label; false
163+
| Eio.Net.Sockopt.SO_SNDBUF -> traceln "%s: getsockopt SO_SNDBUF = 0" t.label; 0
164+
| Eio.Net.Sockopt.SO_RCVBUF -> traceln "%s: getsockopt SO_RCVBUF = 0" t.label; 0
165+
| Eio.Net.Sockopt.SO_TYPE -> traceln "%s: getsockopt SO_TYPE = 0" t.label; 0
166+
| Eio.Net.Sockopt.SO_RCVLOWAT -> traceln "%s: getsockopt SO_RCVLOWAT = 0" t.label; 0
167+
| Eio.Net.Sockopt.SO_SNDLOWAT -> traceln "%s: getsockopt SO_SNDLOWAT = 0" t.label; 0
168+
| Eio.Net.Sockopt.SO_LINGER -> traceln "%s: getsockopt SO_LINGER = None" t.label; None
169+
| Eio.Net.Sockopt.SO_RCVTIMEO -> traceln "%s: getsockopt SO_RCVTIMEO = 0.0" t.label; 0.0
170+
| Eio.Net.Sockopt.SO_SNDTIMEO -> traceln "%s: getsockopt SO_SNDTIMEO = 0.0" t.label; 0.0
171+
| _ -> raise (Failure "Mock getsockopt not implemented")
172+
126173
type (_, _, _) Eio.Resource.pi += Type : ('t, 't -> t, listening_socket_ty) Eio.Resource.pi
127174
let raw (Eio.Resource.T (t, ops)) = Eio.Resource.get ops Type t
128175
end

lib_eio/net.ml

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,31 @@ module Sockaddr = struct
159159
Format.fprintf f "udp:%a:%d" Ipaddr.pp_for_uri addr port
160160
end
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]
163187
type 'a socket = ([> socket_ty] as 'a) r
164188

165189
type '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

183207
module 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+
281327
let 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

lib_eio/net.mli

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,37 @@ module Sockaddr : sig
102102
val pp : Format.formatter -> [< t] -> unit
103103
end
104104

105+
(** Socket options. *)
106+
module Sockopt : sig
107+
(** An extensible type for socket options. Portable options can be defined
108+
here, while platform-specific options can be added by backends. *)
109+
110+
type _ t = ..
111+
112+
type _ t +=
113+
| SO_DEBUG : bool t (** Enable socket debugging *)
114+
| SO_BROADCAST : bool t (** Permit sending of broadcast messages *)
115+
| SO_REUSEADDR : bool t (** Allow reuse of local addresses *)
116+
| SO_KEEPALIVE : bool t (** Keep TCP connection alive *)
117+
| SO_DONTROUTE : bool t (** Bypass routing tables *)
118+
| SO_OOBINLINE : bool t (** Leave out-of-band data in line *)
119+
| SO_ACCEPTCONN : bool t (** Socket is listening (get only) *)
120+
| TCP_NODELAY : bool t (** Disable Nagle's algorithm *)
121+
| IPV6_ONLY : bool t (** Restrict to IPv6 only *)
122+
| SO_REUSEPORT : bool t (** Allow reuse of local port *)
123+
| SO_SNDBUF : int t (** Send buffer size *)
124+
| SO_RCVBUF : int t (** Receive buffer size *)
125+
| SO_TYPE : int t (** Socket type (get only) *)
126+
| SO_RCVLOWAT : int t (** Receive low water mark *)
127+
| SO_SNDLOWAT : int t (** Send low water mark *)
128+
| SO_LINGER : int option t (** Linger on close if data present *)
129+
| SO_RCVTIMEO : float t (** Receive timeout *)
130+
| SO_SNDTIMEO : float t (** Send timeout *)
131+
end
132+
105133
(** {2 Types} *)
106134

107-
type socket_ty = [`Socket | `Close]
135+
type socket_ty = [`Socket | `Close | `Sockopt]
108136
type 'a socket = ([> socket_ty] as 'a) r
109137

110138
type 'tag stream_socket_ty = [`Stream | `Platform of 'tag | `Shutdown | socket_ty | Flow.source_ty | Flow.sink_ty]
@@ -127,6 +155,14 @@ type 'tag ty = [`Network | `Platform of 'tag]
127155
type 'a t = 'a r
128156
constraint 'a = [> [> `Generic] ty]
129157

158+
(** {2 Socket options} *)
159+
160+
val setsockopt : [> `Sockopt] r -> 'a Sockopt.t -> 'a -> unit
161+
(** [setsockopt s opt v] sets socket option [opt] to value [v] on socket [s]. *)
162+
163+
val getsockopt : [> `Sockopt] r -> 'a Sockopt.t -> 'a
164+
(** [getsockopt s opt] gets the value of socket option [opt] on socket [s]. *)
165+
130166
(** {2 Out-bound Connections} *)
131167

132168
val connect : sw:Switch.t -> [> 'tag ty] t -> Sockaddr.stream -> 'tag stream_socket_ty r
@@ -304,11 +340,18 @@ val close : [> `Close] r -> unit
304340
(** {2 Provider Interface} *)
305341

306342
module Pi : sig
343+
module type SOCKET = sig
344+
type t
345+
val setsockopt : t -> 'a Sockopt.t -> 'a -> unit
346+
val getsockopt : t -> 'a Sockopt.t -> 'a
347+
end
348+
307349
module type STREAM_SOCKET = sig
308350
type tag
309351
include Flow.Pi.SHUTDOWN
310352
include Flow.Pi.SOURCE with type t := t
311353
include Flow.Pi.SINK with type t := t
354+
include SOCKET with type t := t
312355
val close : t -> unit
313356
end
314357

@@ -319,6 +362,7 @@ module Pi : sig
319362
module type DATAGRAM_SOCKET = sig
320363
type tag
321364
include Flow.Pi.SHUTDOWN
365+
include SOCKET with type t := t
322366
val send : t -> ?dst:Sockaddr.datagram -> Cstruct.t list -> unit
323367
val recv : t -> Cstruct.t -> Sockaddr.datagram * int
324368
val close : t -> unit
@@ -331,7 +375,7 @@ module Pi : sig
331375
module type LISTENING_SOCKET = sig
332376
type t
333377
type tag
334-
378+
include SOCKET with type t := t
335379
val accept : t -> sw:Switch.t -> tag stream_socket_ty r * Sockaddr.stream
336380
val close : t -> unit
337381
val listening_addr : t -> Sockaddr.stream

lib_eio/unix/net.ml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,67 @@ let socketpair_datagram ~sw ?(domain=Unix.PF_UNIX) ?(protocol=0) () =
9191

9292
let fd socket =
9393
Option.get (Resource.fd_opt socket)
94+
95+
module Sockopt = struct
96+
type _ Eio.Net.Sockopt.t +=
97+
| Unix_bool : Unix.socket_bool_option -> bool Eio.Net.Sockopt.t
98+
| Unix_int : Unix.socket_int_option -> int Eio.Net.Sockopt.t
99+
| Unix_optint : Unix.socket_optint_option -> int option Eio.Net.Sockopt.t
100+
| Unix_float : Unix.socket_float_option -> float Eio.Net.Sockopt.t
101+
102+
let set : type a. Fd.t -> a Eio.Net.Sockopt.t -> a -> unit = fun fd opt v ->
103+
Fd.use_exn "setsockopt" fd @@ fun fd ->
104+
match opt with
105+
| Eio.Net.Sockopt.SO_DEBUG -> Unix.setsockopt fd Unix.SO_DEBUG v
106+
| Eio.Net.Sockopt.SO_BROADCAST -> Unix.setsockopt fd Unix.SO_BROADCAST v
107+
| Eio.Net.Sockopt.SO_REUSEADDR -> Unix.setsockopt fd Unix.SO_REUSEADDR v
108+
| Eio.Net.Sockopt.SO_KEEPALIVE -> Unix.setsockopt fd Unix.SO_KEEPALIVE v
109+
| Eio.Net.Sockopt.SO_DONTROUTE -> Unix.setsockopt fd Unix.SO_DONTROUTE v
110+
| Eio.Net.Sockopt.SO_OOBINLINE -> Unix.setsockopt fd Unix.SO_OOBINLINE v
111+
| Eio.Net.Sockopt.SO_ACCEPTCONN -> invalid_arg "SO_ACCEPTCONN is read-only"
112+
| Eio.Net.Sockopt.TCP_NODELAY -> Unix.setsockopt fd Unix.TCP_NODELAY v
113+
| Eio.Net.Sockopt.IPV6_ONLY -> Unix.setsockopt fd Unix.IPV6_ONLY v
114+
| Eio.Net.Sockopt.SO_REUSEPORT -> Unix.setsockopt fd Unix.SO_REUSEPORT v
115+
| Eio.Net.Sockopt.SO_SNDBUF -> Unix.setsockopt_int fd Unix.SO_SNDBUF v
116+
| Eio.Net.Sockopt.SO_RCVBUF -> Unix.setsockopt_int fd Unix.SO_RCVBUF v
117+
| Eio.Net.Sockopt.SO_TYPE -> invalid_arg "SO_TYPE is read-only"
118+
| Eio.Net.Sockopt.SO_RCVLOWAT -> Unix.setsockopt_int fd Unix.SO_RCVLOWAT v
119+
| Eio.Net.Sockopt.SO_SNDLOWAT -> Unix.setsockopt_int fd Unix.SO_SNDLOWAT v
120+
| Eio.Net.Sockopt.SO_LINGER -> Unix.setsockopt_optint fd Unix.SO_LINGER v
121+
| Eio.Net.Sockopt.SO_RCVTIMEO -> Unix.setsockopt_float fd Unix.SO_RCVTIMEO v
122+
| Eio.Net.Sockopt.SO_SNDTIMEO -> Unix.setsockopt_float fd Unix.SO_SNDTIMEO v
123+
| Unix_bool bo -> Unix.setsockopt fd bo v
124+
| Unix_int bo -> Unix.setsockopt_int fd bo v
125+
| Unix_optint bo -> Unix.setsockopt_optint fd bo v
126+
| Unix_float bo -> Unix.setsockopt_float fd bo v
127+
| _ -> raise (Invalid_argument "Unsupported socket option")
128+
129+
let get_descr : type a. Unix.file_descr -> a Eio.Net.Sockopt.t -> a = fun fd opt ->
130+
match opt with
131+
| Eio.Net.Sockopt.SO_DEBUG -> Unix.getsockopt fd Unix.SO_DEBUG
132+
| Eio.Net.Sockopt.SO_BROADCAST -> Unix.getsockopt fd Unix.SO_BROADCAST
133+
| Eio.Net.Sockopt.SO_REUSEADDR -> Unix.getsockopt fd Unix.SO_REUSEADDR
134+
| Eio.Net.Sockopt.SO_KEEPALIVE -> Unix.getsockopt fd Unix.SO_KEEPALIVE
135+
| Eio.Net.Sockopt.SO_DONTROUTE -> Unix.getsockopt fd Unix.SO_DONTROUTE
136+
| Eio.Net.Sockopt.SO_OOBINLINE -> Unix.getsockopt fd Unix.SO_OOBINLINE
137+
| Eio.Net.Sockopt.SO_ACCEPTCONN -> Unix.getsockopt fd Unix.SO_ACCEPTCONN
138+
| Eio.Net.Sockopt.TCP_NODELAY -> Unix.getsockopt fd Unix.TCP_NODELAY
139+
| Eio.Net.Sockopt.IPV6_ONLY -> Unix.getsockopt fd Unix.IPV6_ONLY
140+
| Eio.Net.Sockopt.SO_REUSEPORT -> Unix.getsockopt fd Unix.SO_REUSEPORT
141+
| Eio.Net.Sockopt.SO_SNDBUF -> Unix.getsockopt_int fd Unix.SO_SNDBUF
142+
| Eio.Net.Sockopt.SO_RCVBUF -> Unix.getsockopt_int fd Unix.SO_RCVBUF
143+
| Eio.Net.Sockopt.SO_TYPE -> Unix.getsockopt_int fd Unix.SO_TYPE
144+
| Eio.Net.Sockopt.SO_RCVLOWAT -> Unix.getsockopt_int fd Unix.SO_RCVLOWAT
145+
| Eio.Net.Sockopt.SO_SNDLOWAT -> Unix.getsockopt_int fd Unix.SO_SNDLOWAT
146+
| Eio.Net.Sockopt.SO_LINGER -> Unix.getsockopt_optint fd Unix.SO_LINGER
147+
| Eio.Net.Sockopt.SO_RCVTIMEO -> Unix.getsockopt_float fd Unix.SO_RCVTIMEO
148+
| Eio.Net.Sockopt.SO_SNDTIMEO -> Unix.getsockopt_float fd Unix.SO_SNDTIMEO
149+
| Unix_bool bo -> Unix.getsockopt fd bo
150+
| Unix_int bo -> Unix.getsockopt_int fd bo
151+
| Unix_optint bo -> Unix.getsockopt_optint fd bo
152+
| Unix_float bo -> Unix.getsockopt_float fd bo
153+
| _ -> raise (Invalid_argument "Unsupported socket option")
154+
155+
let get : type a. Fd.t -> a Eio.Net.Sockopt.t -> a = fun fd opt ->
156+
Fd.use_exn "getsockopt" fd @@ fun fd -> get_descr fd opt
157+
end

0 commit comments

Comments
 (0)