File tree 14 files changed +62
-26
lines changed
14 files changed +62
-26
lines changed Original file line number Diff line number Diff line change @@ -36,7 +36,7 @@ module Impl = struct
36
36
Switch. on_release sw (fun () -> Eio.Resource. close socket);
37
37
socket
38
38
39
- let connect t ~sw addr =
39
+ let connect t ~sw ~ options : _ addr =
40
40
traceln " %s: connect to %a" t.label Eio.Net.Sockaddr. pp addr;
41
41
let socket = Handler. run t.on_connect in
42
42
Switch. on_release sw (fun () -> Eio.Flow. close socket);
Original file line number Diff line number Diff line change @@ -180,6 +180,12 @@ type 'tag ty = [`Network | `Platform of 'tag]
180
180
type 'a t = 'a r
181
181
constraint 'a = [> [> `Generic ] ty ]
182
182
183
+ type option = ..
184
+ type option + =
185
+ | Source_addr of Sockaddr .stream
186
+ | Reuse_addr
187
+ | Reuse_port
188
+
183
189
module Pi = struct
184
190
module type STREAM_SOCKET = sig
185
191
type tag
@@ -235,7 +241,7 @@ module Pi = struct
235
241
type tag
236
242
237
243
val listen : t -> reuse_addr :bool -> reuse_port :bool -> backlog :int -> sw :Switch .t -> Sockaddr .stream -> tag listening_socket_ty r
238
- val connect : t -> sw :Switch .t -> Sockaddr .stream -> tag stream_socket_ty r
244
+ val connect : t -> sw :Switch .t -> options : option list -> Sockaddr .stream -> tag stream_socket_ty r
239
245
val datagram_socket :
240
246
t
241
247
-> reuse_addr :bool
@@ -295,10 +301,10 @@ let listen (type tag) ?(reuse_addr=false) ?(reuse_port=false) ~backlog ~sw (t:[>
295
301
let module X = (val (Resource. get ops Pi. Network )) in
296
302
X. listen t ~reuse_addr ~reuse_port ~backlog ~sw
297
303
298
- let connect (type tag ) ~sw (t :[> tag ty] r ) addr =
304
+ let connect (type tag ) ~sw ?( options = [] ) (t :[> tag ty] r ) addr =
299
305
let (Resource. T (t, ops)) = t in
300
306
let module X = (val (Resource. get ops Pi. Network )) in
301
- try X. connect t ~sw addr
307
+ try X. connect t ~sw ~options addr
302
308
with Exn. Io _ as ex ->
303
309
let bt = Printexc. get_raw_backtrace () in
304
310
Exn. reraise_with_context ex bt " connecting to %a" Sockaddr. pp addr
Original file line number Diff line number Diff line change @@ -129,7 +129,13 @@ type 'a t = 'a r
129
129
130
130
(* * {2 Out-bound Connections} *)
131
131
132
- val connect : sw :Switch .t -> [> 'tag ty ] t -> Sockaddr .stream -> 'tag stream_socket_ty r
132
+ type option = ..
133
+ type option + =
134
+ | Source_addr of Sockaddr .stream
135
+ | Reuse_addr
136
+ | Reuse_port
137
+
138
+ val connect : sw :Switch .t -> ?options : option list -> [> 'tag ty ] t -> Sockaddr .stream -> 'tag stream_socket_ty r
133
139
(* * [connect ~sw t addr] is a new socket connected to remote address [addr].
134
140
135
141
The new socket will be closed when [sw] finishes, unless closed manually first. *)
@@ -346,7 +352,7 @@ module Pi : sig
346
352
t -> reuse_addr :bool -> reuse_port :bool -> backlog :int -> sw :Switch .t ->
347
353
Sockaddr .stream -> tag listening_socket_ty r
348
354
349
- val connect : t -> sw :Switch .t -> Sockaddr .stream -> tag stream_socket_ty r
355
+ val connect : t -> sw :Switch .t -> options : option list -> Sockaddr .stream -> tag stream_socket_ty r
350
356
351
357
val datagram_socket :
352
358
t
Original file line number Diff line number Diff line change @@ -85,3 +85,15 @@ let socketpair_datagram ~sw ?(domain=Unix.PF_UNIX) ?(protocol=0) () =
85
85
86
86
let fd socket =
87
87
Option. get (Resource. fd_opt socket)
88
+
89
+ let apply_option fd = function
90
+ | Eio.Net. Source_addr addr ->
91
+ Unix. bind fd (sockaddr_to_unix addr)
92
+ | Eio.Net. Reuse_addr ->
93
+ Unix. setsockopt fd Unix. SO_REUSEADDR true
94
+ | Eio.Net. Reuse_port ->
95
+ Unix. setsockopt fd Unix. SO_REUSEPORT true
96
+ | _ ->
97
+ invalid_arg " Unknown Eio.Net.option"
98
+
99
+ let configure options fd = List. iter (apply_option fd) options
Original file line number Diff line number Diff line change @@ -97,6 +97,9 @@ val socketpair_datagram :
97
97
val getnameinfo : Eio.Net.Sockaddr .t -> (string * string )
98
98
(* * [getnameinfo sockaddr] returns domain name and service for [sockaddr]. *)
99
99
100
+ val configure : Eio.Net .option list -> Unix .file_descr -> unit
101
+ (* * [configure options fd] prepare the socket with the chosen options. *)
102
+
100
103
type _ Effect.t + =
101
104
| Import_socket_stream :
102
105
Switch .t * bool * Unix .file_descr -> [`Unix_fd | stream_socket_ty ] r Effect .t (* * See {!import_socket_stream} *)
Original file line number Diff line number Diff line change @@ -249,11 +249,11 @@ let socket_domain_of = function
249
249
~v4: (fun _ -> Unix. PF_INET )
250
250
~v6: (fun _ -> Unix. PF_INET6 )
251
251
252
- let connect ~sw connect_addr =
252
+ let connect ~sw ~ options connect_addr =
253
253
let addr = Eio_unix.Net. sockaddr_to_unix connect_addr in
254
254
let sock_unix = Unix. socket ~cloexec: true (socket_domain_of connect_addr) Unix. SOCK_STREAM 0 in
255
255
let sock = Fd. of_unix ~sw ~seekable: false ~close_unix: true sock_unix in
256
- Low_level. connect sock addr;
256
+ Low_level. connect sock ~options addr;
257
257
(flow sock :> _ Eio_unix.Net.stream_socket )
258
258
259
259
module Impl = struct
@@ -289,7 +289,8 @@ module Impl = struct
289
289
Unix. listen sock_unix backlog;
290
290
(listening_socket sock :> _ Eio.Net.listening_socket_ty r )
291
291
292
- let connect () ~sw addr = (connect ~sw addr :> [`Generic | `Unix ] Eio.Net. stream_socket_ty r)
292
+ let connect () ~sw ~options addr =
293
+ (connect ~sw ~options addr :> [`Generic | `Unix ] Eio.Net. stream_socket_ty r)
293
294
294
295
let datagram_socket () ~reuse_addr ~reuse_port ~sw saddr =
295
296
if reuse_addr then (
Original file line number Diff line number Diff line change @@ -221,8 +221,9 @@ let splice src ~dst ~len =
221
221
else if res = 0 then raise End_of_file
222
222
else raise @@ Err. wrap (Uring. error_of_errno res) " splice" " "
223
223
224
- let connect fd addr =
224
+ let connect fd ~ options addr =
225
225
Fd. use_exn " connect" fd @@ fun fd ->
226
+ Eio_unix.Net. configure options fd ;
226
227
let res = Sched. enter " connect" (enqueue_connect fd addr) in
227
228
if res < 0 then (
228
229
let ex =
Original file line number Diff line number Diff line change @@ -111,8 +111,9 @@ val splice : fd -> dst:fd -> len:int -> int
111
111
@raise End_of_file [src] is at the end of the file.
112
112
@raise Unix.Unix_error(EINVAL, "splice", _) if splice is not supported for these FDs. *)
113
113
114
- val connect : fd -> Unix .sockaddr -> unit
115
- (* * [connect fd addr] attempts to connect socket [fd] to [addr]. *)
114
+ val connect : fd -> options :Eio .Net .option list -> Unix .sockaddr -> unit
115
+ (* * [connect fd ~options addr] attempts to connect socket [fd] to [addr]
116
+ after configuring the socket with [options]. *)
116
117
117
118
val await_readable : fd -> unit
118
119
(* * [await_readable fd] blocks until [fd] is readable (or has an error). *)
Original file line number Diff line number Diff line change @@ -67,15 +67,18 @@ let socket ~sw socket_domain socket_type protocol =
67
67
Unix. set_nonblock sock_unix;
68
68
Fd. of_unix ~sw ~blocking: false ~close_unix: true sock_unix
69
69
70
- let connect fd addr =
70
+ let connect fd ~ options addr =
71
71
try
72
- Fd. use_exn " connect" fd (fun fd -> Unix. connect fd addr)
72
+ Fd. use_exn " connect" fd @@ fun fd ->
73
+ Eio_unix.Net. configure options fd ;
74
+ Unix. connect fd addr
73
75
with
74
76
| Unix. Unix_error ((EINTR | EAGAIN | EWOULDBLOCK | EINPROGRESS ), _ , _ ) ->
75
77
await_writable " connect" fd;
76
- match Fd. use_exn " connect" fd Unix. getsockopt_error with
78
+ ( match Fd. use_exn " connect" fd Unix. getsockopt_error with
77
79
| None -> ()
78
- | Some code -> raise (Err. wrap code " connect-in-progress" " " )
80
+ | Some code -> raise (Err. wrap code " connect-in-progress" " " ))
81
+ | Unix. Unix_error (code , name , arg ) -> raise (Err. wrap code name arg)
79
82
80
83
let accept ~sw sock =
81
84
Fd. use_exn " accept" sock @@ fun sock ->
Original file line number Diff line number Diff line change @@ -28,7 +28,7 @@ val read : fd -> bytes -> int -> int -> int
28
28
val write : fd -> bytes -> int -> int -> int
29
29
30
30
val socket : sw :Switch .t -> Unix .socket_domain -> Unix .socket_type -> int -> fd
31
- val connect : fd -> Unix .sockaddr -> unit
31
+ val connect : fd -> options : Eio . Net . option list -> Unix .sockaddr -> unit
32
32
val accept : sw :Switch .t -> fd -> fd * Unix .sockaddr
33
33
34
34
val shutdown : fd -> Unix .shutdown_command -> unit
Original file line number Diff line number Diff line change @@ -138,7 +138,7 @@ let listen ~reuse_addr ~reuse_port ~backlog ~sw (listen_addr : Eio.Net.Sockaddr.
138
138
);
139
139
(listening_socket ~hook sock :> _ Eio.Net. listening_socket_ty r)
140
140
141
- let connect ~sw connect_addr =
141
+ let connect ~sw ~ options connect_addr =
142
142
let socket_type, addr =
143
143
match connect_addr with
144
144
| `Unix path -> Unix. SOCK_STREAM , Unix. ADDR_UNIX path
@@ -148,7 +148,7 @@ let connect ~sw connect_addr =
148
148
in
149
149
let sock = Low_level. socket ~sw (socket_domain_of connect_addr) socket_type 0 in
150
150
try
151
- Low_level. connect sock addr;
151
+ Low_level. connect sock ~options addr;
152
152
(Flow. of_fd sock :> _ Eio_unix.Net.stream_socket )
153
153
with Unix. Unix_error (code , name , arg ) -> raise (Err. wrap code name arg)
154
154
@@ -174,8 +174,8 @@ module Impl = struct
174
174
175
175
let listen () = listen
176
176
177
- let connect () ~sw addr =
178
- let socket = connect ~sw addr in
177
+ let connect () ~sw ~ options addr =
178
+ let socket = connect ~sw ~options addr in
179
179
(socket :> [`Generic | `Unix] Eio.Net.stream_socket_ty r )
180
180
181
181
let datagram_socket () ~reuse_addr ~reuse_port ~sw saddr =
Original file line number Diff line number Diff line change @@ -60,15 +60,18 @@ let socket ~sw socket_domain socket_type protocol =
60
60
Unix. set_nonblock sock_unix;
61
61
Fd. of_unix ~sw ~blocking: false ~close_unix: true sock_unix
62
62
63
- let connect fd addr =
63
+ let connect fd ~ options addr =
64
64
try
65
- Fd. use_exn " connect" fd (fun fd -> Unix. connect fd addr)
65
+ Fd. use_exn " connect" fd @@ fun fd ->
66
+ Eio_unix.Net. configure options fd ;
67
+ Unix. connect fd addr
66
68
with
67
69
| Unix. Unix_error ((EINTR | EAGAIN | EWOULDBLOCK | EINPROGRESS ), _ , _ ) ->
68
70
await_writable fd;
69
71
match Fd. use_exn " connect" fd Unix. getsockopt_error with
70
72
| None -> ()
71
73
| Some code -> raise (Err. wrap code " connect-in-progress" " " )
74
+ | Unix. Unix_error (code , name , arg ) -> raise (Err. wrap code name arg)
72
75
73
76
let accept ~sw sock =
74
77
Fd. use_exn " accept" sock @@ fun sock ->
Original file line number Diff line number Diff line change @@ -24,7 +24,7 @@ val read_cstruct : fd -> Cstruct.t -> int
24
24
val write : fd -> bytes -> int -> int -> int
25
25
26
26
val socket : sw :Switch .t -> Unix .socket_domain -> Unix .socket_type -> int -> fd
27
- val connect : fd -> Unix .sockaddr -> unit
27
+ val connect : fd -> options : Eio . Net . option list -> Unix .sockaddr -> unit
28
28
val accept : sw :Switch .t -> fd -> fd * Unix .sockaddr
29
29
30
30
val shutdown : fd -> Unix .shutdown_command -> unit
Original file line number Diff line number Diff line change @@ -142,7 +142,7 @@ let listen ~reuse_addr ~reuse_port ~backlog ~sw (listen_addr : Eio.Net.Sockaddr.
142
142
);
143
143
(listening_socket ~hook sock :> _ Eio.Net. listening_socket_ty r)
144
144
145
- let connect ~sw connect_addr =
145
+ let connect ~sw ~ options connect_addr =
146
146
let socket_type, addr =
147
147
match connect_addr with
148
148
| `Unix path -> Unix. SOCK_STREAM , Unix. ADDR_UNIX path
@@ -152,7 +152,7 @@ let connect ~sw connect_addr =
152
152
in
153
153
let sock = Low_level. socket ~sw (socket_domain_of connect_addr) socket_type 0 in
154
154
try
155
- Low_level. connect sock addr;
155
+ Low_level. connect sock ~options addr;
156
156
(Flow. of_fd sock :> _ Eio_unix.Net.stream_socket )
157
157
with Unix. Unix_error (code , name , arg ) -> raise (Err. wrap code name arg)
158
158
You can’t perform that action at this time.
0 commit comments