// safe wrapper around ->send pipe_t pipe_send(pipe_t pipe, lob_t packet, link_t link) { if(!pipe || !packet) return NULL; if(!pipe->send || pipe->down) { LOG("dropping packet to down pipe %s: %s",pipe->id, lob_json(packet)); lob_free(packet); return pipe; } pipe->send(pipe, packet, link); return pipe; }
// encrypt and send this one packet on this pipe link_t link_direct(link_t link, lob_t inner, pipe_t pipe) { if(!link || !inner) return LOG("bad args"); if(!pipe && (!link->pipes || !(pipe = link->pipes->pipe))) return LOG("no network"); // add an outgoing cid if none set if(!lob_get_int(inner,"c")) lob_set_uint(inner,"c",e3x_exchange_cid(link->x, NULL)); pipe->send(pipe, e3x_exchange_send(link->x, inner), link); return link; }
// process an incoming handshake link_t link_handshake(link_t link, lob_t inner, lob_t outer, pipe_t pipe) { link_t ready; uint32_t out; if(!link || !inner || !outer) return LOG("bad args"); if(!link->key && link_key(link->mesh,inner) != link) return LOG("invalid/mismatch handshake key"); out = exchange3_out(link->x,0); ready = link_ready(link); // if bad at, always send current handshake if(exchange3_in(link->x, lob_get_int(inner,"at")) < out) { LOG("old/bad at: %s (%d,%d,%d)",lob_json(inner),lob_get_int(inner,"at"),exchange3_in(link->x,0),exchange3_out(link->x,0)); if(pipe) pipe->send(pipe,exchange3_handshake(link->x),link); return NULL; } // trust/add this pipe if(pipe) link_pipe(link,pipe); // try to sync ephemeral key if(!exchange3_sync(link->x,outer)) return LOG("sync failed"); // we may need to re-sync if(out != exchange3_out(link->x,0)) link_sync(link); // notify of ready state change if(!ready && link_ready(link)) { LOG("link ready"); mesh_link(link->mesh, link); } return link; }