/** Read <b>buf</b>, which should contain an Extended ORPort message * from a transport proxy. If well-formed, create and populate * <b>out</b> with the Extended ORport message. Return 0 if the * buffer was incomplete, 1 if it was well-formed and -1 if we * encountered an error while parsing it. */ int fetch_ext_or_command_from_buf(buf_t *buf, ext_or_cmd_t **out) { char hdr[EXT_OR_CMD_HEADER_SIZE]; uint16_t len; if (buf_datalen(buf) < EXT_OR_CMD_HEADER_SIZE) return 0; buf_peek(buf, hdr, sizeof(hdr)); len = ntohs(get_uint16(hdr+2)); if (buf_datalen(buf) < (unsigned)len + EXT_OR_CMD_HEADER_SIZE) return 0; *out = ext_or_cmd_new(len); (*out)->cmd = ntohs(get_uint16(hdr)); (*out)->len = len; buf_drain(buf, EXT_OR_CMD_HEADER_SIZE); buf_get_bytes(buf, (*out)->body, len); return 1; }
static void flip_ip_svr() { char reqbuf[1024], replbuf[1024]; char *repl_ptr; char *bp, *ep; errstat req_size, repl_size; am_header_t req_header, repl_header; for (;;) { req_header.h_port= fis_priv_port; req_size= rpc_getreq(&req_header, reqbuf, sizeof(reqbuf)); repl_ptr= replbuf; repl_header.h_status= STD_OK; if (ERR_STATUS(req_size)) panic(( "getreq() failed: %s", err_why(ERR_CONVERT(req_size)) )); switch (req_header.h_command) { case STD_INFO: repl_ptr= bprintf(repl_ptr, replbuf + sizeof(replbuf), "flip_ip server"); break; case STD_STATUS: { int i; mu_lock(&mu_flip_ip_inited); mu_lock(&mu_generic); bp= replbuf; ep= replbuf+sizeof(replbuf); for (i= 0; i<FIP_PORT_NR; i++) bp= print_fip_port(bp, ep, fip_port_table+i); repl_ptr= bp; mu_unlock(&mu_generic); mu_unlock(&mu_flip_ip_inited); break; } case UNREGISTERED_FIRST_COM: { int proto; ipaddr_t host; tcpport_t listen_port, connect_port; mu_lock(&mu_flip_ip_inited); mu_lock(&mu_generic); bp= reqbuf; ep= bp + req_size; bp= buf_get_uint32(bp, ep, &proto); bp= buf_get_bytes(bp, ep, &host, sizeof(host)); bp= buf_get_bytes(bp, ep, &listen_port, sizeof(listen_port)); bp= buf_get_bytes(bp, ep, &connect_port, sizeof(connect_port)); if (bp != ep) { repl_header.h_status= STD_ARGBAD; break; } if (proto != FPNT_TCP) { repl_header.h_status= STD_ARGBAD; break; } fip_add_tcp_peer (0, host, listen_port, connect_port); mu_unlock(&mu_generic); mu_unlock(&mu_flip_ip_inited); break; } default: repl_header.h_status= STD_COMBAD; break; } if (!repl_ptr) repl_size= sizeof(replbuf); else repl_size= repl_ptr-replbuf; repl_header.h_size= repl_size; rpc_putrep(&repl_header, replbuf, repl_size); } }