diff --git a/server/reds.c b/server/reds.c index 9da89580..8b179f8d 100644 --- a/server/reds.c +++ b/server/reds.c @@ -1157,260 +1157,12 @@ typedef struct WriteQueueInfo { void reds_marshall_migrate_data_item(SpiceMarshaller *m, MainMigrateData *data) { - VDIPortState *state = &reds->agent_state; - int buf_index; - RingItem *now; - - data->version = MAIN_CHANNEL_MIG_DATA_VERSION; - - data->agent_connected = !!vdagent; - data->client_agent_started = !state->write_filter.discard_all; - data->num_client_tokens = state->num_client_tokens; - data->send_tokens = ~0; - - data->read_state = state->read_state; - data->vdi_chunk_header = state->vdi_chunk_header; - data->recive_len = state->recive_len; - data->message_recive_len = state->message_recive_len; - - if (state->current_read_buf) { - data->read_buf_len = state->current_read_buf->len; - - if (data->read_buf_len - data->recive_len) { - spice_marshaller_add_ref(m, - state->current_read_buf->data, - data->read_buf_len - data->recive_len); - } - } else { - data->read_buf_len = 0; - } - - now = &state->write_queue; - data->write_queue_size = 0; - while ((now = ring_prev(&state->write_queue, now))) { - data->write_queue_size++; - } - if (data->write_queue_size) { - WriteQueueInfo *queue_info; - - queue_info = (WriteQueueInfo *) - spice_marshaller_reserve_space(m, - data->write_queue_size * sizeof(queue_info[0])); - - buf_index = 0; - now = &state->write_queue; - while ((now = ring_prev(&state->write_queue, now))) { - VDIPortBuf *buf = (VDIPortBuf *)now; - queue_info[buf_index].port = buf->chunk_header.port; - queue_info[buf_index++].len = buf->write_len; - spice_marshaller_add_ref(m, buf->now, buf->write_len); - } - } -} - - -static int reds_main_channel_restore_vdi_read_state(MainMigrateData *data, uint8_t **in_pos, - uint8_t *end) -{ - VDIPortState *state = &reds->agent_state; - uint8_t *pos = *in_pos; - RingItem *ring_item; - - state->read_state = data->read_state; - state->vdi_chunk_header = data->vdi_chunk_header; - state->recive_len = data->recive_len; - state->message_recive_len = data->message_recive_len; - - switch (state->read_state) { - case VDI_PORT_READ_STATE_READ_HADER: - if (data->read_buf_len) { - spice_printerr("unexpected receive buf"); - reds_disconnect(); - return FALSE; - } - state->recive_pos = (uint8_t *)(&state->vdi_chunk_header + 1) - state->recive_len; - break; - case VDI_PORT_READ_STATE_GET_BUFF: - if (state->message_recive_len > state->vdi_chunk_header.size) { - spice_printerr("invalid message receive len"); - reds_disconnect(); - return FALSE; - } - - if (data->read_buf_len) { - spice_printerr("unexpected receive buf"); - reds_disconnect(); - return FALSE; - } - break; - case VDI_PORT_READ_STATE_READ_DATA: { - VDIReadBuf *buff; - uint32_t n; - - if (!data->read_buf_len) { - spice_printerr("read state and read_buf_len == 0"); - reds_disconnect(); - return FALSE; - } - - if (state->message_recive_len > state->vdi_chunk_header.size) { - spice_printerr("invalid message receive len"); - reds_disconnect(); - return FALSE; - } - - - if (!(ring_item = ring_get_head(&state->read_bufs))) { - spice_printerr("get read buf failed"); - reds_disconnect(); - return FALSE; - } - - ring_remove(ring_item); - buff = state->current_read_buf = (VDIReadBuf *)ring_item; - buff->len = data->read_buf_len; - n = buff->len - state->recive_len; - if (buff->len > SPICE_AGENT_MAX_DATA_SIZE || n > SPICE_AGENT_MAX_DATA_SIZE) { - spice_printerr("bad read position"); - reds_disconnect(); - return FALSE; - } - memcpy(buff->data, pos, n); - pos += n; - state->recive_pos = buff->data + n; - break; - } - default: - spice_printerr("invalid read state"); - reds_disconnect(); - return FALSE; - } - *in_pos = pos; - return TRUE; -} - -static void free_tmp_internal_buf(VDIPortBuf *buf) -{ - free(buf); -} - -static int reds_main_channel_restore_vdi_wqueue(MainMigrateData *data, uint8_t *pos, uint8_t *end) -{ - VDIPortState *state = &reds->agent_state; - WriteQueueInfo *inf; - WriteQueueInfo *inf_end; - RingItem *ring_item; - - if (!data->write_queue_size) { - return TRUE; - } - - inf = (WriteQueueInfo *)pos; - inf_end = inf + data->write_queue_size; - pos = (uint8_t *)inf_end; - if (pos > end) { - spice_printerr("access violation"); - reds_disconnect(); - return FALSE; - } - - for (; inf < inf_end; inf++) { - if (pos + inf->len > end) { - spice_printerr("access violation"); - reds_disconnect(); - return FALSE; - } - if (inf->port == VDP_SERVER_PORT) { - VDInternalBuf *buf; - - if (inf->len > sizeof(*buf) - SPICE_OFFSETOF(VDInternalBuf, header)) { - spice_printerr("bad buffer len"); - reds_disconnect(); - return FALSE; - } - buf = spice_new(VDInternalBuf, 1); - ring_item_init(&buf->base.link); - buf->base.free = free_tmp_internal_buf; - buf->base.now = (uint8_t *)&buf->base.chunk_header; - buf->base.write_len = inf->len; - memcpy(buf->base.now, pos, buf->base.write_len); - ring_add(&reds->agent_state.write_queue, &buf->base.link); - } else if (inf->port == VDP_CLIENT_PORT) { - VDAgentExtBuf *buf; - - state->num_tokens--; - if (inf->len > sizeof(*buf) - SPICE_OFFSETOF(VDAgentExtBuf, buf)) { - spice_printerr("bad buffer len"); - reds_disconnect(); - return FALSE; - } - if (!(ring_item = ring_get_head(&reds->agent_state.external_bufs))) { - spice_printerr("no external buff"); - reds_disconnect(); - return FALSE; - } - ring_remove(ring_item); - buf = (VDAgentExtBuf *)ring_item; - memcpy(&buf->buf, pos, inf->len); - buf->base.now = (uint8_t *)buf->buf; - buf->base.write_len = inf->len; - ring_add(&reds->agent_state.write_queue, &buf->base.link); - } else { - spice_printerr("invalid data"); - reds_disconnect(); - return FALSE; - } - pos += inf->len; - } - return TRUE; + spice_error("not implemented"); } void reds_on_main_receive_migrate_data(MainMigrateData *data, uint8_t *end) { - VDIPortState *state = &reds->agent_state; - uint8_t *pos; - - if (data->version != MAIN_CHANNEL_MIG_DATA_VERSION) { - spice_printerr("version mismatch"); - reds_disconnect(); - return; - } - - state->num_client_tokens = data->num_client_tokens; - spice_assert(state->num_client_tokens + data->write_queue_size <= REDS_AGENT_WINDOW_SIZE + - REDS_NUM_INTERNAL_AGENT_MESSAGES); - state->num_tokens = REDS_AGENT_WINDOW_SIZE - state->num_client_tokens; - - if (!data->agent_connected) { - if (vdagent) { - main_channel_push_agent_connected(reds->main_channel); - } - return; - } - - if (!vdagent) { - main_channel_push_agent_disconnected(reds->main_channel); - return; - } - - if (state->plug_generation > 1) { - main_channel_push_agent_disconnected(reds->main_channel); - main_channel_push_agent_connected(reds->main_channel); - return; - } - - state->write_filter.discard_all = !data->client_agent_started; - - pos = (uint8_t *)(data + 1); - - if (!reds_main_channel_restore_vdi_read_state(data, &pos, end)) { - return; - } - - reds_main_channel_restore_vdi_wqueue(data, pos, end); - spice_assert(state->num_client_tokens + state->num_tokens == REDS_AGENT_WINDOW_SIZE); - - while (write_to_vdi_port() || read_from_vdi_port()); + spice_error("not implemented"); } static int sync_write(RedsStream *stream, const void *in_buf, size_t n)