|
@@ -8,7 +8,7 @@ import "compress/zlib"
|
|
|
import "github.com/beoran/woe/monolog"
|
|
|
|
|
|
|
|
|
-// This Telnet struct implements a subset of the Telnet protocol.
|
|
|
+// This Telnet module implements a subset of the Telnet protocol.
|
|
|
|
|
|
// Telnet states
|
|
|
type TelnetState int
|
|
@@ -25,26 +25,45 @@ const (
|
|
|
sb_data_iac_state = iota
|
|
|
)
|
|
|
|
|
|
+// Telnet event type constants
|
|
|
+type EventType int
|
|
|
|
|
|
+const (
|
|
|
+ TELNET_DATA_EVENT EventType = iota
|
|
|
+ TELNET_NAWS_EVENT EventType = iota
|
|
|
+ TELNET_TTYPE_EVENT EventType = iota
|
|
|
+ TELNET_SUBNEGOTIATE_EVENT EventType = iota
|
|
|
+ TELNET_IAC_EVENT EventType = iota
|
|
|
+ TELNET_COMPRESS_EVENT EventType = iota
|
|
|
+ TELNET_ENVIRONMENT_EVENT EventType = iota
|
|
|
+ TELNET_MSSP_EVENT EventType = iota
|
|
|
+ TELNET_ZMP_EVENT EventType = iota
|
|
|
+ TELNET_WILL_EVENT EventType = iota
|
|
|
+ TELNET_WONT_EVENT EventType = iota
|
|
|
+ TELNET_DO_EVENT EventType = iota
|
|
|
+ TELNET_DONT_EVENT EventType = iota
|
|
|
+ TELNET_ERROR_EVENT EventType = iota
|
|
|
+ TELNET_UNKNOWN_EVENT EventType = iota
|
|
|
+)
|
|
|
|
|
|
// Telnet event types
|
|
|
|
|
|
type Event interface {
|
|
|
- isEvent()
|
|
|
+ Type() EventType
|
|
|
}
|
|
|
|
|
|
type DataEvent struct {
|
|
|
Data [] byte
|
|
|
}
|
|
|
|
|
|
-func (me DataEvent) isEvent() {}
|
|
|
+func (me DataEvent) Type() EventType { return TELNET_DATA_EVENT; }
|
|
|
|
|
|
type NAWSEvent struct {
|
|
|
W int
|
|
|
H int
|
|
|
}
|
|
|
|
|
|
-func (me NAWSEvent) isEvent() {}
|
|
|
+func (me NAWSEvent) Type() EventType { return TELNET_NAWS_EVENT; }
|
|
|
|
|
|
|
|
|
type TTypeEvent struct {
|
|
@@ -52,7 +71,7 @@ type TTypeEvent struct {
|
|
|
Name string
|
|
|
}
|
|
|
|
|
|
-func (me TTypeEvent) isEvent() {}
|
|
|
+func (me TTypeEvent) Type() EventType { return TELNET_TTYPE_EVENT; }
|
|
|
|
|
|
|
|
|
type SubnegotiateEvent struct {
|
|
@@ -60,24 +79,24 @@ type SubnegotiateEvent struct {
|
|
|
Buffer [] byte
|
|
|
}
|
|
|
|
|
|
-func (me SubnegotiateEvent) isEvent() {}
|
|
|
+func (me SubnegotiateEvent) Type() EventType { return TELNET_SUBNEGOTIATE_EVENT; }
|
|
|
|
|
|
|
|
|
type IACEvent struct {
|
|
|
Telopt byte
|
|
|
}
|
|
|
|
|
|
-func (me IACEvent) isEvent() {}
|
|
|
+func (me IACEvent) Type() EventType { return TELNET_IAC_EVENT; }
|
|
|
|
|
|
|
|
|
type CompressEvent struct {
|
|
|
Compress bool
|
|
|
}
|
|
|
|
|
|
-func (me CompressEvent) isEvent() {}
|
|
|
+func (me CompressEvent) Type() EventType { return TELNET_COMPRESS_EVENT; }
|
|
|
|
|
|
|
|
|
-//Storage for environment values
|
|
|
+// Storage for environment values
|
|
|
type Environment struct {
|
|
|
Type byte
|
|
|
Value string
|
|
@@ -89,7 +108,7 @@ type EnvironmentEvent struct {
|
|
|
Vars [] Environment
|
|
|
}
|
|
|
|
|
|
-func (me EnvironmentEvent) isEvent() {}
|
|
|
+func (me EnvironmentEvent) Type() EventType { return TELNET_ENVIRONMENT_EVENT; }
|
|
|
|
|
|
|
|
|
type MSSPEvent struct {
|
|
@@ -97,95 +116,52 @@ type MSSPEvent struct {
|
|
|
Vars map[string] string
|
|
|
}
|
|
|
|
|
|
-func (me MSSPEvent) isEvent() {}
|
|
|
+func (me MSSPEvent) Type() EventType { return TELNET_MSSP_EVENT; }
|
|
|
|
|
|
|
|
|
type ZMPEvent struct {
|
|
|
Vars []string
|
|
|
}
|
|
|
|
|
|
-func (me ZMPEvent) isEvent() {}
|
|
|
+func (me ZMPEvent) Type() EventType { return TELNET_ZMP_EVENT; }
|
|
|
|
|
|
type WillEvent struct {
|
|
|
Telopt byte
|
|
|
}
|
|
|
|
|
|
-func (me WillEvent) isEvent() {}
|
|
|
+func (me WillEvent) Type() EventType { return TELNET_WILL_EVENT; }
|
|
|
|
|
|
type WontEvent struct {
|
|
|
Telopt byte
|
|
|
}
|
|
|
|
|
|
-func (me WontEvent) isEvent() {}
|
|
|
+func (me WontEvent) Type() EventType { return TELNET_WONT_EVENT; }
|
|
|
|
|
|
|
|
|
type DoEvent struct {
|
|
|
Telopt byte
|
|
|
}
|
|
|
|
|
|
-func (me DoEvent) isEvent() {}
|
|
|
+func (me DoEvent) Type() EventType { return TELNET_DO_EVENT; }
|
|
|
|
|
|
type DontEvent struct {
|
|
|
Telopt byte
|
|
|
}
|
|
|
|
|
|
-func (me DontEvent) isEvent() {}
|
|
|
+func (me DontEvent) Type() EventType { return TELNET_DONT_EVENT; }
|
|
|
|
|
|
|
|
|
-// Telnet event type constants
|
|
|
-type EventType int
|
|
|
+// For protocol errors.
|
|
|
+type ErrorEvent struct {
|
|
|
+ error string
|
|
|
+}
|
|
|
|
|
|
-const (
|
|
|
- TELNET_DATA_EVENT EventType = iota
|
|
|
- TELNET_NAWS_EVENT EventType = iota
|
|
|
- TELNET_TTYPE_EVENT EventType = iota
|
|
|
- TELNET_SUBNEGOTIATE_EVENT EventType = iota
|
|
|
- TELNET_IAC_EVENT EventType = iota
|
|
|
- TELNET_COMPRESS_EVENT EventType = iota
|
|
|
- TELNET_ENVIRONMENT_EVENT EventType = iota
|
|
|
- TELNET_MSSP_EVENT EventType = iota
|
|
|
- TELNET_ZMP_EVENT EventType = iota
|
|
|
- TELNET_WILL_EVENT EventType = iota
|
|
|
- TELNET_WONT_EVENT EventType = iota
|
|
|
- TELNET_DO_EVENT EventType = iota
|
|
|
- TELNET_DONT_EVENT EventType = iota
|
|
|
- TELNET_UNKNOWN_EVENT EventType = iota
|
|
|
-)
|
|
|
+func (me ErrorEvent) Type() EventType { return TELNET_ERROR_EVENT; }
|
|
|
|
|
|
|
|
|
-/* Returns the numerical event type of an event. Useful for direct comparison. */
|
|
|
+// Returns the numerical event type of an event. Useful for direct comparison.
|
|
|
func EventTypeOf(event Event) EventType {
|
|
|
- switch event.(type) {
|
|
|
- case DataEvent, *DataEvent:
|
|
|
- return TELNET_DATA_EVENT
|
|
|
- case NAWSEvent, *NAWSEvent:
|
|
|
- return TELNET_NAWS_EVENT
|
|
|
- case TTypeEvent, *TTypeEvent:
|
|
|
- return TELNET_TTYPE_EVENT
|
|
|
- case SubnegotiateEvent, *SubnegotiateEvent:
|
|
|
- return TELNET_SUBNEGOTIATE_EVENT
|
|
|
- case IACEvent, *IACEvent:
|
|
|
- return TELNET_IAC_EVENT
|
|
|
- case CompressEvent, *CompressEvent:
|
|
|
- return TELNET_COMPRESS_EVENT
|
|
|
- case EnvironmentEvent, *EnvironmentEvent:
|
|
|
- return TELNET_ENVIRONMENT_EVENT
|
|
|
- case MSSPEvent, *MSSPEvent:
|
|
|
- return TELNET_MSSP_EVENT
|
|
|
- case ZMPEvent, *ZMPEvent:
|
|
|
- return TELNET_ZMP_EVENT
|
|
|
- case WillEvent, *WillEvent:
|
|
|
- return TELNET_WILL_EVENT
|
|
|
- case WontEvent, *WontEvent:
|
|
|
- return TELNET_WONT_EVENT
|
|
|
- case DoEvent, *DoEvent:
|
|
|
- return TELNET_DO_EVENT
|
|
|
- case DontEvent, *DontEvent:
|
|
|
- return TELNET_DONT_EVENT
|
|
|
- default:
|
|
|
- monolog.Error("Unknown event type %T %v", event, event)
|
|
|
- return TELNET_UNKNOWN_EVENT
|
|
|
- }
|
|
|
+ return event.Type()
|
|
|
}
|
|
|
|
|
|
// Returns true if the event is of the given type, or false if not
|
|
@@ -193,7 +169,6 @@ func IsEventType(event Event, typ EventType) bool {
|
|
|
return EventTypeOf(event) == typ;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
type EventChannel chan(Event)
|
|
|
|
|
|
|
|
@@ -206,8 +181,8 @@ type Telopt struct {
|
|
|
type Telnet struct {
|
|
|
Events EventChannel
|
|
|
ToClient chan([]byte)
|
|
|
- telopts map[byte] Telopt
|
|
|
- state TelnetState
|
|
|
+ telopts map[byte] Telopt
|
|
|
+ state TelnetState
|
|
|
compress bool
|
|
|
zwriter zlib.Writer
|
|
|
zreader io.ReadCloser
|
|
@@ -216,7 +191,6 @@ type Telnet struct {
|
|
|
}
|
|
|
|
|
|
func New() (telnet * Telnet) {
|
|
|
-
|
|
|
events := make(EventChannel, 64)
|
|
|
toclient := make(chan([]byte), 64)
|
|
|
telopts := make (map[byte] Telopt)
|
|
@@ -501,7 +475,6 @@ func (me * Telnet) maybeSendDataEventAndEmptyBuffer() {
|
|
|
}
|
|
|
|
|
|
// Append a byte to the data buffer
|
|
|
-// Also empties the buffer if it wasn't emmpty
|
|
|
func (me * Telnet) appendByte(bin byte) {
|
|
|
monolog.Debug("Appending to telnet buffer: %d %d", len(me.buffer), cap(me.buffer))
|
|
|
me.buffer = append(me.buffer, bin)
|