refactored player code

This commit is contained in:
amit bezalel 2017-07-19 00:23:45 +03:00
parent 2038848b8e
commit 662e8393e9
17 changed files with 423 additions and 208 deletions

View File

@ -80,11 +80,9 @@
<file leaf-file-name="fbs-reader.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/player/fbs-reader.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="285">
<state relative-caret-position="165">
<caret line="19" column="0" lean-forward="false" selection-start-line="19" selection-start-column="0" selection-end-line="19" selection-end-column="0" />
<folding>
<element signature="e#16#126#0" expanded="true" />
</folding>
<folding />
</state>
</provider>
</entry>
@ -92,19 +90,11 @@
<file leaf-file-name="player_test.go" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/player/player_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="372">
<caret line="45" column="36" lean-forward="true" selection-start-line="45" selection-start-column="36" selection-end-line="45" selection-end-column="36" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="multiListener.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/common/multiListener.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="18" column="0" lean-forward="false" selection-start-line="18" selection-start-column="0" selection-end-line="18" selection-end-column="0" />
<folding />
<state relative-caret-position="75">
<caret line="5" column="10" lean-forward="false" selection-start-line="5" selection-start-column="10" selection-end-line="5" selection-end-column="10" />
<folding>
<element signature="n#!!block;n#loadFbsFile#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
@ -132,11 +122,14 @@
<file leaf-file-name="proxy.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/proxy/proxy.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2130">
<caret line="154" column="0" lean-forward="false" selection-start-line="154" selection-start-column="0" selection-end-line="154" selection-end-column="0" />
<state relative-caret-position="345">
<caret line="180" column="0" lean-forward="true" selection-start-line="180" selection-start-column="0" selection-end-line="180" selection-end-column="0" />
<folding>
<element signature="n#!!block;n#createClientConnection#0" expanded="false" />
<element signature="n#!!block;n#getTargetServerFromSession#0" expanded="false" />
<element signature="n#!!block;n#newServerConnHandler#0" expanded="false" />
<element signature="n#!!block;n#StartListening#0" expanded="false" />
<marker date="1500386875000" expanded="false" signature="22:26" ph="..." />
<marker date="1500386875000" expanded="true" signature="4939:5453" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" />
</folding>
@ -144,16 +137,12 @@
</provider>
</entry>
</file>
<file leaf-file-name="write-to.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/tee-listeners/write-to.go">
<file leaf-file-name="proxy_test.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/proxy/proxy_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450">
<caret line="34" column="12" lean-forward="false" selection-start-line="34" selection-start-column="12" selection-end-line="34" selection-end-column="12" />
<folding>
<marker date="1500088058000" expanded="false" signature="26:30" ph="..." />
<marker date="1500088058000" expanded="true" signature="189:257" ph="{...}" />
<marker date="1500088058000" expanded="true" signature="1040:1041" ph="{...}" />
</folding>
<state relative-caret-position="315">
<caret line="21" column="5" lean-forward="true" selection-start-line="21" selection-start-column="5" selection-end-line="21" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
@ -245,6 +234,7 @@
<option value="$PROJECT_DIR$/server/server-conn.go" />
<option value="$PROJECT_DIR$/server/ws-server-go.go" />
<option value="$PROJECT_DIR$/player/fbs-reader.go" />
<option value="$PROJECT_DIR$/player/FBSPlayListener.go" />
<option value="$PROJECT_DIR$/player/player_test.go" />
</list>
</option>
@ -457,6 +447,20 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="vncproxy" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="vncproxy" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="proxy" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="vncproxy" />
@ -1072,7 +1076,7 @@
<workItem from="1499416701375" duration="1802000" />
<workItem from="1499522471716" duration="431000" />
<workItem from="1499965517741" duration="5709000" />
<workItem from="1500411167182" duration="560000" />
<workItem from="1500411167182" duration="1498000" />
</task>
<servers />
</component>
@ -1109,7 +1113,7 @@
</history-entry>
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="63915000" />
<option name="totallyTimeSpent" value="64853000" />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
@ -1130,7 +1134,7 @@
<window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.35068494" sideWeight="0.31260097" order="8" side_tool="true" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.13972603" sideWeight="0.31260097" order="8" side_tool="true" content_ui="tabs" />
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32956383" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.30136988" sideWeight="0.49676898" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="true" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32876712" sideWeight="0.4676898" order="10" side_tool="false" content_ui="tabs" />
@ -1290,24 +1294,14 @@
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/player/player_test.go</url>
<line>77</line>
<line>13</line>
<option name="timeStamp" value="133" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/player/player_test.go</url>
<line>81</line>
<option name="timeStamp" value="134" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/player/player_test.go</url>
<line>45</line>
<option name="timeStamp" value="135" />
</line-breakpoint>
</breakpoints>
<breakpoints-dialog>
<breakpoints-dialog />
</breakpoints-dialog>
<option name="time" value="136" />
<option name="time" value="137" />
</breakpoint-manager>
<watches-manager>
<configuration name="GoApplicationRunConfiguration">
@ -1323,14 +1317,6 @@
<option name="FILTER_TARGETS" value="false" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/client/client-conn.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="27" column="27" lean-forward="true" selection-start-line="27" selection-start-column="27" selection-end-line="27" selection-end-column="27" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/server/security.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
@ -1512,13 +1498,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="15" column="43" lean-forward="true" selection-start-line="15" selection-start-column="43" selection-end-line="15" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/main.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="414">
@ -1597,19 +1576,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2130">
<caret line="154" column="0" lean-forward="false" selection-start-line="154" selection-start-column="0" selection-end-line="154" selection-end-column="0" />
<folding>
<marker date="1500386875000" expanded="false" signature="22:26" ph="..." />
<marker date="1500386875000" expanded="true" signature="4939:5453" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tee-listeners/write-to.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450">
@ -1670,21 +1636,53 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="345">
<caret line="180" column="0" lean-forward="true" selection-start-line="180" selection-start-column="0" selection-end-line="180" selection-end-column="0" />
<folding>
<element signature="n#!!block;n#createClientConnection#0" expanded="false" />
<element signature="n#!!block;n#getTargetServerFromSession#0" expanded="false" />
<element signature="n#!!block;n#newServerConnHandler#0" expanded="false" />
<element signature="n#!!block;n#StartListening#0" expanded="false" />
<marker date="1500386875000" expanded="false" signature="22:26" ph="..." />
<marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="315">
<caret line="21" column="5" lean-forward="true" selection-start-line="21" selection-start-column="5" selection-end-line="21" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/player/fbs-reader.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="285">
<state relative-caret-position="165">
<caret line="19" column="0" lean-forward="false" selection-start-line="19" selection-start-column="0" selection-end-line="19" selection-end-column="0" />
<folding>
<element signature="e#16#126#0" expanded="true" />
</folding>
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/player/FBSPlayListener.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="180">
<caret line="12" column="0" lean-forward="true" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/player/player_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="372">
<caret line="45" column="36" lean-forward="true" selection-start-line="45" selection-start-column="36" selection-end-line="45" selection-end-column="36" />
<folding />
<state relative-caret-position="75">
<caret line="5" column="10" lean-forward="false" selection-start-line="5" selection-start-column="10" selection-end-line="5" selection-end-column="10" />
<folding>
<element signature="n#!!block;n#loadFbsFile#0" expanded="false" />
</folding>
</state>
</provider>
</entry>

