int main(void) { switch_t s; chan_t c; packet_t p; path_t in; int sock; crypt_init(); s = switch_new(0); if(util_loadjson(s) != 0 || (sock = util_server(0,1000)) <= 0) { printf("failed to startup %s or %s\n", strerror(errno), crypt_err()); return -1; } printf("loaded hashname %s\n",s->id->hexname); // create/send a ping packet c = chan_new(s, bucket_get(s->seeds, 0), "link", 0); p = chan_packet(c); chan_send(c, p); util_sendall(s,sock); in = path_new("ipv4"); while(util_readone(s, sock, in) == 0) { switch_loop(s); while((c = switch_pop(s))) { printf("channel active %d %s %s\n",c->state,c->hexid,c->to->hexname); if(util_cmp(c->type,"connect") == 0) ext_connect(c); if(util_cmp(c->type,"link") == 0) ext_link(c); if(util_cmp(c->type,"path") == 0) ext_path(c); while((p = chan_pop(c))) { printf("unhandled channel packet %.*s\n", p->json_len, p->json); packet_free(p); } if(c->state == ENDED) chan_free(c); } util_sendall(s,sock); } perror("exiting"); return 0; }
// create/track a new channel for this open chan_t link_chan(link_t link, lob_t open) { chan_t c; if(!link || !open) return LOG("bad args"); // add an outgoing cid if none set if(!lob_get_int(open,"c")) lob_set_uint(open,"c",e3x_exchange_cid(link->x, NULL)); c = chan_new(open); if(!c) return LOG("invalid open %s",lob_json(open)); LOG("new outgoing channel %d open: %s",chan_id(c), lob_get(open,"type")); c->link = link; c->next = link->chans; link->chans = c; return c; }
// generate an outgoing request, send the response attached to the note chan_t thtp_req(switch_t s, lob_t note) { char *uri, *path, *method; hashname_t to = NULL; lob_t req; chan_t c; if(!s || !note) return NULL; method = lob_get_str(note,"method"); path = lob_get_str(note,"path"); if((uri = lob_get_str(note,"uri")) && strncmp(uri,"thtp://",7) == 0) { uri += 7; path = strchr(uri,'/'); to = hashname_gethex(s->index,uri); } if(!to) to = hashname_gethex(s->index,lob_get_str(note,"to")); if(!to) return NULL; req = lob_linked(note); if(!req) { req = lob_chain(note); lob_set_str(req,"path",path?path:"/"); lob_set_str(req,"method",method?method:"get"); } DEBUG_PRINTF("thtp req %s %s %s %.*s",lob_get_str(req,"method"),lob_get_str(req,"path"),to->hexname,note->json_len,note->json); // open channel and send req c = chan_new(s, to, "thtp", 0); c->arg = lob_link(NULL,note); // create buffer packet w/ the note linked c->handler = ext_thtp; // shortcut chan_reliable(c,10); thtp_send(c,req); return c; }