link_t link_key(mesh_t mesh, lob_t key) { uint8_t csid; hashname_t hn; link_t link; if(!mesh || !key) return LOG("invalid args"); csid = hashname_id(mesh->keys,key); if(!csid) return LOG("no supported key"); hn = hashname_key(key); if(!hn) return LOG("invalid key"); link = link_get(mesh, hn->hashname); if(link) { hashname_free(hn); }else{ link = link_new(mesh,hn); } // load key if it's not yet if(!link->key) return link_load(link, csid, key); return link; }
int main(int argc, char **argv) { hashname_t hn; fail_unless(e3x_init(NULL) == 0); hn = hashname_vchar("uvabrvfqacyvgcu8kbrrmk9apjbvgvn2wjechqr3vf9c1zm3hv7g"); fail_unless(!hn); hn = hashname_vchar("jvdoio6kjvf3yqnxfvck43twaibbg4pmb7y3mqnvxafb26rqllwa"); fail_unless(hn); fail_unless(strlen(hashname_char(hn)) == 52); hashname_free(hn); // create intermediate fixture lob_t im = lob_new(); lob_set(im,"1a","ym7p66flpzyncnwkzxv2qk5dtosgnnstgfhw6xj2wvbvm7oz5oaq"); lob_set(im,"3a","bmxelsxgecormqjlnati6chxqua7wzipxliw5le35ifwxlge2zva"); hn = hashname_vkey(im, 0); fail_unless(hn); fail_unless(util_cmp(hashname_char(hn),"jvdoio6kjvf3yqnxfvck43twaibbg4pmb7y3mqnvxafb26rqllwa") == 0); lob_t keys = lob_new(); lob_set(keys,"1a","vgjz3yjb6cevxjomdleilmzasbj6lcc7"); lob_set(keys,"3a","hp6yglmmqwcbw5hno37uauh6fn6dx5oj7s5vtapaifrur2jv6zha"); hn = hashname_vkeys(keys); fail_unless(hn); fail_unless(util_cmp(hashname_char(hn),"jvdoio6kjvf3yqnxfvck43twaibbg4pmb7y3mqnvxafb26rqllwa") == 0); fail_unless(hashname_id(NULL,NULL) == 0); fail_unless(hashname_id(im,keys) == 0x3a); lob_t test = lob_new(); lob_set(test,"1a","test"); lob_set(test,"2a","test"); fail_unless(hashname_id(keys,test) == 0x1a); // check short utils hn = hashname_schar("uvabrvfq"); fail_unless(hn); fail_unless(hashname_isshort(hn)); fail_unless(util_cmp(hashname_short(hn),"uvabrvfq") == 0); return 0; }
void link_free(link_t link) { if(!link) return; LOG("dropping link %s",link->id->hashname); xht_set(link->mesh->index,link->id->hashname,NULL); // TODO go through ->pipes // TODO go through link->channels xht_free(link->channels); xht_free(link->index); hashname_free(link->id); if(link->x) { xht_set(link->mesh->index,link->token,NULL); exchange3_free(link->x); } free(link); }
link_t link_new(mesh_t mesh, hashname_t id) { link_t link; if(!mesh || !id) return LOG("invalid args"); LOG("adding link %s",id->hashname); if(!(link = malloc(sizeof (struct link_struct)))) return (link_t)hashname_free(id); memset(link,0,sizeof (struct link_struct)); link->id = id; link->mesh = mesh; xht_set(mesh->index,id->hashname,link); // to size larger, app can xht_free(); link->channels = xht_new(BIGGER) at start itself link->channels = xht_new(5); // index of all channels link->index = xht_new(5); // index for active channels and extensions return link; }
void link_free(link_t link) { if(!link) return; LOG("dropping link %s",hashname_short(link->id)); mesh_t mesh = link->mesh; if(mesh->links == link) { mesh->links = link->next; }else{ link_t li; for(li = mesh->links;li;li = li->next) if(li->next == link) { li->next = link->next; } } // drop if(link->x) { e3x_exchange_free(link->x); link->x = NULL; } // notify pipe w/ NULL packet if(link->send_cb) link->send_cb(link, NULL, link->send_arg); // go through link->chans chan_t c, cnext; for(c = link->chans;c;c = cnext) { cnext = chan_next(c); chan_free(c); } hashname_free(link->id); lob_free(link->key); lob_free(link->handshake); free(link); }
mesh_t mesh_free(mesh_t mesh) { on_t on; if(!mesh) return NULL; // free all links first link_t link, next; for(link = mesh->links;link;link = next) { next = link->next; link_free(link); } // free any triggers first while(mesh->on) { on = mesh->on; mesh->on = on->next; if(on->free) on->free(mesh); free(on->id); free(on); } xht_free(mesh->index); lob_free(mesh->keys); lob_free(mesh->paths); lob_freeall(mesh->cached); hashname_free(mesh->id); e3x_self_free(mesh->self); if(mesh->uri) free(mesh->uri); if(mesh->ipv4_local) free(mesh->ipv4_local); if(mesh->ipv4_public) free(mesh->ipv4_public); free(mesh); return NULL; }