static void sample_process_receive(rdpSvcPlugin* plugin, STREAM* data_in) { int bytes; STREAM* data_out; samplePlugin* sample = (samplePlugin*) plugin; printf("sample_process_receive:\n"); if (!sample) { printf("sample_process_receive: sample is nil\n"); return; } /* process data in (from server) here */ /* here we just send the same data back */ bytes = stream_get_size(data_in); printf("sample_process_receive: got bytes %d\n", bytes); if (bytes > 0) { data_out = stream_new(bytes); stream_copy(data_out, data_in, bytes); /* svc_plugin_send takes ownership of data_out, that is why we do not free it */ bytes = stream_get_length(data_in); printf("sample_process_receive: sending bytes %d\n", bytes); svc_plugin_send(plugin, data_out); } stream_free(data_in); }
result_t cat_name_action(cli_t *context, const char * name) { result_t result; if(name == 0) return e_bad_parameter; handle_t stream; if(failed(result = stream_open(get_context(context), name, &stream))) return result; stream_copy(stream, context->cfg.console_out); stream_close(stream); stream_puts(context->cfg.console_out, "\r\n"); return result; }
static int drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp, int cbChId, STREAM* s) { int pos; int error; UINT32 ChannelId; STREAM* data_out; ChannelId = drdynvc_read_variable_uint(s, cbChId); pos = stream_get_pos(s); DEBUG_DVC("ChannelId=%d ChannelName=%s", ChannelId, stream_get_tail(s)); error = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) stream_get_tail(s)); data_out = stream_new(pos + 4); stream_write_BYTE(data_out, 0x10 | cbChId); stream_set_pos(s, 1); stream_copy(data_out, s, pos - 1); if (error == 0) { DEBUG_DVC("channel created"); stream_write_UINT32(data_out, 0); } else { DEBUG_DVC("no listener"); stream_write_UINT32(data_out, (UINT32)(-1)); } error = svc_plugin_send((rdpSvcPlugin*) drdynvc, data_out); if (error != CHANNEL_RC_OK) { DEBUG_WARN("VirtualChannelWrite failed %d", error); return 1; } return 0; }
int transport_check_fds(rdpTransport* transport) { int pos; int status; uint16 length; STREAM* received; wait_obj_clear(transport->recv_event); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = stream_get_pos(transport->recv_buffer)) > 0) { stream_set_pos(transport->recv_buffer, 0); if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = tpkt_read_header(transport->recv_buffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = fastpath_read_header(NULL, transport->recv_buffer); } if (length == 0) { printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); freerdp_hexdump(stream_get_head(transport->recv_buffer), pos); return -1; } if (pos < length) { stream_set_pos(transport->recv_buffer, pos); return 0; /* Packet is not yet completely received. */ } /* * A complete packet has been received. In case there are trailing data * for the next packet, we copy it to the new receive buffer. */ received = transport->recv_buffer; transport->recv_buffer = stream_new(BUFFER_SIZE); if (pos > length) { stream_set_pos(received, length); stream_check_size(transport->recv_buffer, pos - length); stream_copy(transport->recv_buffer, received, pos - length); } stream_set_pos(received, length); stream_seal(received); stream_set_pos(received, 0); if (transport->recv_callback(transport, received, transport->recv_extra) == False) status = -1; stream_free(received); if (status < 0) return status; } return 0; }
/* Zebra client message read function. */ static int zclient_read (struct thread *thread) { size_t already; uint16_t length, command; uint8_t marker, version; struct zclient *zclient; /* Get socket to zebra. */ zclient = THREAD_ARG (thread); zclient->t_read = NULL; /* Read zebra header (if we don't have it already). */ if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) { ssize_t nbyte; if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock, ZEBRA_HEADER_SIZE-already)) == 0) || (nbyte == -1)) { if (zclient_debug) zlog_debug ("zclient connection closed socket [%d].", zclient->sock); return zclient_failed(zclient); } if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already)) { /* Try again later. */ zclient_event (ZCLIENT_READ, zclient); return 0; } already = ZEBRA_HEADER_SIZE; } /* Reset to read from the beginning of the incoming packet. */ stream_set_getp(zclient->ibuf, 0); /* Fetch header values. */ length = stream_getw (zclient->ibuf); marker = stream_getc (zclient->ibuf); version = stream_getc (zclient->ibuf); command = stream_getw (zclient->ibuf); if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { zlog_err("%s: socket %d version mismatch, marker %d, version %d", __func__, zclient->sock, marker, version); return zclient_failed(zclient); } if (length < ZEBRA_HEADER_SIZE) { zlog_err("%s: socket %d message length %u is less than %d ", __func__, zclient->sock, length, ZEBRA_HEADER_SIZE); return zclient_failed(zclient); } /* Length check. */ if (length > STREAM_SIZE(zclient->ibuf)) { struct stream *ns; zlog_warn("%s: message size %u exceeds buffer size %lu, expanding...", __func__, length, (u_long)STREAM_SIZE(zclient->ibuf)); ns = stream_new(length); stream_copy(ns, zclient->ibuf); stream_free (zclient->ibuf); zclient->ibuf = ns; } /* Read rest of zebra packet. */ if (already < length) { ssize_t nbyte; if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock, length-already)) == 0) || (nbyte == -1)) { if (zclient_debug) zlog_debug("zclient connection closed socket [%d].", zclient->sock); return zclient_failed(zclient); } if (nbyte != (ssize_t)(length-already)) { /* Try again later. */ zclient_event (ZCLIENT_READ, zclient); return 0; } } length -= ZEBRA_HEADER_SIZE; if (zclient_debug) zlog_debug("zclient 0x%p command 0x%x \n", (void *)zclient, command); switch (command) { case ZEBRA_ROUTER_ID_UPDATE: if (zclient->router_id_update) (*zclient->router_id_update) (command, zclient, length); break; case ZEBRA_INTERFACE_ADD: if (zclient->interface_add) (*zclient->interface_add) (command, zclient, length); break; case ZEBRA_INTERFACE_DELETE: if (zclient->interface_delete) (*zclient->interface_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_ADD: if (zclient->interface_address_add) (*zclient->interface_address_add) (command, zclient, length); break; case ZEBRA_INTERFACE_ADDRESS_DELETE: if (zclient->interface_address_delete) (*zclient->interface_address_delete) (command, zclient, length); break; case ZEBRA_INTERFACE_UP: if (zclient->interface_up) (*zclient->interface_up) (command, zclient, length); break; case ZEBRA_INTERFACE_DOWN: if (zclient->interface_down) (*zclient->interface_down) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_ADD: if (zclient->ipv4_route_add) (*zclient->ipv4_route_add) (command, zclient, length); break; case ZEBRA_IPV4_ROUTE_DELETE: if (zclient->ipv4_route_delete) (*zclient->ipv4_route_delete) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_ADD: if (zclient->ipv6_route_add) (*zclient->ipv6_route_add) (command, zclient, length); break; case ZEBRA_IPV6_ROUTE_DELETE: if (zclient->ipv6_route_delete) (*zclient->ipv6_route_delete) (command, zclient, length); break; default: break; } if (zclient->sock < 0) /* Connection was closed during packet processing. */ return -1; /* Register read thread. */ stream_reset(zclient->ibuf); zclient_event (ZCLIENT_READ, zclient); return 0; }
int transport_check_fds(rdpTransport** ptransport) { int pos; int status; uint16 length; STREAM* received; rdpTransport* transport = *ptransport; wait_obj_clear(transport->recv_event); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = stream_get_pos(transport->recv_buffer)) > 0) { stream_set_pos(transport->recv_buffer, 0); if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = tpkt_read_header(transport->recv_buffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { stream_set_pos(transport->recv_buffer, pos); return 0; } /* Fastpath header can be two or three bytes long. */ length = fastpath_header_length(transport->recv_buffer); if (pos < length) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = fastpath_read_header(NULL, transport->recv_buffer); } if (length == 0) { printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); freerdp_hexdump(stream_get_head(transport->recv_buffer), pos); return -1; } if (pos < length) { stream_set_pos(transport->recv_buffer, pos); return 0; /* Packet is not yet completely received. */ } /* * A complete packet has been received. In case there are trailing data * for the next packet, we copy it to the new receive buffer. */ received = transport->recv_buffer; transport->recv_buffer = stream_new(BUFFER_SIZE); if (pos > length) { stream_set_pos(received, length); stream_check_size(transport->recv_buffer, pos - length); stream_copy(transport->recv_buffer, received, pos - length); } stream_set_pos(received, length); stream_seal(received); stream_set_pos(received, 0); if (transport->recv_callback(transport, received, transport->recv_extra) == false) status = -1; stream_free(received); if (status < 0) return status; /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ transport = *ptransport; if (transport->process_single_pdu) { /* one at a time but set event if data buffered * so the main loop will call freerdp_check_fds asap */ if (stream_get_pos(transport->recv_buffer) > 0) wait_obj_set(transport->recv_event); break; } } return 0; }
int shim_sisis_read(struct thread * thread) { struct sisis_listener *listener; int sisis_sock; uint16_t length, command, checksum; int already; u_int ifindex; struct shim_interface * si; struct in6_addr src; char src_buf[INET6_ADDRSTRLEN]; struct in6_addr dst; char dst_buf[INET6_ADDRSTRLEN]; zlog_notice("Reading packet from SISIS connection!\n"); /* first of all get listener pointer. */ listener = THREAD_ARG (thread); sisis_sock = THREAD_FD (thread); if ((already = stream_get_endp(listener->ibuf)) < SV_HEADER_SIZE) { ssize_t nbytes; if (((nbytes = stream_read_try (listener->ibuf, sisis_sock, SV_HEADER_SIZE-already)) == 0) || (nbytes == -1)) { return -1; } if(nbytes != (SV_HEADER_SIZE - already)) { listener->thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } already = SV_HEADER_SIZE; } stream_set_getp(listener->ibuf, 0); /* read header packet. */ length = stream_getw (listener->ibuf); command = stream_getw (listener->ibuf); // will be 0 so may be discarded stream_get (&src, listener->ibuf, sizeof (struct in6_addr)); stream_get (&dst, listener->ibuf, sizeof (struct in6_addr)); ifindex = stream_getl(listener->ibuf); checksum = stream_getw(listener->ibuf); inet_ntop(AF_INET6, &src, src_buf, sizeof(src_buf)); inet_ntop(AF_INET6, &dst, dst_buf, sizeof(dst_buf)); zlog_debug("SISIS: length: %d, command: %d, ifindex: %d, checksum: %d sock %d, src: %s, dst: %s\n", length, command, ifindex, checksum, sisis_sock, src_buf, dst_buf); if(length > STREAM_SIZE(listener->ibuf)) { struct stream * ns; zlog_warn("message size exceeds buffer size"); ns = stream_new(length); stream_copy(ns, listener->ibuf); stream_free(listener->ibuf); listener->ibuf = ns; } if(already < length) { ssize_t nbytes; if(((nbytes = stream_read_try(listener->ibuf, sisis_sock, length-already)) == 0) || nbytes == -1) { return -1; } if(nbytes != (length-already)) { listener->thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } } length -= SV_HEADER_SIZE; switch(command) { case SV_JOIN_ALLSPF: zlog_debug("join allspf received"); shim_join_allspfrouters (ifindex); break; case SV_LEAVE_ALLSPF: zlog_debug("leave allspf received"); shim_leave_allspfrouters (ifindex); zlog_debug("index: %d\n", ifindex); break; case SV_JOIN_ALLD: zlog_debug("join alld received"); shim_join_alldrouters (ifindex); zlog_debug("index: %d", ifindex); break; case SV_LEAVE_ALLD: zlog_debug("leave alld received"); shim_leave_alldrouters (ifindex); zlog_debug("index: %d", ifindex); break; case SV_MESSAGE: zlog_debug("SISIS message received"); unsigned int num_of_addrs = number_of_sisis_addrs_for_process_type(SISIS_PTYPE_RIBCOMP_OSPF6); unsigned int num_of_listeners = number_of_listeners(); zlog_debug("num of listeners: %d, num of addrs: %d", num_of_listeners, num_of_addrs); float received_ratio = num_of_listeners/num_of_addrs; listener->chksum = checksum; if(received_ratio > (1/2)) { if(are_checksums_same()) { si = shim_interface_lookup_by_ifindex (ifindex); reset_checksums(); shim_send(&src, &dst, si, listener->ibuf, length); // shim_send(si->linklocal_addr, &dst, si, listener->ibuf, length); } else { zlog_notice("Checksums are not all the same"); } } else { zlog_notice("Not enough processes have sent their data: buffering ..."); } break; default: break; } if (sisis_sock < 0) /* Connection was closed during packet processing. */ return -1; /* Register read thread. */ stream_reset(listener->ibuf); /* prepare for next packet. */ listener->thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; }
int shim_sisis_read(struct thread * thread) { struct sisis_listener *listener; int sisis_sock; uint16_t length, checksum; int already; u_int ifindex; struct shim_interface * si; struct in6_addr src; char src_buf[INET6_ADDRSTRLEN]; struct in6_addr dst; char dst_buf[INET6_ADDRSTRLEN]; zlog_notice("Reading packet from SISIS connection!"); /* first of all get listener pointer. */ listener = THREAD_ARG (thread); sisis_sock = THREAD_FD (thread); stream_reset(listener->ibuf); if ((already = stream_get_endp(listener->ibuf)) < SVZ_OUT_HEADER_SIZE) { ssize_t nbytes; if (((nbytes = stream_read_try (listener->ibuf, sisis_sock, SVZ_OUT_HEADER_SIZE-already)) == 0) || (nbytes == -1)) { return -1; } if(nbytes != (SVZ_OUT_HEADER_SIZE - already)) { listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } already = SVZ_OUT_HEADER_SIZE; } stream_set_getp(listener->ibuf, 0); length = stream_getw(listener->ibuf); checksum = stream_getw(listener->ibuf); if(length > STREAM_SIZE(listener->ibuf)) { struct stream * ns; zlog_warn("message size exceeds buffer size"); ns = stream_new(length); stream_copy(ns, listener->ibuf); stream_free(listener->ibuf); listener->ibuf = ns; } if(already < length) { ssize_t nbytes; if(((nbytes = stream_read_try(listener->ibuf, sisis_sock, length-already)) == 0) || nbytes == -1) { return -1; } if(nbytes != (length-already)) { listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; } } unsigned int num_of_addrs = number_of_sisis_addrs_for_process_type(SISIS_PTYPE_RIBCOMP_OSPF6); unsigned int num_of_listeners = number_of_listeners(); zlog_notice("Number of addr: %d", num_of_addrs); zlog_notice("Number of listeners: %d", num_of_listeners); pthread_mutex_lock(&bmap_mutex); struct bmap * bmap = bmap_set(checksum); // if we added initially // set timer at which to recycle bmap // if there are no more processes sending data if(bmap->count == 0) { uint16_t * chcksum_ptr = malloc(sizeof(uint16_t)); *chcksum_ptr = checksum; listener->bmap_thread = thread_add_timer_msec (master, svz_sisis_clean_bmap, chcksum_ptr, 100); } bmap->count++; zlog_notice("# of streams %d for checksum %d with length %d", bmap->count, checksum, length); float received_ratio = (float)bmap->count/(float)num_of_addrs; stream_putw(listener->chksum_stream, checksum); if((received_ratio > 1.0/2.0) && !bmap->sent) { if(are_checksums_same()) { zlog_notice("Checksums are all the same"); if(primary_listener == NULL) primary_listener = listener; reset_checksum_streams(); svz_send(listener->ibuf); bmap->sent = 1; } else { zlog_notice("Checksums are not all the same"); stream_fifo_push(listener->dif, listener->ibuf); listener->dif_size++; } } else if(!bmap->sent) { zlog_notice("Not enough processes have sent their data; buffering..."); } else { zlog_notice("Data has already been sent..."); } if((bmap->count == num_of_addrs) && (bmap->sent)) { zlog_notice("Bmap no longer needed, freeing..."); bmap->count = 0; bmap->sent = 0; clear_checksum_streams(checksum); bmap_unset(checksum); } pthread_mutex_unlock(&bmap_mutex); if (sisis_sock < 0) /* Connection was closed during packet processing. */ return -1; /* Register read thread. */ // stream_reset(listener->ibuf); /* prepare for next packet. */ listener->read_thread = thread_add_read (master, shim_sisis_read, listener, sisis_sock); return 0; }
static int dbox_file_fix_write_stream(struct dbox_file *file, uoff_t start_offset, const char *temp_path, struct ostream *output) { struct dbox_message_header msg_hdr; uoff_t offset, msg_size, hdr_offset, body_offset; bool pre, write_header, have_guid; struct message_size body; struct istream *body_input; uint8_t guid_128[MAIL_GUID_128_SIZE]; int ret; i_stream_seek(file->input, 0); if (start_offset > 0) { /* copy the valid data */ if (stream_copy(file, output, temp_path, start_offset) < 0) return -1; } else { /* the file header is broken. recreate it */ if (dbox_file_header_write(file, output) < 0) { dbox_file_set_syscall_error(file, "write()"); return -1; } } while ((ret = dbox_file_find_next_magic(file, &offset, &pre)) > 0) { msg_size = offset - file->input->v_offset; if (msg_size < 256 && pre) { /* probably some garbage or some broken headers. we most likely don't miss anything by skipping over this data. */ i_stream_skip(file->input, msg_size); hdr_offset = file->input->v_offset; ret = dbox_file_read_mail_header(file, &msg_size); if (ret <= 0) { if (ret < 0) return -1; dbox_file_skip_broken_header(file); body_offset = file->input->v_offset; msg_size = (uoff_t)-1; } else { i_stream_skip(file->input, file->msg_header_size); body_offset = file->input->v_offset; i_stream_skip(file->input, msg_size); } ret = dbox_file_find_next_magic(file, &offset, &pre); if (ret <= 0) break; if (!pre && msg_size == offset - body_offset) { /* msg header ok, copy it */ i_stream_seek(file->input, hdr_offset); if (stream_copy(file, output, temp_path, file->msg_header_size) < 0) return -1; write_header = FALSE; } else { /* msg header is broken. write our own. */ i_stream_seek(file->input, body_offset); if (msg_size != (uoff_t)-1) { /* previous magic find might have skipped too much. seek back and make sure */ ret = dbox_file_find_next_magic(file, &offset, &pre); if (ret <= 0) break; } write_header = TRUE; msg_size = offset - body_offset; } } else { /* treat this data as a separate message. */ write_header = TRUE; body_offset = file->input->v_offset; } /* write msg header */ if (write_header) { dbox_msg_header_fill(&msg_hdr, msg_size); (void)o_stream_send(output, &msg_hdr, sizeof(msg_hdr)); } /* write msg body */ i_assert(file->input->v_offset == body_offset); if (stream_copy(file, output, temp_path, msg_size) < 0) return -1; i_assert(file->input->v_offset == offset); /* get message body size */ i_stream_seek(file->input, body_offset); body_input = i_stream_create_limit(file->input, msg_size); ret = message_get_body_size(body_input, &body, NULL); i_stream_unref(&body_input); if (ret < 0) { errno = output->stream_errno; mail_storage_set_critical(&file->storage->storage, "read(%s) failed: %m", file->cur_path); return -1; } /* write msg metadata. */ i_assert(file->input->v_offset == offset); ret = dbox_file_metadata_skip_header(file); if (ret < 0) return -1; o_stream_send_str(output, DBOX_MAGIC_POST); if (ret == 0) have_guid = FALSE; else dbox_file_copy_metadata(file, output, &have_guid); if (!have_guid) { mail_generate_guid_128(guid_128); o_stream_send_str(output, t_strdup_printf("%c%s\n", DBOX_METADATA_GUID, binary_to_hex(guid_128, sizeof(guid_128)))); } o_stream_send_str(output, t_strdup_printf("%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE, (unsigned long long)body.virtual_size)); o_stream_send_str(output, "\n"); if (output->stream_errno != 0) { errno = output->stream_errno; mail_storage_set_critical(&file->storage->storage, "write(%s) failed: %m", temp_path); return -1; } } return ret; }