wire.bend

bend-kit-wire@0.4.0.3 · 80 lines · 0 definitions

1# Byte-exact TCP, UDP, and TLS sockets. Source: https://github.com/paymog/bend-kit/tree/main/wire
2import Base
3
4# Socket IO on octets: one Char per byte (0..255). Base's TCP/UDP effects
5# decode UTF-8, which breaks byte counts and binary protocols.
6# ms arguments are deadlines in milliseconds (0: none); a miss is ETIMEDOUT.
7#   import ./wire.bend as Wire
8
9# TCP connect to an IPv4 address, with a deadline.
10def connect(host: String, port: U32, ms: U32) ->
11  IO(Result<&1, &1, U32 & String, Socket>):
12  import "./effs/wire.c"
13  import "./effs/wire.js"
14
15def recv(sock: Socket, max: U32, ms: U32) ->
16  IO(Socket & Result<&1, &1, U32 & String, String>):
17  import "./effs/wire.c"
18  import "./effs/wire.js"
19
20def send(sock: Socket, data: String) ->
21  IO(Socket & Result<&1, &1, U32 & String, Unit>):
22  import "./effs/wire.c"
23  import "./effs/wire.js"
24
25def recv_from(sock: Socket, max: U32, ms: U32) ->
26  IO(Socket & Result<&1, &1, U32 & String, String & U32 & String>):
27  import "./effs/wire.c"
28  import "./effs/wire.js"
29
30def send_to(sock: Socket, host: String, port: U32, data: String) ->
31  IO(Socket & Result<&1, &1, U32 & String, Unit>):
32  import "./effs/wire.c"
33  import "./effs/wire.js"
34
35# TLS over a connected TCP socket (OpenSSL 3, loaded at run time; BEND_LIBSSL
36# overrides its path). The certificate chain and host name are always checked.
37def tls.connect(sock: Socket, host: String, ms: U32) ->
38  IO(Socket & Result<&1, &1, U32 & String, Unit>):
39  import "./effs/wire.c"
40  import "./effs/wire.js"
41
42def tls.send(sock: Socket, data: String) ->
43  IO(Socket & Result<&1, &1, U32 & String, Unit>):
44  import "./effs/wire.c"
45  import "./effs/wire.js"
46
47# "" once the peer sends close_notify. A bare EOF is an error.
48def tls.recv(sock: Socket, max: U32, ms: U32) ->
49  IO(Socket & Result<&1, &1, U32 & String, String>):
50  import "./effs/wire.c"
51  import "./effs/wire.js"
52
53# Ends the TLS session and closes the socket.
54def tls.close(sock: Socket) -> IO(Unit):
55  import "./effs/wire.c"
56  import "./effs/wire.js"
57
58# The .words forms move (len, words): bytes packed four to a U32, laid out as
59# bytes/bytes.bend packs them, so no String cell is made per byte.
60def recv.words(sock: Socket, max: U32, ms: U32) ->
61  IO(Socket & Result<&1, &1, U32 & String, U32 & Array<U32>>):
62  import "./effs/wire.c"
63  import "./effs/wire.js"
64
65# len past the end of words fails with EINVAL.
66def send.words(sock: Socket, len: U32, words: Array<U32>) ->
67  IO(Socket & Result<&1, &1, U32 & String, Unit>):
68  import "./effs/wire.c"
69  import "./effs/wire.js"
70
71# len 0 once the peer sends close_notify.
72def tls.recv.words(sock: Socket, max: U32, ms: U32) ->
73  IO(Socket & Result<&1, &1, U32 & String, U32 & Array<U32>>):
74  import "./effs/wire.c"
75  import "./effs/wire.js"
76
77def tls.send.words(sock: Socket, len: U32, words: Array<U32>) ->
78  IO(Socket & Result<&1, &1, U32 & String, Unit>):
79  import "./effs/wire.c"
80  import "./effs/wire.js"