static void accept_new(int accept_fd) { int from, to, feid, teid; while (1) { feid = evt_get(); assert(feid > 0); from = from_tsplit(cos_spd_id(), accept_fd, "", 0, TOR_RW, feid); assert(from != accept_fd); if (-EAGAIN == from) { evt_put(feid); return; } else if (from < 0) { printc("from torrent returned %d\n", from); BUG(); return; } teid = evt_get(); assert(teid > 0); to = tsplit(cos_spd_id(), td_root, "", 0, TOR_RW, teid); if (to < 0) { printc("torrent split returned %d", to); BUG(); } mapping_add(from, to, feid, teid); } }
static void from_data_new(struct tor_conn *tc) { int from, to, amnt; char *buf; from = tc->from; to = tc->to; while (1) { int ret; cbuf_t cb; buf = cbuf_alloc(BUFF_SZ, &cb); assert(buf); amnt = from_tread(cos_spd_id(), from, cb, BUFF_SZ-1); if (0 == amnt) break; else if (-EPIPE == amnt) { goto close; } else if (amnt < 0) { printc("read from fd %d produced %d.\n", from, amnt); BUG(); } assert(amnt <= BUFF_SZ); if (amnt != (ret = twrite(cos_spd_id(), to, cb, amnt))) { printc("conn_mgr: write failed w/ %d on fd %d\n", ret, to); goto close; } cbuf_free(buf); } done: cbuf_free(buf); return; close: mapping_remove(from, to, tc->feid, tc->teid); from_trelease(cos_spd_id(), from); trelease(cos_spd_id(), to); assert(tc->feid && tc->teid); evt_put(tc->feid); evt_put(tc->teid); goto done; }
// Searching for either a NAND block or a sync point static int st_scanning(struct state *st) { struct pkt pkt; int ret; while ((ret = packet_get_next(st, &pkt)) == 0) { if (pkt.header.type == PACKET_HELLO) { evt_write_hello(st, &pkt); } else if (pkt.header.type == PACKET_RESET) { evt_write_reset(st, &pkt); } else if (pkt.header.type == PACKET_NAND_CYCLE) { write_nand_cmd(st, &pkt); } else if (pkt.header.type == PACKET_COMMAND) { if (pkt.data.command.start_stop == CMD_STOP) { struct evt_net_cmd *net = evt_take(st, EVT_NET_CMD); if (!net) { struct evt_net_cmd evt; fprintf(stderr, "NET_CMD end without begin\n"); evt_fill_header(&evt, pkt.header.sec, pkt.header.nsec, sizeof(evt), EVT_NET_CMD); evt.cmd[0] = pkt.data.command.cmd[0]; evt.cmd[1] = pkt.data.command.cmd[1]; evt.arg = pkt.data.command.arg; evt_fill_end(&evt, pkt.header.sec, pkt.header.nsec); evt.arg = htonl(evt.arg); write(st->out_fd, &evt, sizeof(evt)); } else { evt_fill_end(net, pkt.header.sec, pkt.header.nsec); net->arg = htonl(net->arg); write(st->out_fd, net, sizeof(*net)); free(net); } } else { struct evt_net_cmd *net = evt_take(st, EVT_NET_CMD); if (net) { fprintf(stderr, "Multiple NET_CMDs going at once\n"); free(net); } net = malloc(sizeof(struct evt_net_cmd)); evt_fill_header(net, pkt.header.sec, pkt.header.nsec, sizeof(*net), EVT_NET_CMD); net->cmd[0] = pkt.data.command.cmd[0]; net->cmd[1] = pkt.data.command.cmd[1]; net->arg = pkt.data.command.arg; evt_put(st, net); } } else if (pkt.header.type == PACKET_BUFFER_DRAIN) { if (pkt.data.buffer_drain.start_stop == PKT_BUFFER_DRAIN_STOP) { struct evt_buffer_drain *evt = evt_take(st, EVT_BUFFER_DRAIN); if (!evt) { struct evt_buffer_drain evt; fprintf(stderr, "BUFFER_DRAIN end without begin\n"); evt_fill_header(&evt, pkt.header.sec, pkt.header.nsec, sizeof(evt), EVT_BUFFER_DRAIN); evt_fill_end(&evt, pkt.header.sec, pkt.header.nsec); write(st->out_fd, &evt, sizeof(evt)); } else { evt_fill_end(evt, pkt.header.sec, pkt.header.nsec); write(st->out_fd, evt, sizeof(*evt)); free(evt); } } else { struct evt_buffer_drain *evt = evt_take(st, EVT_BUFFER_DRAIN); if (evt) { fprintf(stderr, "Multiple BUFFER_DRAINs going at once\n"); free(evt); } evt = malloc(sizeof(struct evt_buffer_drain)); evt_fill_header(evt, pkt.header.sec, pkt.header.nsec, sizeof(*evt), EVT_BUFFER_DRAIN); evt_put(st, evt); } } else if (pkt.header.type == PACKET_SD_CMD_ARG) { struct evt_sd_cmd *evt = evt_take(st, EVT_SD_CMD); struct pkt_sd_cmd_arg *sd = &pkt.data.sd_cmd_arg; if (!evt) { evt = malloc(sizeof(struct evt_sd_cmd)); memset(evt, 0, sizeof(*evt)); evt_fill_header(evt, pkt.header.sec, pkt.header.nsec, sizeof(*evt), EVT_SD_CMD); } // Ignore args for CMD55 if ((evt->num_args || sd->reg>0) && evt->cmd != 0x55) { evt->args[evt->num_args++] = sd->val; } // Register 0 implies this is a CMD. else if (sd->reg == 0) { if (evt->cmd == 0x55) evt->cmd = 0x80 | (0x3f & sd->val); else evt->cmd = 0x3f & sd->val; } evt_put(st, evt); } else if (pkt.header.type == PACKET_SD_RESPONSE) { struct evt_sd_cmd *evt = evt_take(st, EVT_SD_CMD); // Ignore CMD17, as we'll pick it up on the PACKET_SD_DATA packet if (evt->cmd == 17) { evt_put(st, evt); } else { struct pkt_sd_response *sd = &pkt.data.response; if (!evt) { fprintf(stderr, "Couldn't find old EVT_SD_CMD in SD_RESPONSE\n"); continue; } evt->result[evt->num_results++] = sd->byte; evt->num_results = htonl(evt->num_results); evt->num_args = htonl(evt->num_args); evt_fill_end(evt, pkt.header.sec, pkt.header.nsec); write(st->out_fd, evt, sizeof(*evt)); free(evt); } } else if (pkt.header.type == PACKET_SD_DATA) { struct evt_sd_cmd *evt = evt_take(st, EVT_SD_CMD); struct pkt_sd_data *sd = &pkt.data.sd_data; int offset; if (!evt) { fprintf(stderr, "Couldn't find old SD_EVT_CMD in SD_DATA\n"); continue; } for (offset=0; offset<sizeof(sd->data); offset++) evt->result[evt->num_results++] = sd->data[offset]; evt->num_results = htonl(evt->num_results); evt->num_args = htonl(evt->num_args); evt_fill_end(evt, pkt.header.sec, pkt.header.nsec); write(st->out_fd, evt, sizeof(*evt)); free(evt); } else { printf("Unknown packet type: %s\n", types[pkt.header.type]); } } return ret; }