nx_gap_junction.nx source
↩ module page · 97 lines · 3209 B
1// nx_gap_junction.nx -- direct private channel (VPN/tunnel class).
2//
3// Biology: gap junctions connect adjacent cells' cytoplasm directly,
4// allowing ions + small molecules to pass without entering extracellular
5// space. Substrate: encrypted private channel between two peers
6// bypassing the public mesh.
7
8import "nx_syscalls.nx"
9import "nx_tier.nx"
10
11const NX_GJ_STATE_PENDING: nx_int = 0 // handshake started
12const NX_GJ_STATE_OPEN: nx_int = 1 // active
13const NX_GJ_STATE_CLOSED: nx_int = 2
14const NX_GJ_STATE_FAILED: nx_int = 3
15const NX_GJ_N_STATES: nx_int = 4
16
17const NX_GJ_V_OK: nx_int = 0
18const NX_GJ_V_ERR_INVALID: nx_int = 1
19const NX_GJ_V_ERR_KEY_MISMATCH: nx_int = 2
20const NX_GJ_V_ERR_NULL: nx_int = 3
21const NX_GJ_V_N: nx_int = 4
22
23struct NxGapJunction {
24 peer_a: nx_int,
25 peer_b: nx_int,
26 state: nx_int,
27 shared_key_hash: nx_size,
28 established_at_us: nx_size,
29 bytes_sent: nx_size,
30 bytes_received: nx_size,
31}
32
33const NX_GJ_BYTES: nx_int = 48
34
35func nx_gj_state_is_valid(s: nx_int) -> nx_int {
36 if s < 0 { return 0 }
37 if s >= NX_GJ_N_STATES { return 0 }
38 return 1
39}
40
41func nx_gj_v_is_valid(v: nx_int) -> nx_int {
42 if v < 0 { return 0 }
43 if v >= NX_GJ_V_N { return 0 }
44 return 1
45}
46
47func nx_gj_new(peer_a: nx_int, peer_b: nx_int) -> *NxGapJunction {
48 let raw: *u8 = sys_mmap(NX_GJ_BYTES)
49 let j: *NxGapJunction = raw as *NxGapJunction
50 j.peer_a = peer_a
51 j.peer_b = peer_b
52 j.state = NX_GJ_STATE_PENDING
53 j.shared_key_hash = 0
54 j.established_at_us = 0
55 j.bytes_sent = 0
56 j.bytes_received = 0
57 return j
58}
59
60func nx_gj_establish(j: *NxGapJunction,
61 shared_key_hash: nx_size,
62 now_us: nx_size) -> nx_int {
63 if (j as i64) == 0 { return NX_GJ_V_ERR_NULL }
64 if j.state != NX_GJ_STATE_PENDING { return NX_GJ_V_ERR_INVALID }
65 if shared_key_hash == 0 { return NX_GJ_V_ERR_KEY_MISMATCH }
66 j.shared_key_hash = shared_key_hash
67 j.established_at_us = now_us
68 j.state = NX_GJ_STATE_OPEN
69 return NX_GJ_V_OK
70}
71
72func nx_gj_send(j: *NxGapJunction,
73 bytes: nx_size,
74 verify_key_hash: nx_size) -> nx_int {
75 if (j as i64) == 0 { return NX_GJ_V_ERR_NULL }
76 if j.state != NX_GJ_STATE_OPEN { return NX_GJ_V_ERR_INVALID }
77 if j.shared_key_hash != verify_key_hash { return NX_GJ_V_ERR_KEY_MISMATCH }
78 j.bytes_sent = j.bytes_sent + bytes
79 return NX_GJ_V_OK
80}
81
82func nx_gj_receive(j: *NxGapJunction,
83 bytes: nx_size,
84 verify_key_hash: nx_size) -> nx_int {
85 if (j as i64) == 0 { return NX_GJ_V_ERR_NULL }
86 if j.state != NX_GJ_STATE_OPEN { return NX_GJ_V_ERR_INVALID }
87 if j.shared_key_hash != verify_key_hash { return NX_GJ_V_ERR_KEY_MISMATCH }
88 j.bytes_received = j.bytes_received + bytes
89 return NX_GJ_V_OK
90}
91
92func nx_gj_close(j: *NxGapJunction) -> nx_int {
93 if (j as i64) == 0 { return NX_GJ_V_ERR_NULL }
94 if j.state == NX_GJ_STATE_CLOSED { return NX_GJ_V_OK }
95 j.state = NX_GJ_STATE_CLOSED
96 return NX_GJ_V_OK
97}