View File

@ -506,7 +506,7 @@ func (c *ClientConn) mainLoop() {
// Unsupported message type! Bad!
break
}
logger.Debugf("ClientConn.MainLoop: got ServerMessage:%s", common.ServerMessageType(messageType))
logger.Infof("ClientConn.MainLoop: got ServerMessage:%s", common.ServerMessageType(messageType))
reader.SendMessageSeparator(common.ServerMessageType(messageType))
reader.PublishBytes([]byte{byte(messageType)})

View File

@ -19,9 +19,13 @@ type FramebufferUpdateMessage struct {
}
func (m *FramebufferUpdateMessage) String() string {
str := fmt.Sprintf("FramebufferUpdateMessage (type=%d) Rects: \n", m.Type())
str := fmt.Sprintf("FramebufferUpdateMessage (type=%d) Rects: ", m.Type())
for _, rect := range m.Rectangles {
str += rect.String() + "\n"
//if this is the last rect, break the loop
if rect.Enc.Type() == int32(common.EncLastRectPseudo) {
break
}
}
return str
}
@ -60,11 +64,11 @@ func (fbm *FramebufferUpdateMessage) Read(c common.IClientConn, r *common.RfbRea
// We must always support the raw encoding
rawEnc := new(encodings.RawEncoding)
encMap[rawEnc.Type()] = rawEnc
logger.Debugf("numrects= %d", numRects)
logger.Infof("FrameBufferUpdateMessage.Read: numrects= %d", numRects)
rects := make([]common.Rectangle, numRects)
for i := uint16(0); i < numRects; i++ {
logger.Debugf("###############rect################: %d\n", i)
logger.Debugf("FrameBufferUpdateMessage.Read: ###############rect################: %d", i)
var encodingTypeInt int32
r.SendRectSeparator(-1)
@ -87,7 +91,7 @@ func (fbm *FramebufferUpdateMessage) Read(c common.IClientConn, r *common.RfbRea
encType := common.EncodingType(encodingTypeInt)
logger.Debugf("rect hdr data: enctype=%s, data: %s\n", encType, string(jBytes))
logger.Infof("FrameBufferUpdateMessage.Read: rect# %d, rect hdr data: enctype=%s, data: %s", i, encType, string(jBytes))
enc, supported := encMap[encodingTypeInt]
if supported {
var err error
@ -98,9 +102,14 @@ func (fbm *FramebufferUpdateMessage) Read(c common.IClientConn, r *common.RfbRea
} else {
if strings.Contains(encType.String(), "Pseudo") {
rect.Enc = &encodings.PseudoEncoding{encodingTypeInt}
//if this is the last rect, break the for loop
if rect.Enc.Type() == int32(common.EncLastRectPseudo) {
break
}
} else {
logger.Errorf("unsupported encoding type: %d, %s", encodingTypeInt, encType)
return nil, fmt.Errorf("unsupported encoding type: %d, %s", encodingTypeInt, encType)
logger.Errorf("FrameBufferUpdateMessage.Read: unsupported encoding type: %d, %s", encodingTypeInt, encType)
return nil, fmt.Errorf("FrameBufferUpdateMessage.Read: unsupported encoding type: %d, %s", encodingTypeInt, encType)
}
}
}
@ -194,6 +203,42 @@ func (*BellMessage) Read(common.IClientConn, *common.RfbReadHelper) (common.Serv
return new(BellMessage), nil
}
type ServerFenceMessage byte
func (fbm *ServerFenceMessage) CopyTo(r io.Reader, w io.Writer, c common.IClientConn) error {
return nil
}
func (m *ServerFenceMessage) String() string {
return fmt.Sprintf("ServerFenceMessage (type=%d)", m.Type())
}
func (*ServerFenceMessage) Type() uint8 {
return uint8(common.ServerFence)
}
func (sf *ServerFenceMessage) Read(info common.IClientConn, c *common.RfbReadHelper) (common.ServerMessage, error) {
bytes := make([]byte, 3)
c.Read(bytes)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
var flags uint32
if err := binary.Read(c, binary.BigEndian, &flags); err != nil {
return nil, err
}
var length uint8
if err := binary.Read(c, binary.BigEndian, &length); err != nil {
return nil, err
}
bytes = make([]byte, length)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
return sf, nil
}
// ServerCutTextMessage indicates the server has new text in the cut buffer.
//
// See RFC 6143 Section 7.6.4

View File

@ -2,7 +2,6 @@ package common
import (
"io"
)
type ClientMessageType uint8
@ -18,6 +17,7 @@ const (
KeyEventMsgType
PointerEventMsgType
ClientCutTextMsgType
ClientFenceMsgType = 248
)
// Color represents a single color in a color map.

View File

@ -71,8 +71,8 @@ func (enct EncodingType) String() string {
return "EncJPEGQualityLevelPseudo2"
case EncJPEGQualityLevelPseudo1:
return "EncJPEGQualityLevelPseudo1"
case EncColorPseudo:
return "EncColorPseudo"
case EncCursorPseudo:
return "EncCursorPseudo"
case EncDesktopSizePseudo:
return "EncDesktopSizePseudo"
case EncLastRectPseudo:
@ -164,7 +164,7 @@ const (
EncJPEGQualityLevelPseudo3 EncodingType = -30
EncJPEGQualityLevelPseudo2 EncodingType = -31
EncJPEGQualityLevelPseudo1 EncodingType = -32
EncColorPseudo EncodingType = -239
EncCursorPseudo EncodingType = -239
EncDesktopSizePseudo EncodingType = -223
EncLastRectPseudo EncodingType = -224
EncCompressionLevel10 EncodingType = -247

View File

@ -23,6 +23,7 @@ const (
SetColourMapEntries
Bell
ServerCutText
ServerFence = 248
)
func (typ ServerMessageType) String() string {

View File

@ -0,0 +1,28 @@
package encodings
import (
"io"
"math"
"vncproxy/common"
)
type EncCursorPseudo struct {
}
func (pe *EncCursorPseudo) Type() int32 {
return int32(common.EncCursorPseudo)
}
func (z *EncCursorPseudo) WriteTo(w io.Writer) (n int, err error) {
return 0, nil
}
func (pe *EncCursorPseudo) Read(pf *common.PixelFormat, rect *common.Rectangle, r *common.RfbReadHelper) (common.Encoding, error) {
if rect.Width*rect.Height == 0 {
return pe, nil
}
bytesPixel := int(pf.BPP / 8) //calcTightBytePerPixel(pf)
r.ReadBytes(int(rect.Width*rect.Height) * bytesPixel)
mask := ((rect.Width + 7) / 8) * rect.Height
r.ReadBytes(int(math.Floor(float64(mask))))
return pe, nil
}

View File

@ -14,39 +14,109 @@ type Logger interface {
Fatal(v ...interface{})
Fatalf(format string, v ...interface{})
}
type LogLevel int
func Debug(v ...interface{}) {
const (
LogLevelDebug LogLevel = iota
LogLevelInfo
LogLevelWarn
LogLevelError
LogLevelFatal
)
type SimpleLogger struct {
level LogLevel
}
func (sl *SimpleLogger) Debug(v ...interface{}) {
if sl.level <= LogLevelDebug {
fmt.Print("[Debug] ")
fmt.Println(v...)
}
}
func Debugf(format string, v ...interface{}) {
func (sl *SimpleLogger) Debugf(format string, v ...interface{}) {
if sl.level <= LogLevelDebug {
fmt.Printf("[Debug] "+format+"\n", v...)
}
}
func Info(v ...interface{}) {
func (sl *SimpleLogger) Info(v ...interface{}) {
if sl.level <= LogLevelInfo {
fmt.Print("[Info] ")
fmt.Println(v...)
}
}
func Infof(format string, v ...interface{}) {
func (sl *SimpleLogger) Infof(format string, v ...interface{}) {
if sl.level <= LogLevelInfo {
fmt.Printf("[Info] "+format+"\n", v...)
}
}
func Warn(v ...interface{}) {
func (sl *SimpleLogger) Warn(v ...interface{}) {
if sl.level <= LogLevelWarn {
fmt.Print("[Warn] ")
fmt.Println(v...)
}
}
func Warnf(format string, v ...interface{}) {
func (sl *SimpleLogger) Warnf(format string, v ...interface{}) {
if sl.level <= LogLevelWarn {
fmt.Printf("[Warn] "+format+"\n", v...)
}
}
func Error(v ...interface{}) {
func (sl *SimpleLogger) Error(v ...interface{}) {
if sl.level <= LogLevelError {
fmt.Print("[Error] ")
fmt.Println(v...)
}
}
func Errorf(format string, v ...interface{}) {
func (sl *SimpleLogger) Errorf(format string, v ...interface{}) {
if sl.level <= LogLevelError {
fmt.Printf("[Error] "+format+"\n", v...)
}
}
func Fatal(v ...interface{}) {
func (sl *SimpleLogger) Fatal(v ...interface{}) {
if sl.level <= LogLevelFatal {
fmt.Print("[Fatal] ")
fmt.Println(v...)
}
}
func (sl *SimpleLogger) Fatalf(format string, v ...interface{}) {
if sl.level <= LogLevelFatal {
fmt.Printf("[Fatal] "+format+"\n", v)
}
}
var simpleLogger = SimpleLogger{LogLevelInfo}
func Debug(v ...interface{}) {
simpleLogger.Debug(v...)
}
func Debugf(format string, v ...interface{}) {
simpleLogger.Debugf(format, v...)
}
func Info(v ...interface{}) {
simpleLogger.Info(v...)
}
func Infof(format string, v ...interface{}) {
simpleLogger.Infof(format, v...)
}
func Warn(v ...interface{}) {
simpleLogger.Warn(v...)
}
func Warnf(format string, v ...interface{}) {
simpleLogger.Warnf(format, v...)
}
func Error(v ...interface{}) {
simpleLogger.Error(v...)
}
func Errorf(format string, v ...interface{}) {
simpleLogger.Errorf(format, v...)
}
func Fatal(v ...interface{}) {
simpleLogger.Fatal(v...)
}
func Fatalf(format string, v ...interface{}) {
fmt.Printf("[Fatal] "+format+"\n", v)
simpleLogger.Fatalf(format, v...)
}

View File

@ -23,8 +23,12 @@ func main() {
//vncSrvMessagesChan := make(chan common.ServerMessage)
//rec := listeners.NewRecorder("c:/Users/betzalel/recording.rbs")
rec := listeners.NewRecorder("/Users/amitbet/vncRec/recording.rbs")
rec, err := listeners.NewRecorder("c:/Users/betzalel/recording.rbs")
//rec, err := listeners.NewRecorder("/Users/amitbet/vncRec/recording.rbs")
if err != nil {
logger.Errorf("error creating recorder: %s", err)
return
}
clientConn, err := client.NewClientConn(nc,
&client.ClientConfig{
@ -37,6 +41,7 @@ func main() {
if err != nil {
logger.Errorf("error creating client: %s", err)
return
}
// err = clientConn.FramebufferUpdateRequest(false, 0, 0, 1024, 768)
// if err != nil {

View File

@ -0,0 +1,81 @@
package player
import (
"encoding/binary"
"time"
"vncproxy/client"
"vncproxy/common"
"vncproxy/logger"
"vncproxy/server"
)
type FBSPlayListener struct {
Conn *server.ServerConn
Fbs *FbsReader
serverMessageMap map[uint8]common.ServerMessage
firstSegDone bool
startTime int
}
func NewFBSPlayListener(conn *server.ServerConn, r *FbsReader) *FBSPlayListener {
h := &FBSPlayListener{Conn: conn, Fbs: r}
cm := client.BellMessage(0)
h.serverMessageMap = make(map[uint8]common.ServerMessage)
h.serverMessageMap[0] = &client.FramebufferUpdateMessage{}
h.serverMessageMap[1] = &client.SetColorMapEntriesMessage{}
h.serverMessageMap[2] = &cm
h.serverMessageMap[3] = &client.ServerCutTextMessage{}
return h
}
func (handler *FBSPlayListener) Consume(seg *common.RfbSegment) error {
switch seg.SegmentType {
case common.SegmentFullyParsedClientMessage:
clientMsg := seg.Message.(common.ClientMessage)
logger.Debugf("ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=%s", clientMsg.Type())
switch clientMsg.Type() {
case common.FramebufferUpdateRequestMsgType:
if !handler.firstSegDone {
handler.firstSegDone = true
handler.startTime = int(time.Now().UnixNano() / int64(time.Millisecond))
}
handler.sendFbsMessage()
}
// server.FramebufferUpdateRequest:
}
return nil
}
func (h *FBSPlayListener) sendFbsMessage() {
var messageType uint8
//messages := make(map[uint8]common.ServerMessage)
fbs := h.Fbs
//conn := h.Conn
err := binary.Read(fbs, binary.BigEndian, &messageType)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
//common.IClientConn{}
binary.Write(h.Conn, binary.BigEndian, messageType)
msg := h.serverMessageMap[messageType]
if msg == nil {
logger.Error("TestServer.NewConnHandler: Error unknown message type: ", messageType)
return
}
timeSinceStart := int(time.Now().UnixNano()/int64(time.Millisecond)) - h.startTime
timeToSleep := fbs.currentTimestamp - timeSinceStart
if timeToSleep > 0 {
time.Sleep(time.Duration(timeToSleep) * time.Millisecond)
}
err = msg.CopyTo(fbs, h.Conn, fbs)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
}

View File

@ -1,84 +1,16 @@
package player
import (
"encoding/binary"
"testing"
"time"
"vncproxy/client"
"vncproxy/common"
"vncproxy/encodings"
"vncproxy/logger"
"vncproxy/server"
)
type ServerMessageHandler struct {
Conn *server.ServerConn
Fbs *FbsReader
serverMessageMap map[uint8]common.ServerMessage
firstSegDone bool
startTime int
}
func NewServerMessageHandler(conn *server.ServerConn, r *FbsReader) *ServerMessageHandler {
h := &ServerMessageHandler{Conn: conn, Fbs: r}
cm := client.BellMessage(0)
h.serverMessageMap = make(map[uint8]common.ServerMessage)
h.serverMessageMap[0] = &client.FramebufferUpdateMessage{}
h.serverMessageMap[1] = &client.SetColorMapEntriesMessage{}
h.serverMessageMap[2] = &cm
h.serverMessageMap[3] = &client.ServerCutTextMessage{}
return h
}
func (handler *ServerMessageHandler) Consume(seg *common.RfbSegment) error {
switch seg.SegmentType {
case common.SegmentFullyParsedClientMessage:
clientMsg := seg.Message.(common.ClientMessage)
logger.Debugf("ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=%s", clientMsg.Type())
switch clientMsg.Type() {
case common.FramebufferUpdateRequestMsgType:
if !handler.firstSegDone {
handler.firstSegDone = true
handler.startTime = int(time.Now().UnixNano() / int64(time.Millisecond))
}
handler.sendFbsMessage()
}
// server.FramebufferUpdateRequest:
}
return nil
}
func (h *ServerMessageHandler) sendFbsMessage() {
var messageType uint8
//messages := make(map[uint8]common.ServerMessage)
fbs := h.Fbs
//conn := h.Conn
err := binary.Read(fbs, binary.BigEndian, &messageType)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
//common.IClientConn{}
binary.Write(h.Conn, binary.BigEndian, messageType)
msg := h.serverMessageMap[messageType]
if msg == nil {
logger.Error("TestServer.NewConnHandler: Error unknown message type: ", messageType)
return
}
timeSinceStart := int(time.Now().UnixNano()/int64(time.Millisecond)) - h.startTime
timeToSleep := fbs.currentTimestamp - timeSinceStart
if timeToSleep > 0 {
time.Sleep(time.Duration(timeToSleep) * time.Millisecond)
}
err = msg.CopyTo(fbs, h.Conn, fbs)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
}
func loadFbsFile(filename string, conn *server.ServerConn) (*FbsReader, error) {
fbs, err := NewFbsReader(filename)
@ -117,12 +49,15 @@ func TestServer(t *testing.T) {
}
cfg.NewConnHandler = func(cfg *server.ServerConfig, conn *server.ServerConn) error {
fbs, err := loadFbsFile("/Users/amitbet/Dropbox/recording.rbs", conn)
//fbs, err := loadFbsFile("/Users/amitbet/Dropbox/recording.rbs", conn)
//fbs, err := loadFbsFile("/Users/amitbet/vncRec/recording.rbs", conn)
fbs, err := loadFbsFile("/Users/amitbet/vncRec/recording1500411789.rbs", conn)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in loading FBS: ", err)
return err
}
conn.Listeners.AddListener(NewServerMessageHandler(conn, fbs))
conn.Listeners.AddListener(NewFBSPlayListener(conn, fbs))
return nil
}

View File

@ -69,7 +69,12 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
recFile := "recording" + strconv.FormatInt(time.Now().Unix(), 10) + ".rbs"
recPath := path.Join(vp.recordingDir, recFile)
rec := listeners.NewRecorder(recPath)
rec, err := listeners.NewRecorder(recPath)
if err != nil {
logger.Errorf("Proxy.newServerConnHandler can't open recorder save path: %s", recPath)
return err
}
session, err := vp.getTargetServerFromSession(sconn.SessionId)
if err != nil {
logger.Errorf("Proxy.newServerConnHandler can't get session: %d", sconn.SessionId)
@ -113,13 +118,14 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
encs := []common.Encoding{
&encodings.RawEncoding{},
&encodings.TightEncoding{},
&encodings.EncCursorPseudo{},
//encodings.TightPngEncoding{},
//encodings.RREEncoding{},
//encodings.ZLibEncoding{},
//encodings.ZRLEEncoding{},
//encodings.CopyRectEncoding{},
//encodings.CoRREEncoding{},
//encodings.HextileEncoding{},
&encodings.RREEncoding{},
&encodings.ZLibEncoding{},
&encodings.ZRLEEncoding{},
&encodings.CopyRectEncoding{},
&encodings.CoRREEncoding{},
&encodings.HextileEncoding{},
}
cconn.Encs = encs
//err = cconn.SetEncodings(encs)

View File

@ -8,6 +8,7 @@ func TestProxy(t *testing.T) {
proxy := &VncProxy{
wsListeningUrl: "http://localhost:7777/", // empty = not listening on ws
recordingDir: "/Users/amitbet/vncRec", // empty = no recording
//recordingDir: "C:\\vncRec", // empty = no recording
targetServersPassword: "Ch_#!T@8", //empty = no auth
SingleSession: &VncSession{
TargetHostname: "localhost",

View File

@ -193,6 +193,40 @@ func (msg *PointerEvent) Write(c io.Writer) error {
return nil
}
type ClientFence struct {
}
func (*ClientFence) Type() common.ClientMessageType {
return common.ClientFenceMsgType
}
func (cf *ClientFence) Read(c io.Reader) (common.ClientMessage, error) {
bytes := make([]byte, 3)
c.Read(bytes)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
var flags uint32
if err := binary.Read(c, binary.BigEndian, &flags); err != nil {
return nil, err
}
var length uint8
if err := binary.Read(c, binary.BigEndian, &length); err != nil {
return nil, err
}
bytes = make([]byte, length)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
return cf, nil
}
func (msg *ClientFence) Write(c io.Writer) error {
panic("not implemented!")
}
// ClientCutText holds the wire format message, sans the text field.
type ClientCutText struct {
_ [3]byte // padding

View File

@ -197,7 +197,11 @@ func (c *ServerConn) handle() error {
return err
}
logger.Debugf("ServerConn.Handle got ClientMessage: %s, %v", parsedMsg.Type(), parsedMsg)
logger.Infof("ServerConn.Handle got ClientMessage: %s, %v", parsedMsg.Type(), parsedMsg)
//TODO: treat set encodings by allowing only supported encoding in proxy configurations
//// if parsedMsg.Type() == common.SetEncodingsMsgType{
//// c.cfg.Encodings
//// }
seg := &common.RfbSegment{
SegmentType: common.SegmentFullyParsedClientMessage,

View File

@ -88,6 +88,14 @@ func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig, sessionId string) e
return err
}
//run the handler for this new incoming connection from a vnc-client
//this is done before the init sequence to allow listening to server-init messages (and maybe even interception in the future)
err = cfg.NewConnHandler(cfg, conn)
if err != nil {
conn.Close()
return err
}
if err := ServerClientInitHandler(cfg, conn); err != nil {
conn.Close()
return err
@ -102,7 +110,6 @@ func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig, sessionId string) e
if cfg.UseDummySession {
conn.SessionId = "dummySession"
}
cfg.NewConnHandler(cfg, conn)
//go here will kill ws connections
conn.handle()

View File

@ -27,7 +27,7 @@ func getNowMillisec() int {
return int(time.Now().UnixNano() / int64(time.Millisecond))
}
func NewRecorder(saveFilePath string) *Recorder {
func NewRecorder(saveFilePath string) (*Recorder, error) {
//delete file if it exists
if _, err := os.Stat(saveFilePath); err == nil {
os.Remove(saveFilePath)
@ -41,7 +41,7 @@ func NewRecorder(saveFilePath string) *Recorder {
rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err)
return nil
return nil, err
}
//buffer the channel so we don't halt the proxying flow for slow writes when under pressure
@ -53,7 +53,7 @@ func NewRecorder(saveFilePath string) *Recorder {
}
}()
return &rec
return &rec, nil
}
const versionMsg_3_3 = "RFB 003.003\n"
@ -114,8 +114,8 @@ func (r *Recorder) 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: recorder queue is full")
// default:
// logger.Error("error: recorder queue is full")
}
return nil