mirror of
https://github.com/amitbet/vncproxy.git
synced 2025-08-17 21:26:37 +00:00
custom recorders added
This commit is contained in:
parent
b65099a6bc
commit
a6e1fdbf7d
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
27
bin/recordings/recording_1565211076/client.rbs
Normal file
27
bin/recordings/recording_1565211076/client.rbs
Normal file
@ -0,0 +1,27 @@
|
||||
W
|
||||
FBS 001.000RFB 003.003
|
||||
─ ─(0╒оФН:TigerVNC (0f680132c2eb)B (Ъ0Ъ8Ъ@H╧┴ F ╧┬ ≥ ╧┴ ы ╥█ ░ ╛⌠ ╗ ²≤ ю ░² ь ┌╒ П |ё ┬
|
||||
z╓ ═
|
||||
y╔ ╦
|
||||
w╔ ь
|
||||
v╔ ╧v╔ А
|
||||
v╔ пv╔ ь
v╔ И
s╖ яp╜ Иk╣ │h╪ ≥c╩ ыW╡ ЯQ╜ ┴K╘ ║G╔ ╧E╓ ыCё Ы=ё ▒6╒ ╗0÷ ю*² ы(⌡ Ы
|
||||
(⌡ ю(⌡ ю(⌡ я(÷ ╠(ё и(╔ А)╘ Ы+╙ ═,╚ п,╛ П-╝ ╟-╠ и-Ё И-╢ ▒-╤ я/╦ И0╦ ▒1╦ ╘
|
||||
1╦ Ю1╦ ╦1╦ и1╦ Я 1╤ ы!1╤ │"
|
||||
1╤ П"1╤ Х#1╤ Ы#1╣ Ы%0╣ ╠&0╣ А&.╣ ┴'+╥ ╘')╦ Я'(╦ х('╧ ▒))╥ И*.╥ │+5╤ ≥+
|
||||
5╤ п+5╤ ю,5╤ я,1╧ ы.0╩ ┴00ю Ы00е ▒10к ╝10п ю10ж ы10Ю Я13О ┴25З ║25─ ╧27┴ я28░ И28≤ │3:· ≥3:÷ ╦3
|
||||
:÷ ╦4:÷ ю5:÷ я59· Я78° ┴88≈ ║87▓ ╧87█ я87├ Х87│ ─96Э ≤96В ╠96У и96П з96К Я95Е ┬:5А ║:5Ю ╧<5ш я<5ж И<5р │=5о ≥=
|
||||
5о х=5о ╟>5о а>5в ыA3ъ ЯA2И ┬B2Я ║B2Ж ╧B2Ш ≥C3─ ╧C3┘ яC3┼ ЯC3▐ ┴D4▒ ║D
|
||||
4▒ ХD
|
||||
4⌠ │E4⌠ ─F4⌠ ▒F4█ │H4└ ≥H5З ╠H8Р иH;Й АH>Ц ЫH?э ▒IBт ╘IDл аIGг АIHц ЫIIб ▒JIг ╠KIл иKHя АKHв ЫKFш ▒LFв ┴M
|
||||
Fв ьMFв пNFв АNCы ┴Q@щ ║Q=Б ╨Q:Х яQ7М ЯQ6М ▒S
|
||||
6М юS6М юT6М яT8И ║W:ч ╧W=т яW@м ИWEф │XHа ≥XK╩ ╧XN╣ яXQ╝ ИXR╜ │YS╘ ≥Y
|
||||
S╘ ьZS╘ ю[S╘ я[S╝ ┴]S╢ ║]S╨ ╧]S© я]Sе И]Sн │^Qз ≥^OЦ ╠^NГ я^NЛ И^LП │_KР ≥_EР И_AП ┴`<Л ║`:Ф ╧`9Д я`
|
||||
9Д ≥a9Д ╗b9Д ╧b:Б аd=ъ ыd?э ЯdBв ┴eJк ║eOе ╧eS© яeU╪ ИeW╨ ≥fX╦ ╡fY╣ иfYЁ АfZ╡ Ыf
|
||||
Z╡ иhZ╡ юiZ╡ яiZ╢ яkY╧ ЯkU© ┴lQг ║lLн ╧lGт яlBш Иl=Б │m4Н ≥m,В ╠m+Ш иm+Э │n
|
||||
+Э Аn+Э Хo+Э Ыo+В Иr.Л │s1з ≥s5о ╠s6к иs8х Иs:е │t=б ≥t>ю ╠t?╩ иt@╧ АtB╤ ЫtC╤ ≥u
|
||||
C╤ ИuC╤ ьvC╤ ИvB╦ ≥xA╩ ╠x@а иx@ф Аx?к Ыx?я ▒y=ь ╘y;щ аy;ъ ыy:А ╘z8Б яz
|
||||
8Б ╠{8Б ╗|8Б ╧|8ъ я8в И 8п │─ 9г ≥─ :а ╠─ :╨ и─ <╣ А─ >╟ Ы─ @╚ ≥│ A╙ я│A╙ а┌ A╙ ╟┐ A╙ а┐ A╛ │┘ ?╡ ≥┘ 9╫ ╠┘ 6д и┘ 3к А┘ 0я Ы┘ .ж ▒├ -ы ╘├-ы а┤ -ы ю┬ -ы я┬ -в ▒▀ .с ╘▀ 0к а▀ 4ю ы▀ 6╞ Я▀ 9╕ ┴▄ 9╓ ╘▄ :ё а▄:ё ▒▐ :ё Ь▐ :ё ┴░ :╘ ║▓ 9╠ ╧▓ 8╦ я▓ 8╪ И▓ 8ю ┴⌠ 7е ║⌠ 7й ╧⌠ 7л я⌠ 7я Б⌠ 7з Ы⌠ 7Е ▒■ 7П ╘■ 6Ж а■ 6З ы■ 6─ Я■ 6┘ ┴∙ 6┴ ║∙ 6┼ а∙6┼ а√ 6┼ ╦≈ 6┼ и≈ 6├ ║ 6Ч ╧ 7Р я ;Х И ;Б │⌡ <э ≥⌡ =ы ╠⌡ @р и⌡ Bй А⌡ Dа Ы⌡ E╩ ▒° F╦ ╘°F╦ а² F╦ ю· F╦ я· D╫ Ы═ Bф ▒║ ?о ╘║ <з а║ 8А ы║ 6И Я║ 4Н ┴╒ 3П ╠╒ 3С и╒ 3Ж А╒ 3Ш │ё 3┌ ≥ё 3┴ ╠ё 3▒ иё 3√ Аё 3² Ыё 3╒ ▒╓ 3ё ╘╓3ё И╓ 3ё Х╔ 3ё З╔ 4⌡ Ы╖ 8▌ ▒╗ BЗ ╘╗ Zъ а╗ oл ы╗
|
||||
┐╧ Я╗
|
||||
≤╓ ┴╘
|
||||
╜┼ ║╘ дp ╧╘ в_ я╘ ИP И╘ Ж@ │╙ ┼. ≥╙ ⌠# ╠╙ · и╙ ╓ Б╙ ╙ │╚ ╜ ≥╚ ╠ ╧╚ ╣
я╚ ╫ И╚ и │╛у ╛
|
BIN
bin/recordings/recording_1565211076/server.rbs
Normal file
BIN
bin/recordings/recording_1565211076/server.rbs
Normal file
Binary file not shown.
BIN
bin/vnc_reader
BIN
bin/vnc_reader
Binary file not shown.
BIN
bin/vnc_recorder
BIN
bin/vnc_recorder
Binary file not shown.
134
proto/demo.pb.go
134
proto/demo.pb.go
@ -391,6 +391,45 @@ func (m *PixelFormat) GetBlueShift() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
type MessageType struct {
|
||||
Type uint32 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *MessageType) Reset() { *m = MessageType{} }
|
||||
func (m *MessageType) String() string { return proto.CompactTextString(m) }
|
||||
func (*MessageType) ProtoMessage() {}
|
||||
func (*MessageType) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ca53982754088a9d, []int{5}
|
||||
}
|
||||
|
||||
func (m *MessageType) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_MessageType.Unmarshal(m, b)
|
||||
}
|
||||
func (m *MessageType) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_MessageType.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *MessageType) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_MessageType.Merge(m, src)
|
||||
}
|
||||
func (m *MessageType) XXX_Size() int {
|
||||
return xxx_messageInfo_MessageType.Size(m)
|
||||
}
|
||||
func (m *MessageType) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_MessageType.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_MessageType proto.InternalMessageInfo
|
||||
|
||||
func (m *MessageType) GetType() uint32 {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Rectangle struct {
|
||||
X uint32 `protobuf:"varint,1,opt,name=X,json=x,proto3" json:"X,omitempty"`
|
||||
Y uint32 `protobuf:"varint,2,opt,name=Y,json=y,proto3" json:"Y,omitempty"`
|
||||
@ -407,7 +446,7 @@ func (m *Rectangle) Reset() { *m = Rectangle{} }
|
||||
func (m *Rectangle) String() string { return proto.CompactTextString(m) }
|
||||
func (*Rectangle) ProtoMessage() {}
|
||||
func (*Rectangle) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ca53982754088a9d, []int{5}
|
||||
return fileDescriptor_ca53982754088a9d, []int{6}
|
||||
}
|
||||
|
||||
func (m *Rectangle) XXX_Unmarshal(b []byte) error {
|
||||
@ -482,7 +521,7 @@ func (m *FramebufferUpdate) Reset() { *m = FramebufferUpdate{} }
|
||||
func (m *FramebufferUpdate) String() string { return proto.CompactTextString(m) }
|
||||
func (*FramebufferUpdate) ProtoMessage() {}
|
||||
func (*FramebufferUpdate) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ca53982754088a9d, []int{6}
|
||||
return fileDescriptor_ca53982754088a9d, []int{7}
|
||||
}
|
||||
|
||||
func (m *FramebufferUpdate) XXX_Unmarshal(b []byte) error {
|
||||
@ -532,7 +571,7 @@ func (m *Demonstration) Reset() { *m = Demonstration{} }
|
||||
func (m *Demonstration) String() string { return proto.CompactTextString(m) }
|
||||
func (*Demonstration) ProtoMessage() {}
|
||||
func (*Demonstration) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ca53982754088a9d, []int{7}
|
||||
return fileDescriptor_ca53982754088a9d, []int{8}
|
||||
}
|
||||
|
||||
func (m *Demonstration) XXX_Unmarshal(b []byte) error {
|
||||
@ -594,6 +633,7 @@ func init() {
|
||||
proto.RegisterType((*KeyEvent)(nil), "proto.KeyEvent")
|
||||
proto.RegisterType((*FbsSegment)(nil), "proto.FbsSegment")
|
||||
proto.RegisterType((*PixelFormat)(nil), "proto.PixelFormat")
|
||||
proto.RegisterType((*MessageType)(nil), "proto.MessageType")
|
||||
proto.RegisterType((*Rectangle)(nil), "proto.Rectangle")
|
||||
proto.RegisterType((*FramebufferUpdate)(nil), "proto.FramebufferUpdate")
|
||||
proto.RegisterType((*Demonstration)(nil), "proto.Demonstration")
|
||||
@ -602,47 +642,49 @@ func init() {
|
||||
func init() { proto.RegisterFile("demo.proto", fileDescriptor_ca53982754088a9d) }
|
||||
|
||||
var fileDescriptor_ca53982754088a9d = []byte{
|
||||
// 669 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0xcb, 0x6a, 0xdb, 0x40,
|
||||
0x14, 0x45, 0x96, 0x5f, 0xba, 0x8a, 0xdb, 0x64, 0x1a, 0x82, 0x28, 0xa5, 0x18, 0xaf, 0xbc, 0x49,
|
||||
0x28, 0x69, 0x29, 0x74, 0x57, 0x5c, 0xc7, 0x4d, 0x09, 0x09, 0x66, 0x9c, 0xbe, 0xa0, 0x1b, 0xc9,
|
||||
0xba, 0x92, 0x85, 0xad, 0x91, 0x98, 0x19, 0x27, 0xf1, 0xa2, 0x3f, 0x50, 0xe8, 0x07, 0xf4, 0x6f,
|
||||
0xcb, 0x3c, 0x24, 0xdb, 0xe9, 0xa2, 0x2b, 0x71, 0xee, 0x99, 0x7b, 0x38, 0xf7, 0x25, 0x80, 0x18,
|
||||
0xf3, 0xe2, 0xac, 0xe4, 0x85, 0x2c, 0x48, 0x4b, 0x7f, 0x06, 0xbf, 0x1b, 0xd0, 0xf9, 0xc4, 0x32,
|
||||
0x79, 0x2d, 0x52, 0xf2, 0x02, 0x3c, 0x9a, 0x44, 0x97, 0x18, 0xc6, 0xc8, 0x03, 0xa7, 0xef, 0x0c,
|
||||
0x3d, 0xea, 0xf1, 0x2a, 0x40, 0x5e, 0x02, 0xd0, 0x24, 0xfa, 0x82, 0x5c, 0x64, 0x05, 0x0b, 0x1a,
|
||||
0x9a, 0x06, 0x5e, 0x47, 0xc8, 0x73, 0xe8, 0x4e, 0x46, 0x97, 0x98, 0xa5, 0x0b, 0x19, 0xb8, 0x7d,
|
||||
0x67, 0xd8, 0xa3, 0xdd, 0xc4, 0x62, 0x12, 0x40, 0x67, 0x32, 0xfa, 0x9a, 0xc5, 0x72, 0x11, 0x34,
|
||||
0x35, 0xd5, 0x49, 0x0c, 0x54, 0xcc, 0x0c, 0xe7, 0xb7, 0x9b, 0x12, 0x83, 0x96, 0x61, 0x84, 0x81,
|
||||
0xca, 0xcd, 0x4c, 0x86, 0x5c, 0xde, 0x66, 0x39, 0x06, 0x6d, 0xcd, 0x79, 0xa2, 0x0a, 0x90, 0x3e,
|
||||
0xf8, 0x63, 0x14, 0x4b, 0x59, 0x94, 0x37, 0x61, 0x8e, 0x41, 0x47, 0xdb, 0xf1, 0xe3, 0x6d, 0x88,
|
||||
0xbc, 0x01, 0x7f, 0x9a, 0x3d, 0xe0, 0x6a, 0x52, 0xf0, 0x3c, 0x94, 0x41, 0xb7, 0xef, 0x0c, 0xfd,
|
||||
0x73, 0x62, 0xaa, 0x3f, 0xdb, 0x61, 0xa8, 0x5f, 0x6e, 0xc1, 0xe0, 0x07, 0x1c, 0x4c, 0x8b, 0x8c,
|
||||
0x49, 0xe4, 0x17, 0x77, 0xc8, 0x24, 0x21, 0xd0, 0xbc, 0x0e, 0xc5, 0x52, 0xb7, 0xa3, 0x47, 0x9b,
|
||||
0x79, 0x28, 0x96, 0xe4, 0x00, 0x9c, 0x6f, 0xba, 0x01, 0x3d, 0xea, 0x3c, 0x28, 0xf4, 0xdd, 0x16,
|
||||
0xec, 0x6c, 0x94, 0x6b, 0x99, 0xe5, 0x28, 0x64, 0x98, 0x97, 0xb6, 0xd6, 0x6d, 0x60, 0x70, 0x03,
|
||||
0xdd, 0x2b, 0xdc, 0xd4, 0xca, 0xe3, 0xe2, 0x9e, 0x55, 0xca, 0x71, 0x71, 0xcf, 0xc8, 0x21, 0xb8,
|
||||
0x57, 0xb8, 0xb1, 0xda, 0xee, 0x12, 0x1f, 0xe9, 0xb9, 0x8f, 0xf5, 0xde, 0x03, 0x4c, 0x22, 0x31,
|
||||
0xc3, 0x34, 0x57, 0x8a, 0xc7, 0xd0, 0x8a, 0x36, 0x12, 0x85, 0x96, 0x3c, 0xa0, 0x06, 0xec, 0x2b,
|
||||
0x34, 0x1e, 0x2b, 0xfc, 0x69, 0xec, 0xb5, 0x49, 0x39, 0x18, 0x4d, 0xa7, 0xd6, 0x94, 0x1b, 0x4d,
|
||||
0xa7, 0x4a, 0x75, 0x8c, 0xa5, 0x5c, 0xd8, 0xdc, 0x56, 0xac, 0x80, 0x52, 0x1d, 0x65, 0xe9, 0x05,
|
||||
0x8b, 0xb3, 0x90, 0x55, 0xbe, 0xa2, 0x2a, 0xa0, 0xd8, 0x5b, 0xbe, 0xc6, 0x0f, 0xc5, 0xaa, 0xe0,
|
||||
0x75, 0x17, 0xaa, 0x00, 0x39, 0x81, 0x36, 0xc5, 0xf8, 0x3a, 0x7c, 0xb0, 0x23, 0x6f, 0x73, 0x8d,
|
||||
0xd4, 0x06, 0x7d, 0xe4, 0x88, 0x4c, 0x31, 0x66, 0xe0, 0xdd, 0xd4, 0x62, 0xb5, 0x27, 0xa3, 0xd5,
|
||||
0x1a, 0x15, 0xd5, 0x31, 0x7b, 0x12, 0x19, 0xa8, 0xb2, 0x28, 0xc6, 0xb3, 0x45, 0x96, 0x98, 0x21,
|
||||
0xf7, 0x68, 0x97, 0x5b, 0xac, 0x76, 0x56, 0x2b, 0x1a, 0xd6, 0xd3, 0x2c, 0xa4, 0x75, 0x44, 0x57,
|
||||
0xb1, 0x5a, 0xa3, 0xa1, 0xc1, 0x56, 0x51, 0x05, 0x06, 0x3f, 0xc1, 0xa3, 0x38, 0x97, 0x21, 0x4b,
|
||||
0x57, 0x68, 0x86, 0xee, 0xec, 0x0d, 0xbd, 0x51, 0x0d, 0xfd, 0x18, 0x5a, 0x66, 0xb9, 0x4d, 0x23,
|
||||
0x5a, 0xf7, 0x7a, 0xb5, 0x4f, 0xa0, 0x6d, 0xcf, 0xc1, 0x74, 0xa0, 0xbd, 0x30, 0xc7, 0x70, 0x08,
|
||||
0xee, 0x05, 0x9b, 0xdb, 0xda, 0x5d, 0x64, 0x73, 0x95, 0x3f, 0xd2, 0x83, 0x6b, 0xef, 0x0c, 0x6e,
|
||||
0x30, 0x87, 0xa3, 0x09, 0x0f, 0x73, 0x8c, 0xd6, 0x49, 0x82, 0xfc, 0x73, 0x19, 0x87, 0x12, 0xc9,
|
||||
0x2b, 0x00, 0x5e, 0x79, 0x52, 0x83, 0x76, 0x87, 0xfe, 0xf9, 0xa1, 0x5d, 0xea, 0xda, 0x2c, 0xdd,
|
||||
0x79, 0xf3, 0x9f, 0xf9, 0xff, 0x6a, 0x40, 0x6f, 0x8c, 0x79, 0xc1, 0x84, 0xe4, 0xa1, 0x54, 0x77,
|
||||
0x3c, 0x84, 0x4e, 0xc6, 0x32, 0x99, 0x8b, 0x54, 0x97, 0xeb, 0x9f, 0x3f, 0xb1, 0xf2, 0xf6, 0x37,
|
||||
0x41, 0x2b, 0x9a, 0xbc, 0x05, 0x2f, 0x89, 0xd6, 0xda, 0x97, 0x08, 0x1a, 0xda, 0x4a, 0x60, 0xdf,
|
||||
0xfe, 0x63, 0x9c, 0x6e, 0x9f, 0x92, 0x53, 0xe8, 0x0a, 0xb3, 0xb2, 0x22, 0x70, 0x75, 0xda, 0x51,
|
||||
0x95, 0x56, 0x2f, 0x33, 0xad, 0x9f, 0x90, 0x77, 0xd0, 0x2b, 0xcd, 0x49, 0xe2, 0x9d, 0xce, 0x69,
|
||||
0xea, 0x9c, 0x67, 0xd5, 0x29, 0xef, 0x9c, 0x2b, 0xdd, 0x7f, 0x49, 0x4e, 0xc1, 0x5b, 0xe2, 0xc6,
|
||||
0xa6, 0xb5, 0x74, 0xda, 0x53, 0x9b, 0x56, 0xdd, 0x21, 0xdd, 0xbe, 0x88, 0xda, 0x9a, 0x7a, 0xfd,
|
||||
0x37, 0x00, 0x00, 0xff, 0xff, 0xb0, 0x19, 0x99, 0xbe, 0x28, 0x05, 0x00, 0x00,
|
||||
// 692 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0x5d, 0x6b, 0xdb, 0x4a,
|
||||
0x10, 0x45, 0x96, 0xbf, 0x34, 0x8a, 0xef, 0x4d, 0xf6, 0x86, 0x20, 0x2e, 0x97, 0x8b, 0xeb, 0x27,
|
||||
0xbf, 0x24, 0x94, 0xb4, 0x14, 0xfa, 0x56, 0x5c, 0xc7, 0x4d, 0x09, 0x0e, 0x66, 0x9d, 0x7e, 0x41,
|
||||
0x5f, 0x24, 0x6b, 0x24, 0x0b, 0x5b, 0x2b, 0xb1, 0xbb, 0x4e, 0xe2, 0x87, 0xfe, 0x81, 0x42, 0x7f,
|
||||
0x40, 0xff, 0x6d, 0xd9, 0x0f, 0xc9, 0x76, 0xfa, 0xd0, 0x27, 0x7b, 0xe6, 0xec, 0x1c, 0xce, 0xcc,
|
||||
0x9c, 0x11, 0x40, 0x8c, 0x79, 0x71, 0x51, 0xf2, 0x42, 0x16, 0xa4, 0xa5, 0x7f, 0x06, 0x3f, 0x1a,
|
||||
0xd0, 0x79, 0xcf, 0x32, 0x39, 0x15, 0x29, 0xf9, 0x0f, 0x3c, 0x9a, 0x44, 0xd7, 0x18, 0xc6, 0xc8,
|
||||
0x03, 0xa7, 0xef, 0x0c, 0x3d, 0xea, 0xf1, 0x2a, 0x41, 0xfe, 0x07, 0xa0, 0x49, 0xf4, 0x11, 0xb9,
|
||||
0xc8, 0x0a, 0x16, 0x34, 0x34, 0x0c, 0xbc, 0xce, 0x90, 0x7f, 0xa1, 0x3b, 0x19, 0x5d, 0x63, 0x96,
|
||||
0x2e, 0x65, 0xe0, 0xf6, 0x9d, 0x61, 0x8f, 0x76, 0x13, 0x1b, 0x93, 0x00, 0x3a, 0x93, 0xd1, 0xa7,
|
||||
0x2c, 0x96, 0xcb, 0xa0, 0xa9, 0xa1, 0x4e, 0x62, 0x42, 0x85, 0xcc, 0x71, 0x71, 0xb7, 0x2d, 0x31,
|
||||
0x68, 0x19, 0x44, 0x98, 0x50, 0xa9, 0x99, 0xcb, 0x90, 0xcb, 0xbb, 0x2c, 0xc7, 0xa0, 0xad, 0x31,
|
||||
0x4f, 0x54, 0x09, 0xd2, 0x07, 0x7f, 0x8c, 0x62, 0x25, 0x8b, 0xf2, 0x36, 0xcc, 0x31, 0xe8, 0x68,
|
||||
0x39, 0x7e, 0xbc, 0x4b, 0x91, 0x97, 0xe0, 0xcf, 0xb2, 0x47, 0x5c, 0x4f, 0x0a, 0x9e, 0x87, 0x32,
|
||||
0xe8, 0xf6, 0x9d, 0xa1, 0x7f, 0x49, 0x4c, 0xf7, 0x17, 0x7b, 0x08, 0xf5, 0xcb, 0x5d, 0x30, 0xf8,
|
||||
0x0a, 0x47, 0xb3, 0x22, 0x63, 0x12, 0xf9, 0xd5, 0x3d, 0x32, 0x49, 0x08, 0x34, 0xa7, 0xa1, 0x58,
|
||||
0xe9, 0x71, 0xf4, 0x68, 0x33, 0x0f, 0xc5, 0x8a, 0x1c, 0x81, 0xf3, 0x59, 0x0f, 0xa0, 0x47, 0x9d,
|
||||
0x47, 0x15, 0x7d, 0xb1, 0x0d, 0x3b, 0x5b, 0xa5, 0x5a, 0x66, 0x39, 0x0a, 0x19, 0xe6, 0xa5, 0xed,
|
||||
0x75, 0x97, 0x18, 0xdc, 0x42, 0xf7, 0x06, 0xb7, 0x35, 0xf3, 0xb8, 0x78, 0x60, 0x15, 0x73, 0x5c,
|
||||
0x3c, 0x30, 0x72, 0x0c, 0xee, 0x0d, 0x6e, 0x2d, 0xb7, 0xbb, 0xc2, 0x27, 0x7c, 0xee, 0x53, 0xbe,
|
||||
0x37, 0x00, 0x93, 0x48, 0xcc, 0x31, 0xcd, 0x15, 0xe3, 0x29, 0xb4, 0xa2, 0xad, 0x44, 0xa1, 0x29,
|
||||
0x8f, 0xa8, 0x09, 0x0e, 0x19, 0x1a, 0x4f, 0x19, 0x7e, 0x36, 0x0e, 0xc6, 0xa4, 0x14, 0x8c, 0x66,
|
||||
0x33, 0x2b, 0xca, 0x8d, 0x66, 0x33, 0xc5, 0x3a, 0xc6, 0x52, 0x2e, 0x6d, 0x6d, 0x2b, 0x56, 0x81,
|
||||
0x62, 0x1d, 0x65, 0xe9, 0x15, 0x8b, 0xb3, 0x90, 0x55, 0xba, 0xa2, 0x2a, 0xa1, 0xd0, 0x3b, 0xbe,
|
||||
0xc1, 0xb7, 0xc5, 0xba, 0xe0, 0xf5, 0x14, 0xaa, 0x04, 0x39, 0x83, 0x36, 0xc5, 0x78, 0x1a, 0x3e,
|
||||
0xda, 0x95, 0xb7, 0xb9, 0x8e, 0x94, 0x83, 0xde, 0x71, 0x44, 0xa6, 0x10, 0xb3, 0xf0, 0x6e, 0x6a,
|
||||
0x63, 0xe5, 0x93, 0xd1, 0x7a, 0x83, 0x0a, 0xea, 0x18, 0x9f, 0x44, 0x26, 0x54, 0x55, 0x14, 0xe3,
|
||||
0xf9, 0x32, 0x4b, 0xcc, 0x92, 0x7b, 0xb4, 0xcb, 0x6d, 0xac, 0x3c, 0xab, 0x19, 0x0d, 0xea, 0x69,
|
||||
0x14, 0xd2, 0x3a, 0xa3, 0xbb, 0x58, 0x6f, 0xd0, 0xc0, 0x60, 0xbb, 0xa8, 0x12, 0x83, 0x67, 0xe0,
|
||||
0x4f, 0x51, 0x88, 0x30, 0x45, 0x6d, 0x48, 0x02, 0x4d, 0xa9, 0x7c, 0x6a, 0x17, 0xa6, 0xfe, 0x0f,
|
||||
0xbe, 0x81, 0x47, 0x71, 0x21, 0x43, 0x96, 0xae, 0xd1, 0xf8, 0xc2, 0x39, 0xf0, 0x45, 0xa3, 0xf2,
|
||||
0xc5, 0x29, 0xb4, 0x8c, 0xff, 0xcd, 0xac, 0x5a, 0x0f, 0xda, 0xfd, 0x67, 0xd0, 0xb6, 0x17, 0x63,
|
||||
0x86, 0xd4, 0x5e, 0x9a, 0x7b, 0x39, 0x06, 0xf7, 0x8a, 0x2d, 0xec, 0x78, 0x5c, 0x64, 0x0b, 0x55,
|
||||
0x3f, 0xd2, 0xbb, 0x6d, 0xef, 0xed, 0x76, 0xb0, 0x80, 0x93, 0x09, 0x0f, 0x73, 0x8c, 0x36, 0x49,
|
||||
0x82, 0xfc, 0x43, 0x19, 0x87, 0x12, 0xc9, 0x73, 0x00, 0x5e, 0x69, 0x52, 0x5e, 0x70, 0x87, 0xfe,
|
||||
0xe5, 0xb1, 0xf5, 0x7d, 0x2d, 0x96, 0xee, 0xbd, 0xf9, 0x83, 0x45, 0xbe, 0x37, 0xa0, 0x37, 0xc6,
|
||||
0xbc, 0x60, 0x42, 0xf2, 0x50, 0xaa, 0x53, 0x1f, 0x42, 0x27, 0x63, 0x99, 0xcc, 0x45, 0xaa, 0xdb,
|
||||
0xf5, 0x2f, 0xff, 0xb2, 0xf4, 0xf6, 0x4b, 0x42, 0x2b, 0x98, 0xbc, 0x02, 0x2f, 0x89, 0x36, 0x5a,
|
||||
0x97, 0x08, 0x1a, 0x5a, 0x4a, 0x60, 0xdf, 0xfe, 0x26, 0x9c, 0xee, 0x9e, 0x92, 0x73, 0xe8, 0x0a,
|
||||
0xe3, 0x6a, 0x11, 0xb8, 0xba, 0xec, 0xa4, 0x2a, 0xab, 0xfd, 0x4e, 0xeb, 0x27, 0xe4, 0x35, 0xf4,
|
||||
0x4a, 0x73, 0xb5, 0x78, 0xaf, 0x6b, 0x9a, 0xba, 0xe6, 0x9f, 0xea, 0xda, 0xf7, 0x2e, 0x9a, 0x1e,
|
||||
0xbe, 0x24, 0xe7, 0xe0, 0xad, 0x70, 0x6b, 0xcb, 0x5a, 0xba, 0xec, 0x6f, 0x5b, 0x56, 0x9d, 0x2a,
|
||||
0xdd, 0xbd, 0x88, 0xda, 0x1a, 0x7a, 0xf1, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x8a, 0x74, 0x30,
|
||||
0x4b, 0x05, 0x00, 0x00,
|
||||
}
|
||||
|
@ -44,6 +44,10 @@ message PixelFormat{
|
||||
uint32 BlueShift = 10;
|
||||
}
|
||||
|
||||
message MessageType{
|
||||
uint32 type = 1;
|
||||
}
|
||||
|
||||
message Rectangle {
|
||||
uint32 X = 1;
|
||||
uint32 Y = 2;
|
||||
|
@ -3,11 +3,12 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/matttproud/golang_protobuf_extensions/pbutil"
|
||||
"github.com/sibeshkar/vncproxy/logger"
|
||||
pb "github.com/sibeshkar/vncproxy/proto"
|
||||
)
|
||||
|
||||
@ -18,18 +19,64 @@ func main() {
|
||||
}
|
||||
fname := os.Args[1]
|
||||
|
||||
// [START unmarshal_proto]
|
||||
// Read the existing address book.
|
||||
in, err := ioutil.ReadFile(fname)
|
||||
reader, err := os.OpenFile(fname, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatalln("Error reading file:", err)
|
||||
}
|
||||
demonstration := &pb.Demonstration{}
|
||||
if err := proto.Unmarshal(in, demonstration); err != nil {
|
||||
log.Fatalln("Failed to parse demonstration file:", err)
|
||||
logger.Errorf("unable to open file: %s, error: %v", fname, err)
|
||||
|
||||
}
|
||||
|
||||
listPeople(os.Stdout, demonstration)
|
||||
// [START unmarshal_proto]
|
||||
// Read the existing address book.
|
||||
// in, err := ioutil.ReadFile(fname)
|
||||
// if err != nil {
|
||||
// log.Fatalln("Error reading file:", err)
|
||||
// }
|
||||
// demonstration := &pb.Demonstration{}
|
||||
// if err := proto.Unmarshal(in, demonstration); err != nil {
|
||||
// log.Fatalln("Failed to parse demonstration file:", err)
|
||||
// }
|
||||
|
||||
// pf := &pb.PixelFormat{}
|
||||
// pbutil.ReadDelimited(reader, pf)
|
||||
|
||||
// fmt.Println(pf)
|
||||
|
||||
initMsg := &pb.InitMsg{}
|
||||
pbutil.ReadDelimited(reader, initMsg)
|
||||
|
||||
fmt.Printf("FBHeight: %v \n", initMsg.GetFBHeight())
|
||||
fmt.Printf("FBWidth: %v \n", initMsg.GetFBWidth())
|
||||
fmt.Printf("RfbHeader: %v \n", initMsg.GetRfbHeader())
|
||||
fmt.Printf("RfbVersion: %v \n", initMsg.GetRfbVersion())
|
||||
fmt.Printf("SecType: %v \n", initMsg.GetSecType())
|
||||
fmt.Printf("StartTime: %v \n", initMsg.GetStartTime())
|
||||
fmt.Printf("DesktopName: %v \n", initMsg.GetDesktopName())
|
||||
fmt.Printf("PixelFormat: %v \n", initMsg.GetPixelFormat())
|
||||
|
||||
i := 0
|
||||
|
||||
for {
|
||||
|
||||
// msgType := &pb.MessageType{}
|
||||
// pbutil.ReadDelimited(reader, msgType)
|
||||
// if msgType.GetType() == uint32(4) {
|
||||
// keyEvent := &pb.KeyEvent{}
|
||||
// pbutil.ReadDelimited(reader, keyEvent)
|
||||
// fmt.Printf("Key event is %v", keyEvent)
|
||||
|
||||
// } else if msgType.GetType() == uint32(5) {
|
||||
// pointerEvent := &pb.PointerEvent{}
|
||||
// pbutil.ReadDelimited(reader, pointerEvent)
|
||||
// fmt.Println("Pointer event is ", pointerEvent)
|
||||
|
||||
// }
|
||||
fbupdate := &pb.FramebufferUpdate{}
|
||||
pbutil.ReadDelimited(reader, fbupdate)
|
||||
writeFbupdate(fbupdate, &i)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
//listPeople(os.Stdout, demonstration)
|
||||
|
||||
}
|
||||
|
||||
@ -55,13 +102,13 @@ func listPeople(w io.Writer, demo *pb.Demonstration) {
|
||||
// writePointerEvent(w, p)
|
||||
// }
|
||||
|
||||
i := 0
|
||||
// i := 0
|
||||
|
||||
for _, p := range demo.Fbupdates {
|
||||
writeFbupdate(w, p, &i)
|
||||
}
|
||||
// for _, p := range demo.Fbupdates {
|
||||
// writeFbupdate(w, p, &i)
|
||||
// }
|
||||
|
||||
fmt.Println(i)
|
||||
// fmt.Println(i)
|
||||
|
||||
}
|
||||
|
||||
@ -70,7 +117,7 @@ func writeSegment(w io.Writer, p *pb.FbsSegment) {
|
||||
|
||||
}
|
||||
|
||||
func writeFbupdate(w io.Writer, p *pb.FramebufferUpdate, i *int) {
|
||||
func writeFbupdate(p *pb.FramebufferUpdate, i *int) {
|
||||
|
||||
*i++
|
||||
fmt.Printf("----------FRAMEBUFFERUPDATE NUMBER %v -------------- \n", *i)
|
||||
|
224
vnc_rec/custom-client-recorder.go
Normal file
224
vnc_rec/custom-client-recorder.go
Normal file
@ -0,0 +1,224 @@
|
||||
package vnc_rec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
|
||||
"github.com/amitbet/vncproxy/common"
|
||||
"github.com/amitbet/vncproxy/logger"
|
||||
"github.com/amitbet/vncproxy/server"
|
||||
"github.com/matttproud/golang_protobuf_extensions/pbutil"
|
||||
pb "github.com/sibeshkar/vncproxy/proto"
|
||||
)
|
||||
|
||||
type CustomClientRecorder struct {
|
||||
//common.BytesListener
|
||||
RBSFileName string
|
||||
writer *os.File
|
||||
//logger common.Logger
|
||||
Rectbuffer bytes.Buffer
|
||||
FramebufferUpdate *pb.FramebufferUpdate
|
||||
Rect *pb.Rectangle
|
||||
startTime int
|
||||
buffer bytes.Buffer
|
||||
serverInitMessage *common.ServerInit
|
||||
sessionStartWritten bool
|
||||
segmentChan chan *common.RfbSegment
|
||||
maxWriteSize int
|
||||
}
|
||||
|
||||
func NewCustomClientRecorder(saveFilePath string) (*CustomClientRecorder, error) {
|
||||
//delete file if it exists
|
||||
if _, err := os.Stat(saveFilePath); err == nil {
|
||||
os.Remove(saveFilePath)
|
||||
}
|
||||
|
||||
rec := CustomClientRecorder{RBSFileName: saveFilePath, startTime: getNowMillisec()}
|
||||
var err error
|
||||
|
||||
rec.maxWriteSize = 65535
|
||||
|
||||
rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0644)
|
||||
// if err != nil {
|
||||
// logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err)
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
//buffer the channel so we don't halt the proxying flow for slow writes when under pressure
|
||||
rec.segmentChan = make(chan *common.RfbSegment, 100)
|
||||
go func() {
|
||||
for {
|
||||
data := <-rec.segmentChan
|
||||
rec.HandleRfbSegment(data)
|
||||
}
|
||||
}()
|
||||
|
||||
return &rec, nil
|
||||
}
|
||||
|
||||
func (r *CustomClientRecorder) writeStartSession(initMsg *common.ServerInit) error {
|
||||
r.sessionStartWritten = true
|
||||
desktopName := string(initMsg.NameText)
|
||||
framebufferWidth := initMsg.FBWidth
|
||||
framebufferHeight := initMsg.FBHeight
|
||||
// //write rfb header information (the only part done without the [size|data|timestamp] block wrapper)
|
||||
// r.writer.WriteString("FBS 001.000\n")
|
||||
// r.demonstration.Initmsg.
|
||||
|
||||
// //push the version message into the buffer so it will be written in the first rbs block
|
||||
// r.buffer.WriteString(versionMsg_3_3)
|
||||
|
||||
// //push sec type and fb dimensions
|
||||
// binary.Write(&r.buffer, binary.BigEndian, int32(SecTypeNone))
|
||||
// binary.Write(&r.buffer, binary.BigEndian, int16(framebufferWidth))
|
||||
// binary.Write(&r.buffer, binary.BigEndian, int16(framebufferHeight))
|
||||
|
||||
// buff := bytes.Buffer{}
|
||||
// //binary.Write(&buff, binary.BigEndian, initMsg.FBWidth)
|
||||
// //binary.Write(&buff, binary.BigEndian, initMsg.FBHeight)
|
||||
// binary.Write(&buff, binary.BigEndian, initMsg.PixelFormat)
|
||||
// buff.Write([]byte{0, 0, 0}) //padding
|
||||
// r.buffer.Write(buff.Bytes())
|
||||
// //logger.Debugf(">>>>>>buffer for initMessage:%v ", buff.Bytes())
|
||||
|
||||
// //var fbsServerInitMsg = []byte{32, 24, 0, 1, 0, byte(0xFF), 0, byte(0xFF), 0, byte(0xFF), 16, 8, 0, 0, 0, 0}
|
||||
// //r.buffer.Write(fbsServerInitMsg)
|
||||
|
||||
// binary.Write(&r.buffer, binary.BigEndian, uint32(len(desktopName)))
|
||||
|
||||
// r.buffer.WriteString(desktopName)
|
||||
|
||||
pixel_format := &pb.PixelFormat{
|
||||
BPP: uint32(initMsg.PixelFormat.BPP),
|
||||
Depth: uint32(initMsg.PixelFormat.Depth),
|
||||
BigEndian: uint32(initMsg.PixelFormat.BigEndian),
|
||||
TrueColor: uint32(initMsg.PixelFormat.TrueColor),
|
||||
RedMax: uint32(initMsg.PixelFormat.RedMax),
|
||||
GreenMax: uint32(initMsg.PixelFormat.GreenMax),
|
||||
BlueMax: uint32(initMsg.PixelFormat.BlueMax),
|
||||
RedShift: uint32(initMsg.PixelFormat.RedShift),
|
||||
GreenShift: uint32(initMsg.PixelFormat.GreenShift),
|
||||
BlueShift: uint32(initMsg.PixelFormat.BlueShift),
|
||||
}
|
||||
|
||||
initMsgProto := &pb.InitMsg{
|
||||
RfbHeader: "FBS 001.000",
|
||||
RfbVersion: versionMsg_3_3,
|
||||
FBHeight: uint32(framebufferHeight),
|
||||
FBWidth: uint32(framebufferWidth),
|
||||
SecType: uint32(SecTypeNone),
|
||||
StartTime: uint32(r.startTime),
|
||||
DesktopName: desktopName,
|
||||
PixelFormat: pixel_format,
|
||||
}
|
||||
|
||||
pbutil.WriteDelimited(r.writer, initMsgProto)
|
||||
//binary.Write(&r.buffer, binary.BigEndian, byte(0)) // add null termination for desktop string
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CustomClientRecorder) Consume(data *common.RfbSegment) error {
|
||||
//using async writes so if chan buffer overflows, proxy will not be affected
|
||||
select {
|
||||
case r.segmentChan <- data:
|
||||
// default:
|
||||
// logger.Error("error: CustomClientRecorder queue is full")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CustomClientRecorder) HandleRfbSegment(data *common.RfbSegment) error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
logger.Error("Recovered in HandleRfbSegment: ", r)
|
||||
}
|
||||
}()
|
||||
|
||||
timeSinceStart := uint32(getNowMillisec() - r.startTime)
|
||||
|
||||
switch data.SegmentType {
|
||||
case common.SegmentMessageStart:
|
||||
if !r.sessionStartWritten {
|
||||
logger.Debugf("CustomClientRecorder.HandleRfbSegment: writing start session segment: %v", r.serverInitMessage)
|
||||
r.writeStartSession(r.serverInitMessage)
|
||||
}
|
||||
|
||||
switch common.ServerMessageType(data.UpcomingObjectType) {
|
||||
case common.FramebufferUpdate:
|
||||
logger.Debugf("CustomClientRecorder.HandleRfbSegment: saving FramebufferUpdate segment")
|
||||
|
||||
case common.SetColourMapEntries:
|
||||
case common.Bell:
|
||||
case common.ServerCutText:
|
||||
default:
|
||||
logger.Warn("CustomClientRecorder.HandleRfbSegment: unknown message type:" + string(data.UpcomingObjectType))
|
||||
}
|
||||
case common.SegmentConnectionClosed:
|
||||
logger.Debugf("CustomClientRecorder.HandleRfbSegment: connection closed")
|
||||
case common.SegmentRectSeparator:
|
||||
logger.Debugf("CustomClientRecorder.HandleRfbSegment: writing rect")
|
||||
//r.Rect.Reset()
|
||||
//r.writeToDisk()
|
||||
case common.SegmentBytes:
|
||||
logger.Debug("CustomClientRecorder.HandleRfbSegment: writing bytes, len:", len(data.Bytes))
|
||||
// if r.buffer.Len()+len(data.Bytes) > r.maxWriteSize-4 {
|
||||
// r.writeToDisk()
|
||||
// }
|
||||
case common.SegmentServerInitMessage:
|
||||
r.serverInitMessage = data.Message.(*common.ServerInit)
|
||||
case common.SegmentFullyParsedClientMessage:
|
||||
clientMsg := data.Message.(common.ClientMessage)
|
||||
|
||||
switch clientMsg.Type() {
|
||||
case common.SetPixelFormatMsgType:
|
||||
clientMsg := data.Message.(*server.MsgSetPixelFormat)
|
||||
logger.Debugf("ClientRecorder.HandleRfbSegment: client message %v", *clientMsg)
|
||||
r.serverInitMessage.PixelFormat = clientMsg.PF
|
||||
case common.KeyEventMsgType:
|
||||
clientMsg := data.Message.(*server.MsgKeyEvent)
|
||||
//clientMsg.Write(r.writer)
|
||||
keyevent := &pb.KeyEvent{
|
||||
Down: uint32(clientMsg.Down),
|
||||
Key: uint32(clientMsg.Key),
|
||||
Timestamp: timeSinceStart,
|
||||
}
|
||||
logger.Debug("CustomClientRecorder.HandleRfbSegment: writing bytes for KeyEventMsgType, len:", *keyevent)
|
||||
|
||||
pbutil.WriteDelimited(r.writer, &pb.MessageType{Type: uint32(4)})
|
||||
pbutil.WriteDelimited(r.writer, keyevent)
|
||||
//r.demonstration.Keyevents = append(r.demonstration.Keyevents, keyevent)
|
||||
case common.PointerEventMsgType:
|
||||
clientMsg := data.Message.(*server.MsgPointerEvent)
|
||||
|
||||
//clientMsg.Write(r.writer)
|
||||
pointerevent := &pb.PointerEvent{
|
||||
Mask: uint32(clientMsg.Mask),
|
||||
X: uint32(clientMsg.X),
|
||||
Y: uint32(clientMsg.Y),
|
||||
Timestamp: timeSinceStart,
|
||||
}
|
||||
logger.Debug("CustomClientRecorder.HandleRfbSegment: writing bytes for PointerEventMsgType, len:", *pointerevent)
|
||||
//r.demonstration.Pointerevents = append(r.demonstration.Pointerevents, pointerevent)
|
||||
pbutil.WriteDelimited(r.writer, &pb.MessageType{Type: uint32(5)})
|
||||
pbutil.WriteDelimited(r.writer, pointerevent)
|
||||
default:
|
||||
//return errors.New("unknown client message type:" + string(data.UpcomingObjectType))
|
||||
}
|
||||
|
||||
default:
|
||||
//return errors.New("undefined RfbSegment type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CustomClientRecorder) Close() {
|
||||
r.writer.Close()
|
||||
}
|
332
vnc_rec/custom-server-recorder.go
Normal file
332
vnc_rec/custom-server-recorder.go
Normal file
@ -0,0 +1,332 @@
|
||||
package vnc_rec
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"os"
|
||||
|
||||
"github.com/amitbet/vncproxy/common"
|
||||
"github.com/amitbet/vncproxy/logger"
|
||||
"github.com/amitbet/vncproxy/server"
|
||||
"github.com/matttproud/golang_protobuf_extensions/pbutil"
|
||||
pb "github.com/sibeshkar/vncproxy/proto"
|
||||
)
|
||||
|
||||
type CustomServerRecorder struct {
|
||||
//common.BytesListener
|
||||
RBSFileName string
|
||||
writer *os.File
|
||||
//logger common.Logger
|
||||
Rectbuffer bytes.Buffer
|
||||
FramebufferUpdate *pb.FramebufferUpdate
|
||||
Rect *pb.Rectangle
|
||||
startTime int
|
||||
buffer bytes.Buffer
|
||||
serverInitMessage *common.ServerInit
|
||||
sessionStartWritten bool
|
||||
segmentChan chan *common.RfbSegment
|
||||
maxWriteSize int
|
||||
}
|
||||
|
||||
func NewCustomServerRecorder(saveFilePath string) (*CustomServerRecorder, error) {
|
||||
//delete file if it exists
|
||||
if _, err := os.Stat(saveFilePath); err == nil {
|
||||
os.Remove(saveFilePath)
|
||||
}
|
||||
|
||||
rec := CustomServerRecorder{RBSFileName: saveFilePath, startTime: getNowMillisec()}
|
||||
var err error
|
||||
|
||||
rec.maxWriteSize = 65535
|
||||
|
||||
rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0644)
|
||||
// if err != nil {
|
||||
// logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err)
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
//buffer the channel so we don't halt the proxying flow for slow writes when under pressure
|
||||
rec.segmentChan = make(chan *common.RfbSegment, 100)
|
||||
go func() {
|
||||
for {
|
||||
data := <-rec.segmentChan
|
||||
rec.HandleRfbSegment(data)
|
||||
}
|
||||
}()
|
||||
|
||||
return &rec, nil
|
||||
}
|
||||
|
||||
func (r *CustomServerRecorder) writeStartSession(initMsg *common.ServerInit) error {
|
||||
r.sessionStartWritten = true
|
||||
desktopName := string(initMsg.NameText)
|
||||
framebufferWidth := initMsg.FBWidth
|
||||
framebufferHeight := initMsg.FBHeight
|
||||
// //write rfb header information (the only part done without the [size|data|timestamp] block wrapper)
|
||||
// r.writer.WriteString("FBS 001.000\n")
|
||||
// r.demonstration.Initmsg.
|
||||
|
||||
// //push the version message into the buffer so it will be written in the first rbs block
|
||||
// r.buffer.WriteString(versionMsg_3_3)
|
||||
|
||||
// //push sec type and fb dimensions
|
||||
// binary.Write(&r.buffer, binary.BigEndian, int32(SecTypeNone))
|
||||
// binary.Write(&r.buffer, binary.BigEndian, int16(framebufferWidth))
|
||||
// binary.Write(&r.buffer, binary.BigEndian, int16(framebufferHeight))
|
||||
|
||||
// buff := bytes.Buffer{}
|
||||
// //binary.Write(&buff, binary.BigEndian, initMsg.FBWidth)
|
||||
// //binary.Write(&buff, binary.BigEndian, initMsg.FBHeight)
|
||||
// binary.Write(&buff, binary.BigEndian, initMsg.PixelFormat)
|
||||
// buff.Write([]byte{0, 0, 0}) //padding
|
||||
// r.buffer.Write(buff.Bytes())
|
||||
// //logger.Debugf(">>>>>>buffer for initMessage:%v ", buff.Bytes())
|
||||
|
||||
// //var fbsServerInitMsg = []byte{32, 24, 0, 1, 0, byte(0xFF), 0, byte(0xFF), 0, byte(0xFF), 16, 8, 0, 0, 0, 0}
|
||||
// //r.buffer.Write(fbsServerInitMsg)
|
||||
|
||||
// binary.Write(&r.buffer, binary.BigEndian, uint32(len(desktopName)))
|
||||
|
||||
// r.buffer.WriteString(desktopName)
|
||||
|
||||
pixel_format := &pb.PixelFormat{
|
||||
BPP: uint32(initMsg.PixelFormat.BPP),
|
||||
Depth: uint32(initMsg.PixelFormat.Depth),
|
||||
BigEndian: uint32(initMsg.PixelFormat.BigEndian),
|
||||
TrueColor: uint32(initMsg.PixelFormat.TrueColor),
|
||||
RedMax: uint32(initMsg.PixelFormat.RedMax),
|
||||
GreenMax: uint32(initMsg.PixelFormat.GreenMax),
|
||||
BlueMax: uint32(initMsg.PixelFormat.BlueMax),
|
||||
RedShift: uint32(initMsg.PixelFormat.RedShift),
|
||||
GreenShift: uint32(initMsg.PixelFormat.GreenShift),
|
||||
BlueShift: uint32(initMsg.PixelFormat.BlueShift),
|
||||
}
|
||||
|
||||
initMsgProto := &pb.InitMsg{
|
||||
RfbHeader: "FBS 001.000",
|
||||
RfbVersion: versionMsg_3_3,
|
||||
FBHeight: uint32(framebufferHeight),
|
||||
FBWidth: uint32(framebufferWidth),
|
||||
SecType: uint32(SecTypeNone),
|
||||
StartTime: uint32(r.startTime),
|
||||
DesktopName: desktopName,
|
||||
PixelFormat: pixel_format,
|
||||
}
|
||||
|
||||
pbutil.WriteDelimited(r.writer, initMsgProto)
|
||||
//binary.Write(&r.buffer, binary.BigEndian, byte(0)) // add null termination for desktop string
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CustomServerRecorder) Consume(data *common.RfbSegment) error {
|
||||
//using async writes so if chan buffer overflows, proxy will not be affected
|
||||
select {
|
||||
case r.segmentChan <- data:
|
||||
// default:
|
||||
// logger.Error("error: CustomServerRecorder queue is full")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *CustomServerRecorder) HandleRfbSegment(data *common.RfbSegment) error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
logger.Error("Recovered in HandleRfbSegment: ", r)
|
||||
}
|
||||
}()
|
||||
|
||||
timeSinceStart := uint32(getNowMillisec() - r.startTime)
|
||||
|
||||
switch data.SegmentType {
|
||||
case common.SegmentMessageStart:
|
||||
if !r.sessionStartWritten {
|
||||
logger.Debugf("CustomServerRecorder.HandleRfbSegment: writing start session segment: %v", r.serverInitMessage)
|
||||
r.writeStartSession(r.serverInitMessage)
|
||||
}
|
||||
|
||||
switch common.ServerMessageType(data.UpcomingObjectType) {
|
||||
case common.FramebufferUpdate:
|
||||
logger.Debugf("CustomServerRecorder.HandleRfbSegment: saving FramebufferUpdate segment")
|
||||
//FBUpdate := data.Message.(*server.FramebufferUpdate)
|
||||
if len(r.FramebufferUpdate.GetRectangles()) != 0 {
|
||||
logger.Debugf("[IMP STUFF] Nil not found, now appending")
|
||||
pbutil.WriteDelimited(r.writer, r.FramebufferUpdate)
|
||||
|
||||
}
|
||||
// logger.Debugf("[IMPORTANT] This FrameBufferUpdate is: %v", data.Bytes)
|
||||
|
||||
// logger.Debugf("The FrameBuffer is: %v", r.FramebufferUpdate)
|
||||
|
||||
//r.FramebufferUpdate.Reset()
|
||||
|
||||
r.FramebufferUpdate = &pb.FramebufferUpdate{
|
||||
Timestamp: timeSinceStart,
|
||||
}
|
||||
|
||||
// FBUpdateProto := &pb.FramebufferUpdate{}
|
||||
|
||||
// for _, rect := range FBUpdate.Rects {
|
||||
|
||||
// RectProto := &pb.Rectangle{
|
||||
// X: uint32(rect.X),
|
||||
// Y: uint32(rect.Y),
|
||||
// Width: uint32(rect.Width),
|
||||
// Height: uint32(rect.Height),
|
||||
// Enc: uint32(rect.Enc.Type()),
|
||||
// }
|
||||
|
||||
// FBUpdateProto.Rectangles = append(FBUpdateProto.Rectangles, RectProto)
|
||||
// }
|
||||
|
||||
// r.demonstration.Fbupdates = append(r.demonstration.Fbupdates, FBUpdateProto)
|
||||
|
||||
//r.writeToDisk()
|
||||
case common.SetColourMapEntries:
|
||||
case common.Bell:
|
||||
case common.ServerCutText:
|
||||
default:
|
||||
logger.Warn("CustomServerRecorder.HandleRfbSegment: unknown message type:" + string(data.UpcomingObjectType))
|
||||
}
|
||||
case common.SegmentConnectionClosed:
|
||||
logger.Debugf("CustomServerRecorder.HandleRfbSegment: connection closed")
|
||||
case common.SegmentRectSeparator:
|
||||
logger.Debugf("CustomServerRecorder.HandleRfbSegment: writing rect")
|
||||
//r.Rect.Reset()
|
||||
//r.writeToDisk()
|
||||
case common.SegmentBytes:
|
||||
logger.Debug("CustomServerRecorder.HandleRfbSegment: writing bytes, len:", len(data.Bytes))
|
||||
// if r.buffer.Len()+len(data.Bytes) > r.maxWriteSize-4 {
|
||||
// r.writeToDisk()
|
||||
// }
|
||||
|
||||
if len(data.Bytes) > 4 {
|
||||
|
||||
idx := r.Rectbuffer.Len() - 16
|
||||
p := make([]byte, idx)
|
||||
r.Rectbuffer.Read(p)
|
||||
main := make([]byte, 16)
|
||||
r.Rectbuffer.Read(main)
|
||||
r.Rect = &pb.Rectangle{
|
||||
X: uint32(binary.BigEndian.Uint16(main[:2])),
|
||||
Y: uint32(binary.BigEndian.Uint16(main[2:4])),
|
||||
Width: uint32(binary.BigEndian.Uint16(main[4:6])),
|
||||
Height: uint32(binary.BigEndian.Uint16(main[6:8])),
|
||||
Enc: binary.BigEndian.Uint32(main[8:12]),
|
||||
Bytes: data.Bytes,
|
||||
}
|
||||
//logger.Debugf("Received Main Pixel Buffer Content %v \n", r.Rect)
|
||||
if r.Rect.GetEnc() <= 300 {
|
||||
r.FramebufferUpdate.Rectangles = append(r.FramebufferUpdate.Rectangles, r.Rect)
|
||||
}
|
||||
|
||||
r.Rectbuffer.Reset()
|
||||
} else if len(data.Bytes) <= 4 {
|
||||
//logger.Debugf("Received Extra Short byte content %v , %v \n", len(data.Bytes), data.Bytes)
|
||||
r.Rectbuffer.Write(data.Bytes)
|
||||
// r.Rectbuffer = append(r.Rectbuffer, data.Bytes...)
|
||||
//logger.Debugf("Rectbuffer currently is, %v", r.Rectbuffer)
|
||||
}
|
||||
|
||||
// segment := &pb.FbsSegment{
|
||||
// Bytes: data.Bytes,
|
||||
// Timestamp: timeSinceStart,
|
||||
// }
|
||||
|
||||
// r.demonstration.Segments = append(r.demonstration.Segments, segment)
|
||||
//_, err := r.buffer.Write(data.Bytes)
|
||||
//return err
|
||||
case common.SegmentServerInitMessage:
|
||||
r.serverInitMessage = data.Message.(*common.ServerInit)
|
||||
case common.SegmentFullyParsedClientMessage:
|
||||
clientMsg := data.Message.(common.ClientMessage)
|
||||
|
||||
switch clientMsg.Type() {
|
||||
case common.SetPixelFormatMsgType:
|
||||
clientMsg := data.Message.(*server.MsgSetPixelFormat)
|
||||
logger.Debugf("ClientRecorder.HandleRfbSegment: client message %v", *clientMsg)
|
||||
r.serverInitMessage.PixelFormat = clientMsg.PF
|
||||
case common.KeyEventMsgType:
|
||||
clientMsg := data.Message.(*server.MsgKeyEvent)
|
||||
//clientMsg.Write(r.writer)
|
||||
keyevent := &pb.KeyEvent{
|
||||
Down: uint32(clientMsg.Down),
|
||||
Key: uint32(clientMsg.Key),
|
||||
Timestamp: timeSinceStart,
|
||||
}
|
||||
logger.Debug("CustomServerRecorder.HandleRfbSegment: writing bytes for KeyEventMsgType, len:", *keyevent)
|
||||
|
||||
//r.demonstration.Keyevents = append(r.demonstration.Keyevents, keyevent)
|
||||
case common.PointerEventMsgType:
|
||||
clientMsg := data.Message.(*server.MsgPointerEvent)
|
||||
|
||||
//clientMsg.Write(r.writer)
|
||||
pointerevent := &pb.PointerEvent{
|
||||
Mask: uint32(clientMsg.Mask),
|
||||
X: uint32(clientMsg.X),
|
||||
Y: uint32(clientMsg.Y),
|
||||
Timestamp: timeSinceStart,
|
||||
}
|
||||
logger.Debug("CustomServerRecorder.HandleRfbSegment: writing bytes for PointerEventMsgType, len:", *pointerevent)
|
||||
//r.demonstration.Pointerevents = append(r.demonstration.Pointerevents, pointerevent)
|
||||
|
||||
default:
|
||||
//return errors.New("unknown client message type:" + string(data.UpcomingObjectType))
|
||||
}
|
||||
|
||||
default:
|
||||
//return errors.New("undefined RfbSegment type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// func (r *CustomServerRecorder) writeToDisk() error {
|
||||
|
||||
// out, err := proto.Marshal(r.demonstration)
|
||||
// if err != nil {
|
||||
// log.Fatalln("Failed to encode address book:", err)
|
||||
// }
|
||||
// if err := ioutil.WriteFile(r.RBSFileName, out, 0644); err != nil {
|
||||
// log.Fatalln("Failed to write address book:", err)
|
||||
// }
|
||||
// // timeSinceStart := getNowMillisec() - r.startTime
|
||||
// // if r.buffer.Len() == 0 {
|
||||
// // return nil
|
||||
// // }
|
||||
|
||||
// // //write buff length
|
||||
// // bytesLen := r.buffer.Len()
|
||||
// // binary.Write(r.writer, binary.BigEndian, uint32(bytesLen))
|
||||
// // paddedSize := (bytesLen + 3) & 0x7FFFFFFC
|
||||
// // paddingSize := paddedSize - bytesLen
|
||||
|
||||
// // //logger.Debugf("paddedSize=%d paddingSize=%d bytesLen=%d", paddedSize, paddingSize, bytesLen)
|
||||
// // //write buffer padded to 32bit
|
||||
// // _, err := r.buffer.WriteTo(r.writer)
|
||||
// // padding := make([]byte, paddingSize)
|
||||
// // //logger.Debugf("padding=%v ", padding)
|
||||
|
||||
// // binary.Write(r.writer, binary.BigEndian, padding)
|
||||
|
||||
// // //write timestamp
|
||||
// // binary.Write(r.writer, binary.BigEndian, uint32(timeSinceStart))
|
||||
// // r.buffer.Reset()
|
||||
// return err
|
||||
// }
|
||||
|
||||
// func (r *CustomServerRecorder) WriteUInt8(data uint8) error {
|
||||
// buf := make([]byte, 1)
|
||||
// buf[0] = byte(data) // cast int8 to byte
|
||||
// return r.Write(buf)
|
||||
// }
|
||||
|
||||
func (r *CustomServerRecorder) Close() {
|
||||
r.writer.Close()
|
||||
}
|
@ -79,43 +79,54 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
|
||||
return err
|
||||
}
|
||||
|
||||
var rec_s *ServerRecorder
|
||||
var rec_c *ClientRecorder
|
||||
//var rec_p *ProtoRecorder
|
||||
// var rec_s *ServerRecorder
|
||||
// var rec_c *ClientRecorder
|
||||
var rec_c *CustomClientRecorder
|
||||
var rec_s *CustomServerRecorder
|
||||
|
||||
if session.Type == SessionTypeRecordingProxy {
|
||||
timeCurrent := strconv.FormatInt(time.Now().Unix(), 10)
|
||||
recFolder := path.Join(vp.RecordingDir, "recording_"+timeCurrent)
|
||||
os.MkdirAll(recFolder, os.ModePerm)
|
||||
recServerFile := "server.rbs"
|
||||
recServerPath := path.Join(recFolder, recServerFile)
|
||||
rec_s, err = NewServerRecorder(recServerPath)
|
||||
// recServerFile := "server.rbs"
|
||||
// recServerPath := path.Join(recFolder, recServerFile)
|
||||
// rec_s, err = NewServerRecorder(recServerPath)
|
||||
// if err != nil {
|
||||
// logger.Errorf("Proxy.newServerConnHandler can't open ServerRecorder save path: %s", recServerPath)
|
||||
// return err
|
||||
// }
|
||||
|
||||
// sconn.Listeners.AddListener(rec_s)
|
||||
|
||||
// recClientFile := "client.rbs"
|
||||
// recClientPath := path.Join(recFolder, recClientFile)
|
||||
// rec_c, err = NewClientRecorder(recClientPath)
|
||||
// if err != nil {
|
||||
// logger.Errorf("Proxy.newServerConnHandler can't open ServerRecorder save path: %s", recClientPath)
|
||||
// return err
|
||||
// }
|
||||
|
||||
// sconn.Listeners.AddListener(rec_c)
|
||||
|
||||
recCustomServerFile := "server.rbs"
|
||||
recCustomServerPath := path.Join(recFolder, recCustomServerFile)
|
||||
rec_s, err = NewCustomServerRecorder(recCustomServerPath)
|
||||
if err != nil {
|
||||
logger.Errorf("Proxy.newServerConnHandler can't open ServerRecorder save path: %s", recServerPath)
|
||||
logger.Errorf("Proxy.newServerConnHandler can't open CustomRecorder save path: %s", recCustomServerPath)
|
||||
return err
|
||||
}
|
||||
|
||||
sconn.Listeners.AddListener(rec_s)
|
||||
|
||||
recClientFile := "client.rbs"
|
||||
recClientPath := path.Join(recFolder, recClientFile)
|
||||
rec_c, err = NewClientRecorder(recClientPath)
|
||||
recCustomClientFile := "client.rbs"
|
||||
recCustomClientPath := path.Join(recFolder, recCustomClientFile)
|
||||
rec_c, err = NewCustomClientRecorder(recCustomClientPath)
|
||||
if err != nil {
|
||||
logger.Errorf("Proxy.newServerConnHandler can't open ServerRecorder save path: %s", recClientPath)
|
||||
logger.Errorf("Proxy.newServerConnHandler can't open CustomRecorder save path: %s", recCustomClientPath)
|
||||
return err
|
||||
}
|
||||
|
||||
sconn.Listeners.AddListener(rec_c)
|
||||
|
||||
// recProtoFile := "proto.rbs"
|
||||
// recProtoPath := path.Join(recFolder, recProtoFile)
|
||||
// rec_p, err = NewProtoRecorder(recProtoPath)
|
||||
// if err != nil {
|
||||
// logger.Errorf("Proxy.newServerConnHandler can't open ProtoRecorder save path: %s", recProtoPath)
|
||||
// return err
|
||||
// }
|
||||
|
||||
// sconn.Listeners.AddListener(rec_p)
|
||||
}
|
||||
|
||||
session.Status = SessionStatusInit
|
||||
@ -132,7 +143,10 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
|
||||
return err
|
||||
}
|
||||
if session.Type == SessionTypeRecordingProxy {
|
||||
//cconn.Listeners.AddListener(rec_c)
|
||||
cconn.Listeners.AddListener(rec_c)
|
||||
cconn.Listeners.AddListener(rec_s)
|
||||
//cconn.Listeners.AddListener(rec_s)
|
||||
}
|
||||
|
||||
//creating cross-listeners between server and client parts to pass messages through the proxy:
|
||||
|
Loading…
Reference in New Issue
Block a user