int PacketProtoFlow_Init (PacketProtoFlow *o, int input_mtu, int num_packets, PacketPassInterface *output, BPendingGroup *pg) { ASSERT(input_mtu >= 0) ASSERT(input_mtu <= PACKETPROTO_MAXPAYLOAD) ASSERT(num_packets > 0) ASSERT(PacketPassInterface_GetMTU(output) >= PACKETPROTO_ENCLEN(input_mtu)) // init async input BufferWriter_Init(&o->ainput, input_mtu, pg); // init encoder PacketProtoEncoder_Init(&o->encoder, BufferWriter_GetOutput(&o->ainput), pg); // init buffer if (!PacketBuffer_Init(&o->buffer, PacketProtoEncoder_GetOutput(&o->encoder), output, num_packets, pg)) { goto fail0; } DebugObject_Init(&o->d_obj); return 1; fail0: PacketProtoEncoder_Free(&o->encoder); BufferWriter_Free(&o->ainput); return 0; }
static void listener_handler (struct instance *o) { ASSERT(!o->dying) BReactor *reactor = o->i->params->iparams->reactor; BPendingGroup *pg = BReactor_PendingGroup(reactor); struct connection *c = malloc(sizeof(*c)); if (!c) { ModuleLog(o->i, BLOG_ERROR, "malloc failed"); goto fail0; } c->inst = o; LinkedList0_Prepend(&o->connections_list, &c->connections_list_node); if (!BConnection_Init(&c->con, BConnection_source_listener(&o->listener, &c->addr), reactor, c, (BConnection_handler)connection_con_handler)) { ModuleLog(o->i, BLOG_ERROR, "BConnection_Init failed"); goto fail1; } BConnection_SendAsync_Init(&c->con); BConnection_RecvAsync_Init(&c->con); StreamPassInterface *con_send_if = BConnection_SendAsync_GetIf(&c->con); StreamRecvInterface *con_recv_if = BConnection_RecvAsync_GetIf(&c->con); PacketPassInterface_Init(&c->recv_if, RECV_MTU, (PacketPassInterface_handler_send)connection_recv_if_handler_send, c, pg); if (!PacketProtoDecoder_Init(&c->recv_decoder, con_recv_if, &c->recv_if, pg, c, (PacketProtoDecoder_handler_error)connection_recv_decoder_handler_error)) { ModuleLog(o->i, BLOG_ERROR, "PacketProtoDecoder_Init failed"); goto fail2; } PacketStreamSender_Init(&c->send_pss, con_send_if, PACKETPROTO_ENCLEN(SEND_MTU), pg); PacketPassFifoQueue_Init(&c->send_queue, PacketStreamSender_GetInput(&c->send_pss), pg); LinkedList0_Init(&c->requests_list); LinkedList0_Init(&c->replies_list); c->state = CONNECTION_STATE_RUNNING; ModuleLog(o->i, BLOG_INFO, "connection initialized"); return; fail2: PacketPassInterface_Free(&c->recv_if); BConnection_RecvAsync_Free(&c->con); BConnection_SendAsync_Free(&c->con); BConnection_Free(&c->con); fail1: LinkedList0_Remove(&o->connections_list, &c->connections_list_node); free(c); fail0: return; }
static void input_handler_done (PacketProtoEncoder *enc, int in_len) { ASSERT(enc->output_packet) DebugObject_Access(&enc->d_obj); // write length struct packetproto_header pp; pp.len = htol16(in_len); memcpy(enc->output_packet, &pp, sizeof(pp)); // finish output packet enc->output_packet = NULL; PacketRecvInterface_Done(&enc->output, PACKETPROTO_ENCLEN(in_len)); }
void PacketProtoEncoder_Init (PacketProtoEncoder *enc, PacketRecvInterface *input, BPendingGroup *pg) { ASSERT(PacketRecvInterface_GetMTU(input) <= PACKETPROTO_MAXPAYLOAD) // init arguments enc->input = input; // init input PacketRecvInterface_Receiver_Init(enc->input, (PacketRecvInterface_handler_done)input_handler_done, enc); // init output PacketRecvInterface_Init( &enc->output, PACKETPROTO_ENCLEN(PacketRecvInterface_GetMTU(enc->input)), (PacketRecvInterface_handler_recv)output_handler_recv, enc, pg ); // set no output packet enc->output_packet = NULL; DebugObject_Init(&enc->d_obj); }
int PacketProtoDecoder_Init (PacketProtoDecoder *enc, StreamRecvInterface *input, PacketPassInterface *output, BPendingGroup *pg, void *user, PacketProtoDecoder_handler_error handler_error) { // init arguments enc->input = input; enc->output = output; enc->user = user; enc->handler_error = handler_error; // init input StreamRecvInterface_Receiver_Init(enc->input, (StreamRecvInterface_handler_done)input_handler_done, enc); // init output PacketPassInterface_Sender_Init(enc->output, (PacketPassInterface_handler_done)output_handler_done, enc); // set output MTU, limit by maximum payload size enc->output_mtu = bmin_int(PacketPassInterface_GetMTU(enc->output), PACKETPROTO_MAXPAYLOAD); // init buffer state enc->buf_size = PACKETPROTO_ENCLEN(enc->output_mtu); enc->buf_start = 0; enc->buf_used = 0; // allocate buffer if (!(enc->buf = (uint8_t *)malloc(enc->buf_size))) { goto fail0; } // start receiving StreamRecvInterface_Receiver_Recv(enc->input, enc->buf, enc->buf_size); DebugObject_Init(&enc->d_obj); return 1; fail0: return 0; }