feature: Adds remaining commands.

This commit is contained in:
greysoh 2024-12-02 16:06:08 -05:00
parent 889be65392
commit 0b6e40a944
Signed by: imterah
GPG key ID: 8FA7DD57BA6CEA37
4 changed files with 856 additions and 24 deletions

View file

@ -1,13 +1,5 @@
package commonbackend
// Not all of these structs are implemented commands.
// Currently unimplemented commands:
// GetAllConnectionsRequest
// BackendStatusResponse
// BackendStatusRequest
// ProxyStatusRequest
// ProxyStatusResponse
// TODO (imterah): Rename AddConnectionCommand/RemoveConnectionCommand to AddProxyCommand/RemoveProxyCommand
// and their associated function calls
@ -37,7 +29,7 @@ type RemoveConnectionCommand struct {
}
type ProxyStatusRequest struct {
Type string // Will be 'getProxyStatus' always
Type string // Will be 'proxyStatusRequest' always
SourceIP string
SourcePort uint16
DestPort uint16
@ -62,19 +54,22 @@ type ProxyConnection struct {
type ProxyConnectionResponse struct {
Type string // Will be 'proxyConnectionResponse' always
Connections []*ProxyConnection // List of connections
Proxies []*ProxyConnection // List of connections
}
type ProxyConnectionRequest struct {
Type string // Will be 'proxyConnectionRequest' always
}
type BackendStatusResponse struct {
Type string // Will be 'backendStatusResponse' always
InResponseTo string // Can be either for 'start' or 'stop'
IsRunning bool // Can be either for 'start' or 'stop'
StatusCode int // Either the 'Success' or 'Failure' constant
Message string // String message from the client (ex. failed to dial TCP)
}
type BackendStatusRequest struct {
Type string // Will be 'backendStatusRequest' always
ForProperty string // Can be either for 'start' or 'stop'
}
type GetAllConnectionsRequest struct {
@ -130,6 +125,8 @@ const (
BackendStatusRequestID
ProxyStatusRequestID
ProxyStatusResponseID
ProxyConnectionResponseID
ProxyConnectionRequestID
)
const (

View file

@ -36,6 +36,7 @@ func marshalIndividualConnectionStruct(conn *ClientConnection) []byte {
connectionBlock[0] = serverIPVer
copy(connectionBlock[1:len(sourceIP)+1], sourceIP)
binary.BigEndian.PutUint16(connectionBlock[1+len(sourceIP):3+len(sourceIP)], conn.SourcePort)
binary.BigEndian.PutUint16(connectionBlock[3+len(sourceIP):5+len(sourceIP)], conn.DestPort)
@ -46,6 +47,43 @@ func marshalIndividualConnectionStruct(conn *ClientConnection) []byte {
return connectionBlock
}
func marshalIndividualProxyStruct(conn *ProxyConnection) ([]byte, error) {
sourceIPOriginal := net.ParseIP(conn.SourceIP)
var sourceIPVer uint8
var sourceIP []byte
if sourceIPOriginal.To4() == nil {
sourceIPVer = IPv6
sourceIP = sourceIPOriginal.To16()
} else {
sourceIPVer = IPv4
sourceIP = sourceIPOriginal.To4()
}
proxyBlock := make([]byte, 6+len(sourceIP))
proxyBlock[0] = sourceIPVer
copy(proxyBlock[1:len(sourceIP)+1], sourceIP)
binary.BigEndian.PutUint16(proxyBlock[1+len(sourceIP):3+len(sourceIP)], conn.SourcePort)
binary.BigEndian.PutUint16(proxyBlock[3+len(sourceIP):5+len(sourceIP)], conn.DestPort)
var protocolVersion uint8
if conn.Protocol == "tcp" {
protocolVersion = TCP
} else if conn.Protocol == "udp" {
protocolVersion = UDP
} else {
return proxyBlock, fmt.Errorf("invalid protocol recieved")
}
proxyBlock[5+len(sourceIP)] = protocolVersion
return proxyBlock, nil
}
func Marshal(commandType string, command interface{}) ([]byte, error) {
switch commandType {
case "start":
@ -68,10 +106,7 @@ func Marshal(commandType string, command interface{}) ([]byte, error) {
return nil, fmt.Errorf("failed to typecast")
}
stopCommandBytes := make([]byte, 1)
stopCommandBytes[0] = StopCommandID
return stopCommandBytes, nil
return []byte{StopCommandID}, nil
case "addConnection":
addConnectionCommand, ok := command.(*AddConnectionCommand)
@ -273,6 +308,190 @@ func Marshal(commandType string, command interface{}) ([]byte, error) {
}
return checkResponseBytes, nil
case "backendStatusResponse":
backendStatusResponse, ok := command.(*BackendStatusResponse)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
var isRunning uint8
if backendStatusResponse.IsRunning {
isRunning = 1
} else {
isRunning = 0
}
statusResponseBytes := make([]byte, 3+2+len(backendStatusResponse.Message))
statusResponseBytes[0] = BackendStatusResponseID
statusResponseBytes[1] = isRunning
statusResponseBytes[2] = byte(backendStatusResponse.StatusCode)
binary.BigEndian.PutUint16(statusResponseBytes[3:5], uint16(len(backendStatusResponse.Message)))
if len(backendStatusResponse.Message) != 0 {
copy(statusResponseBytes[5:], []byte(backendStatusResponse.Message))
}
return statusResponseBytes, nil
case "backendStatusRequest":
_, ok := command.(*BackendStatusRequest)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
statusRequestBytes := make([]byte, 2)
statusRequestBytes[0] = BackendStatusRequestID
return statusRequestBytes, nil
case "proxyStatusRequest":
proxyStatusRequest, ok := command.(*ProxyStatusRequest)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
sourceIP := net.ParseIP(proxyStatusRequest.SourceIP)
var ipVer uint8
var ipBytes []byte
if sourceIP.To4() == nil {
ipBytes = sourceIP.To16()
ipVer = IPv6
} else {
ipBytes = sourceIP.To4()
ipVer = IPv4
}
proxyStatusRequestBytes := make([]byte, 1+1+len(ipBytes)+2+2+1)
proxyStatusRequestBytes[0] = ProxyStatusRequestID
proxyStatusRequestBytes[1] = ipVer
copy(proxyStatusRequestBytes[2:2+len(ipBytes)], ipBytes)
binary.BigEndian.PutUint16(proxyStatusRequestBytes[2+len(ipBytes):4+len(ipBytes)], proxyStatusRequest.SourcePort)
binary.BigEndian.PutUint16(proxyStatusRequestBytes[4+len(ipBytes):6+len(ipBytes)], proxyStatusRequest.DestPort)
var protocol uint8
if proxyStatusRequest.Protocol == "tcp" {
protocol = TCP
} else if proxyStatusRequest.Protocol == "udp" {
protocol = UDP
} else {
return nil, fmt.Errorf("invalid protocol")
}
proxyStatusRequestBytes[6+len(ipBytes)] = protocol
return proxyStatusRequestBytes, nil
case "proxyStatusResponse":
proxyStatusResponse, ok := command.(*ProxyStatusResponse)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
sourceIP := net.ParseIP(proxyStatusResponse.SourceIP)
var ipVer uint8
var ipBytes []byte
if sourceIP.To4() == nil {
ipBytes = sourceIP.To16()
ipVer = IPv6
} else {
ipBytes = sourceIP.To4()
ipVer = IPv4
}
proxyStatusResponseBytes := make([]byte, 1+1+len(ipBytes)+2+2+1+1)
proxyStatusResponseBytes[0] = ProxyStatusResponseID
proxyStatusResponseBytes[1] = ipVer
copy(proxyStatusResponseBytes[2:2+len(ipBytes)], ipBytes)
binary.BigEndian.PutUint16(proxyStatusResponseBytes[2+len(ipBytes):4+len(ipBytes)], proxyStatusResponse.SourcePort)
binary.BigEndian.PutUint16(proxyStatusResponseBytes[4+len(ipBytes):6+len(ipBytes)], proxyStatusResponse.DestPort)
var protocol uint8
if proxyStatusResponse.Protocol == "tcp" {
protocol = TCP
} else if proxyStatusResponse.Protocol == "udp" {
protocol = UDP
} else {
return nil, fmt.Errorf("invalid protocol")
}
proxyStatusResponseBytes[6+len(ipBytes)] = protocol
var isActive uint8
if proxyStatusResponse.IsActive {
isActive = 1
} else {
isActive = 0
}
proxyStatusResponseBytes[7+len(ipBytes)] = isActive
return proxyStatusResponseBytes, nil
case "proxyConnectionResponse":
proxyConectionResponse, ok := command.(*ProxyConnectionResponse)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
proxyArray := make([][]byte, len(proxyConectionResponse.Proxies))
totalSize := 0
for proxyIndex, proxy := range proxyConectionResponse.Proxies {
var err error
proxyArray[proxyIndex], err = marshalIndividualProxyStruct(proxy)
if err != nil {
return nil, err
}
totalSize += len(proxyArray[proxyIndex]) + 1
}
connectionCommandArray := make([]byte, totalSize+1)
connectionCommandArray[0] = ProxyConnectionResponseID
currentPosition := 1
for _, connection := range proxyArray {
copy(connectionCommandArray[currentPosition:currentPosition+len(connection)], connection)
connectionCommandArray[currentPosition+len(connection)] = '\r'
currentPosition += len(connection) + 1
}
connectionCommandArray[totalSize] = '\n'
return connectionCommandArray, nil
case "proxyConnectionRequest":
_, ok := command.(*ProxyConnectionRequest)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
return []byte{ProxyConnectionRequestID}, nil
case "getAllConnectionsRequest":
_, ok := command.(*GetAllConnectionsRequest)
if !ok {
return nil, fmt.Errorf("failed to typecast")
}
return []byte{GetAllConnectionsRequestID}, nil
}
return nil, fmt.Errorf("couldn't match command")

View file

@ -292,17 +292,17 @@ func TestGetAllConnectionsCommandMarshalSupport(t *testing.T) {
log.Printf("(in #%d) SourcePort's are not equal (orig: %d, unmsh: %d)", commandIndex, originalConnection.SourcePort, remoteConnection.SourcePort)
}
if originalConnection.SourcePort != remoteConnection.SourcePort {
if originalConnection.DestPort != remoteConnection.DestPort {
t.Fail()
log.Printf("(in #%d) DestPort's are not equal (orig: %d, unmsh: %d)", commandIndex, originalConnection.DestPort, remoteConnection.DestPort)
}
if originalConnection.SourcePort != remoteConnection.SourcePort {
if originalConnection.ClientIP != remoteConnection.ClientIP {
t.Fail()
log.Printf("(in #%d) ClientIP's are not equal (orig: %s, unmsh: %s)", commandIndex, originalConnection.ClientIP, remoteConnection.ClientIP)
}
if originalConnection.SourcePort != remoteConnection.SourcePort {
if originalConnection.ClientPort != remoteConnection.ClientPort {
t.Fail()
log.Printf("(in #%d) ClientPort's are not equal (orig: %d, unmsh: %d)", commandIndex, originalConnection.ClientPort, remoteConnection.ClientPort)
}
@ -472,3 +472,353 @@ func TestCheckParametersResponseMarshalSupport(t *testing.T) {
log.Printf("Messages are not equal (orig: %s, unmsh: %s)", commandInput.Message, commandUnmarshalled.Message)
}
}
func TestBackendStatusRequestMarshalSupport(t *testing.T) {
commandInput := &BackendStatusRequest{
Type: "backendStatusRequest",
}
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
if logLevel == "debug" {
log.Printf("Generated array contents: %v", commandMarshalled)
}
if err != nil {
t.Fatalf(err.Error())
}
buf := bytes.NewBuffer(commandMarshalled)
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
if err != nil {
t.Fatal(err.Error())
}
if commandType != commandInput.Type {
t.Fail()
log.Print("command type does not match up!")
}
commandUnmarshalled, ok := commandUnmarshalledRaw.(*BackendStatusRequest)
if !ok {
t.Fatal("failed typecast")
}
if commandInput.Type != commandUnmarshalled.Type {
t.Fail()
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
}
}
func TestBackendStatusResponseMarshalSupport(t *testing.T) {
commandInput := &BackendStatusResponse{
Type: "backendStatusResponse",
IsRunning: true,
StatusCode: StatusFailure,
Message: "Hello from automated testing",
}
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
if logLevel == "debug" {
log.Printf("Generated array contents: %v", commandMarshalled)
}
if err != nil {
t.Fatalf(err.Error())
}
buf := bytes.NewBuffer(commandMarshalled)
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
if err != nil {
t.Fatal(err.Error())
}
if commandType != commandInput.Type {
t.Fail()
log.Print("command type does not match up!")
}
commandUnmarshalled, ok := commandUnmarshalledRaw.(*BackendStatusResponse)
if !ok {
t.Fatal("failed typecast")
}
if commandInput.Type != commandUnmarshalled.Type {
t.Fail()
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
}
if commandInput.IsRunning != commandUnmarshalled.IsRunning {
t.Fail()
log.Printf("IsRunning's are not equal (orig: %t, unmsh: %t)", commandInput.IsRunning, commandUnmarshalled.IsRunning)
}
if commandInput.StatusCode != commandUnmarshalled.StatusCode {
t.Fail()
log.Printf("StatusCodes are not equal (orig: %d, unmsh: %d)", commandInput.StatusCode, commandUnmarshalled.StatusCode)
}
if commandInput.Message != commandUnmarshalled.Message {
t.Fail()
log.Printf("Messages are not equal (orig: %s, unmsh: %s)", commandInput.Message, commandUnmarshalled.Message)
}
}
func TestProxyStatusRequestMarshalSupport(t *testing.T) {
commandInput := &ProxyStatusRequest{
Type: "proxyStatusRequest",
SourceIP: "192.168.0.139",
SourcePort: 19132,
DestPort: 19132,
Protocol: "tcp",
}
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
if err != nil {
t.Fatalf(err.Error())
}
if logLevel == "debug" {
log.Printf("Generated array contents: %v", commandMarshalled)
}
buf := bytes.NewBuffer(commandMarshalled)
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
if err != nil {
t.Fatal(err.Error())
}
if commandType != commandInput.Type {
t.Fail()
log.Print("command type does not match up!")
}
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyStatusRequest)
if !ok {
t.Fatal("failed typecast")
}
if commandInput.Type != commandUnmarshalled.Type {
t.Fail()
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
}
if commandInput.SourceIP != commandUnmarshalled.SourceIP {
t.Fail()
log.Printf("SourceIP's are not equal (orig: %s, unmsh: %s)", commandInput.SourceIP, commandUnmarshalled.SourceIP)
}
if commandInput.SourcePort != commandUnmarshalled.SourcePort {
t.Fail()
log.Printf("SourcePort's are not equal (orig: %d, unmsh: %d)", commandInput.SourcePort, commandUnmarshalled.SourcePort)
}
if commandInput.DestPort != commandUnmarshalled.DestPort {
t.Fail()
log.Printf("DestPort's are not equal (orig: %d, unmsh: %d)", commandInput.DestPort, commandUnmarshalled.DestPort)
}
if commandInput.Protocol != commandUnmarshalled.Protocol {
t.Fail()
log.Printf("Protocols are not equal (orig: %s, unmsh: %s)", commandInput.Protocol, commandUnmarshalled.Protocol)
}
}
func TestProxyStatusResponseMarshalSupport(t *testing.T) {
commandInput := &ProxyStatusResponse{
Type: "proxyStatusResponse",
SourceIP: "192.168.0.139",
SourcePort: 19132,
DestPort: 19132,
Protocol: "tcp",
IsActive: true,
}
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
if err != nil {
t.Fatalf(err.Error())
}
if logLevel == "debug" {
log.Printf("Generated array contents: %v", commandMarshalled)
}
buf := bytes.NewBuffer(commandMarshalled)
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
if err != nil {
t.Fatal(err.Error())
}
if commandType != commandInput.Type {
t.Fail()
log.Print("command type does not match up!")
}
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyStatusResponse)
if !ok {
t.Fatal("failed typecast")
}
if commandInput.Type != commandUnmarshalled.Type {
t.Fail()
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
}
if commandInput.SourceIP != commandUnmarshalled.SourceIP {
t.Fail()
log.Printf("SourceIP's are not equal (orig: %s, unmsh: %s)", commandInput.SourceIP, commandUnmarshalled.SourceIP)
}
if commandInput.SourcePort != commandUnmarshalled.SourcePort {
t.Fail()
log.Printf("SourcePort's are not equal (orig: %d, unmsh: %d)", commandInput.SourcePort, commandUnmarshalled.SourcePort)
}
if commandInput.DestPort != commandUnmarshalled.DestPort {
t.Fail()
log.Printf("DestPort's are not equal (orig: %d, unmsh: %d)", commandInput.DestPort, commandUnmarshalled.DestPort)
}
if commandInput.Protocol != commandUnmarshalled.Protocol {
t.Fail()
log.Printf("Protocols are not equal (orig: %s, unmsh: %s)", commandInput.Protocol, commandUnmarshalled.Protocol)
}
if commandInput.IsActive != commandUnmarshalled.IsActive {
t.Fail()
log.Printf("IsActive's are not equal (orig: %t, unmsh: %t)", commandInput.IsActive, commandUnmarshalled.IsActive)
}
}
func TestProxyConnectionRequestMarshalSupport(t *testing.T) {
commandInput := &ProxyConnectionRequest{
Type: "proxyConnectionRequest",
}
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
if logLevel == "debug" {
log.Printf("Generated array contents: %v", commandMarshalled)
}
if err != nil {
t.Fatalf(err.Error())
}
buf := bytes.NewBuffer(commandMarshalled)
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
if err != nil {
t.Fatal(err.Error())
}
if commandType != commandInput.Type {
t.Fail()
log.Print("command type does not match up!")
}
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionRequest)
if !ok {
t.Fatal("failed typecast")
}
if commandInput.Type != commandUnmarshalled.Type {
t.Fail()
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
}
}
func TestProxyConnectionResponseMarshalSupport(t *testing.T) {
commandInput := &ProxyConnectionResponse{
Type: "proxyConnectionResponse",
Proxies: []*ProxyConnection{
{
SourceIP: "192.168.0.168",
SourcePort: 25565,
DestPort: 25565,
Protocol: "tcp",
},
{
SourceIP: "127.0.0.1",
SourcePort: 19132,
DestPort: 19132,
Protocol: "udp",
},
{
SourceIP: "68.42.203.47",
SourcePort: 22,
DestPort: 2222,
Protocol: "tcp",
},
},
}
commandMarshalled, err := Marshal(commandInput.Type, commandInput)
if err != nil {
t.Fatalf(err.Error())
}
if logLevel == "debug" {
log.Printf("Generated array contents: %v", commandMarshalled)
}
buf := bytes.NewBuffer(commandMarshalled)
commandType, commandUnmarshalledRaw, err := Unmarshal(buf)
if err != nil {
t.Fatal(err.Error())
}
if commandType != commandInput.Type {
t.Fail()
log.Print("command type does not match up!")
}
commandUnmarshalled, ok := commandUnmarshalledRaw.(*ProxyConnectionResponse)
if !ok {
t.Fatal("failed typecast")
}
if commandInput.Type != commandUnmarshalled.Type {
t.Fail()
log.Printf("Types are not equal (orig: %s, unmsh: %s)", commandInput.Type, commandUnmarshalled.Type)
}
for proxyIndex, originalProxy := range commandInput.Proxies {
remoteProxy := commandUnmarshalled.Proxies[proxyIndex]
if originalProxy.SourceIP != remoteProxy.SourceIP {
t.Fail()
log.Printf("(in #%d) SourceIP's are not equal (orig: %s, unmsh: %s)", proxyIndex, originalProxy.SourceIP, remoteProxy.SourceIP)
}
if originalProxy.SourcePort != remoteProxy.SourcePort {
t.Fail()
log.Printf("(in #%d) SourcePort's are not equal (orig: %d, unmsh: %d)", proxyIndex, originalProxy.SourcePort, remoteProxy.SourcePort)
}
if originalProxy.DestPort != remoteProxy.DestPort {
t.Fail()
log.Printf("(in #%d) DestPort's are not equal (orig: %d, unmsh: %d)", proxyIndex, originalProxy.DestPort, remoteProxy.DestPort)
}
if originalProxy.Protocol != remoteProxy.Protocol {
t.Fail()
log.Printf("(in #%d) ClientIP's are not equal (orig: %s, unmsh: %s)", proxyIndex, originalProxy.Protocol, remoteProxy.Protocol)
}
}
}

View file

@ -79,6 +79,65 @@ func unmarshalIndividualConnectionStruct(conn io.Reader) (*ClientConnection, err
}, nil
}
func unmarshalIndividualProxyStruct(conn io.Reader) (*ProxyConnection, error) {
ipVersion := make([]byte, 1)
if _, err := conn.Read(ipVersion); err != nil {
return nil, fmt.Errorf("couldn't read ip version")
}
var ipSize uint8
if ipVersion[0] == 4 {
ipSize = IPv4Size
} else if ipVersion[0] == 6 {
ipSize = IPv6Size
} else {
return nil, fmt.Errorf("invalid IP version recieved")
}
ip := make(net.IP, ipSize)
if _, err := conn.Read(ip); err != nil {
return nil, fmt.Errorf("couldn't read source IP")
}
sourcePort := make([]byte, 2)
if _, err := conn.Read(sourcePort); err != nil {
return nil, fmt.Errorf("couldn't read source port")
}
destPort := make([]byte, 2)
if _, err := conn.Read(destPort); err != nil {
return nil, fmt.Errorf("couldn't read destination port")
}
protocolBytes := make([]byte, 1)
if _, err := conn.Read(protocolBytes); err != nil {
return nil, fmt.Errorf("couldn't read protocol")
}
var protocol string
if protocolBytes[0] == TCP {
protocol = "tcp"
} else if protocolBytes[0] == UDP {
protocol = "udp"
} else {
return nil, fmt.Errorf("invalid protocol")
}
return &ProxyConnection{
SourceIP: ip.String(),
SourcePort: binary.BigEndian.Uint16(sourcePort),
DestPort: binary.BigEndian.Uint16(destPort),
Protocol: protocol,
}, nil
}
func Unmarshal(conn io.Reader) (string, interface{}, error) {
commandType := make([]byte, 1)
@ -381,6 +440,213 @@ func Unmarshal(conn io.Reader) (string, interface{}, error) {
IsValid: isValid[0] == 1,
Message: message,
}, nil
case BackendStatusResponseID:
isRunning := make([]byte, 1)
if _, err := conn.Read(isRunning); err != nil {
return "", nil, fmt.Errorf("couldn't read isRunning field")
}
statusCode := make([]byte, 1)
if _, err := conn.Read(statusCode); err != nil {
return "", nil, fmt.Errorf("couldn't read status code field")
}
messageLengthBytes := make([]byte, 2)
if _, err := conn.Read(messageLengthBytes); err != nil {
return "", nil, fmt.Errorf("couldn't read message length")
}
messageLength := binary.BigEndian.Uint16(messageLengthBytes)
var message string
if messageLength != 0 {
messageBytes := make([]byte, messageLength)
if _, err := conn.Read(messageBytes); err != nil {
return "", nil, fmt.Errorf("couldn't read message")
}
message = string(messageBytes)
}
return "backendStatusResponse", &BackendStatusResponse{
Type: "backendStatusResponse",
IsRunning: isRunning[0] == 1,
StatusCode: int(statusCode[0]),
Message: message,
}, nil
case BackendStatusRequestID:
return "backendStatusRequest", &BackendStatusRequest{
Type: "backendStatusRequest",
}, nil
case ProxyStatusRequestID:
ipVersion := make([]byte, 1)
if _, err := conn.Read(ipVersion); err != nil {
return "", nil, fmt.Errorf("couldn't read ip version")
}
var ipSize uint8
if ipVersion[0] == 4 {
ipSize = IPv4Size
} else if ipVersion[0] == 6 {
ipSize = IPv6Size
} else {
return "", nil, fmt.Errorf("invalid IP version recieved")
}
ip := make(net.IP, ipSize)
if _, err := conn.Read(ip); err != nil {
return "", nil, fmt.Errorf("couldn't read source IP")
}
sourcePort := make([]byte, 2)
if _, err := conn.Read(sourcePort); err != nil {
return "", nil, fmt.Errorf("couldn't read source port")
}
destPort := make([]byte, 2)
if _, err := conn.Read(destPort); err != nil {
return "", nil, fmt.Errorf("couldn't read destination port")
}
protocolBytes := make([]byte, 1)
if _, err := conn.Read(protocolBytes); err != nil {
return "", nil, fmt.Errorf("couldn't read protocol")
}
var protocol string
if protocolBytes[0] == TCP {
protocol = "tcp"
} else if protocolBytes[1] == UDP {
protocol = "udp"
} else {
return "", nil, fmt.Errorf("invalid protocol")
}
return "proxyStatusRequest", &ProxyStatusRequest{
Type: "proxyStatusRequest",
SourceIP: ip.String(),
SourcePort: binary.BigEndian.Uint16(sourcePort),
DestPort: binary.BigEndian.Uint16(destPort),
Protocol: protocol,
}, nil
case ProxyStatusResponseID:
ipVersion := make([]byte, 1)
if _, err := conn.Read(ipVersion); err != nil {
return "", nil, fmt.Errorf("couldn't read ip version")
}
var ipSize uint8
if ipVersion[0] == 4 {
ipSize = IPv4Size
} else if ipVersion[0] == 6 {
ipSize = IPv6Size
} else {
return "", nil, fmt.Errorf("invalid IP version recieved")
}
ip := make(net.IP, ipSize)
if _, err := conn.Read(ip); err != nil {
return "", nil, fmt.Errorf("couldn't read source IP")
}
sourcePort := make([]byte, 2)
if _, err := conn.Read(sourcePort); err != nil {
return "", nil, fmt.Errorf("couldn't read source port")
}
destPort := make([]byte, 2)
if _, err := conn.Read(destPort); err != nil {
return "", nil, fmt.Errorf("couldn't read destination port")
}
protocolBytes := make([]byte, 1)
if _, err := conn.Read(protocolBytes); err != nil {
return "", nil, fmt.Errorf("couldn't read protocol")
}
var protocol string
if protocolBytes[0] == TCP {
protocol = "tcp"
} else if protocolBytes[1] == UDP {
protocol = "udp"
} else {
return "", nil, fmt.Errorf("invalid protocol")
}
isActive := make([]byte, 1)
if _, err := conn.Read(isActive); err != nil {
return "", nil, fmt.Errorf("couldn't read isActive field")
}
return "proxyStatusResponse", &ProxyStatusResponse{
Type: "proxyStatusResponse",
SourceIP: ip.String(),
SourcePort: binary.BigEndian.Uint16(sourcePort),
DestPort: binary.BigEndian.Uint16(destPort),
Protocol: protocol,
IsActive: isActive[0] == 1,
}, nil
case ProxyConnectionRequestID:
return "proxyConnectionRequest", &ProxyConnectionRequest{
Type: "proxyConnectionRequest",
}, nil
case ProxyConnectionResponseID:
proxies := []*ProxyConnection{}
delimiter := make([]byte, 1)
var errorReturn error
// Infinite loop because we don't know the length
for {
proxy, err := unmarshalIndividualProxyStruct(conn)
if err != nil {
return "", nil, err
}
proxies = append(proxies, proxy)
if _, err := conn.Read(delimiter); err != nil {
return "", nil, fmt.Errorf("couldn't read delimiter")
}
if delimiter[0] == '\r' {
continue
} else if delimiter[0] == '\n' {
break
} else {
// WTF? This shouldn't happen. Break out and return, but give an error
errorReturn = fmt.Errorf("invalid delimiter recieved while processing stream")
break
}
}
return "proxyConnectionResponse", &ProxyConnectionResponse{
Type: "proxyConnectionResponse",
Proxies: proxies,
}, errorReturn
case GetAllConnectionsRequestID:
return "getAllConnectionsRequest", &GetAllConnectionsRequest{
Type: "getAllConnectionsRequest",
}, nil
}
return "", nil, fmt.Errorf("couldn't match command")