package eio

  1. Overview
  2. Docs

Source file net.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
open Eio.Std

type t = <
  Eio.Net.t;
  on_listen : Eio.Net.listening_socket Handler.t;
  on_connect : <Eio.Net.stream_socket; Eio.Flow.close> Handler.t;
  on_datagram_socket : <Eio.Net.datagram_socket; Eio.Flow.close> Handler.t;
  on_getaddrinfo : Eio.Net.Sockaddr.t list Handler.t;
  on_getnameinfo : (string * string) Handler.t;
>

let make label =
  let on_listen = Handler.make (`Raise (Failure "Mock listen handler not configured")) in
  let on_connect = Handler.make (`Raise (Failure "Mock connect handler not configured")) in
  let on_datagram_socket = Handler.make (`Raise (Failure "Mock datagram_socket handler not configured")) in
  let on_getaddrinfo = Handler.make (`Raise (Failure "Mock getaddrinfo handler not configured")) in
  let on_getnameinfo = Handler.make (`Raise (Failure "Mock getnameinfo handler not configured")) in
  object
    inherit Eio.Net.t

    method on_listen = on_listen
    method on_connect = on_connect
    method on_datagram_socket = on_datagram_socket
    method on_getaddrinfo = on_getaddrinfo
    method on_getnameinfo = on_getnameinfo

    method listen ~reuse_addr:_ ~reuse_port:_ ~backlog:_ ~sw addr =
      traceln "%s: listen on %a" label Eio.Net.Sockaddr.pp addr;
      let socket = Handler.run on_listen in
      Switch.on_release sw (fun () -> Eio.Flow.close socket);
      socket

    method connect ~sw addr =
      traceln "%s: connect to %a" label Eio.Net.Sockaddr.pp addr;
      let socket = Handler.run on_connect in
      Switch.on_release sw (fun () -> Eio.Flow.close socket);
      socket

    method datagram_socket ~sw addr =
      traceln "%s: datagram_socket %a" label Eio.Net.Sockaddr.pp addr;
      let socket = Handler.run on_datagram_socket in
      Switch.on_release sw (fun () -> Eio.Flow.close socket);
      socket

    method getaddrinfo ~service node =
      traceln "%s: getaddrinfo ~service:%s %s" label service node;
      Handler.run on_getaddrinfo

    method getnameinfo sockaddr =
      traceln "%s: getnameinfo %a" label Eio.Net.Sockaddr.pp sockaddr;
      Handler.run on_getnameinfo
  end

let on_connect (t:t) actions =
  let as_socket x = (x :> <Eio.Net.stream_socket; Eio.Flow.close>) in
  Handler.seq t#on_connect (List.map (Action.map as_socket) actions)

let on_listen (t:t) actions =
  let as_socket x = (x :> <Eio.Net.listening_socket; Eio.Flow.close>) in
  Handler.seq t#on_listen (List.map (Action.map as_socket) actions)

let on_datagram_socket (t:t) actions =
  let as_socket x = (x :> <Eio.Net.datagram_socket; Eio.Flow.close>) in
  Handler.seq t#on_datagram_socket (List.map (Action.map as_socket) actions)

let on_getaddrinfo (t:t) actions = Handler.seq t#on_getaddrinfo actions

let on_getnameinfo (t:t) actions = Handler.seq t#on_getnameinfo actions

type listening_socket = <
  Eio.Net.listening_socket;
  on_accept : (Flow.t * Eio.Net.Sockaddr.stream) Handler.t;
>

let listening_socket label =
  let on_accept = Handler.make (`Raise (Failure "Mock accept handler not configured")) in
  object
    inherit Eio.Net.listening_socket

    method on_accept = on_accept

    method accept ~sw =
      let socket, addr = Handler.run on_accept in
      Flow.attach_to_switch socket sw;
      traceln "%s: accepted connection from %a" label Eio.Net.Sockaddr.pp addr;
      (socket :> <Eio.Net.stream_socket; Eio.Flow.close>), addr

    method close =
      traceln "%s: closed" label
  end

let on_accept (l:listening_socket) actions =
  let as_accept_pair x = (x :> Flow.t * Eio.Net.Sockaddr.stream) in
  Handler.seq l#on_accept (List.map (Action.map as_accept_pair) actions)
OCaml

Innovation. Community. Security.