package tcpip
OCaml TCP/IP networking stack, used in MirageOS
Install
Dune Dependency
Authors
Maintainers
Sources
tcpip-9.0.1.tbz
sha256=fac07ce986811cf5e3d71373d92b631cc30fbef548d6da21b0917212dcf90b03
sha512=01de13f560d58b1524c39619e4e4cb6ebbf069155eb43d0f264aa12b00e0cc8c39792719e3ca46585dd596b692b8e1e3f8c132f005ed9e2d77747c0c158bf4d9
doc/src/tcpip.tcp/state.ml.html
Source file state.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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
(* * Copyright (c) 2012 Balraj Singh <bs375@cl.cam.ac.uk> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Lwt.Infix let src = Logs.Src.create "tcp.state" ~doc:"Mirage TCP State module" module Log = (val Logs.src_log src : Logs.LOG) type action = | Passive_open | Recv_rst | Recv_synack of Sequence.t | Recv_ack of Sequence.t | Recv_fin (* | Recv_finack of Sequence.t *) | Send_syn of Sequence.t | Send_synack of Sequence.t | Send_rst | Send_fin of Sequence.t | Timeout type tcpstate = | Closed | Listen | Syn_rcvd of Sequence.t | Syn_sent of Sequence.t | Established | Close_wait | Last_ack of Sequence.t | Fin_wait_1 of Sequence.t | Fin_wait_2 of int | Closing of Sequence.t | Time_wait | Reset type close_cb = unit -> unit type t = { on_close: close_cb; id: int; mutable state: tcpstate; } let t ~id ~on_close = { on_close; id; state=Closed } let on_close t = t.on_close () let state t = t.state let pf = Format.fprintf let pp_action fmt = function | Passive_open -> pf fmt "Passive_open" | Recv_rst -> pf fmt "Recv_rst" | Recv_synack x -> pf fmt "Recv_synack(%a)" Sequence.pp x | Recv_ack x -> pf fmt "Recv_ack(%a)" Sequence.pp x | Recv_fin -> pf fmt "Recv_fin" (* | Recv_finack x -> pf fmt "Recv_finack(%a)" Sequence.pp x *) | Send_syn x -> pf fmt "Send_syn(%a)" Sequence.pp x | Send_synack x -> pf fmt "Send_synack(%a)" Sequence.pp x | Send_rst -> pf fmt "Send_rst" | Send_fin x -> pf fmt "Send_fin(%a)" Sequence.pp x | Timeout -> pf fmt "Timeout" let pp_tcpstate fmt = function | Closed -> pf fmt "Closed" | Listen -> pf fmt "Listen" | Syn_rcvd x -> pf fmt "Syn_rcvd(%a)" Sequence.pp x | Syn_sent x -> pf fmt "Syn_sent(%a)" Sequence.pp x | Established -> pf fmt "Established" | Close_wait -> pf fmt "Close_wait" | Last_ack x -> pf fmt "Last_ack(%a)" Sequence.pp x | Fin_wait_1 x -> pf fmt "Fin_wait_1(%a)" Sequence.pp x | Fin_wait_2 i -> pf fmt "Fin_wait_2(%d)" i | Closing x -> pf fmt "Closing(%a)" Sequence.pp x | Time_wait -> pf fmt "Time_wait" | Reset -> pf fmt "Reset" let pp fmt t = pf fmt "{ %a }" pp_tcpstate t.state let fin_wait_2_time = (* 60 *) Duration.of_sec 10 let time_wait_time = (* 30 *) Duration.of_sec 2 let rec finwait2timer t count timeout = Log.debug (fun fmt -> fmt "finwait2timer %Lu" timeout); Mirage_sleep.ns timeout >>= fun () -> match t.state with | Fin_wait_2 i -> Log.debug (fun f -> f "finwait2timer: Fin_wait_2"); if i = count then begin t.state <- Closed; t.on_close (); Lwt.return_unit end else begin finwait2timer t i timeout end | s -> Log.debug (fun fmt -> fmt "finwait2timer: %a" pp_tcpstate s); Lwt.return_unit let timewait t twomsl = Log.debug (fun fmt -> fmt "timewait %Lu" twomsl); Mirage_sleep.ns twomsl >>= fun () -> t.state <- Closed; Log.debug (fun fmt -> fmt "timewait on_close"); t.on_close (); Lwt.return_unit let transition_to_timewait t = Lwt.async (fun () -> timewait t time_wait_time); Time_wait let tick t (i:action) = let diffone x y = Sequence.succ y = x in let tstr s (i:action) = match s, i with | Closed, Passive_open -> Listen | Closed, Send_syn a -> Syn_sent a | Listen, Send_synack a -> Syn_rcvd a | Syn_rcvd _, Timeout -> t.on_close (); Closed | Syn_rcvd _, Recv_rst -> Closed | Syn_sent _, Timeout -> t.on_close (); Closed | Syn_sent a, Recv_synack b-> if diffone b a then Established else Syn_sent a | Syn_rcvd a, Recv_ack b -> if diffone b a then Established else Syn_rcvd a | Established, Recv_ack _ -> Established | Established, Send_fin a -> Fin_wait_1 a | Established, Recv_fin -> Close_wait | Established, Timeout -> t.on_close (); Closed | Established, Recv_rst -> t.on_close (); Reset | Fin_wait_1 a, Recv_ack b -> if diffone b a then let count = 0 in Lwt.async (fun () -> finwait2timer t count fin_wait_2_time); Fin_wait_2 count else Fin_wait_1 a | Fin_wait_1 a, Recv_fin -> Closing a | Fin_wait_1 _, Timeout -> t.on_close (); Closed | Fin_wait_1 _, Recv_rst -> t.on_close (); Reset | Fin_wait_2 i, Recv_ack _ -> Fin_wait_2 (i + 1) | Fin_wait_2 _, Recv_rst -> t.on_close (); Reset | Fin_wait_2 _, Recv_fin -> transition_to_timewait t | Closing a, Recv_ack b -> if diffone b a then transition_to_timewait t else Closing a | Closing _, Timeout -> t.on_close (); Closed | Closing _, Recv_rst -> t.on_close (); Reset | Time_wait, Timeout -> t.on_close (); Closed | Close_wait, Send_fin a -> Last_ack a | Close_wait, Timeout -> t.on_close (); Closed | Close_wait, Recv_rst -> t.on_close (); Reset | Last_ack a, Recv_ack b -> if diffone b a then (t.on_close (); Closed) else Last_ack a | Last_ack _, Timeout -> t.on_close (); Closed | Last_ack _, Recv_rst -> t.on_close (); Reset | x, _ -> x in let old_state = t.state in let new_state = tstr t.state i in Log.debug (fun fmt -> fmt "%d %a - %a -> %a" t.id pp_tcpstate old_state pp_action i pp_tcpstate new_state); t.state <- new_state;
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>