void ext_connect(chan_t c) { lob_t p; hashname_t hn; while((p = chan_pop(c))) { hn = hashname_fromjson(c->s->index,p); lob_free(p); if(!hn) continue; DEBUG_PRINTF("connect HN %s\n",hn?hn->hexname:"null"); switch_open(c->s, hn, NULL); // TODO relay } }
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; }
void ext_thtp(chan_t c) { lob_t p, buf, req, match, note; char *path; thtp_t t = thtp_get(c->s); // incoming note as an answer if((note = chan_notes(c))) { DEBUG_PRINTF("got note resp %.*s",note->json_len,note->json); thtp_send(c,lob_linked(note)); lob_free(note); return; } while((p = chan_pop(c))) { if(!c->arg) { c->arg = buf = p; }else{ buf = c->arg; lob_append(buf,p->body,p->body_len); lob_free(p); } // for now we're processing whole-requests-at-once, to do streaming we can try parsing note->body for the headers anytime if(c->ended) continue; // parse the payload p = lob_parse(buf->body,buf->body_len); // this is a response, send it if((note = lob_unlink(buf))) { lob_free(buf); if(p) { DEBUG_PRINTF("got response %.*s for %.*s",p->json_len,p->json,note->json_len,note->json); } lob_link(note,p); lob_set_str(note,"thtp","resp"); chan_reply(c,note); chan_end(c,NULL); return; } // this is an incoming request lob_free(buf); if(!p) return (void)chan_fail(c,"422"); req = p; DEBUG_PRINTF("thtp req packet %.*s", req->json_len, req->json); path = lob_get_str(req,"path"); match = xht_get(t->index,path); if(!match) match = _thtp_glob(t,path); if(!match) { chan_fail(c,"404"); lob_free(req); return; } // built in response if(lob_linked(match)) { thtp_send(c,lob_linked(match)); lob_free(req); return; } // attach and route request to a new note note = lob_copy(match); lob_link(note,req); lob_set_str(note,"thtp","req"); if(chan_reply(c,note) == 0) return; chan_fail(c,"500"); lob_free(req); } // optionally sends ack if needed chan_ack(c); }