diff --git a/pkg/c3/motes.h b/pkg/c3/motes.h index db17834057..beaa33d63b 100644 --- a/pkg/c3/motes.h +++ b/pkg/c3/motes.h @@ -999,6 +999,7 @@ # define c3__sard c3_s4('s','a','r','d') # define c3__sav c3_s3('s','a','v') # define c3__save c3_s4('s','a','v','e') +# define c3__saxo c3_s4('s','a','x','o') # define c3__scam c3_s4('s','c','a','m') # define c3__scan c3_s4('s','c','a','n') # define c3__scry c3_s4('s','c','r','y') @@ -1112,6 +1113,7 @@ # define c3__ston c3_s4('s','t','o','n') # define c3__stop c3_s4('s','t','o','p') # define c3__stub c3_s4('s','t','u','b') +# define c3__stun c3_s4('s','t','u','n') # define c3__stur c3_s4('s','t','u','r') # define c3__sub c3_s3('s','u','b') # define c3__sunt c3_s4('s','u','n','t') diff --git a/pkg/noun/jets/b/mate.c b/pkg/noun/jets/b/mate.c new file mode 100644 index 0000000000..f8dbd31654 --- /dev/null +++ b/pkg/noun/jets/b/mate.c @@ -0,0 +1,30 @@ +/// @file + +#include "jets/q.h" +#include "jets/w.h" + +#include "noun.h" + + + u3_noun + u3qb_mate(u3_noun a, + u3_noun b) + { + if ( u3_nul == b ) { + return u3k(a); + } else if ( u3_nul == a ) { + return u3k(b); + } else if ( c3y == u3r_sing(u3t(a), u3t(b)) ) { + return u3k(a); + } else { + return u3m_error("mate"); + } + } + u3_noun + u3wb_mate(u3_noun cor) + { + u3_noun a, b; + u3x_mean(cor, u3x_sam_2, &a, u3x_sam_3, &b, 0); + return u3qb_mate(a, b); + } + diff --git a/pkg/noun/jets/d/by_bif.c b/pkg/noun/jets/d/by_bif.c index d9e27d1756..0a2f23a666 100644 --- a/pkg/noun/jets/d/by_bif.c +++ b/pkg/noun/jets/d/by_bif.c @@ -17,19 +17,17 @@ _b_bif_putroot(u3_noun a, else { u3_noun n_a, l_a, r_a; u3_noun p_n_a, q_n_a; - u3_noun p_b, q_b; u3x_trel(a, &n_a, &l_a, &r_a); - u3x_cell(b, &p_b, &q_b); u3x_cell(n_a, &p_n_a, &q_n_a); - if ( c3y == u3r_sing(p_b, p_n_a) ) { + if ( c3y == u3r_sing(b, p_n_a) ) { return u3nt(u3k(b), u3k(l_a), u3k(r_a)); } else { u3_noun c, n_c, l_c, r_c; u3_noun d; - if ( c3y == u3qc_gor(p_b, p_n_a) ) { + if ( c3y == u3qc_gor(b, p_n_a) ) { c = _b_bif_putroot(l_a, b); u3r_trel(c, &n_c, &l_c, &r_c); d = u3nt(u3k(n_c), diff --git a/pkg/noun/jets/d/by_dif.c b/pkg/noun/jets/d/by_dif.c index a3f35f3cde..44dcd1ad1b 100644 --- a/pkg/noun/jets/d/by_dif.c +++ b/pkg/noun/jets/d/by_dif.c @@ -61,11 +61,12 @@ u3qdb_dif(u3_noun a, return u3k(a); } else { - u3_noun n_b, l_b, r_b; + u3_noun n_b, p_n_b, q_n_b, l_b, r_b; u3_noun c, l_c, r_c; u3x_trel(b, &n_b, &l_b, &r_b); + u3x_cell(n_b, &p_n_b, &q_n_b); - c = u3qdb_bif(a, n_b); + c = u3qdb_bif(a, p_n_b); u3x_cell(c, &l_c, &r_c); u3_noun d = u3qdb_dif(l_c, l_b); diff --git a/pkg/noun/jets/f/ap.c b/pkg/noun/jets/f/ap.c deleted file mode 100644 index c1c872c797..0000000000 --- a/pkg/noun/jets/f/ap.c +++ /dev/null @@ -1,1081 +0,0 @@ -/// @file - -#include "jets/q.h" -#include "jets/w.h" - -#include "noun.h" - - -/** forward declares -**/ - u3_noun u3wfp_rake(u3_noun); - u3_noun u3wfp_open(u3_noun); - u3_noun u3wfp_hack(u3_noun); - - static u3_noun - _ap_open_l(u3_noun, u3_noun, u3_noun); - - // make sure these match the array below! - // -# define _ap_jet_open 0 -# define _ap_jet_rake 1 -# define _ap_jet_hack 2 - -#if 0 - static u3_noun - _open_in(u3_noun ter, u3_noun gen); - /* ~(. al gen) - */ - static u3_noun - _al_bore(u3_noun ter, - u3_noun gen) - { - u3_noun gat = u3j_hook(u3k(ter), "al"); - - return u3i_molt(gat, u3x_sam, u3nc(c3__herb, u3k(gen)), 0); - } - /* ~(. al gen) - */ - static u3_noun - _al_core(u3_noun ter, - u3_noun gen) - { - u3_noun gat = u3j_hook(u3k(ter), "al"); - - return u3i_molt(gat, u3x_sam, u3k(gen), 0); - } - - /* van is transferred, gen is retained - */ - static u3_noun - _ap_bunt(u3_noun van, - u3_noun gen) - { - u3_noun pro = u3qfl_bunt(van, gen); - - u3z(van); - return pro; - } - -/** open cases -**/ - -#define _open_do_p(stem) \ - static u3_noun _open_in_##stem \ - ( u3_noun ter, u3_noun p_gen) - -#define _open_do_pq(stem) \ - static u3_noun _open_in_##stem \ - ( u3_noun ter, u3_noun p_gen, u3_noun q_gen) - -#define _open_do_pqr(stem) \ - static u3_noun _open_in_##stem \ - ( u3_noun ter, u3_noun p_gen, u3_noun q_gen, u3_noun r_gen) - -#define _open_do_pqrs(stem) \ - static u3_noun _open_in_##stem \ - ( u3_noun ter, u3_noun p_gen, u3_noun q_gen, u3_noun r_gen, \ - u3_noun s_gen) - -/*** -**** -***/ - _open_do_pq(tsbr) // =: - { - return u3nt(c3__tsls, - _ap_bunt(_al_core(ter, p_gen), p_gen), - u3k(q_gen)); - } - _open_do_pq(tscl) // =: - { - return u3nt(c3__tsgr, - u3nt(c3__cncb, - u3nc(u3nc(u3_nul, 1), - u3_nul), - u3k(p_gen)), - u3k(q_gen)); - } - _open_do_pqr(tsdt) // =. - { - return u3nt(c3__tsgr, - u3nt(c3__cncb, - u3nc(u3nc(u3_nul, 1), - u3_nul), - u3nc(u3nc(u3k(p_gen), - u3k(q_gen)), - u3_nul)), - u3k(r_gen)); - } - _open_do_pq(tsgl) // =< - { - return u3nt(c3__tsgr, - u3k(q_gen), - u3k(p_gen)); - } - _open_do_pq(tshp) // =- - { - return u3nt(c3__tsls, - u3k(q_gen), - u3k(p_gen)); - } - _open_do_pq(tsls) // =+ - { - return u3nt(c3__tsgr, - u3nc(u3k(p_gen), - u3nc(u3_nul, 1)), - u3k(q_gen)); - } - _open_do_p(tssg) // =~ - { - if ( !_(u3du(p_gen)) ) { - return u3nc(0, 1); - } else { - u3_noun tp_gen = u3t(p_gen); - u3_noun ip_gen = u3h(p_gen); - - if ( (u3_nul == p_gen) ) { - return u3nc(u3_blip, 1); - } - else if ( (u3_nul == tp_gen) ) { - return u3k(ip_gen); - } - else { - return u3nt(c3__tsgr, - u3k(ip_gen), - _open_in_tssg(ter, tp_gen)); - } - } - } -/*** -**** -***/ - _open_do_p(bccb) // $_ - { - return _ap_bunt(_al_core(ter, p_gen), p_gen); - } - _open_do_p(bctr) // $* - { - return - u3nc(c3__ktsg, - _ap_bunt(_al_core(ter, p_gen), - p_gen)); - } - _open_do_p(bczp) // $! - { - return u3nt(c3__bccb, - c3__axil, - u3k(p_gen)); - } -/*** -**** -***/ - _open_do_p(brhp) // |- - { - return u3nt(c3__tsgl, - u3nc(c3__cnzy, u3_blip), - u3nc(c3__brdt, u3k(p_gen))); - } - _open_do_p(brdt) // |. - { - return u3nc(c3__brcn, - u3nt(u3nt(u3_blip, c3__ash, u3k(p_gen)), - u3_nul, - u3_nul)); - } - -/*** -**** -***/ - _open_do_p(wtbr) // ?| - { - if ( (u3_nul == p_gen) ) { - return u3nt(c3__dtzz, 'f', c3n); - } - else { - u3_noun ip_gen = u3h(p_gen); - u3_noun tp_gen = u3t(p_gen); - - return u3nq(c3__wtcl, - u3k(ip_gen), - u3nt(c3__dtzz, 'f', c3y), - _open_in_wtbr(ter, tp_gen)); - } - } - _open_do_pqr(wtkt) // ?^ - { - return u3nq(c3__wtcl, - u3nt(c3__wtts, - u3nt(c3__axil, c3__atom, u3_blip), - u3k(p_gen)), - u3k(r_gen), - u3k(q_gen)); - } - _open_do_pq(wtgl) // ?< - { - return u3nq(c3__wtcl, - u3k(p_gen), - u3nc(c3__zpzp, u3_nul), - u3k(q_gen)); - } - _open_do_pqr(wtdt) // ?. - { - return u3nq(c3__wtcl, - u3k(p_gen), - u3k(r_gen), - u3k(q_gen)); - } - _open_do_pq(wtgr) // ?> - { - return u3nq(c3__wtcl, - u3k(p_gen), - u3k(q_gen), - u3nc(c3__zpzp, u3_nul)); - } - _open_do_pq(wthp) // ?- - { - if ( (u3_nul == q_gen) ) { - return u3nc(c3__zpfs, - u3nc(c3__cnzz, - u3k(p_gen))); - } - else { - u3_noun iq_gen = u3h(q_gen); - u3_noun tq_gen = u3t(q_gen); - u3_noun piq_gen = u3h(iq_gen); - u3_noun qiq_gen = u3t(iq_gen); - - return u3nq(c3__wtcl, - u3nt(c3__wtts, - u3k(piq_gen), - u3k(p_gen)), - u3k(qiq_gen), - _open_in_wthp(ter, p_gen, tq_gen)); - } - } - _open_do_p(wtpm) // ?& - { - if ( (u3_nul == p_gen) ) { - return u3nt(c3__dtzz, 'f', c3y); - } - else { - u3_noun ip_gen = u3h(p_gen); - u3_noun tp_gen = u3t(p_gen); - - return u3nq(c3__wtcl, - u3k(ip_gen), - _open_in_wtpm(ter, tp_gen), - u3nt(c3__dtzz, 'f', c3n)); - } - } - _open_do_pqr(wtls) // ?+ - { u3_noun tul = u3nc(u3nc(u3nc(c3__axil, c3__noun), - u3k(q_gen)), - u3_nul); - u3_noun zal = u3qb_weld(r_gen, tul); - u3_noun ret = u3nt(c3__wthp, u3k(p_gen), zal); - - u3z(tul); - return ret; - - } - _open_do_pqr(wtpt) // ?@ - { - return u3nq(c3__wtcl, - u3nt(c3__wtts, - u3nt(c3__axil, - c3__atom, - u3_blip), - u3k(p_gen)), - u3k(q_gen), - u3k(r_gen)); - } - _open_do_pqr(wtsg) // ?~ - { - return u3nq(c3__wtcl, - u3nt(c3__wtts, - u3nc(c3__axil, c3__null), - u3k(p_gen)), - u3k(q_gen), - u3k(r_gen)); - } - _open_do_p(wtzp) // ?! - { - return u3nq(c3__wtcl, - u3k(p_gen), - u3nt(c3__dtzz, 'f', c3n), - u3nt(c3__dtzz, 'f', c3y)); - } -/*** -**** -***/ - _open_do_pq(zpcb) // !_ - { - return u3k(q_gen); - } - _open_do_p(zpgr) // !> - { - return u3nq(c3__cnhp, - u3nc(c3__cnzy, c3__onan), - u3nt(c3__zpsm, - u3nc(c3__bctr, - u3nc(c3__herb, - u3nc(c3__cnzy, - c3__abel))), - u3k(p_gen)), - u3_nul); - } -/*** -**** -***/ - _open_do_pq(clhp) // :- - { - return u3nc(u3k(p_gen), - u3k(q_gen)); - } - _open_do_pq(clcb) // :_ - { - return u3nc(u3k(q_gen), - u3k(p_gen)); - } - _open_do_p(clcn) // :% - { - return u3nc(u3nc(c3__clsg, - u3k(p_gen)), - u3nc(c3__bczp, c3__null)); - } - _open_do_pqrs(clkt) // :^ - { - return u3nq(u3k(p_gen), - u3k(q_gen), - u3k(r_gen), - u3k(s_gen)); - } - _open_do_pqr(clls) // :+ - { - return u3nt(u3k(p_gen), - u3k(q_gen), - u3k(r_gen)); - } - _open_do_p(clsg) // :~ - { - if ( (u3_nul == p_gen) ) { - return u3nt(c3__dtzz, 'n', u3_nul); - } - else { - u3_noun ip_gen = u3h(p_gen); - u3_noun tp_gen = u3t(p_gen); - - return u3nc(u3k(ip_gen), - _open_in_clsg(ter, tp_gen)); - } - } - _open_do_p(cltr) // :* - { - if ( (u3_nul == p_gen) ) { - return u3nc(c3__zpzp, u3_nul); - } - else { - u3_noun ip_gen = u3h(p_gen); - u3_noun tp_gen = u3t(p_gen); - - if ( (u3_nul == tp_gen) ) { - return u3k(ip_gen); - } else { - return u3nc(u3k(ip_gen), - _open_in_cltr(ter, tp_gen)); - } - } - } -/*** -**** -***/ - _open_do_pq(cncb) // %_ - { - return u3nc(c3__ktls, - u3nq(u3nc(c3__cnzz, u3k(p_gen)), - c3__cnts, - u3k(p_gen), - u3k(q_gen))); - } -#if 0 - _open_do_pq(cncl) // %: - { - return u3nq - (c3__cnsg, - u3nc(u3_blip, u3_nul), - u3k(p_gen), - u3k(q_gen)); - } -#endif - _open_do_pq(cndt) // %. - { - return u3nt(c3__cnhp, - u3k(q_gen), - u3nc(u3k(p_gen), u3_nul)); - } - _open_do_pqrs(cnkt) // %^ - { - return u3nq(c3__cnhp, - u3k(p_gen), - u3k(q_gen), - u3nt(u3k(r_gen), - u3k(s_gen), - u3_nul)); - } - _open_do_pq(cnhp) // %- - { - if ( (u3_nul == q_gen) ) { - return u3nt(c3__tsgr, - u3k(p_gen), - u3nc(c3__cnzy, u3_blip)); - } else { - return u3nq(c3__cncl, - u3k(p_gen), - c3__cltr, - u3k(q_gen)); - } - } - _open_do_pqr(cnls) // %+ - { - return u3nc(c3__cnhp, - u3nq(u3k(p_gen), - u3k(q_gen), - u3k(r_gen), - u3_nul)); - } - _open_do_pqr(cnsg) // %~ - { - return u3nq(c3__cntr, - u3k(p_gen), - u3k(q_gen), - u3nc(u3nc(u3nc(u3nc(u3_nul, 6), 0), u3k(r_gen)), 0)); - } - _open_do_p(cnzy) // %cnzy - { - return u3nt(c3__cnts, - u3nc(u3k(p_gen), u3_nul), - u3_nul); - } - _open_do_p(cnzz) // %cnzz - { - return u3nt(c3__cnts, u3k(p_gen), u3_nul); - } -/*** -**** -***/ - _open_do_p(hxgl) // #< - { - return u3nq(c3__cnhp, - u3nc(c3__cnzy, c3__noah), - u3nc(c3__zpgr, - u3nc(c3__cltr, u3k(p_gen))), - u3_nul); - } - _open_do_p(hxgr) // #> - { - return u3nq(c3__cnhp, - u3nc(c3__cnzy, c3__cain), - u3nc(c3__zpgr, - u3nc(c3__cltr, u3k(p_gen))), - u3_nul); - } -/*** -**** -***/ - _open_do_pq(ktdt) // ^. - { - return u3nt(c3__ktls, - u3nq(c3__cnhp, u3k(p_gen), u3k(q_gen), u3_nul), - u3k(q_gen)); - } -#if 0 - _open_do_pq(kthp) // ^- - { - return u3nt(c3__ktls, - _ap_bunt(_al_bore(ter, p_gen), p_gen), - u3k(q_gen)); - } -#endif -/*** -**** -***/ - _open_do_pq(brcb) // |_ - { - return u3nt(c3__tsls, - u3nc(c3__bctr, u3k(p_gen)), - u3nc(c3__brcn, u3k(q_gen))); - } - _open_do_pq(brkt) // |^ - { - u3_noun diz = u3nc(c3__ash, u3k(p_gen)); - u3_noun ret = u3nt(c3__tsgr, - u3nc(c3__brcn, - u3qdb_put(q_gen, u3_blip, diz)), - u3nc(c3__cnzy, u3_blip)); - - u3_assert(0); - u3z(diz); - return ret; - } - _open_do_pq(brls) // |+ - { - return u3nc(c3__ktbr, - u3nt(c3__brts, - u3k(p_gen), - u3k(q_gen))); - } - _open_do_p(brwt) // |? - { - return u3nt(c3__ktwt, - c3__brdt, - u3k(p_gen)); - } -/*** -**** -***/ - _open_do_pq(sgts) // ~= - { - return u3nt(c3__sggr, - u3nc(c3__germ, u3k(p_gen)), - u3k(q_gen)); - } -#if 0 - _open_do_pq(sgbr) // ~| - { - return u3nt - (c3__sggr, - u3nc(c3__mean, u3k(p_gen)), - u3k(q_gen)); - } -#endif - _open_do_pq(sggl) // ~> - { - return u3nt(c3__tsgl, - u3nq(c3__sggr, u3k(p_gen), u3_nul, 1), - u3k(q_gen)); - } - _open_do_pq(sgbc) // ~$ - { - return u3nt(c3__sggr, - u3nq(c3__live, - c3__dtzz, - u3_blip, - u3k(p_gen)), - u3k(q_gen)); - } - _open_do_pq(sgcb) // ~_ - { - return u3nt(c3__sggr, - u3nc(c3__mean, - u3nc(c3__brdt, - u3k(p_gen))), - u3k(q_gen)); - } - static u3_noun - _sgcn_a(u3_noun r_gen, - u3_noun nob) - { - if ( c3n == u3du(r_gen) ) { - return u3k(nob); - } else { - u3_noun ir_gen = u3h(r_gen); - u3_noun tr_gen = u3t(r_gen); - u3_noun pir_gen, qir_gen; - - u3x_cell(ir_gen, &pir_gen, &qir_gen); - - return u3nc(u3nc(u3nt(c3__dtzz, u3_blip, u3k(pir_gen)), - u3nc(c3__zpts, u3k(qir_gen))), - _sgcn_a(tr_gen, nob)); - } - } - _open_do_pqrs(sgcn) // ~% - { - return u3nt(c3__sggl, - u3nq(c3__sgcn, - c3__clls, - u3nt(c3__dtzz, u3_blip, u3k(p_gen)), - u3nt(u3nc(c3__zpts, u3k(q_gen)), - c3__clsg, - _sgcn_a(r_gen, u3_nul))), - u3k(s_gen)); - } - _open_do_pq(sgfs) // ~/ - { - return u3nc(c3__sgcn, - u3nq(u3k(p_gen), - u3nc(u3_nul, 7), - u3_nul, - u3k(q_gen))); - } - _open_do_pq(sgls) // ~+ - { - return u3nt(c3__sggr, - u3nq(c3__sgls, c3__dtzz, u3_blip, u3k(p_gen)), - u3k(q_gen)); - } - _open_do_pqr(sgpm) // ~& - { - return u3nt(c3__sggr, - u3nt(c3__slog, - u3nt(c3__dtzy, u3_blip, u3k(p_gen)), - u3nq(c3__cnhp, u3nc(c3__cnzy, c3__cain), - u3nc(c3__zpgr, u3k(q_gen)), u3_nul)), - u3k(r_gen)); - } - _open_do_pqrs(sgwt) // ~? - { - return u3nt(c3__tsls, - u3nq(c3__wtdt, - u3k(q_gen), - u3nc(c3__bczp, c3__null), - u3nc(u3nc(c3__bczp, c3__null), u3k(r_gen))), - u3nq(c3__wtsg, - u3nc(u3nc(u3_nul, 2),u3_nul), - u3nt(c3__tsgr, - u3nc(u3_nul, 3), - u3k(s_gen)), - u3nq(c3__sgpm, - u3k(p_gen), - u3nc(u3_nul, 5), - u3nt(c3__tsgr, - u3nc(u3_nul, 3), - u3k(s_gen))))); - } -/*** -**** -***/ - static u3_noun - _smcl_in(u3_noun q_gen) - { - u3_noun hq_gen = u3h(q_gen); - u3_noun tq_gen = u3t(q_gen); - - if ( c3n == u3du(tq_gen) ) { - return u3nt(c3__tsgr, - u3nc(u3_nul, 3), - u3k(hq_gen)); - } else { - return u3nc(c3__cnhp, - u3nq(u3nc(u3_nul, 2), - u3nt(c3__tsgr, - u3nc(u3_nul, 3), - u3k(hq_gen)), - _smcl_in(tq_gen), - u3_nul)); - } - } - _open_do_pq(smcl) - { - if ( c3n == u3du(q_gen) ) { - return u3nc(c3__zpzp, u3_nul); - } - else if ( u3_nul == u3t(q_gen) ) { - return u3k(u3h(q_gen)); - } - else { - return u3nt(c3__tsls, - u3k(p_gen), - _smcl_in(q_gen)); - } - } -#if 0 - _open_do_pq(smsm) - { - return - u3nt(c3__tsgr, u3nq(c3__ktts, c3__v, u3_nul, 1), - u3nt(c3__tsls, - u3nt(c3__ktts, c3__a, - u3nt(c3__tsgr, u3nc(c3__cnzy, c3__v), - u3k(p_gen))), - u3nt(c3__tsls, - u3nt(c3__ktts, c3__b, - u3nt(c3__tsgr, - u3nc(c3__cnzy, c3__v), - u3k(q_gen))), - u3nt(c3__tsls, - u3nt(c3__ktts, c3__c, - u3nq(c3__cnhp, - u3nc(c3__cnzy, c3__a), - u3nc(c3__cnzy, c3__b), - u3_nul)), - u3nt(c3__wtgr, - u3nt(c3__dtts, - u3nc(c3__cnzy, c3__c), - u3nc(c3__cnzy, c3__b)), - u3nc(c3__cnzy, c3__c)))))); - } -#endif - - /** open - **/ - static u3_noun - _open_in(u3_noun ter, - u3_noun gen) - { - u3_noun p_gen, q_gen, r_gen, s_gen; - - return u3_none; - - if ( c3y == u3ud(gen) ) { - // printf("studly\n"); - // u3_err("stud m", gen); - return u3m_bail(c3__exit); - - return u3nt(c3__cnts, - u3nc(u3k(gen), u3_nul), - u3_nul); - } - else switch ( u3h(gen) ) { - default: return u3_none; - - case u3_nul: { - return u3nt(c3__cnts, - u3nc(u3k(gen), u3_nul), - u3_nul); - } - -# define _open_p(stem) \ - case c3__##stem: \ - return _open_in_##stem(ter, u3t(gen)); \ - -# define _open_pq(stem) \ - case c3__##stem: \ - if ( c3n == u3r_cell(u3t(gen), &p_gen, &q_gen) ) { \ - return u3m_bail(c3__fail); \ - } else return _open_in_##stem(ter, p_gen, q_gen); - -# define _open_pqr(stem) \ - case c3__##stem: \ - if ( c3n == u3r_trel(u3t(gen), &p_gen, &q_gen, &r_gen) ) { \ - return u3m_bail(c3__fail); \ - } else return _open_in_##stem(ter, p_gen, q_gen, r_gen); - -# define _open_pqrs(stem) \ - case c3__##stem: \ - if ( c3n == u3r_qual\ - (u3t(gen), &p_gen, &q_gen, &r_gen, &s_gen) )\ - { \ - return u3m_bail(c3__fail); \ - } else return _open_in_##stem(ter, p_gen, q_gen, r_gen, s_gen); - - _open_p (bccb); - _open_p (bctr); - _open_p (bczp); - - _open_p (brdt); - _open_pq (brcb); - _open_p (brhp); - _open_pq (brkt); - _open_pq (brls); - _open_p (brwt); - - _open_pq (clcb); - _open_p (clcn); - _open_pq (clhp); - _open_pqrs(clkt); - _open_pqr (clls); - _open_p (cltr); - _open_p (clsg); - _open_pq (cncb); - // _open_pq (cncl); - _open_pq (cndt); - _open_pqrs(cnkt); - _open_pq (cnhp); - _open_pqr (cnls); - _open_pqr (cnsg); - _open_p (cnzy); - _open_p (cnzz); - - _open_p (hxgl); - _open_p (hxgr); - - _open_pq (ktdt); -// _open_pq (kthp); - - _open_pq (sgts); -// _open_pq (sgbr); - _open_pq (sggl); - _open_pq (sgbc); - _open_pq (sgcb); - _open_pqrs(sgcn); - _open_pq (sgfs); - _open_pq (sgls); - _open_pqr (sgpm); - _open_pqrs(sgwt); - - _open_pq (smcl); - // _open_pq (smsm); - - _open_pq (tsbr); - _open_pq (tscl); - _open_pqr (tsdt); - _open_pq (tsgl); - _open_pq (tshp); - _open_pq (tsls); - _open_p (tssg); - - _open_pqr (wtdt); - _open_pq (wtgl); - _open_pqr (wtpt); - _open_pqr (wtsg); - _open_p (wtzp); - _open_p (wtbr); - _open_pq (wthp); - _open_pq (wtgr); - _open_pqr (wtls); - _open_pqr (wtkt); - _open_p (wtpm); - - _open_pq (zpcb); - _open_p (zpgr); - } - } - - /** rake - **/ - u3_noun - u3qfp_rake(u3_noun gen) - { - u3_noun p_gen, q_gen; - - if ( c3y == u3ud(gen) ) { - return u3nc(u3k(gen), u3_nul); - } - else switch ( u3h(gen) ) { - default: return u3m_error("rake-twig"); - - case u3_nul: return u3nc(u3k(gen), u3_nul); - - case c3__cnzy: { - return u3nc(u3k(u3t(gen)), u3_nul); - } - case c3__cnzz: { - return u3k(u3t(gen)); - } - case c3__cnts: { - if ( c3n == u3r_cell(u3t(gen), &p_gen, &q_gen) ) { - return u3m_bail(c3__fail); - } - else { - if ( u3_nul != q_gen ) { - return u3m_bail(c3__fail); - } - else { - return u3k(p_gen); - } - } - } - case c3__zpcb: { - if ( c3n == u3r_cell(u3t(gen), &p_gen, &q_gen) ) { - return u3m_bail(c3__fail); - } - else return u3qfp_rake(q_gen); - } - } - } - u3_noun - u3wfp_rake(u3_noun cor) - { - u3_noun gen; - - if ( u3_none == (gen = u3r_at(u3x_sam, cor)) ) { - return u3m_bail(c3__fail); - } else { - return u3qfp_rake(gen); - } - } - - /** hack - **/ - u3_noun - u3qfp_hack(u3_noun ter, - u3_noun gen) - { - u3_noun p_gen, q_gen; - u3_noun ret; - - if ( c3y == u3du(u3h(gen)) ) { - return u3nt(c3y, - u3k(u3h(gen)), - u3k(u3t(gen))); - } - else switch ( u3h(gen) ) { - case c3__tsgr: u3x_cell(u3t(gen), &p_gen, &q_gen); - { - if ( (c3n == u3du(p_gen)) || (u3_nul != u3h(p_gen)) ) { - return u3nc(c3n, u3k(gen)); - } - else { - u3_noun pyr = u3qfp_hack(ter, q_gen); - - if ( c3y == u3h(pyr) ) { - ret = u3nt(c3y, - u3nt(c3__tsgr, - u3k(p_gen), - u3k(u3h(u3t(pyr)))), - u3nt(c3__tsgr, - u3k(p_gen), - u3k(u3t(u3t(pyr))))); - } - else { - ret = u3nc(c3n, - u3nt(c3__tsgr, - u3k(p_gen), - u3k(u3t(pyr)))); - } - u3z(pyr); - return ret; - } - } - case c3__zpcb: u3x_cell(u3t(gen), &p_gen, &q_gen); - { - u3_noun pyr = u3qfp_hack(ter, q_gen); - - if ( c3y == u3h(pyr) ) { - ret = u3nt(c3y, - u3nt(c3__zpcb, - u3k(p_gen), - u3k(u3h(u3t(pyr)))), - u3nt(c3__zpcb, - u3k(p_gen), - u3k(u3t(u3t(pyr))))); - } - else { - ret = u3nc(c3n, - u3nt(c3__zpcb, - u3k(p_gen), - u3k(u3t(pyr)))); - } - u3z(pyr); - return ret; - } - default: break; - } - - { - u3_noun voq = _ap_open_l(ter, gen); - - if ( u3_none == voq ) { - return u3nc(c3n, u3k(gen)); - } - else if ( c3y == u3r_sing(voq, gen) ) { - return u3nc(c3n, voq); - } - else { - ret = u3qfp_hack(ter, voq); - - u3z(voq); - return ret; - } - } - } - - u3_noun - u3wfp_hack(u3_noun cor) - { - u3_noun gen; - - if ( u3_none == (gen = u3r_at(u3x_sam, cor)) ) { - return u3m_bail(c3__fail); - } else { - u3_noun ter = u3r_at(u3x_con, cor); - - return u3qfp_hack(ter, gen); - } - } -#endif - -/* boilerplate -*/ - static u3_noun - _ap_core(u3_noun ter, - u3_noun gen) - { - u3_noun gat = u3j_cook("_ap_core-ap", u3k(ter), "ap"); - - return u3i_molt(gat, u3x_sam, u3k(gen), 0); - } - - static u3_noun - _ar_core(u3_noun van, - u3_noun ref, - u3_noun syn) - { - u3_noun gat = u3j_hook(u3k(van), "ar"); - - return u3i_molt(gat, u3x_sam, u3nc(u3k(ref), u3k(syn)), 0); - } - -/* fish -*/ - u3_noun - u3qfr_fish(u3_noun van, - u3_noun ref, - u3_noun syn, - u3_noun axe) - { - u3_noun gat = u3j_soft(_ar_core(van, ref, syn), "fish"); - - return u3n_kick_on(u3i_molt(gat, - u3x_sam, - u3k(axe), - 0)); - } - -/* open -*/ - static u3_noun - _ap_open_n(u3_noun ter, - u3_noun fab, - u3_noun gen) - { - u3_noun cor = _ap_core(ter, gen); - -#if 1 - if ( c3n == fab ) { - cor = u3i_molt(cor, 14, c3n, 0); - } -#endif - return u3j_soft(cor, "open"); - } - static u3_noun - _ap_open_l(u3_noun ter, - u3_noun fab, - u3_noun gen) - { -#if 0 - u3_noun pro = _open_in(ter, gen); - - if ( u3_none != pro ) { - return pro; - } else { - return _ap_open_n(ter, gen); - } -#else - return _ap_open_n(ter, fab, gen); -#endif - } - - u3_noun - u3qfp_open(u3_noun ter, - u3_noun fab, - u3_noun gen) - { - return _ap_open_l(ter, fab, gen); - } - - u3_noun - u3wfp_open(u3_noun cor) - { - u3_noun gen; - - if ( u3_none == (gen = u3r_at(u3x_sam, cor)) ) { - return u3m_bail(c3__fail); - } else { - u3_noun ter = u3r_at(u3x_con, cor); - - return u3qfp_open(ter, c3y, gen); - } - } - diff --git a/pkg/noun/jets/f/fitz.c b/pkg/noun/jets/f/fitz.c index f8cff2b1c9..b1c2a5dfb3 100644 --- a/pkg/noun/jets/f/fitz.c +++ b/pkg/noun/jets/f/fitz.c @@ -5,63 +5,71 @@ #include "noun.h" +static u3_noun +_fitz_fiz(u3_noun yaz, + u3_noun wix) +{ + c3_w yaz_w = u3r_met(3, yaz); + c3_w wix_w = u3r_met(3, wix); + c3_y yaz_y, wix_y; - static u3_noun - _fitz_fiz(u3_noun yaz, - u3_noun wix) - { - c3_w yaz_w = u3r_met(3, yaz); - c3_w wix_w = u3r_met(3, wix); - c3_y yaz_y, wix_y; - - yaz_y = (0 == yaz_w) ? 0 : u3r_byte((yaz_w - 1), yaz); - if ( (yaz_y < 'A') || (yaz_y > 'Z') ) yaz_y = 0; + yaz_y = (0 == yaz_w) ? 0 : u3r_byte((yaz_w - 1), yaz); + if ( (yaz_y < 'A') || (yaz_y > 'Z') ) yaz_y = 0; - wix_y = (0 == wix_w) ? 0 : u3r_byte((wix_w - 1), wix); - if ( (wix_y < 'A') || (wix_y > 'Z') ) wix_y = 0; + wix_y = (0 == wix_w) ? 0 : u3r_byte((wix_w - 1), wix); + if ( (wix_y < 'A') || (wix_y > 'Z') ) wix_y = 0; - if ( yaz_y && wix_y ) { - if ( !wix_y || (wix_y > yaz_y) ) { - return c3n; - } + if ( yaz_y && wix_y ) { + if ( wix_y > yaz_y ) { + return c3n; } - return c3y; } - u3_noun - u3qf_fitz(u3_noun yaz, - u3_noun wix) - { - c3_w i_w, met_w = c3_min(u3r_met(3, yaz), u3r_met(3, wix)); + return c3y; +} - if ( c3n == _fitz_fiz(yaz, wix) ) { - return c3n; +u3_noun +u3qf_fitz(u3_noun yaz, + u3_noun wix) +{ + c3_w yet_w = u3r_met(3, yaz); + c3_w wet_w = u3r_met(3, wix); + + c3_w i_w, met_w = c3_min(yet_w, wet_w); + + if ( c3n == _fitz_fiz(yaz, wix) ) { + return c3n; + } + for ( i_w = 0; i_w < met_w; i_w++ ) { + c3_y yaz_y = u3r_byte(i_w, yaz); + c3_y wix_y = u3r_byte(i_w, wix); + + if ( (i_w == (yet_w - 1)) && (yaz_y >= 'A') && (yaz_y <= 'Z')) { + return c3y; } - for ( i_w = 0; i_w < met_w; i_w++ ) { - c3_y yaz_y = u3r_byte(i_w, yaz); - c3_y wix_y = u3r_byte(i_w, wix); - if ( (yaz_y >= 'A') && (yaz_y <= 'Z') ) yaz_y = 0; - if ( (wix_y >= 'A') && (wix_y <= 'Z') ) wix_y = 0; + if ( (i_w == (wet_w - 1)) && (wix_y >= 'A') && (wix_y <= 'Z')) { + return c3y; + } - if ( yaz_y && wix_y && (yaz_y != wix_y) ) { - return c3n; - } + if ( yaz_y != wix_y ) { + return c3n; } - return c3y; } + return c3y; +} - u3_noun - u3wf_fitz(u3_noun cor) - { - u3_noun yaz, wix; +u3_noun +u3wf_fitz(u3_noun cor) +{ + u3_noun yaz, wix; - if ( (c3n == u3r_mean(cor, u3x_sam_2, &yaz, u3x_sam_3, &wix, 0)) || - (c3n == u3ud(yaz)) || - (c3n == u3ud(wix)) ) - { - return u3m_bail(c3__fail); - } else { - return u3qf_fitz(yaz, wix); - } + if ( (c3n == u3r_mean(cor, u3x_sam_2, &yaz, u3x_sam_3, &wix, 0)) || + (c3n == u3ud(yaz)) || + (c3n == u3ud(wix)) ) + { + return u3m_bail(c3__fail); + } else { + return u3qf_fitz(yaz, wix); } +} diff --git a/pkg/noun/jets/f/flan.c b/pkg/noun/jets/f/flan.c index 93fa95ba1e..319e1f0547 100644 --- a/pkg/noun/jets/f/flan.c +++ b/pkg/noun/jets/f/flan.c @@ -35,7 +35,7 @@ } } u3_noun - u3wf_flan(u3_noun cor) + u3wf_flan_139(u3_noun cor) { u3_noun bos, nif; diff --git a/pkg/noun/jets/f/flip.c b/pkg/noun/jets/f/flip.c index d306c88e7a..9eb922e5e1 100644 --- a/pkg/noun/jets/f/flip.c +++ b/pkg/noun/jets/f/flip.c @@ -27,7 +27,7 @@ } } u3_noun - u3wf_flip(u3_noun cor) + u3wf_flip_139(u3_noun cor) { u3_noun hel; diff --git a/pkg/noun/jets/f/flor.c b/pkg/noun/jets/f/flor.c index f67997bba4..031168e953 100644 --- a/pkg/noun/jets/f/flor.c +++ b/pkg/noun/jets/f/flor.c @@ -35,7 +35,7 @@ } } u3_noun - u3wf_flor(u3_noun cor) + u3wf_flor_139(u3_noun cor) { u3_noun bos, nif; diff --git a/pkg/noun/jets/f/hike.c b/pkg/noun/jets/f/hike.c deleted file mode 100644 index 8183e32283..0000000000 --- a/pkg/noun/jets/f/hike.c +++ /dev/null @@ -1,137 +0,0 @@ -/// @file - -#include "jets/q.h" -#include "jets/w.h" - -#include "noun.h" - - -/* internal tools -*/ - /* _lily_hike_belt_root(): convert (pac) to a list of root tools. - */ - static u3_noun - _lily_hike_belt_root(u3_noun pac) - { - if ( (u3_nul == pac) ) { - return u3_nul; - } - else { - u3_atom axis = u3h(u3h(pac)); - u3_noun tool = u3t(u3h(pac)); - u3_noun list_tool = _lily_hike_belt_root(u3t(pac)); - - if ( c3y == u3r_sing(1, axis) ) { - return u3nc(u3k(tool), - list_tool); - } - else return list_tool; - } - } - - /* _lily_hike_belt_l(): factor (pac) left. - */ - static u3_noun - _lily_hike_belt_l(u3_noun pac) - { - if ( (u3_nul == pac) ) { - return u3_nul; - } - else { - u3_atom axis = u3h(u3h(pac)); - u3_noun tool = u3t(u3h(pac)); - u3_noun belt_l = _lily_hike_belt_l(u3t(pac)); - - { - if ( (1 != axis) && - (c3y == u3r_sing(2, u3qc_cap(axis))) ) - { - u3_atom axis_tap = u3qc_mas(axis); - - return u3nc(u3nc(u3k(axis_tap), - u3k(tool)), - belt_l); - } - else return belt_l; - } - } - } - - /* _lily_hike_belt_r(): factor (pac) right. - */ - static u3_noun - _lily_hike_belt_r(u3_noun pac) - { - if ( (u3_nul == pac) ) { - return u3_nul; - } - else { - u3_atom axis = u3h(u3h(pac)); - u3_noun tool = u3t(u3h(pac)); - u3_noun belt_r = _lily_hike_belt_r(u3t(pac)); - - { - if ( (1 != axis) && - (c3y == u3r_sing(3, u3qc_cap(axis))) ) - { - u3_atom axis_tap = u3qc_mas(axis); - - return u3nc(u3nc(u3k(axis_tap), - u3k(tool)), - belt_r); - } - else return belt_r; - } - } - } - - u3_noun - u3qf_hike(u3_noun axe, - u3_noun pac) - { - u3_assert(0); - if ( (u3_nul == pac) ) { - return u3nc(0, u3k(axe)); - } - else { - u3_noun zet = _lily_hike_belt_root(pac); - - if ( u3_nul != zet ) { - u3_noun fol = u3k(u3h(zet)); - - u3z(zet); - return fol; - } - else { - u3_noun tum = _lily_hike_belt_l(pac); - u3_noun gam = _lily_hike_belt_r(pac); - u3_noun hax = u3qc_peg(axe, 2); - u3_noun moz = u3qc_peg(axe, 3); - u3_noun zip = u3qf_hike(hax, tum); - u3_noun dof = u3qf_hike(moz, gam); - u3_noun fol = u3qf_cons(zip, dof); - - u3z(tum); - u3z(gam); - u3z(hax); - u3z(moz); - u3z(zip); - u3z(dof); - - return fol; - } - } - } - u3_noun - u3wf_hike(u3_noun cor) - { - u3_noun axe, pac; - - if ( (c3n == u3r_mean(cor, u3x_sam_2, &axe, u3x_sam_3, &pac, 0)) || - (c3n == u3ud(axe)) ) - { - return u3m_bail(c3__fail); - } else { - return u3qf_hike(axe, pac); - } - } diff --git a/pkg/noun/jets/q.h b/pkg/noun/jets/q.h index 33c63ef42b..fd7c5981fb 100644 --- a/pkg/noun/jets/q.h +++ b/pkg/noun/jets/q.h @@ -32,6 +32,7 @@ u3_noun u3qb_lien(u3_noun, u3_noun); u3_noun u3qb_murn(u3_noun, u3_noun); u3_noun u3qb_need(u3_noun); + u3_noun u3qb_mate(u3_noun, u3_noun); u3_noun u3qb_reap(u3_atom, u3_noun); u3_noun u3qb_reel(u3_noun, u3_noun); u3_noun u3qb_roll(u3_noun, u3_noun); @@ -222,10 +223,7 @@ u3_noun u3qf_face(u3_noun, u3_noun); u3_noun u3qf_fine(u3_noun, u3_noun, u3_noun); u3_noun u3qf_fitz(u3_noun, u3_noun); - u3_noun u3qf_flan(u3_noun, u3_noun); u3_noun u3qf_flay(u3_noun); - u3_noun u3qf_flip(u3_noun); - u3_noun u3qf_flor(u3_noun, u3_noun); u3_noun u3qf_forq(u3_noun, u3_noun); u3_noun u3qf_fork(u3_noun); u3_noun u3qf_grof(u3_noun); @@ -254,3 +252,4 @@ void u3qf_test(const c3_c*, u3_noun); #endif /* ifndef U3_JETS_Q_H */ + diff --git a/pkg/noun/jets/tree.c b/pkg/noun/jets/tree.c index b0264327d1..9e920becda 100644 --- a/pkg/noun/jets/tree.c +++ b/pkg/noun/jets/tree.c @@ -546,17 +546,17 @@ static c3_c* _140_pen_fitz_ha[] = { "469abe976ec15eeff9a87bce385f2c87c9bd89814ce2858aa9fee094beea1e5d", 0 }; -static u3j_harm _140_pen_flan_a[] = {{".2", u3wf_flan}, {}}; +static u3j_harm _140_pen_flan_a[] = {{".2", u3wf_flan_139}, {}}; static c3_c* _140_pen_flan_ha[] = { "cc00cb9373b0274af4e17d7acd77f65d8a2fa886e422c949c12d9d9e7cb3525b", 0 }; -static u3j_harm _140_pen_flip_a[] = {{".2", u3wf_flip}, {}}; +static u3j_harm _140_pen_flip_a[] = {{".2", u3wf_flip_139}, {}}; static c3_c* _140_pen_flip_ha[] = { "6e97fab9d039e715a30af5da93ef97389babfdcae7ef87655d278e77a1af0f0c", 0 }; -static u3j_harm _140_pen_flor_a[] = {{".2", u3wf_flor}, {}}; +static u3j_harm _140_pen_flor_a[] = {{".2", u3wf_flor_139}, {}}; static c3_c* _140_pen_flor_ha[] = { "ab5360aacf0c9a325727e90e1caea9c42f5d94ccc248c9e1f253b0922b4c4e63", 0 @@ -567,10 +567,6 @@ static c3_c* _140_pen_fork_ha[] = { 0 }; -// hike disabled while implementing edit -// static u3j_harm _140_pen_hike_a[] = {{".2", u3wf_hike}, {}}; -// static c3_c* _140_pen_hike_ha[] = {0}; - static u3j_harm _140_pen_look_a[] = {{".2", u3wf_look}, {}}; static c3_c* _140_pen_look_ha[] = { "fdda2166a2b9e1a9bda6ab375dd6fb6c610e18f54636a5e89896b45fd0a7169b", @@ -702,17 +698,6 @@ static u3j_hood _140_pen__ut_ho[] = {}, }; -// XX unused, hook removed, delete source -// -#if 0 -static u3j_harm _140_pen__ap_a[] = - { {"open", u3wfp_open}, - {"rake", u3wfp_rake}, - {} - }; -static c3_c* _140_pen__ap_ha[] = {0}; -#endif - static u3j_core _140_pen_d[] = { { "hex", 7, 0, _140_hex_d, _140_hex_ha }, @@ -726,15 +711,8 @@ static u3j_core _140_pen_d[] = { "flip", 7, _140_pen_flip_a, 0, _140_pen_flip_ha }, { "flor", 7, _140_pen_flor_a, 0, _140_pen_flor_ha }, { "fork", 7, _140_pen_fork_a, 0, _140_pen_fork_ha }, - // XX implementation obsolete, update or remove - // - // { "hike", 7, _140_pen_hike_a, 0, _140_pen_hike_ha }, { "look", 7, _140_pen_look_a, 0, _140_pen_look_ha }, { "loot", 7, _140_pen_loot_a, 0, _140_pen_loot_ha }, - - // XX unused, hook removed, delete source - // - // { "ap", 7, _140_pen__ap_a, 0, _140_pen__ap_ha }, { "ut", 15, 0, _140_pen__ut_d, _140_pen__ut_ha, _140_pen__ut_ho }, {} }; @@ -1825,11 +1803,7 @@ static c3_c* _140_two__in_ha[] = { "1f0a6f8b945b243520b77069060589938d9e651e34b24924db9528d02a98014f", 0 }; - static u3j_harm _140_two__by_bif_a[] = {{".2", u3wdb_bif, c3y}, {}}; - static c3_c* _140_two__by_bif_ha[] = { - "d377a032a3866e76f6f5217c7c0ed0519b768d8b1c5107e35f7dbf18d8f60880", - 0 - }; + static u3j_harm _140_two__by_del_a[] = {{".2", u3wdb_del, c3y}, {}}; static c3_c* _140_two__by_del_ha[] = { "09f78d6235d3fce8303c7bc663988349b7d4592abdacfb09b833d2f43629b6b6", @@ -1909,7 +1883,9 @@ static u3j_core _140_two__by_d[] = { { "all", 7, _140_two__by_all_a, 0, _140_two__by_all_ha }, { "any", 7, _140_two__by_any_a, 0, _140_two__by_any_ha }, { "apt", 7, _140_two__by_apt_a, 0, _140_two__by_apt_ha }, - { "bif", 7, _140_two__by_bif_a, 0, _140_two__by_bif_ha }, + // disabled due to interface change in %138 + // + // { "bif", 7, _140_two__by_bif_a, 0, _140_two__by_bif_ha }, { "del", 7, _140_two__by_del_a, 0, _140_two__by_del_ha }, { "dif", 7, _140_two__by_dif_a, 0, _140_two__by_dif_ha }, { "gas", 7, _140_two__by_gas_a, 0, _140_two__by_gas_ha }, @@ -2181,15 +2157,8 @@ static u3j_core _139_pen_d[] = { "flip", 7, _140_pen_flip_a, 0, no_hashes }, { "flor", 7, _140_pen_flor_a, 0, no_hashes }, { "fork", 7, _140_pen_fork_a, 0, no_hashes }, - // XX implementation obsolete, update or remove - // - // { "hike", 7, _140_pen_hike_a, 0, no_hashes }, { "look", 7, _140_pen_look_a, 0, no_hashes }, { "loot", 7, _140_pen_loot_a, 0, no_hashes }, - - // XX unused, hook removed, delete source - // - // { "ap", 7, _140_pen__ap_a, 0, no_hashes }, { "ut", 15, 0, _140_pen__ut_d, no_hashes, _140_pen__ut_ho }, {} }; @@ -2356,6 +2325,195 @@ u3j_core _k139_d[] = {} }; +static u3j_core _138_pen_d[] = +{ { "hex", 7, 0, _139_hex_d, no_hashes }, + + { "cell", 7, _140_pen_cell_a, 0, no_hashes }, + { "comb", 7, _140_pen_comb_a, 0, no_hashes }, + { "cons", 7, _140_pen_cons_a, 0, no_hashes }, + { "core", 7, _140_pen_core_a, 0, no_hashes }, + { "face", 7, _140_pen_face_a, 0, no_hashes }, + { "fitz", 7, _140_pen_fitz_a, 0, no_hashes }, + // flan, flip, and flor removed + // + { "fork", 7, _140_pen_fork_a, 0, no_hashes }, + { "look", 7, _140_pen_look_a, 0, no_hashes }, + { "loot", 7, _140_pen_loot_a, 0, no_hashes }, + { "ut", 15, 0, _140_pen__ut_d, no_hashes, _140_pen__ut_ho }, + {} +}; + +static u3j_core _138_qua_d[] = +{ { "pen", 3, 0, _138_pen_d, no_hashes, _140_pen_ho }, + + { "po", 7, 0, _140_qua__po_d, no_hashes }, + + { "trip", 7, _140_qua_trip_a, 0, no_hashes }, + + { "bend", 7, 0, _140_qua__bend_d, no_hashes }, + { "cold", 7, 0, _140_qua__cold_d, no_hashes }, + { "comp", 7, 0, _140_qua__comp_d, no_hashes }, + { "cook", 7, 0, _140_qua__cook_d, no_hashes }, + { "easy", 7, 0, _140_qua__easy_d, no_hashes }, + { "glue", 7, 0, _140_qua__glue_d, no_hashes }, + { "here", 7, 0, _140_qua__here_d, no_hashes }, + { "just", 7, 0, _140_qua__just_d, no_hashes }, + { "mask", 7, 0, _140_qua__mask_d, no_hashes }, + { "shim", 7, 0, _140_qua__shim_d, no_hashes }, + { "stag", 7, 0, _140_qua__stag_d, no_hashes }, + { "stew", 7, 0, _140_qua__stew_d, no_hashes }, + { "stir", 7, 0, _140_qua__stir_d, no_hashes }, + + { "pfix", 7, _140_qua_pfix_a, 0, no_hashes }, + { "plug", 7, _140_qua_plug_a, 0, no_hashes }, + { "pose", 7, _140_qua_pose_a, 0, no_hashes }, + { "sfix", 7, _140_qua_sfix_a, 0, no_hashes }, + + { "mink", 7, _140_qua_mink_a, 0, no_hashes }, + { "mole", 7, _140_qua_mole_a, 0, no_hashes }, + { "mule", 7, _140_qua_mule_a, 0, no_hashes }, + + { "scot", 7, _140_qua_scot_a, 0, no_hashes }, + { "scow", 7, _140_qua_scow_a, 0, no_hashes }, + { "slaw", 7, _140_qua_slaw_a, 0, no_hashes }, + {} +}; + +static u3j_core _138_tri_d[] = +{ { "qua", 3, 0, _138_qua_d, no_hashes, _140_qua_ho }, + + { "cofl", 7, 0, _140_tri__cofl_d, no_hashes }, + { "rd", 7, 0, _140_tri__rd_d, no_hashes }, + { "rs", 7, 0, _140_tri__rs_d, no_hashes }, + { "rq", 7, 0, _140_tri__rq_d, no_hashes }, + { "rh", 7, 0, _140_tri__rh_d, no_hashes }, + { "og", 7, 0, _140_tri__og_d, no_hashes }, + + { "sha", 7, 0, _140_tri__sha_d, no_hashes }, + { "shax", 7, _140_tri_shax_a, 0, no_hashes }, + { "shay", 7, _140_tri_shay_a, 0, no_hashes }, + { "shas", 7, _140_tri_shas_a, 0, no_hashes }, + { "shal", 7, _140_tri_shal_a, 0, no_hashes }, + + { "ob", 3, 0, _140_ob_d, no_hashes, _140_ob_ho }, + {} +}; + +static u3j_harm _138_two__by_bif_a[] = {{".2", u3wdb_bif, c3y}, {}}; + +static u3j_core _138_two__by_d[] = + { { "all", 7, _140_two__by_all_a, 0, _140_two__by_all_ha }, + { "any", 7, _140_two__by_any_a, 0, _140_two__by_any_ha }, + { "apt", 7, _140_two__by_apt_a, 0, _140_two__by_apt_ha }, + { "bif", 7, _138_two__by_bif_a, 0, no_hashes }, + { "del", 7, _140_two__by_del_a, 0, _140_two__by_del_ha }, + { "dif", 7, _140_two__by_dif_a, 0, _140_two__by_dif_ha }, + { "gas", 7, _140_two__by_gas_a, 0, _140_two__by_gas_ha }, + { "get", 7, _140_two__by_get_a, 0, _140_two__by_get_ha }, + { "has", 7, _140_two__by_has_a, 0, _140_two__by_has_ha }, + { "int", 7, _140_two__by_int_a, 0, _140_two__by_int_ha }, + { "jab", 7, _140_two__by_jab_a, 0, _140_two__by_jab_ha }, + { "key", 7, _140_two__by_key_a, 0, _140_two__by_key_ha }, + { "put", 7, _140_two__by_put_a, 0, _140_two__by_put_ha }, + { "rep", 7, _140_two__by_rep_a, 0, _140_two__by_rep_ha }, + { "run", 7, _140_two__by_run_a, 0, _140_two__by_run_ha }, + { "tap", 7, _140_two__by_tap_a, 0, _140_two__by_tap_ha }, + { "uni", 7, _140_two__by_uni_a, 0, _140_two__by_uni_ha }, + { "urn", 7, _140_two__by_urn_a, 0, _140_two__by_urn_ha }, + { "wyt", 3, _140_two__by_wyt_a, 0, _140_two__by_wyt_ha }, + {} + }; + +static u3j_harm _138_two_mate_a[] = {{".2", u3wb_mate, c3y}, {}}; + +static u3j_core _138_two_d[] = +{ { "tri", 3, 0, _138_tri_d, no_hashes, _140_tri_ho }, + + { "find", 7, _140_two_find_a, 0, no_hashes }, + { "flop", 7, _140_two_flop_a, 0, no_hashes }, + { "lent", 7, _140_two_lent_a, 0, no_hashes }, + { "levy", 7, _140_two_levy_a, 0, no_hashes }, + { "lien", 7, _140_two_lien_a, 0, no_hashes }, + { "murn", 7, _140_two_murn_a, 0, no_hashes }, + { "need", 7, _140_two_need_a, 0, no_hashes }, + { "mate", 7, _138_two_mate_a, 0, no_hashes }, + { "reap", 7, _140_two_reap_a, 0, no_hashes }, + { "reel", 7, _140_two_reel_a, 0, no_hashes }, + { "roll", 7, _140_two_roll_a, 0, no_hashes }, + { "skid", 7, _140_two_skid_a, 0, no_hashes }, + { "skim", 7, _140_two_skim_a, 0, no_hashes }, + { "skip", 7, _140_two_skip_a, 0, no_hashes }, + { "scag", 7, _140_two_scag_a, 0, no_hashes }, + { "slag", 7, _140_two_slag_a, 0, no_hashes }, + { "snag", 7, _140_two_snag_a, 0, no_hashes }, + { "sort", 7, _140_two_sort_a, 0, no_hashes }, + { "turn", 7, _140_two_turn_a, 0, no_hashes }, + { "weld", 7, _140_two_weld_a, 0, no_hashes }, + { "welp", 7, _140_two_welp_a, 0, no_hashes }, + { "zing", 7, _140_two_zing_a, 0, no_hashes }, + + { "bex", 7, _140_two_bex_a, 0, no_hashes }, + { "cat", 7, _140_two_cat_a, 0, no_hashes }, + { "can", 7, _140_two_can_a, 0, no_hashes }, + { "con", 7, _140_two_con_a, 0, no_hashes }, + { "cue", 7, _140_two_cue_a, 0, no_hashes }, + { "cut", 7, _140_two_cut_a, 0, no_hashes }, + { "dis", 7, _140_two_dis_a, 0, no_hashes }, + { "dor", 7, _140_two_dor_a, 0, no_hashes }, + { "end", 7, _140_two_end_a, 0, no_hashes }, + { "gor", 7, _140_two_gor_a, 0, no_hashes }, + { "jam", 7, _140_two_jam_a, 0, no_hashes }, + { "lsh", 7, _140_two_lsh_a, 0, no_hashes }, + { "mat", 7, _140_two_mat_a, 0, no_hashes }, + { "met", 7, _140_two_met_a, 0, no_hashes }, + { "mix", 7, _140_two_mix_a, 0, no_hashes }, + { "mor", 7, _140_two_mor_a, 0, no_hashes }, + { "mug", 7, _140_two_mug_a, 0, no_hashes }, + { "muk", 59, _140_two_muk_a, 0, no_hashes }, + { "rap", 7, _140_two_rap_a, 0, no_hashes }, + { "rep", 7, _140_two_rep_a, 0, no_hashes }, + { "rev", 7, _140_two_rev_a, 0, no_hashes }, + { "rip", 7, _140_two_rip_a, 0, no_hashes }, + { "rsh", 7, _140_two_rsh_a, 0, no_hashes }, + { "swp", 7, _140_two_swp_a, 0, no_hashes }, + { "rub", 7, _140_two_rub_a, 0, no_hashes }, + { "pow", 7, _140_two_pow_a, 0, no_hashes }, + { "sqt", 7, _140_two_sqt_a, 0, no_hashes }, + { "xeb", 7, _140_two_xeb_a, 0, no_hashes }, + + { "by", 7, 0, _138_two__by_d, no_hashes }, + { "in", 7, 0, _139_two__in_d, no_hashes }, + {} +}; + +static u3j_core _138_one_d[] = +{ { "two", 3, 0, _138_two_d, no_hashes }, + + { "add", 7, _140_one_add_a, 0, no_hashes }, + { "dec", 7, _140_one_dec_a, 0, no_hashes }, + { "div", 7, _140_one_div_a, 0, no_hashes }, + { "dvr", 7, _140_one_dvr_a, 0, no_hashes }, + { "gte", 7, _140_one_gte_a, 0, no_hashes }, + { "gth", 7, _140_one_gth_a, 0, no_hashes }, + { "lte", 7, _140_one_lte_a, 0, no_hashes }, + { "lth", 7, _140_one_lth_a, 0, no_hashes }, + { "max", 7, _140_one_max_a, 0, no_hashes }, + { "min", 7, _140_one_min_a, 0, no_hashes }, + { "mod", 7, _140_one_mod_a, 0, no_hashes }, + { "mul", 7, _140_one_mul_a, 0, no_hashes }, + { "sub", 7, _140_one_sub_a, 0, no_hashes }, + + { "cap", 7, _140_one_cap_a, 0, no_hashes }, + { "mas", 7, _140_one_mas_a, 0, no_hashes }, + { "peg", 7, _140_one_peg_a, 0, no_hashes }, + {} +}; + +u3j_core _k138_d[] = +{ { "one", 3, 0, _138_one_d, no_hashes }, + {} +}; + // TODO: probably need different ha hashes @@ -2425,6 +2583,7 @@ u3j_core _a50_d[] = static u3j_core _d[] = { { "k140", 0, 0, _k140_d, _k140_ha, 0, (u3j_core*) 140, 0 }, { "k139", 0, 0, _k139_d, no_hashes, 0, (u3j_core*) 139, 0 }, + { "k138", 0, 0, _k138_d, no_hashes, 0, (u3j_core*) 138, 0 }, { "a50", 0, 0, _a50_d, _k140_ha, 0, (u3j_core*) c3__a50, 0 }, {} }; @@ -2435,3 +2594,4 @@ u3j_Dash = { 0, 0 }; + diff --git a/pkg/noun/jets/w.h b/pkg/noun/jets/w.h index d838416c03..51dbd4471f 100644 --- a/pkg/noun/jets/w.h +++ b/pkg/noun/jets/w.h @@ -32,6 +32,7 @@ u3_noun u3wb_lien(u3_noun); u3_noun u3wb_murn(u3_noun); u3_noun u3wb_need(u3_noun); + u3_noun u3wb_mate(u3_noun); u3_noun u3wb_reap(u3_noun); u3_noun u3wb_reel(u3_noun); u3_noun u3wb_roll(u3_noun); @@ -298,10 +299,10 @@ u3_noun u3wf_face(u3_noun); u3_noun u3wf_fine(u3_noun); u3_noun u3wf_fitz(u3_noun); - u3_noun u3wf_flan(u3_noun); + u3_noun u3wf_flan_139(u3_noun); u3_noun u3wf_flay(u3_noun); - u3_noun u3wf_flip(u3_noun); - u3_noun u3wf_flor(u3_noun); + u3_noun u3wf_flip_139(u3_noun); + u3_noun u3wf_flor_139(u3_noun); u3_noun u3wf_forq(u3_noun); u3_noun u3wf_fork(u3_noun); u3_noun u3wf_hint(u3_noun); @@ -332,3 +333,4 @@ u3_noun u3wfu_rest(u3_noun); #endif /* ifndef U3_JETS_W_H */ + diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 698a959d66..f994814fe1 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -36,7 +36,7 @@ struct _cs_jam_fib { /* _cs_jam_fib_grow(): reallocate buffer with fibonacci growth */ -static void +static inline void _cs_jam_fib_grow(struct _cs_jam_fib* fib_u, c3_w mor_w) { c3_w wan_w = fib_u->bit_w + mor_w; @@ -45,6 +45,7 @@ _cs_jam_fib_grow(struct _cs_jam_fib* fib_u, c3_w mor_w) // if ( wan_w < mor_w ) { u3m_bail(c3__fail); + return; } if ( wan_w > fib_u->a_w ) { @@ -64,7 +65,7 @@ _cs_jam_fib_grow(struct _cs_jam_fib* fib_u, c3_w mor_w) /* _cs_jam_fib_chop(): chop [met_w] bits of [a] into [fib_u] */ -static void +static inline void _cs_jam_fib_chop(struct _cs_jam_fib* fib_u, c3_w met_w, u3_noun a) { c3_w bit_w = fib_u->bit_w; @@ -86,12 +87,51 @@ _cs_jam_fib_mat(struct _cs_jam_fib* fib_u, u3_noun a) _cs_jam_fib_chop(fib_u, 1, 1); } else { - c3_w a_w = u3r_met(0, a); - c3_w b_w = c3_bits_word(a_w); + c3_w a_w = u3r_met(0, a); + c3_w b_w = c3_bits_word(a_w); + c3_w bit_w = fib_u->bit_w; + + // amortize overflow checks and reallocation + // + { + c3_w met_w = a_w + (2 * b_w); + + if ( a_w > (UINT32_MAX - 64) ) { + u3m_bail(c3__fail); + return; + } + + _cs_jam_fib_grow(fib_u, met_w); + fib_u->bit_w += met_w; + } - _cs_jam_fib_chop(fib_u, b_w+1, 1 << b_w); - _cs_jam_fib_chop(fib_u, b_w-1, a_w & ((1 << (b_w-1)) - 1)); - _cs_jam_fib_chop(fib_u, a_w, a); + { + c3_w src_w[2]; + c3_w* buf_w = fib_u->sab_u->buf_w; + + // _cs_jam_fib_chop(fib_u, b_w+1, 1 << b_w); + // + { + c3_d dat_d = (c3_d)1 << b_w; + src_w[0] = (c3_w)dat_d; + src_w[1] = dat_d >> 32; + + u3r_chop_words(0, 0, b_w + 1, bit_w, buf_w, 2, src_w); + bit_w += b_w + 1; + } + + // _cs_jam_fib_chop(fib_u, b_w-1, a_w); + // + { + src_w[0] = a_w; + u3r_chop_words(0, 0, b_w - 1, bit_w, buf_w, 1, src_w); + bit_w += b_w - 1; + } + + // _cs_jam_fib_chop(fib_u, a_w, a); + // + u3r_chop(0, 0, a_w, bit_w, buf_w, a); + } } } diff --git a/pkg/vere/io/ames.c b/pkg/vere/io/ames.c index 5ecafe9287..9561d6d208 100644 --- a/pkg/vere/io/ames.c +++ b/pkg/vere/io/ames.c @@ -6,6 +6,12 @@ #include "noun.h" #include "ur.h" +#include "zlib.h" + +#include + +#include + #define FINE_PAGE 4096 // packets per page #define FINE_FRAG 1024 // bytes per fragment packet #define FINE_PATH_MAX 384 // longest allowed scry path @@ -18,6 +24,12 @@ #define QUEUE_MAX 30 // max number of packets in queue +typedef enum u3_stun_state { + STUN_OFF = 0, + STUN_TRYING = 1, + STUN_KEEPALIVE = 2, +} u3_stun_state; + /* u3_fine: fine networking */ typedef struct _u3_fine { @@ -46,6 +58,20 @@ c3_w imp_w[256]; // imperial IPs time_t imp_t[256]; // imperial IP timestamps c3_o imp_o[256]; // imperial print status + struct { // stun client state: + u3_stun_state sat_y; // formal state + c3_y tid_y[12]; // last transaction id + c3_y dad_y; // sponsoring galaxy + u3_lane lan_u; // sponsoring galaxy IP and port + uv_timer_t tim_u; // keepalive timer handle + uv_timer_t dns_u; // DNS resolution timer handle + c3_c* dns_c; // sponsoring galaxy fqdn + struct timeval las_u; // XX last sent date (not used?) + struct timeval sar_u; // date we started trying to send + u3_lane sef_u; // our lane, if we know it + c3_o wok_o; // STUN worked, set on first success + } sun_u; // + c3_o nal_o; // lane cache backcompat flag struct { // config: c3_o net_o; // can send c3_o see_o; // can scry @@ -948,13 +974,22 @@ _ames_lane_into_cache(u3p(u3h_root) lax_p, u3_noun who, u3_noun las) { u3z(who); } -/* _ames_lane_from_cache(): retrieve lane for who from cache, if any & fresh +/* _ames_lane_from_cache(): retrieve lane for who from cache, if any */ static u3_weak -_ames_lane_from_cache(u3p(u3h_root) lax_p, u3_noun who) { +_ames_lane_from_cache(u3p(u3h_root) lax_p, u3_noun who, c3_o nal_o) { u3_weak lac = u3h_git(lax_p, who); - if ( u3_none != lac ) { + if ( u3_none == lac ) { + u3z(who); + return lac; + } + + if ( nal_o == c3y ) { + lac = u3k(u3h(lac)); + } + + else { struct timeval tim_tv; gettimeofday(&tim_tv, 0); u3_noun now = u3_time_in_tv(&tim_tv); @@ -993,16 +1028,31 @@ _ames_czar_port(c3_y imp_y) } } +static c3_c* +_ames_czar_dns(c3_y imp_y, c3_c* czar_c) +{ + u3_noun nam = u3dc("scot", 'p', imp_y); + c3_c* nam_c = u3r_string(nam); + c3_w len_w = 3 + strlen(nam_c) + strlen(czar_c); + u3_assert(len_w <= 256); + c3_c* dns_c = c3_malloc(len_w); + + c3_i sas_i = snprintf(dns_c, len_w, "%s.%s.", nam_c + 1, czar_c); + u3_assert(sas_i <= 255); + + c3_free(nam_c); + u3z(nam); + + return dns_c; +} + /* _ames_czar_gone(): galaxy address resolution failed. */ static void -_ames_czar_gone(u3_pact* pac_u, time_t now) +_ames_czar_gone(u3_ames* sam_u, time_t now, c3_d imp_y, c3_c* dns_c) { - u3_ames* sam_u = pac_u->sam_u; - c3_d imp_y = pac_u->rut_u.imp_y; - if ( c3y == sam_u->imp_o[imp_y] ) { - u3l_log("ames: czar at %s: not found (b)", pac_u->rut_u.dns_c); + u3l_log("ames: czar at %s: not found (b)", dns_c); sam_u->imp_o[imp_y] = c3n; } @@ -1015,8 +1065,6 @@ _ames_czar_gone(u3_pact* pac_u, time_t now) // keep existing ip for 5 more minutes // sam_u->imp_t[imp_y] = now; - - _ames_pact_free(pac_u); } /* _ames_czar_here(): galaxy address resolution succeeded. @@ -1046,6 +1094,33 @@ _ames_czar_here(u3_pact* pac_u, time_t now, struct sockaddr_in* add_u) pac_u->rut_u.lan_u.pip_w = pip_w; } +/* _stun_czar_here(): sponsor galaxy address resolution succeeded. +*/ +static c3_w +_stun_czar_here(u3_ames* sam_u, time_t now, struct sockaddr_in* add_u) +{ + c3_y imp_y = sam_u->sun_u.dad_y; + c3_w old_w = sam_u->imp_w[imp_y]; + c3_w pip_w = ntohl(add_u->sin_addr.s_addr); + + if ( pip_w != old_w ) { + u3_noun nam = u3dc("scot", c3__if, u3i_word(pip_w)); + c3_c* nam_c = u3r_string(nam); + + u3l_log("stun: czar %s: ip %s", sam_u->dns_c, nam_c); + + c3_free(nam_c); + u3z(nam); + } + sam_u->sun_u.lan_u.pip_w = pip_w; + + sam_u->imp_w[imp_y] = pip_w; + sam_u->imp_t[imp_y] = now; + sam_u->imp_o[imp_y] = c3y; + + return pip_w; +} + /* _ames_czar_cb(): galaxy address resolution callback. */ static void @@ -1054,14 +1129,17 @@ _ames_czar_cb(uv_getaddrinfo_t* adr_u, struct addrinfo* aif_u) { { - u3_pact* pac_u = (u3_pact*)adr_u->data; - struct addrinfo* rai_u = aif_u; - time_t now = time(0); + u3_pact* pac_u = (u3_pact*)adr_u->data; + struct addrinfo* rai_u = aif_u; + time_t now = time(0); if ( sas_i == 0 ) { _ames_czar_here(pac_u, now, (struct sockaddr_in *)rai_u->ai_addr); } else { - _ames_czar_gone(pac_u, now); + _ames_czar_gone(pac_u->sam_u, now, + pac_u->rut_u.imp_y, + pac_u->rut_u.dns_c); + _ames_pact_free(pac_u); } } @@ -1091,7 +1169,7 @@ _ames_czar(u3_pact* pac_u) if ( !sam_u->dns_c ) { u3_noun nam = u3dc("scot", 'p', pac_u->rut_u.imp_y); c3_c* nam_c = u3r_string(nam); - u3l_log("ames: no galaxy domain for %s, no-op\r", nam_c); + u3l_log("ames: no galaxy domain for %s, no-op", nam_c); c3_free(nam_c); u3z(nam); @@ -1120,33 +1198,14 @@ _ames_czar(u3_pact* pac_u) return; } else { - c3_i sas_i; - - { - u3_noun nam = u3dc("scot", 'p', imp_y); - c3_c* nam_c = u3r_string(nam); - - // NB: . separator not counted, as [nam_c] includes a ~ that we skip - // - pac_u->rut_u.dns_c = - c3_malloc(1 + strlen(nam_c) + strlen(sam_u->dns_c)); - - sas_i = - snprintf(pac_u->rut_u.dns_c, 255, "%s.%s", nam_c + 1, sam_u->dns_c); - - c3_free(nam_c); - u3z(nam); - } - - if ( 255 <= sas_i ) { - u3l_log("ames: czar: galaxy domain %s truncated", sam_u->dns_c); - _ames_pact_free(pac_u); - return; - } + pac_u->rut_u.dns_c = _ames_czar_dns(imp_y, sam_u->dns_c); { uv_getaddrinfo_t* adr_u = c3_malloc(sizeof(*adr_u)); adr_u->data = pac_u; + c3_d imp_y = pac_u->rut_u.imp_y; + c3_c* dns_c = pac_u->rut_u.dns_c; + c3_i sas_i; struct addrinfo hints; memset(&hints, 0, sizeof(hints)); @@ -1157,7 +1216,8 @@ _ames_czar(u3_pact* pac_u) pac_u->rut_u.dns_c, 0, &hints)) ) { u3l_log("ames: %s", uv_strerror(sas_i)); - _ames_czar_gone(pac_u, now); + _ames_czar_gone(pac_u->sam_u, now, imp_y, dns_c); + _ames_pact_free(pac_u); return; } } @@ -1198,6 +1258,597 @@ _fine_put_cache(u3_ames* sam_u, u3_noun pax, c3_w lop_w, u3_noun lis) } } +static void +_stun_stop(u3_ames* sam_u) +{ + switch ( sam_u->sun_u.sat_y ) { + case STUN_OFF: break; // ignore; already stopped + case STUN_TRYING: + case STUN_KEEPALIVE: { + uv_timer_stop(&sam_u->sun_u.tim_u); + uv_timer_stop(&sam_u->sun_u.dns_u); + } break; + default: u3_assert(!"programmer error"); + } + sam_u->sun_u.sat_y = STUN_OFF; +} + +// XX (code reordering?) forward declarations +static void _stun_send_request(u3_ames*); +static void _stun_on_lost(u3_ames* sam_u); +static void _stun_czar(u3_ames* sam_u, c3_d tim_d); +static void _stun_resolve_dns_cb(uv_timer_t* tim_u); +static void _stun_send_request_cb(uv_udp_send_t *req_u, c3_i sas_i); +static void _stun_on_failure(u3_ames* sam_u); +static void _stun_start(u3_ames* sam_u, c3_o fail); +static c3_y* _stun_add_fingerprint(c3_y *message, c3_w index); +static c3_o _stun_find_xor_mapped_address(c3_y* buf_y, c3_w buf_len, u3_lane* lan_u); + +static c3_d +_stun_time_gap(struct timeval start) +{ + struct timeval tim_tv; + gettimeofday(&tim_tv, 0); + u3_noun now = u3_time_in_tv(&tim_tv); + u3_noun den = u3_time_in_tv(&start); + return u3_time_gap_ms(den, now); +} + +/* _stun_reset(): stun failed. start again using max backoff + */ +static void +_stun_reset(uv_timer_t* tim_u) +{ + u3_ames* sam_u = (u3_ames*)(tim_u->data); + + _stun_start(sam_u, c3y); +} + +static void +_stun_timer_cb(uv_timer_t* tim_u) +{ + c3_w rto = 500; + + u3_ames* sam_u = (u3_ames*)(tim_u->data); + + switch ( sam_u->sun_u.sat_y ) { + case STUN_OFF: { + // ignore; stray timer (although this shouldn't happen) + u3l_log("stun: stray timer STUN_OFF"); + } break; + case STUN_KEEPALIVE: { + sam_u->sun_u.sat_y = STUN_TRYING; + sam_u->sun_u.tim_u.data = sam_u; + gettimeofday(&sam_u->sun_u.sar_u, 0); // set start time to now + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, rto, 0); + _stun_send_request(sam_u); + } break; + case STUN_TRYING: { + c3_d gap_d = _stun_time_gap(sam_u->sun_u.sar_u); + c3_d nex_d = (gap_d * 2) + rto - gap_d; + + if ( gap_d >= (39500) ) { + _stun_on_lost(sam_u); + } else if ( gap_d >= (31500) ) { + // wait ~s8 for the last STUN request + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, 8000 , 0); + _stun_send_request(sam_u); + } else { + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, + (nex_d >= 31500) ? 31500 : nex_d, 0); + _stun_send_request(sam_u); + } + } break; + default: u3_assert(!"programmer error"); + } +} + +typedef struct _u3_stun_send { + uv_udp_send_t req_u; // uv udp request handle + u3_ames* sam_u; // backpointer to driver state + c3_y* hun_y; // buffer + +} u3_stun_send; + +static void +_stun_on_request_fail(u3_ames* sam_u, c3_i sas_i) +{ + u3l_log("stun: send callback fail_async: %s", uv_strerror(sas_i)); + + _stun_on_failure(sam_u); // %kick ping app + + sam_u->sun_u.sat_y = STUN_TRYING; + _stun_timer_cb(&sam_u->sun_u.tim_u); // retry sending the failed request +} + +static void +_stun_send_request_cb(uv_udp_send_t *req_u, c3_i sas_i) +{ + u3_stun_send* snd_u = (u3_stun_send*)req_u; + u3_ames* sam_u = snd_u->sam_u; + + if ( sas_i ) { + _stun_on_request_fail(sam_u, sas_i); + } + else { + // XX curently not used + gettimeofday(&sam_u->sun_u.las_u, 0); // overwrite last sent date + } + c3_free(snd_u->hun_y); + c3_free(snd_u); +} + +static void +_stun_send_response_cb(uv_udp_send_t *rep_u, c3_i sas_i) +{ + u3_stun_send* snd_u = (u3_stun_send*)rep_u; + if ( sas_i != 0 ) { + u3l_log("stun: _stun_send_response_cb fail_sync: %s", uv_strerror(sas_i)); + } + c3_free(snd_u->hun_y); + c3_free(snd_u); +} + +static void _stun_on_request(u3_ames *sam_u, c3_y* buf_r, + const struct sockaddr* adr_u) +{ + struct sockaddr_in* add_u = (struct sockaddr_in*)adr_u; + c3_y *buf_y = c3_calloc(40); + c3_w cookie = 0x2112A442; + + c3_w cur_w = 20; // STUN header is 20 bytes + memcpy(buf_y, buf_r, cur_w); // copy STUN request header + buf_y[0] = 0x01; buf_y[1] = 0x01; // 0x0101 SUCCESS RESPONSE + buf_y[2] = 0x00; buf_y[3] = 0x14; // Length: 20 bytes + + // XOR-MAPPED-ADDRESS + buf_y[cur_w] = 0x00; buf_y[cur_w + 1] = 0x20; // attribute type 0x00020 + buf_y[cur_w + 2] = 0x00; buf_y[cur_w + 3] = 0x08; // STUN attribute length + // extra reserved 0x0 byte + buf_y[cur_w + 5] = 0x01; // family 0x01:IPv4 + + c3_s x_port = htons(ntohs(add_u->sin_port) ^ cookie >> 16); + c3_w x_ip = htonl(ntohl(add_u->sin_addr.s_addr) ^ cookie); + memcpy(buf_y + cur_w + 6, &x_port, 2); // X-Port + memcpy(buf_y + cur_w + 8, &x_ip, 4); // X-IP Addres + + // FINGERPRINT + buf_y = _stun_add_fingerprint(buf_y, cur_w + 12); + + uv_buf_t buf_u = uv_buf_init((c3_c*)buf_y, 40); + u3_stun_send* snd_u = c3_calloc(sizeof(*snd_u)); + + snd_u->sam_u = sam_u; + snd_u->hun_y = buf_y; + c3_i sas_i = uv_udp_send( + (uv_udp_send_t*)snd_u, &sam_u->wax_u, &buf_u, 1, + adr_u, _stun_send_response_cb + ); + + if ( sas_i != 0 ) { + u3l_log("stun: send response fail_sync: %s", uv_strerror(sas_i)); + c3_free(buf_y); + c3_free(snd_u); + } +} + +static void +_stun_on_response(u3_ames* sam_u, c3_y* buf_y, c3_w buf_len) +{ + u3_stun_state old_y = sam_u->sun_u.sat_y; + + u3_lane lan_u; + + // Ignore STUN responses that dont' have the XOR-MAPPED-ADDRESS attribute + if ( c3n == _stun_find_xor_mapped_address(buf_y, buf_len, &lan_u) ) { + return; + } + u3_noun wir = u3nc(c3__ames, u3_nul); + if (sam_u->sun_u.wok_o == c3n) { + // stop %ping app + u3_noun cad = u3nq(c3__stun, c3__stop, sam_u->sun_u.dad_y, + u3nc(c3n, u3_ames_encode_lane(lan_u))); + u3_ovum *ovo_u = u3_ovum_init(0, c3__ames, wir, cad); + u3_auto_plan(&sam_u->car_u, ovo_u); + sam_u->sun_u.wok_o = c3y; + } + else if ( (sam_u->sun_u.sef_u.por_s != lan_u.por_s) || + (sam_u->sun_u.sef_u.pip_w != lan_u.pip_w) ) + { + // lane changed + u3_noun cad = u3nq(c3__stun, c3__once, sam_u->sun_u.dad_y, + u3nc(c3n, u3_ames_encode_lane(lan_u))); + u3_ovum *ovo_u = u3_ovum_init(0, c3__ames, wir, cad); + u3_auto_plan(&sam_u->car_u, ovo_u); + } + else { + u3z(wir); + } + sam_u->sun_u.sef_u = lan_u; + + switch ( sam_u->sun_u.sat_y ) { + case STUN_OFF: break; // ignore; stray response + case STUN_KEEPALIVE: break; // ignore; duplicate response + case STUN_TRYING: { + sam_u->sun_u.sat_y = STUN_KEEPALIVE; + if ( ent_getentropy(sam_u->sun_u.tid_y, 12) ) { + u3l_log("stun: getentropy fail: %s", strerror(errno)); + _stun_on_lost(sam_u); + } + else { + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, 25*1000, 0); + } + } break; + default: assert("programmer error"); + } +} + +static void +_stun_on_failure(u3_ames* sam_u) +{ + // only inject event into arvo to %kick ping app on first failure + if (sam_u->sun_u.wok_o == c3y) { + u3_noun wir = u3nc(c3__ames, u3_nul); + u3_noun cad = u3nq(c3__stun, c3__fail, sam_u->sun_u.dad_y, + u3nc(c3n, u3_ames_encode_lane(sam_u->sun_u.sef_u))); + u3_ovum *ovo_u = u3_ovum_init(0, c3__ames, wir, cad); + u3_auto_plan(&sam_u->car_u, ovo_u); + } + sam_u->sun_u.wok_o = c3n; +} + +static void +_stun_on_lost(u3_ames* sam_u) +{ + _stun_stop(sam_u); + _stun_on_failure(sam_u); + // resolve DNS again, and (re)start STUN + // XX call _stun_start(sam_u, c3y) directly? + uv_timer_start(&sam_u->sun_u.dns_u, _stun_reset, 5*1000, 0); +} + +static void +_stun_send_request(u3_ames* sam_u) +{ + u3_assert( STUN_OFF != sam_u->sun_u.sat_y ); + + struct sockaddr_in add_u; + memset(&add_u, 0, sizeof(add_u)); + add_u.sin_family = AF_INET; + add_u.sin_addr.s_addr = htonl(sam_u->sun_u.lan_u.pip_w); + add_u.sin_port = htons(sam_u->sun_u.lan_u.por_s); + + // see STUN RFC 8489 + // https://datatracker.ietf.org/doc/html/rfc8489#section-5 + c3_y *buf_y = c3_calloc(28); + + // STUN message type: "binding request" + buf_y[1] = 0x01; + + // STUN message length: 8 (header and 32-bit FINGERPRINT) + buf_y[2] = 0x00; buf_y[3] = 0x08; + + + // STUN "magic cookie" 0x2112A442 in network byte order + buf_y[4] = 0x21; buf_y[5] = 0x12; buf_y[6] = 0xa4; buf_y[7] = 0x42; + + // STUN "transaction id" + memcpy(buf_y + 8, sam_u->sun_u.tid_y, 12); + + // FINGERPRINT + buf_y = _stun_add_fingerprint(buf_y, 20); + + uv_buf_t buf_u = uv_buf_init((c3_c*)buf_y, 28); + u3_stun_send* snd_u = c3_calloc(sizeof(*snd_u)); + snd_u->sam_u = sam_u; + snd_u->hun_y = buf_y; + + c3_i sas_i = uv_udp_send( + (uv_udp_send_t*)snd_u, &sam_u->wax_u, &buf_u, 1, + (const struct sockaddr*)&add_u, _stun_send_request_cb + ); + + if ( sas_i != 0) { + _stun_on_request_fail(sam_u, sas_i); + c3_free(buf_y); + c3_free(snd_u); + } +} + +static void +_stun_czar_cb(uv_getaddrinfo_t* adr_u, + c3_i sas_i, + struct addrinfo* aif_u) +{ + { + u3_ames* sam_u = (u3_ames*)(adr_u->data); + struct addrinfo* rai_u = aif_u; + time_t now = time(0); + + gettimeofday(&sam_u->sun_u.sar_u, 0); // set start time to now + + if (sas_i == 0) { + _stun_czar_here(sam_u, now, (struct sockaddr_in *)rai_u->ai_addr); + if (sam_u->sun_u.sat_y == STUN_OFF) { + sam_u->sun_u.sat_y = STUN_TRYING; + _stun_send_request(sam_u); + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, 500, 0); + } + // resolve DNS again in five minutes + uv_timer_start(&sam_u->sun_u.dns_u, _stun_resolve_dns_cb, 5*60*1000, 0); + } else { + u3l_log("stun: _stun_czar_cb request fail_sync: %s", uv_strerror(sas_i)); + _ames_czar_gone(sam_u, now, sam_u->sun_u.dad_y, sam_u->dns_c); + _stun_on_lost(sam_u); + } + } + c3_free(adr_u); + uv_freeaddrinfo(aif_u); +} + +static void +_stun_czar(u3_ames* sam_u, c3_d tim_d) +{ + c3_d imp_y = sam_u->sun_u.dad_y; + sam_u->sun_u.lan_u.por_s = _ames_czar_port(imp_y); + + // Enable STUN using -L + // XX maybe enabled with a flag, for development? + if (c3n == u3_Host.ops_u.net) { + sam_u->sun_u.lan_u.pip_w = 0x7f000001; + sam_u->sun_u.sat_y = STUN_TRYING; + _stun_send_request(sam_u); + + gettimeofday(&sam_u->sun_u.sar_u, 0); + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, tim_d, 0); + + return; + } + + + // if we don't have a galaxy domain, no-op + // + if (!sam_u->dns_c) { + u3_noun nam = u3dc("scot", 'p', imp_y); + c3_c *nam_c = u3r_string(nam); + u3l_log("ames: no galaxy domain for %s, no-op", nam_c); + + c3_free(nam_c); + u3z(nam); + return; + } + + { + c3_w pip_w = sam_u->imp_w[imp_y]; + time_t wen = sam_u->imp_t[imp_y]; + time_t now = time(0); + + // XX keep same as ames? + // backoff for 5 minutes after failed lookup + // + if ((now < wen) // time shenanigans! + || ((0xffffffff == pip_w) // sentinal ip address + && ((now - wen) < 300))) { + return; + } + // cached addresses have a 5 minute TTL + // + else if ((0 != pip_w) && ((now - wen) < 300)) { + sam_u->sun_u.sat_y = STUN_TRYING; + sam_u->sun_u.lan_u.pip_w = pip_w; + + _stun_send_request(sam_u); + + gettimeofday(&sam_u->sun_u.sar_u, 0); + uv_timer_start(&sam_u->sun_u.tim_u, _stun_timer_cb, tim_d, 0); + return; + } else { + // call callback right away first time we resolve the sponsor's DNS + sam_u->sun_u.dns_u.data = sam_u; + uv_timer_start(&sam_u->sun_u.dns_u, _stun_resolve_dns_cb, tim_d, 0); + } + } +} + +static void +_stun_start(u3_ames* sam_u, c3_o fail) +{ + if ( ent_getentropy(sam_u->sun_u.tid_y, 12) ) { + u3l_log("stun: getentropy fail: %s", strerror(errno)); + _stun_on_lost(sam_u); + } else { + _stun_czar(sam_u, (fail == c3n) ? 500 : 39500); + } +} + +static void +_stun_resolve_dns_cb(uv_timer_t* tim_u) +{ + u3_ames* sam_u = (u3_ames*)(tim_u->data); + c3_i sas_i; + + c3_y imp_y = sam_u->sun_u.dad_y; + sam_u->sun_u.lan_u.por_s = _ames_czar_port(imp_y); + + if ( !sam_u->sun_u.dns_c ) { + sam_u->sun_u.dns_c = _ames_czar_dns(imp_y, sam_u->dns_c); + } + + { + uv_getaddrinfo_t* adr_u = c3_malloc(sizeof(*adr_u)); + adr_u->data = sam_u; + + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; // only IPv4 addresses + + if (0 != (sas_i = uv_getaddrinfo(u3L, adr_u, _stun_czar_cb, + sam_u->sun_u.dns_c, 0, &hints))) + { + u3l_log("stun: uv_getaddrinfo failed %s %s", uv_strerror(sas_i), sam_u->sun_u.dns_c); + _ames_czar_gone(sam_u, time(0), sam_u->sun_u.dad_y, sam_u->dns_c); + _stun_on_lost(sam_u); + return; + } + } +} + +static c3_o +_stun_find_xor_mapped_address(c3_y* buf_y, c3_w buf_len, u3_lane* lan_u) +{ + c3_y xor_y[4] = {0x00, 0x20, 0x00, 0x08}; + c3_w cookie = 0x2112A442; + + if (buf_len < 40) { // At least STUN header, XOR-MAPPED-ADDRESS & FINGERPRINT + return c3n; + } + + c3_w i = 20; // start after header + + c3_y* fin_y = memmem(buf_y + i, buf_len - i, xor_y, sizeof(xor_y)); + if ( fin_y != 0 ) { + c3_w cur = (c3_w)(fin_y - buf_y) + sizeof(xor_y); + + if ( (buf_y[cur] != 0x0) && (buf_y[cur+1] != 0x1) ) { + return c3n; + } + + cur += 2; + + c3_s port = htons(_ames_sift_short(buf_y + cur)) ^ cookie >> 16; + c3_w ip = ntohl(htonl(_ames_sift_word(buf_y + cur + 2)) ^ cookie); + + lan_u->por_s = ntohs(port); + lan_u->pip_w = ip; + + if ( u3C.wag_w & u3o_verbose ) { + c3_c ip_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &ip, ip_str, INET_ADDRSTRLEN); + u3l_log("stun: hear ip:port %s:%u", ip_str, port); + } + return c3y; + } + return c3n; +} + +static c3_o +_stun_has_fingerprint(c3_y* buf_y, c3_w buf_len) +{ + c3_y ned_y[4] = {0x80, 0x28, 0x00, 0x04}; + if ( buf_len < 28 ) { // At least STUN header and FINGERPRINT + return c3n; + } + + { + c3_y* fin_y = 0; + c3_w i = 20; // start after the header + + fin_y = memmem(buf_y + i, buf_len - i, ned_y, sizeof(ned_y)); + if ( fin_y != 0 ) { + c3_w len_w = fin_y - buf_y; + // Skip attribute type and length + c3_w fingerprint = _ames_sift_word(fin_y + sizeof(ned_y)); + c3_w init = crc32(0L, Z_NULL, 0); + c3_w crc = htonl(crc32(init, buf_y, len_w) ^ 0x5354554e); + if ((fingerprint == crc) && (fin_y - buf_y + 8) == buf_len) { + return c3y; + } + } + + return c3n; + } +} + +static c3_y* +_stun_add_fingerprint(c3_y *message, c3_w index) +{ + // Compute FINGERPRINT value as CRC-32 of the STUN message + // up to (but excluding) the FINGERPRINT attribute itself, + // XOR'ed with the 32-bit value 0x5354554e + c3_w init = crc32(0L, Z_NULL, 0); + c3_w crc = htonl(crc32(init, message, index) ^ 0x5354554e); + + // STUN attribute type: "FINGERPRINT" + message[index] = 0x80; message[index + 1] = 0x28; + // STUN attribute length: 4 bytes + message[index + 2] = 0x00; message[index + 3] = 0x04; + + memcpy(message + index + 4, &crc, 4); + + return message; +} + +static c3_o +_stun_is_our_response(c3_y* buf_y, c3_y tid_y[12], c3_w buf_len) +{ + c3_w cookie = htonl(0x2112A442); + + // Expects at least: + // STUN header, 12 byte XOR-MAPPED-ADDRESS and 8 byte FINGERPRINT + if ( (buf_len == 40) && + (buf_y[0] == 0x01 && buf_y[1] == 0x01) && + (memcmp(&cookie, buf_y + 4, 4) == 0) && + (memcmp(tid_y, buf_y + 8, 12) == 0) && + (c3y == _stun_has_fingerprint(buf_y, buf_len)) ) + { + return c3y; + } + return c3n; +} + +static c3_o +_stun_is_request(c3_y* buf_y, c3_w buf_len) +{ + c3_w cookie = htonl(0x2112A442); + + // Expects at least: + // STUN header and 8 byte FINGERPRINT + if ( (buf_len >= 28) && + (buf_y[0] == 0x0 && buf_y[1] == 0x01) && + (memcmp(&cookie, buf_y + 4, 4) == 0) && + (c3y == _stun_has_fingerprint(buf_y, buf_len)) ) + { + return c3y; + } + return c3n; +} + +static c3_o +_ames_is_czar(u3_noun who) +{ + u3_noun rac = u3do("clan:title", u3k(who)); + c3_o zar = ( c3y == (c3__czar == rac) ); + u3z(rac); + return zar; +} + +/* _ames_ef_saxo(): handle sponsorship chain notification +*/ +static void +_ames_ef_saxo(u3_ames* sam_u, u3_noun zad) +{ + u3_noun daz, dad; + + daz = u3qb_flop(zad); + if ( u3_nul == daz ) { + u3l_log("ames: empty sponsorship chain"); + u3z(zad); u3z(daz); + return; + } + + dad = u3h(daz); + u3_noun our = u3i_chubs(2, sam_u->pir_u->who_d); + + if ( c3y == _ames_is_czar(dad) && c3n == _ames_is_czar(our)) { + // if we are a galaxy, don't STUN + sam_u->sun_u.dad_y = u3r_byte(0, dad); + sam_u->sun_u.wok_o = c3n; + _stun_stop(sam_u); + _stun_start(sam_u, c3n); + } + + u3z(zad); u3z(daz); u3z(our); +} /* _ames_ef_send(): send packet to network (v4). */ @@ -1501,7 +2152,7 @@ _ames_try_send(u3_pact* pac_u, c3_o for_o) // else { u3_noun key = u3i_chubs(2, pac_u->pre_u.rec_d); - lac = _ames_lane_from_cache(sam_u->lax_p, key); + lac = _ames_lane_from_cache(sam_u->lax_p, key, sam_u->nal_o); } // if we know there's no lane, drop the packet @@ -1550,6 +2201,7 @@ _ames_try_send(u3_pact* pac_u, c3_o for_o) // if forwarding, enqueue the packet and scry for the lane // + u3_noun gang = u3nc(u3_nul, u3_nul); if ( c3y == for_o ) { if ( 0 != sam_u->pan_u ) { pan_u->nex_u = sam_u->pan_u; @@ -1558,13 +2210,13 @@ _ames_try_send(u3_pact* pac_u, c3_o for_o) sam_u->pan_u = pan_u; sam_u->sat_u.foq_d++; - u3_pier_peek_last(sam_u->pir_u, u3_nul, c3__ax, + u3_pier_peek_last(sam_u->pir_u, gang, c3__ax, u3_nul, pax, pan_u, _ames_lane_scry_forward_cb); } // otherwise, just scry for the lane // else { - u3_pier_peek_last(sam_u->pir_u, u3_nul, c3__ax, + u3_pier_peek_last(sam_u->pir_u, gang, c3__ax, u3_nul, pax, pan_u, _ames_lane_scry_cb); } } @@ -2055,6 +2707,8 @@ _ames_recv_cb(uv_udp_t* wax_u, const struct sockaddr* adr_u, unsigned flg_i) { + u3_ames* sam_u = wax_u->data; + if ( 0 > nrd_i ) { if ( u3C.wag_w & u3o_verbose ) { u3l_log("ames: recv: fail: %s", uv_strerror(nrd_i)); @@ -2070,7 +2724,21 @@ _ames_recv_cb(uv_udp_t* wax_u, } c3_free(buf_u->base); } - else { + // XX reorg, check if a STUN req/resp can look like an ames packet + // check the mug hash of the body of the packet, if not check if STUN + // otherwise , invalid packet, log failure + // check ames first, assume that STUN could maybe (not likely) overlap with ames + // for next protocol version, have an urbit cookie + // + else if (_stun_is_request((c3_y*)buf_u->base, nrd_i) == c3y) { + _stun_on_request(sam_u, (c3_y *)buf_u->base, adr_u); + c3_free(buf_u->base); + } + else if (_stun_is_our_response((c3_y*)buf_u->base, sam_u->sun_u.tid_y, nrd_i) + == c3y) { + _stun_on_response(sam_u, (c3_y*)buf_u->base, nrd_i); + c3_free(buf_u->base); + } else { u3_ames* sam_u = wax_u->data; struct sockaddr_in* add_u = (struct sockaddr_in*)adr_u; u3_lane lan_u; @@ -2135,10 +2803,11 @@ _ames_io_start(u3_ames* sam_u) { c3_s por_s = sam_u->pir_u->por_s; u3_noun who = u3i_chubs(2, sam_u->pir_u->who_d); - u3_noun rac = u3do("clan:title", u3k(who)); + c3_o zar_o = _ames_is_czar(who); c3_i ret_i; - if ( c3__czar == rac ) { + + if ( c3y == zar_o ) { c3_y num_y = (c3_y)sam_u->pir_u->who_d[0]; c3_s zar_s = _ames_czar_port(num_y); @@ -2168,7 +2837,7 @@ _ames_io_start(u3_ames* sam_u) { u3l_log("ames: bind: %s", uv_strerror(ret_i)); - if ( (c3__czar == rac) && + if ( (c3y == zar_o) && (UV_EADDRINUSE == ret_i) ) { u3l_log(" ...perhaps you've got two copies of vere running?"); @@ -2204,7 +2873,6 @@ _ames_io_start(u3_ames* sam_u) uv_udp_recv_start(&sam_u->wax_u, _ames_alloc, _ames_recv_cb); sam_u->car_u.liv_o = c3y; - u3z(rac); u3z(who); } @@ -2223,8 +2891,15 @@ _ames_ef_turf(u3_ames* sam_u, u3_noun tuf) u3_mcut_host(sam_u->dns_c, 0, hot); sam_u->dns_c[len_w] = 0; + if ( 250 <= len_w ) { + // 3 char for the galaxy (e.g. zod) and two dots + u3l_log("ames: galaxy domain too big %s len=%u", sam_u->dns_c, len_w); + u3_pier_bail(u3_king_stub()); + } + // XX invalidate sam_u->imp_w &c ? - // + c3_free(sam_u->sun_u.dns_c); + sam_u->sun_u.dns_c = 0; u3z(tuf); } @@ -2252,14 +2927,17 @@ _ames_prot_scry_cb(void* vod_p, u3_noun nun) // assume protocol version 0 // sam_u->ver_y = 0; + sam_u->fin_s.ver_y = 0; } else if ( (c3n == u3a_is_cat(ver)) || (7 < ver) ) { u3m_p("ames: strange protocol", nun); sam_u->ver_y = 0; + sam_u->fin_s.ver_y = 0; } else { sam_u->ver_y = ver; + sam_u->fin_s.ver_y = ver; } // XX revise: filtering should probably be disabled if @@ -2269,31 +2947,6 @@ _ames_prot_scry_cb(void* vod_p, u3_noun nun) u3z(nun); } -/* _fine_prot_scry_cb(): receive fine protocol version -*/ -static void -_fine_prot_scry_cb(void* vod_p, u3_noun nun) -{ - u3_ames* sam_u = vod_p; - u3_weak ver = u3r_at(7, nun); - - if ( u3_none == ver ) { - // assume protocol version 0 - // - sam_u->fin_s.ver_y = 0; - } - else if ( (c3n == u3a_is_cat(ver)) - || (7 < ver) ) { - u3m_p("fine: strange protocol", nun); - sam_u->fin_s.ver_y = 0; - } - else { - sam_u->fin_s.ver_y = ver; - } - - u3z(nun); -} - /* _ames_io_talk(): start receiving ames traffic. */ static void @@ -2315,17 +2968,14 @@ _ames_io_talk(u3_auto* car_u) u3_auto_plan(car_u, u3_ovum_init(0, c3__a, wir, cad)); } - u3_pier_peek_last(car_u->pir_u, u3_nul, c3__fx, u3_nul, - u3nt(u3i_string("protocol"), u3i_string("version"), u3_nul), - sam_u, _fine_prot_scry_cb); - // scry the protocol version out of arvo // // XX this should be re-triggered periodically, // or, better yet, %ames should emit a %turf // (or some other reconfig) effect when it is reset. // - u3_pier_peek_last(car_u->pir_u, u3_nul, c3__ax, u3_nul, + u3_noun gang = u3nc(u3_nul, u3_nul); + u3_pier_peek_last(car_u->pir_u, gang, c3__ax, u3_nul, u3nt(u3i_string("protocol"), u3i_string("version"), u3_nul), sam_u, _ames_prot_scry_cb); } @@ -2353,6 +3003,19 @@ _ames_kick_newt(u3_ames* sam_u, u3_noun tag, u3_noun dat) _ames_ef_turf(sam_u, u3k(dat)); ret_o = c3y; } break; + + case c3__saxo: { + _ames_ef_saxo(sam_u, u3k(dat)); + ret_o = c3y; + } + + case c3__nail: { + u3_noun who = u3k(u3h(dat)); + u3_noun las = u3k(u3t(dat)); + _ames_lane_into_cache(sam_u->lax_p, who, las); + sam_u->nal_o = c3y; + ret_o = c3y; + } break; } u3z(tag); u3z(dat); @@ -2443,6 +3106,8 @@ _ames_io_exit(u3_auto* car_u) { u3_ames* sam_u = (u3_ames*)car_u; uv_close(&sam_u->had_u, _ames_exit_cb); + uv_close((uv_handle_t*)&sam_u->sun_u.dns_u, 0); + uv_close((uv_handle_t*)&sam_u->sun_u.tim_u, 0); } /* _ames_io_info(): produce status info. @@ -2534,10 +3199,17 @@ u3_ames_io_init(u3_pier* pir_u) { u3_ames* sam_u = c3_calloc(sizeof(*sam_u)); sam_u->pir_u = pir_u; + sam_u->nal_o = c3n; sam_u->fig_u.net_o = c3y; sam_u->fig_u.see_o = c3y; sam_u->fig_u.fit_o = c3n; + // initialize STUN timers + uv_timer_init(u3L, &sam_u->sun_u.dns_u); + uv_timer_init(u3L, &sam_u->sun_u.tim_u); + sam_u->sun_u.tim_u.data = sam_u; + sam_u->sun_u.dns_u.data = sam_u; + // enable forwarding on galaxies only u3_noun who = u3i_chubs(2, sam_u->pir_u->who_d); u3_noun rac = u3do("clan:title", who); diff --git a/pkg/vere/io/http.c b/pkg/vere/io/http.c index 06a7cff43c..b5cb1d12cb 100644 --- a/pkg/vere/io/http.c +++ b/pkg/vere/io/http.c @@ -742,7 +742,9 @@ _http_req_cache(u3_hreq* req_u) req_u->peq_u->pax = sac; req_u->sat_e = u3_rsat_peek; - u3_pier_peek_last(htd_u->car_u.pir_u, u3_nul, c3__ex, + + u3_noun gang = u3nc(u3_nul, u3_nul); + u3_pier_peek_last(htd_u->car_u.pir_u, gang, c3__ex, u3_nul, sac, req_u->peq_u, _http_cache_scry_cb); return c3y; } diff --git a/pkg/vere/pier.c b/pkg/vere/pier.c index 907e33c319..5c5b047f3e 100644 --- a/pkg/vere/pier.c +++ b/pkg/vere/pier.c @@ -814,8 +814,8 @@ _pier_wyrd_card(u3_pier* pir_u) u3_nul); u3_noun kel = u3nl(u3nc(c3__zuse, VERE_ZUSE), // XX from both king and serf? u3nc(c3__lull, VERE_LULL), // XX from both king and serf? - u3nc(c3__arvo, 237), // XX from both king and serf? - u3nc(c3__hoon, 139), // god_u->hon_y + u3nc(c3__arvo, 236), // XX from both king and serf? + u3nc(c3__hoon, 138), // god_u->hon_y u3nc(c3__nock, 4), // god_u->noc_y u3_none); u3_noun wir = u3nc(c3__arvo, u3_nul);