Files
sshwifty-udp-telnet-http/application/command/header.go
2022-02-13 17:33:52 +08:00

144 lines
3.5 KiB
Go

// Sshwifty - A Web SSH client
//
// Copyright (C) 2019-2022 Ni Rui <ranqus@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package command
import "fmt"
// Header Packet Type
type Header byte
// Packet Types
const (
// 00------: Control signals
// Remaing bits: Data length
//
// Format:
// 0011111 [63 bytes long data] - 63 bytes of control data
//
HeaderControl Header = 0x00
// 01------: Bidirectional stream data
// Remaining bits: Stream ID
// Followed by: Parameter or data
//
// Format:
// 0111111 [Command parameters / data] - Open/use stream 63 to execute
// command or transmit data
HeaderStream Header = 0x40
// 10------: Close stream
// Remaining bits: Stream ID
//
// Format:
// 1011111 - Close stream 63
//
// WARNING: The requester MUST NOT send any data to this stream once this
// header is sent.
//
// WARNING: The receiver MUST reply with a Completed header to indicate
// the success of the Close action. Until a Completed header is
// replied, all data from the sender must be proccessed as normal.
HeaderClose Header = 0x80
// 11------: Stream has been closed/completed in respond to client request
// Remaining bits: Stream ID
//
// Format:
// 1111111 - Stream 63 is completed
//
// WARNING: This header can ONLY be send in respond to a Close header
//
// WARNING: The sender of this header MUST NOT send any data to the stream
// once this header is sent until this stream been re-opened by a
// Data header
HeaderCompleted Header = 0xc0
)
// Control signal types
const (
HeaderControlEcho = 0x00
HeaderControlPauseStream = 0x01
HeaderControlResumeStream = 0x02
)
// Consts
const (
HeaderMaxData = 0x3f
)
// Cutters
const (
headerHeaderCutter = 0xc0
headerDataCutter = 0x3f
)
// Type get packet type
func (p Header) Type() Header {
return (p & headerHeaderCutter)
}
// Data returns the data of current Packet header
func (p Header) Data() byte {
return byte(p & headerDataCutter)
}
// Set set a new value of the Header
func (p *Header) Set(data byte) {
if data > headerDataCutter {
panic("data must not be greater than 0x3f")
}
*p |= (headerDataCutter & Header(data))
}
// Set set a new value of the Header
func (p Header) String() string {
switch p.Type() {
case HeaderControl:
return fmt.Sprintf("Control (%d bytes)", p.Data())
case HeaderStream:
return fmt.Sprintf("Stream (%d)", p.Data())
case HeaderClose:
return fmt.Sprintf("Close (Stream %d)", p.Data())
case HeaderCompleted:
return fmt.Sprintf("Completed (Stream %d)", p.Data())
default:
return "Unknown"
}
}
// IsStreamControl returns true when the header is for stream control, false
// when otherwise
func (p Header) IsStreamControl() bool {
switch p {
case HeaderStream:
fallthrough
case HeaderClose:
fallthrough
case HeaderCompleted:
return true
default:
return false
}
}