diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile.am | 1 | ||||
-rw-r--r-- | client/display_channel.cpp | 14 | ||||
-rw-r--r-- | client/inputs_channel.cpp | 56 | ||||
-rw-r--r-- | client/record_channel.cpp | 35 | ||||
-rw-r--r-- | client/red_channel.cpp | 28 | ||||
-rw-r--r-- | client/red_channel.h | 4 | ||||
-rw-r--r-- | client/red_client.cpp | 43 | ||||
-rw-r--r-- | client/red_peer.cpp | 65 | ||||
-rw-r--r-- | client/red_peer.h | 19 | ||||
-rw-r--r-- | client/tunnel_channel.cpp | 121 |
10 files changed, 219 insertions, 167 deletions
diff --git a/client/Makefile.am b/client/Makefile.am index fa7dbb6a..f1402036 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -36,6 +36,7 @@ RED_COMMON_SRCS = \ common.h \ demarshallers.h \ generated_demarshallers.cpp \ + marshaller.cpp \ generated_marshallers.cpp \ generated_marshallers.h \ cursor_channel.cpp \ diff --git a/client/display_channel.cpp b/client/display_channel.cpp index 9cc5550c..5286aed1 100644 --- a/client/display_channel.cpp +++ b/client/display_channel.cpp @@ -42,6 +42,7 @@ #include "inputs_channel.h" #include "cursor_channel.h" #include "mjpeg_decoder.h" +#include "generated_marshallers.h" class CreatePrimarySurfaceEvent: public SyncEvent { public: @@ -1022,12 +1023,13 @@ private: void DisplayChannel::on_connect() { - Message* message = new Message(SPICE_MSGC_DISPLAY_INIT, sizeof(SpiceMsgcDisplayInit)); - SpiceMsgcDisplayInit* init = (SpiceMsgcDisplayInit*)message->data(); - init->pixmap_cache_id = 1; - init->pixmap_cache_size = get_client().get_pixmap_cache_size(); - init->glz_dictionary_id = 1; - init->glz_dictionary_window_size = get_client().get_glz_window_size(); + Message* message = new Message(SPICE_MSGC_DISPLAY_INIT); + SpiceMsgcDisplayInit init; + init.pixmap_cache_id = 1; + init.pixmap_cache_size = get_client().get_pixmap_cache_size(); + init.glz_dictionary_id = 1; + init.glz_dictionary_window_size = get_client().get_glz_window_size(); + spice_marshall_msgc_display_init(message->marshaller(), &init); post_message(message); AutoRef<AttachChannelsEvent> attach_channels(new AttachChannelsEvent(*this)); get_client().push_event(*attach_channels); diff --git a/client/inputs_channel.cpp b/client/inputs_channel.cpp index 4e99563d..6fd0b4fd 100644 --- a/client/inputs_channel.cpp +++ b/client/inputs_channel.cpp @@ -22,6 +22,7 @@ #include "red_client.h" #include "application.h" #include "display_channel.h" +#include "generated_marshallers.h" #define SYNC_REMOTH_MODIFIRES @@ -114,7 +115,7 @@ private: MotionMessage::MotionMessage(InputsChannel& channel) : RedChannel::OutMessage() - , RedPeer::OutMessage(SPICE_MSGC_INPUTS_MOUSE_MOTION, sizeof(SpiceMsgcMouseMotion)) + , RedPeer::OutMessage(SPICE_MSGC_INPUTS_MOUSE_MOTION) , _channel (channel) { } @@ -126,7 +127,11 @@ void MotionMessage::release() RedPeer::OutMessage& MotionMessage::peer_message() { - _channel.set_motion_event(*(SpiceMsgcMouseMotion*)data()); + SpiceMsgcMouseMotion motion; + + _channel.set_motion_event(motion); + spice_marshall_msgc_inputs_mouse_motion(_marshaller, &motion); + return *this; } @@ -142,7 +147,7 @@ private: PositionMessage::PositionMessage(InputsChannel& channel) : RedChannel::OutMessage() - , RedPeer::OutMessage(SPICE_MSGC_INPUTS_MOUSE_POSITION, sizeof(SpiceMsgcMousePosition)) + , RedPeer::OutMessage(SPICE_MSGC_INPUTS_MOUSE_POSITION) , _channel (channel) { } @@ -154,7 +159,9 @@ void PositionMessage::release() RedPeer::OutMessage& PositionMessage::peer_message() { - _channel.set_position_event(*(SpiceMsgcMousePosition*)data()); + SpiceMsgcMousePosition pos; + _channel.set_position_event(pos); + spice_marshall_msgc_inputs_mouse_position(_marshaller, &pos); return *this; } @@ -311,10 +318,12 @@ void InputsChannel::on_mouse_down(int button, int buttons_state) { Message* message; - message = new Message(SPICE_MSGC_INPUTS_MOUSE_PRESS, sizeof(SpiceMsgcMouseRelease)); - SpiceMsgcMousePress* event = (SpiceMsgcMousePress*)message->data(); - event->button = button; - event->buttons_state = buttons_state; + message = new Message(SPICE_MSGC_INPUTS_MOUSE_PRESS); + SpiceMsgcMousePress event; + event.button = button; + event.buttons_state = buttons_state; + spice_marshall_msgc_inputs_mouse_press(message->marshaller(), &event); + post_message(message); } @@ -322,10 +331,11 @@ void InputsChannel::on_mouse_up(int button, int buttons_state) { Message* message; - message = new Message(SPICE_MSGC_INPUTS_MOUSE_RELEASE, sizeof(SpiceMsgcMouseRelease)); - SpiceMsgcMouseRelease* event = (SpiceMsgcMouseRelease*)message->data(); - event->button = button; - event->buttons_state = buttons_state; + message = new Message(SPICE_MSGC_INPUTS_MOUSE_RELEASE); + SpiceMsgcMouseRelease event; + event.button = button; + event.buttons_state = buttons_state; + spice_marshall_msgc_inputs_mouse_release(message->marshaller(), &event); post_message(message); } @@ -349,9 +359,11 @@ void InputsChannel::on_key_down(RedKey key) return; } - Message* message = new Message(SPICE_MSGC_INPUTS_KEY_DOWN, sizeof(SpiceMsgcKeyDown)); - SpiceMsgcKeyDown* event = (SpiceMsgcKeyDown*)message->data(); - event->code = scan_code; + Message* message = new Message(SPICE_MSGC_INPUTS_KEY_DOWN); + SpiceMsgcKeyDown event; + event.code = scan_code; + spice_marshall_msgc_inputs_key_down(message->marshaller(), &event); + post_message(message); } @@ -363,9 +375,10 @@ void InputsChannel::on_key_up(RedKey key) return; } - Message* message = new Message(SPICE_MSGC_INPUTS_KEY_UP, sizeof(SpiceMsgcKeyUp)); - SpiceMsgcKeyUp* event = (SpiceMsgcKeyUp*)message->data(); - event->code = scan_code; + Message* message = new Message(SPICE_MSGC_INPUTS_KEY_UP); + SpiceMsgcKeyUp event; + event.code = scan_code; + spice_marshall_msgc_inputs_key_up(message->marshaller(), &event); post_message(message); } @@ -391,9 +404,10 @@ void InputsChannel::set_local_modifiers() void InputsChannel::on_focus_in() { #ifdef SYNC_REMOTH_MODIFIRES - Message* message = new Message(SPICE_MSGC_INPUTS_KEY_MODIFIERS, sizeof(SpiceMsgcKeyDown)); - SpiceMsgcKeyModifiers* modifiers = (SpiceMsgcKeyModifiers*)message->data(); - modifiers->modifiers = Platform::get_keyboard_lock_modifiers(); + Message* message = new Message(SPICE_MSGC_INPUTS_KEY_MODIFIERS); + SpiceMsgcKeyModifiers modifiers; + modifiers.modifiers = Platform::get_keyboard_lock_modifiers(); + spice_marshall_msgc_inputs_key_modifiers(message->marshaller(), &modifiers); post_message(message); #else set_local_modifiers(); diff --git a/client/record_channel.cpp b/client/record_channel.cpp index a48df60e..155e8d98 100644 --- a/client/record_channel.cpp +++ b/client/record_channel.cpp @@ -19,6 +19,7 @@ #include "red_client.h" #include "audio_channels.h" #include "audio_devices.h" +#include "generated_marshallers.h" #define NUM_SAMPLES_MESSAGES 4 @@ -33,23 +34,23 @@ public: RecordSamplesMessage(RecordChannel& channel); virtual ~RecordSamplesMessage(); - virtual RedPeer::OutMessage& peer_message() { return *_massage;} + virtual RedPeer::OutMessage& peer_message() { return *_message;} virtual void release(); private: RecordChannel& _channel; - RedPeer::OutMessage *_massage; + RedPeer::OutMessage *_message; }; RecordSamplesMessage::RecordSamplesMessage(RecordChannel& channel) : _channel (channel) - , _massage (new Message(SPICE_MSGC_RECORD_DATA, sizeof(SpiceMsgcRecordPacket) + 4096)) + , _message (new Message(SPICE_MSGC_RECORD_DATA)) { } RecordSamplesMessage::~RecordSamplesMessage() { - delete _massage; + delete _message; } void RecordSamplesMessage::release() @@ -115,19 +116,22 @@ bool RecordChannel::abort(void) void RecordChannel::on_connect() { - Message* message = new Message(SPICE_MSGC_RECORD_MODE, sizeof(SpiceMsgcRecordMode)); - SpiceMsgcRecordMode *mode = (SpiceMsgcRecordMode *)message->data(); - mode->time = get_mm_time(); - mode->mode = _mode = test_capability(SPICE_RECORD_CAP_CELT_0_5_1) ? RecordChannel::data_mode : + Message* message = new Message(SPICE_MSGC_RECORD_MODE); + SpiceMsgcRecordMode mode; + mode.time = get_mm_time(); + mode.mode = _mode = + test_capability(SPICE_RECORD_CAP_CELT_0_5_1) ? RecordChannel::data_mode : SPICE_AUDIO_DATA_MODE_RAW; + spice_marshall_msgc_record_mode(message->marshaller(), &mode); post_message(message); } void RecordChannel::send_start_mark() { - Message* message = new Message(SPICE_MSGC_RECORD_START_MARK, sizeof(SpiceMsgcRecordStartMark)); - SpiceMsgcRecordStartMark *start_mark = (SpiceMsgcRecordStartMark *)message->data(); - start_mark->time = get_mm_time(); + Message* message = new Message(SPICE_MSGC_RECORD_START_MARK); + SpiceMsgcRecordStartMark start_mark; + start_mark.time = get_mm_time(); + spice_marshall_msgc_record_start_mark(message->marshaller(), &start_mark); post_message(message); } @@ -253,10 +257,11 @@ void RecordChannel::push_frame(uint8_t *frame) n = _frame_bytes; } RedPeer::OutMessage& peer_message = message->peer_message(); - peer_message.resize(n + sizeof(SpiceMsgcRecordPacket)); - SpiceMsgcRecordPacket* packet = (SpiceMsgcRecordPacket*)peer_message.data(); - packet->time = get_mm_time(); - memcpy(packet->data, frame, n); + peer_message.reset(SPICE_MSGC_RECORD_DATA); + SpiceMsgcRecordPacket packet; + packet.time = get_mm_time(); + spice_marshall_msgc_record_data(peer_message.marshaller(), &packet); + spice_marshaller_add(peer_message.marshaller(), frame, n); post_message(message); } diff --git a/client/red_channel.cpp b/client/red_channel.cpp index 475cec4a..7065b0a6 100644 --- a/client/red_channel.cpp +++ b/client/red_channel.cpp @@ -21,6 +21,7 @@ #include "application.h" #include "debug.h" #include "utils.h" +#include "generated_marshallers.h" #include "openssl/rsa.h" #include "openssl/evp.h" @@ -507,7 +508,7 @@ void RedChannel::on_send_trigger() void RedChannel::on_message_recived() { if (_message_ack_count && !--_message_ack_count) { - post_message(new Message(SPICE_MSGC_ACK, 0)); + post_message(new Message(SPICE_MSGC_ACK)); _message_ack_count = _message_ack_window; } } @@ -547,8 +548,8 @@ void RedChannel::on_event() { if (_outgoing_message) { RedPeer::OutMessage& peer_message = _outgoing_message->peer_message(); - _outgoing_pos += send(peer_message.base() + _outgoing_pos, - peer_message.message_size() - _outgoing_pos); + + _outgoing_pos += do_send(peer_message, _outgoing_pos); if (_outgoing_pos == peer_message.message_size()) { _outgoing_message->release(); _outgoing_message = NULL; @@ -592,7 +593,7 @@ void RedChannel::send_migrate_flush_mark() { if (_outgoing_message) { RedPeer::OutMessage& peer_message = _outgoing_message->peer_message(); - send(peer_message.base() + _outgoing_pos, peer_message.message_size() - _outgoing_pos); + do_send(peer_message, _outgoing_pos); _outgoing_message->release(); _outgoing_message = NULL; } @@ -605,7 +606,7 @@ void RedChannel::send_migrate_flush_mark() send(message.get()->peer_message()); } lock.unlock(); - std::auto_ptr<RedPeer::OutMessage> message(new RedPeer::OutMessage(SPICE_MSGC_MIGRATE_FLUSH_MARK, 0)); + std::auto_ptr<RedPeer::OutMessage> message(new RedPeer::OutMessage(SPICE_MSGC_MIGRATE_FLUSH_MARK)); send(*message); } @@ -627,9 +628,8 @@ void RedChannel::handle_migrate(RedPeer::InMessage* message) if ((*data_message)->type() != SPICE_MSG_MIGRATE_DATA) { THROW("expect SPICE_MSG_MIGRATE_DATA"); } - std::auto_ptr<RedPeer::OutMessage> message(new RedPeer::OutMessage(SPICE_MSGC_MIGRATE_DATA, - (*data_message)->size())); - memcpy(message->data(), (*data_message)->data(), (*data_message)->size()); + std::auto_ptr<RedPeer::OutMessage> message(new RedPeer::OutMessage(SPICE_MSGC_MIGRATE_DATA)); + spice_marshaller_add(message->marshaller(), (*data_message)->data(), (*data_message)->size()); send(*message); } _loop.add_socket(*this); @@ -643,16 +643,18 @@ void RedChannel::handle_set_ack(RedPeer::InMessage* message) { SpiceMsgSetAck* ack = (SpiceMsgSetAck*)message->data(); _message_ack_window = _message_ack_count = ack->window; - Message *responce = new Message(SPICE_MSGC_ACK_SYNC, sizeof(uint32_t)); - *(uint32_t *)responce->data() = ack->generation; - post_message(responce); + Message *response = new Message(SPICE_MSGC_ACK_SYNC); + SpiceMsgcAckSync sync; + sync.generation = ack->generation; + spice_marshall_msgc_ack_sync(response->marshaller(), &sync); + post_message(response); } void RedChannel::handle_ping(RedPeer::InMessage* message) { SpiceMsgPing *ping = (SpiceMsgPing *)message->data(); - Message *pong = new Message(SPICE_MSGC_PONG, sizeof(SpiceMsgPing)); - *(SpiceMsgPing *)pong->data() = *ping; + Message *pong = new Message(SPICE_MSGC_PONG); + spice_marshall_msgc_pong(pong->marshaller(), ping); post_message(pong); } diff --git a/client/red_channel.h b/client/red_channel.h index 8d6b62f4..a9d3ee54 100644 --- a/client/red_channel.h +++ b/client/red_channel.h @@ -212,9 +212,9 @@ public: class Message: public RedChannel::OutMessage, public RedPeer::OutMessage { public: - Message(uint32_t type, uint32_t size) + Message(uint32_t type) : RedChannel::OutMessage() - , RedPeer::OutMessage(type, size) + , RedPeer::OutMessage(type) { } diff --git a/client/red_client.cpp b/client/red_client.cpp index 8778eebc..c079f3d4 100644 --- a/client/red_client.cpp +++ b/client/red_client.cpp @@ -22,6 +22,7 @@ #include "process_loop.h" #include "utils.h" #include "debug.h" +#include "generated_marshallers.h" #ifdef __GNUC__ typedef struct __attribute__ ((__packed__)) OldRedMigrationBegin { @@ -190,10 +191,10 @@ void Migrate::run() Lock lock(_lock); _cond.notify_one(); if (_connected) { - Message* message = new Message(SPICE_MSGC_MAIN_MIGRATE_CONNECTED, 0); + Message* message = new Message(SPICE_MSGC_MAIN_MIGRATE_CONNECTED); _client.post_message(message); } else { - Message* message = new Message(SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR, 0); + Message* message = new Message(SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR); _client.post_message(message); } _running = false; @@ -593,16 +594,17 @@ void RedClient::send_agent_monitors_config() } } - Message* message = new Message(SPICE_MSGC_MAIN_AGENT_DATA,sizeof(VDAgentMessage) + - sizeof(VDAgentMonitorsConfig) + - monitors.size() * sizeof(VDAgentMonConfig)); - VDAgentMessage* msg = (VDAgentMessage*)message->data(); + Message* message = new Message(SPICE_MSGC_MAIN_AGENT_DATA); + VDAgentMessage* msg = (VDAgentMessage*) + spice_marshaller_reserve_space(message->marshaller(), sizeof(VDAgentMessage)); msg->protocol = VD_AGENT_PROTOCOL; msg->type = VD_AGENT_MONITORS_CONFIG; msg->opaque = 0; msg->size = sizeof(VDAgentMonitorsConfig) + monitors.size() * sizeof(VDAgentMonConfig); - VDAgentMonitorsConfig* mon_config = (VDAgentMonitorsConfig*)msg->data; + VDAgentMonitorsConfig* mon_config = (VDAgentMonitorsConfig*) + spice_marshaller_reserve_space(message->marshaller(), + sizeof(VDAgentMonitorsConfig) + monitors.size() * sizeof(VDAgentMonConfig)); mon_config->num_of_monitors = monitors.size(); mon_config->flags = 0; if (Platform::is_monitors_pos_valid()) { @@ -696,9 +698,12 @@ void RedClient::set_mouse_mode(uint32_t supported_modes, uint32_t current_mode) } // FIXME: use configured mouse mode (currently, use client mouse mode if supported by server) if ((supported_modes & SPICE_MOUSE_MODE_CLIENT) && (current_mode != SPICE_MOUSE_MODE_CLIENT)) { - Message* message = new Message(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, sizeof(SpiceMsgcMainMouseModeRequest)); - SpiceMsgcMainMouseModeRequest* mouse_mode_request = (SpiceMsgcMainMouseModeRequest*)message->data(); - mouse_mode_request->mode = SPICE_MOUSE_MODE_CLIENT; + Message* message = new Message(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST); + SpiceMsgcMainMouseModeRequest mouse_mode_request; + mouse_mode_request.mode = SPICE_MOUSE_MODE_CLIENT; + spice_marshall_msgc_main_mouse_mode_request(message->marshaller(), + &mouse_mode_request); + post_message(message); } } @@ -714,9 +719,10 @@ void RedClient::handle_init(RedPeer::InMessage* message) _agent_tokens = init->agent_tokens; _agent_connected = !!init->agent_connected; if (_agent_connected) { - Message* msg = new Message(SPICE_MSGC_MAIN_AGENT_START, sizeof(SpiceMsgcMainAgentStart)); - SpiceMsgcMainAgentStart* agent_start = (SpiceMsgcMainAgentStart *)msg->data(); - agent_start->num_tokens = ~0; + Message* msg = new Message(SPICE_MSGC_MAIN_AGENT_START); + SpiceMsgcMainAgentStart agent_start; + agent_start.num_tokens = ~0; + spice_marshall_msgc_main_agent_start(msg->marshaller(), &agent_start); post_message(msg); } if (_auto_display_res) { @@ -725,7 +731,7 @@ void RedClient::handle_init(RedPeer::InMessage* message) send_agent_monitors_config(); } } else { - post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS, 0)); + post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS)); } } @@ -754,9 +760,10 @@ void RedClient::handle_agent_connected(RedPeer::InMessage* message) { DBG(0, ""); _agent_connected = true; - Message* msg = new Message(SPICE_MSGC_MAIN_AGENT_START, sizeof(SpiceMsgcMainAgentStart)); - SpiceMsgcMainAgentStart* agent_start = (SpiceMsgcMainAgentStart *)msg->data(); - agent_start->num_tokens = ~0; + Message* msg = new Message(SPICE_MSGC_MAIN_AGENT_START); + SpiceMsgcMainAgentStart agent_start; + agent_start.num_tokens = ~0; + spice_marshall_msgc_main_agent_start(msg->marshaller(), &agent_start); post_message(msg); if (_auto_display_res && !_agent_mon_config_sent) { send_agent_monitors_config(); @@ -781,7 +788,7 @@ void RedClient::on_agent_reply(VDAgentReply* reply) } switch (reply->type) { case VD_AGENT_MONITORS_CONFIG: - post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS, 0)); + post_message(new Message(SPICE_MSGC_MAIN_ATTACH_CHANNELS)); _application.deactivate_interval_timer(*_agent_timer); break; default: diff --git a/client/red_peer.cpp b/client/red_peer.cpp index be18dfbc..9a608adc 100644 --- a/client/red_peer.cpp +++ b/client/red_peer.cpp @@ -726,38 +726,59 @@ uint32_t RedPeer::send(uint8_t *buf, uint32_t size) return pos - buf; } +uint32_t RedPeer::do_send(RedPeer::OutMessage& message, uint32_t skip_bytes) +{ + uint8_t *data; + int free_data; + size_t len; + uint32_t res; + + data = spice_marshaller_linearize(message.marshaller(), skip_bytes, + &len, &free_data); + + res = send(data, len); + + if (free_data) { + free(data); + } + return res; +} + uint32_t RedPeer::send(RedPeer::OutMessage& message) { + message.header().serial = ++_serial; - return send(message.base(), message.message_size()); + message.header().size = message.message_size() - sizeof(SpiceDataHeader); + + return do_send(message, 0); } -RedPeer::OutMessage::OutMessage(uint32_t type, uint32_t size) - : _data (new uint8_t[size + sizeof(SpiceDataHeader)]) - , _size (size) +RedPeer::OutMessage::OutMessage(uint32_t type) + : _marshaller (spice_marshaller_new()) { - header().type = type; - header().size = size; + SpiceDataHeader *header; + header = (SpiceDataHeader *) + spice_marshaller_reserve_space(_marshaller, sizeof(SpiceDataHeader)); + spice_marshaller_set_base(_marshaller, sizeof(SpiceDataHeader)); + + header->type = type; + header->sub_list = 0; } -RedPeer::OutMessage::~OutMessage() +void RedPeer::OutMessage::reset(uint32_t type) { - delete[] _data; + spice_marshaller_reset(_marshaller); + + SpiceDataHeader *header; + header = (SpiceDataHeader *) + spice_marshaller_reserve_space(_marshaller, sizeof(SpiceDataHeader)); + spice_marshaller_set_base(_marshaller, sizeof(SpiceDataHeader)); + + header->type = type; + header->sub_list = 0; } -void RedPeer::OutMessage::resize(uint32_t size) +RedPeer::OutMessage::~OutMessage() { - if (size <= _size) { - header().size = size; - return; - } - uint32_t type = header().type; - delete[] _data; - _data = NULL; - _size = 0; - _data = new uint8_t[size + sizeof(SpiceDataHeader)]; - _size = size; - header().type = type; - header().size = size; + spice_marshaller_destroy(_marshaller); } - diff --git a/client/red_peer.h b/client/red_peer.h index f24e5e7b..001f9fa9 100644 --- a/client/red_peer.h +++ b/client/red_peer.h @@ -26,6 +26,7 @@ #include "process_loop.h" #include "threads.h" #include "platform_utils.h" +#include "marshaller.h" class RedPeer: protected EventSources::Socket { public: @@ -111,6 +112,7 @@ public: void enable() { _shut = false;} virtual CompundInMessage* recive(); + uint32_t do_send(OutMessage& message, uint32_t skip_bytes); uint32_t send(OutMessage& message); uint32_t recive(uint8_t* buf, uint32_t size); @@ -194,20 +196,19 @@ private: class RedPeer::OutMessage { public: - OutMessage(uint32_t type, uint32_t size); + OutMessage(uint32_t type); virtual ~OutMessage(); - SpiceDataHeader& header() { return *(SpiceDataHeader *)_data;} - uint8_t* data() { return _data + sizeof(SpiceDataHeader);} - void resize(uint32_t size); + SpiceMarshaller *marshaller() { return _marshaller;} + void reset(uint32_t type); private: - uint32_t message_size() { return header().size + sizeof(SpiceDataHeader);} - uint8_t* base() { return _data;} + uint32_t message_size() { return spice_marshaller_get_total_size(_marshaller);} + uint8_t* base() { return spice_marshaller_get_ptr(_marshaller);} + SpiceDataHeader& header() { return *(SpiceDataHeader *)base();} -private: - uint8_t* _data; - uint32_t _size; +protected: + SpiceMarshaller *_marshaller; friend class RedPeer; friend class RedChannel; diff --git a/client/tunnel_channel.cpp b/client/tunnel_channel.cpp index cecd9bab..1464b1da 100644 --- a/client/tunnel_channel.cpp +++ b/client/tunnel_channel.cpp @@ -21,6 +21,7 @@ #include "common.h" #include "tunnel_channel.h" +#include "generated_marshallers.h" #include <spice/protocol.h> #define SOCKET_WINDOW_SIZE 60 @@ -93,13 +94,13 @@ public: virtual RedPeer::OutMessage& peer_message() { return *this;} virtual void release(); - virtual uint8_t* buf(); + virtual uint8_t* buf() { return _the_buf; }; virtual uint32_t buf_max_size() {return _max_data_size;} virtual void set_buf_size(uint32_t size); virtual void release_buf(); static void init(uint32_t max_data_size); - static OutSocketMessage& alloc_message(); + static OutSocketMessage& alloc_message(uint16_t id); static void clear_free_messages(); protected: @@ -109,26 +110,22 @@ protected: private: static std::list<OutSocketMessage*> _free_messages; static uint32_t _max_data_size; + uint8_t *_the_buf; }; std::list<OutSocketMessage*> OutSocketMessage::_free_messages; uint32_t OutSocketMessage::_max_data_size; OutSocketMessage::OutSocketMessage() - : RedPeer::OutMessage(SPICE_MSGC_TUNNEL_SOCKET_DATA, sizeof(SpiceMsgcTunnelSocketData) + _max_data_size) + : RedPeer::OutMessage(SPICE_MSGC_TUNNEL_SOCKET_DATA) , RedChannel::OutMessage() , ClientNetSocket::ReceiveBuffer() { } -uint8_t* OutSocketMessage::buf() -{ - return ((SpiceMsgcTunnelSocketData*)RedPeer::OutMessage::data())->data; -} - void OutSocketMessage::set_buf_size(uint32_t size) { - RedPeer::OutMessage::header().size = size + sizeof(SpiceMsgcTunnelSocketData); + spice_marshaller_unreserve_space(_marshaller, _max_data_size - size); } void OutSocketMessage::release() @@ -146,16 +143,22 @@ void OutSocketMessage::init(uint32_t max_data_size) _max_data_size = max_data_size; } -OutSocketMessage& OutSocketMessage::alloc_message() +OutSocketMessage& OutSocketMessage::alloc_message(uint16_t id) { OutSocketMessage* ret; if (!_free_messages.empty()) { ret = _free_messages.front(); _free_messages.pop_front(); + spice_marshaller_reset(ret->marshaller()); } else { ret = new OutSocketMessage(); } + SpiceMsgcTunnelSocketData data; + data.connection_id = id; + spice_marshall_msgc_tunnel_socket_data(ret->marshaller(), &data); + ret->_the_buf = spice_marshaller_reserve_space(ret->marshaller(), _max_data_size); + return *ret; } @@ -198,7 +201,7 @@ public: bool get_guest_closed() {return _guest_closed;} protected: - virtual ReceiveBuffer& alloc_receive_buffer() {return OutSocketMessage::alloc_message();} + virtual ReceiveBuffer& alloc_receive_buffer() {return OutSocketMessage::alloc_message(id());} private: uint32_t _num_tokens; @@ -275,45 +278,33 @@ void TunnelChannel::handle_init(RedPeer::InMessage* message) void TunnelChannel::send_service(TunnelService& service) { - int msg_size = 0; - msg_size += service.name.length() + 1; - msg_size += service.description.length() + 1; - - if (service.type == SPICE_TUNNEL_SERVICE_TYPE_IPP) { - msg_size += sizeof(SpiceMsgcTunnelAddPrintService) + sizeof(SpiceTunnelIPv4); - } else if (service.type == SPICE_TUNNEL_SERVICE_TYPE_GENERIC) { - msg_size += sizeof(SpiceMsgcTunnelAddGenericService); - } else { + if (service.type != SPICE_TUNNEL_SERVICE_TYPE_IPP && + service.type == SPICE_TUNNEL_SERVICE_TYPE_GENERIC) { THROW("%s: invalid service type", __FUNCTION__); } - Message* service_msg = new Message(SPICE_MSGC_TUNNEL_SERVICE_ADD, msg_size); - SpiceMsgcTunnelAddGenericService* out_service = (SpiceMsgcTunnelAddGenericService*)service_msg->data(); - out_service->id = service.id; - out_service->group = service.group; - out_service->type = service.type; - out_service->port = service.port; - int cur_offset; + Message* service_msg = new Message(SPICE_MSGC_TUNNEL_SERVICE_ADD); + SpiceMsgcTunnelAddPrintService add; + SpiceMarshaller *name_out, *description_out; + add.base.id = service.id; + add.base.group = service.group; + add.base.type = service.type; + add.base.port = service.port; + if (service.type == SPICE_TUNNEL_SERVICE_TYPE_IPP) { - cur_offset = sizeof(SpiceMsgcTunnelAddPrintService); - ((SpiceMsgcTunnelAddPrintService*)out_service)->ip.type = SPICE_TUNNEL_IP_TYPE_IPv4; - memcpy(((SpiceMsgcTunnelAddPrintService*)out_service)->ip.data, &(service.ip.s_addr), - sizeof(SpiceTunnelIPv4)); - cur_offset += sizeof(SpiceTunnelIPv4); - } else { - cur_offset = sizeof(SpiceMsgcTunnelAddGenericService); + add.ip.type = SPICE_TUNNEL_IP_TYPE_IPv4; } - out_service->name = cur_offset; - service.name.copy((char*)(service_msg->data() + cur_offset), service.name.length()); - (service_msg->data() + cur_offset)[service.name.length()] = '\0'; - cur_offset += service.name.length() + 1; + spice_marshall_msgc_tunnel_service_add(service_msg->marshaller(), &add.base, + &name_out, &description_out); - out_service->description = cur_offset; - service.description.copy((char*)(service_msg->data() + cur_offset), - service.description.length()); - (service_msg->data() + cur_offset)[service.description.length()] = '\0'; - cur_offset += service.description.length() + 1; + if (service.type == SPICE_TUNNEL_SERVICE_TYPE_IPP) { + spice_marshaller_add(service_msg->marshaller(), (uint8_t *)&(service.ip.s_addr), + sizeof(SpiceTunnelIPv4)); + } + + spice_marshaller_add(name_out, (uint8_t *)service.name.c_str(), service.name.length() + 1); + spice_marshaller_add(description_out, (uint8_t *)service.description.c_str(), service.description.length() + 1); post_message(service_msg); } @@ -361,15 +352,18 @@ void TunnelChannel::handle_socket_open(RedPeer::InMessage* message) if (sckt->connect(open_msg->tokens)) { _sockets[open_msg->connection_id] = sckt; - out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK, sizeof(SpiceMsgcTunnelSocketOpenAck)); + out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK); sckt->set_num_tokens(0); sckt->set_server_num_tokens(SOCKET_WINDOW_SIZE); - - ((SpiceMsgcTunnelSocketOpenAck*)out_msg->data())->connection_id = open_msg->connection_id; - ((SpiceMsgcTunnelSocketOpenAck*)out_msg->data())->tokens = SOCKET_WINDOW_SIZE; + SpiceMsgcTunnelSocketOpenAck ack; + ack.connection_id = open_msg->connection_id; + ack.tokens = SOCKET_WINDOW_SIZE; + spice_marshall_msgc_tunnel_socket_open_ack(out_msg->marshaller(), &ack); } else { - out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK, sizeof(SpiceMsgcTunnelSocketOpenNack)); - ((SpiceMsgcTunnelSocketOpenNack*)out_msg->data())->connection_id = open_msg->connection_id; + out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK); + SpiceMsgcTunnelSocketOpenNack nack; + nack.connection_id = open_msg->connection_id; + spice_marshall_msgc_tunnel_socket_open_nack(out_msg->marshaller(), &nack); delete sckt; } @@ -480,19 +474,19 @@ void TunnelChannel::handle_socket_token(RedPeer::InMessage* message) void TunnelChannel::on_socket_message_recv_done(ClientNetSocket& sckt, ClientNetSocket::ReceiveBuffer& buf) { - TunnelChannel::TunnelSocket* tunnel_sckt = static_cast<TunnelChannel::TunnelSocket*>(&sckt); OutSocketMessage* out_msg = static_cast<OutSocketMessage*>(&buf); - ((SpiceMsgcTunnelSocketData*)(out_msg->data()))->connection_id = tunnel_sckt->id(); post_message(out_msg); } void TunnelChannel::on_socket_fin_recv(ClientNetSocket& sckt) { TunnelChannel::TunnelSocket* tunnel_sckt = static_cast<TunnelChannel::TunnelSocket*>(&sckt); - Message* out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_FIN, sizeof(SpiceMsgcTunnelSocketFin)); + Message* out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_FIN); DBG(0, "FIN from client coonection id=%d", tunnel_sckt->id()); - ((SpiceMsgcTunnelSocketFin*)out_msg->data())->connection_id = tunnel_sckt->id(); + SpiceMsgcTunnelSocketFin fin; + fin.connection_id = tunnel_sckt->id(); + spice_marshall_msgc_tunnel_socket_fin(out_msg->marshaller(), &fin); post_message(out_msg); } @@ -503,14 +497,18 @@ void TunnelChannel::on_socket_disconnect(ClientNetSocket& sckt) // close initiated by server -> needs ack if (tunnel_sckt->get_guest_closed()) { DBG(0, "send close ack connection_id=%d", tunnel_sckt->id()); - out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK, sizeof(SpiceMsgcTunnelSocketClosedAck)); - ((SpiceMsgcTunnelSocketClosedAck*)out_msg->data())->connection_id = tunnel_sckt->id(); + out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK); + SpiceMsgcTunnelSocketClosedAck ack; + ack.connection_id = tunnel_sckt->id(); + spice_marshall_msgc_tunnel_socket_closed_ack(out_msg->marshaller(), &ack); _sockets[tunnel_sckt->id()] = NULL; delete &sckt; } else { // close initiated by client DBG(0, "send close coonection_id=%d", tunnel_sckt->id()); - out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_CLOSED, sizeof(SpiceMsgcTunnelSocketClosed)); - ((SpiceMsgcTunnelSocketClosed*)out_msg->data())->connection_id = tunnel_sckt->id(); + out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_CLOSED); + SpiceMsgcTunnelSocketClosed closed; + closed.connection_id = tunnel_sckt->id(); + spice_marshall_msgc_tunnel_socket_closed(out_msg->marshaller(), &closed); } post_message(out_msg); @@ -523,10 +521,11 @@ void TunnelChannel::on_socket_message_send_done(ClientNetSocket& sckt) num_tokens++; if (num_tokens == SOCKET_TOKENS_TO_SEND) { - Message* out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_TOKEN, sizeof(SpiceMsgcTunnelSocketTokens)); - SpiceMsgcTunnelSocketTokens* tokens_msg = (SpiceMsgcTunnelSocketTokens*)out_msg->data(); - tokens_msg->connection_id = tunnel_sckt->id(); - tokens_msg->num_tokens = num_tokens; + Message* out_msg = new Message(SPICE_MSGC_TUNNEL_SOCKET_TOKEN); + SpiceMsgcTunnelSocketTokens tokens_msg; + tokens_msg.connection_id = tunnel_sckt->id(); + tokens_msg.num_tokens = num_tokens; + spice_marshall_msgc_tunnel_socket_token(out_msg->marshaller(), &tokens_msg); post_message(out_msg); tunnel_sckt->set_num_tokens(0); |