Spice VDAgentMessage 协议及使用
I.概要
Spice 包含三块:绑定在qemu/kvm上的Server(模块), 运行在(远程)主机上的Client(程序),和运行在Guest(虚拟机)上Agent(程序),(虚拟机运行在qemuspice上)。Server将运行在qemuspice上的虚拟机的数据通过channel(socket)传给client 显示输出,并和后者交互;agent 会辅助server/client在虚机上执行一些任务。
Win32中,Spice Agent是服务程序,由vdservice.exe和vdagent.exe组成,前者负责与系统和VDI端口通信,后者负责具体任务。二者之间建立pipe通信。
II.VDAgentMessage结构和操作
1.VDAgentMessage结构示例
这三方关于agent任务的所有数据通信,都基于struct VDAgentMessage
typedef struct SPICE_ATTR_PACKED VDAgentMessage {
uint32_t protocol; //协议名长为32字节的unsigned int
uint32_t type; //类别:剪贴板,鼠标事件...
uint64_t opaque; //掩码:消息发往何处
uint32_t size; //大小=data的长度+某子类型长度
uint8_t data[0]; //附加数据,实际是uint8_t*,所有msg本质上都存在uint8_t[]内。
} VDAgentMessage;
VDAgentMessage存于长度可变的uint8_t[]内,可对.type和.data处理,生成各种子类型。
具体为例,spice实现了agent所在的虚机和client所在的主机共享剪贴板,剪贴板消息的数据结构是
struct VDAgentMessage clip_msg =
new uint8_t[_out_msg_size=sizeof(VDAgentMessage)+sizeof(VDAgentClipboard)+clip_data_len] ={
.protocol = VD_AGENT_PROTOCOL;
.type = VD_AGENT_CLIPBOARD;
.opaque= ...方向
.size= sizeof(VDAgentClipboard)+clip_data_len;
.data= new uin8_t[.size];
};
此时clip_msg.data 即为(VDAgentClipboard*)clip_msg.data:
struct VDAgentClipboard//即把clip_msg.data[]内的数据进行细分当结构体看待:
{
.uint32_t type, //剪贴数据类型
.uint8_t* data = new uint8_t[clip_data_len],//这才是剪贴的数据clip_data
};
2.VDAgentMessage处理过程(以VDAgentClipboard 为例)
1)从虚机复制单词“Massacre”,被agent捕