2017-01-14 16:14:07 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
2018-02-06 00:17:03 +04:00
|
|
|
(* Copyright (c) 2014 - 2018. *)
|
2017-01-14 16:14:07 +04:00
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
include Logging.Make (struct let name = "p2p.welcome" end)
|
|
|
|
|
2018-05-15 15:16:08 +04:00
|
|
|
type pool = Pool : ('msg, 'meta, 'meta_conn) P2p_pool.t -> pool
|
2017-01-14 16:14:07 +04:00
|
|
|
|
|
|
|
type t = {
|
|
|
|
socket: Lwt_unix.file_descr ;
|
2017-11-27 09:13:12 +04:00
|
|
|
canceler: Lwt_canceler.t ;
|
2017-01-14 16:14:07 +04:00
|
|
|
pool: pool ;
|
|
|
|
mutable worker: unit Lwt.t ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let rec worker_loop st =
|
|
|
|
let Pool pool = st.pool in
|
|
|
|
Lwt_unix.yield () >>= fun () ->
|
2018-02-08 13:51:01 +04:00
|
|
|
protect ~canceler:st.canceler begin fun () ->
|
2017-01-14 16:14:07 +04:00
|
|
|
Lwt_unix.accept st.socket >>= return
|
|
|
|
end >>= function
|
|
|
|
| Ok (fd, addr) ->
|
|
|
|
let point =
|
|
|
|
match addr with
|
|
|
|
| Lwt_unix.ADDR_UNIX _ -> assert false
|
|
|
|
| Lwt_unix.ADDR_INET (addr, port) ->
|
|
|
|
(Ipaddr_unix.V6.of_inet_addr_exn addr, port) in
|
2018-01-24 15:48:25 +04:00
|
|
|
P2p_pool.accept pool fd point ;
|
2017-01-14 16:14:07 +04:00
|
|
|
worker_loop st
|
2018-02-08 13:51:01 +04:00
|
|
|
| Error [ Canceled ] ->
|
2017-01-14 16:14:07 +04:00
|
|
|
Lwt.return_unit
|
|
|
|
| Error err ->
|
|
|
|
lwt_log_error "@[<v 2>Unexpected error in the Welcome worker@ %a@]"
|
|
|
|
pp_print_error err >>= fun () ->
|
|
|
|
Lwt.return_unit
|
|
|
|
|
|
|
|
let create_listening_socket ~backlog ?(addr = Ipaddr.V6.unspecified) port =
|
|
|
|
let main_socket = Lwt_unix.(socket PF_INET6 SOCK_STREAM 0) in
|
|
|
|
Lwt_unix.(setsockopt main_socket SO_REUSEADDR true) ;
|
2017-05-07 13:56:30 +04:00
|
|
|
Lwt_unix.bind main_socket
|
2017-01-30 22:10:16 +04:00
|
|
|
Unix.(ADDR_INET (Ipaddr_unix.V6.to_inet_addr addr, port)) >>= fun () ->
|
2017-01-14 16:14:07 +04:00
|
|
|
Lwt_unix.listen main_socket backlog ;
|
|
|
|
Lwt.return main_socket
|
|
|
|
|
2018-02-20 21:28:05 +04:00
|
|
|
let run ?addr ~backlog pool port =
|
2017-01-14 16:14:07 +04:00
|
|
|
Lwt.catch begin fun () ->
|
|
|
|
create_listening_socket
|
|
|
|
~backlog ?addr port >>= fun socket ->
|
2017-11-27 09:13:12 +04:00
|
|
|
let canceler = Lwt_canceler.create () in
|
|
|
|
Lwt_canceler.on_cancel canceler begin fun () ->
|
2018-02-08 13:51:01 +04:00
|
|
|
Lwt_utils_unix.safe_close socket
|
2017-01-14 16:14:07 +04:00
|
|
|
end ;
|
|
|
|
let st = {
|
|
|
|
socket ; canceler ; pool = Pool pool ;
|
|
|
|
worker = Lwt.return_unit ;
|
|
|
|
} in
|
|
|
|
st.worker <-
|
|
|
|
Lwt_utils.worker "welcome"
|
2017-11-13 17:29:28 +04:00
|
|
|
~run:(fun () -> worker_loop st)
|
2017-11-27 09:13:12 +04:00
|
|
|
~cancel:(fun () -> Lwt_canceler.cancel st.canceler) ;
|
2017-01-14 16:14:07 +04:00
|
|
|
Lwt.return st
|
|
|
|
end begin fun exn ->
|
|
|
|
lwt_log_error
|
|
|
|
"@[<v 2>Cannot accept incoming connections@ %a@]"
|
|
|
|
pp_exn exn >>= fun () ->
|
|
|
|
Lwt.fail exn
|
|
|
|
end
|
|
|
|
|
|
|
|
let shutdown st =
|
2017-11-27 09:13:12 +04:00
|
|
|
Lwt_canceler.cancel st.canceler >>= fun () ->
|
2017-01-14 16:14:07 +04:00
|
|
|
st.worker
|