From d0c6ea682d85c062d3fa4975635518841e92e5ba Mon Sep 17 00:00:00 2001 From: abdfnx Date: Thu, 3 Feb 2022 09:52:18 +0300 Subject: [PATCH] add gorilla websocket module, build tran protocol model --- go.mod | 1 + go.sum | 2 + models/protocol/transfer.go | 107 ++++++++++++++++++++++++++++++++++++ models/protocol/tranx.go | 60 ++++++++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 models/protocol/transfer.go create mode 100644 models/protocol/tranx.go diff --git a/go.mod b/go.mod index 6f23c30..915e118 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/charmbracelet/bubbles v0.10.2 github.com/charmbracelet/lipgloss v0.4.0 + github.com/gorilla/websocket v1.4.2 ) require ( diff --git a/go.sum b/go.sum index df8c7a9..c7d7313 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ github.com/charmbracelet/lipgloss v0.4.0 h1:768h64EFkGUr8V5yAKV7/Ta0NiVceiPaV+Pp github.com/charmbracelet/lipgloss v0.4.0/go.mod h1:vmdkHvce7UzX6xkyf4cca8WlwdQ5RQr8fzta+xl7BOM= github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= diff --git a/models/protocol/transfer.go b/models/protocol/transfer.go new file mode 100644 index 0000000..fce52d5 --- /dev/null +++ b/models/protocol/transfer.go @@ -0,0 +1,107 @@ +package protocol + +import ( + "fmt" + "net" + "strings" +) + +// TransferMessageType specifies the message type for the messages in the transfer protocol. +type TransferMessageType int + +const ( + TransferError TransferMessageType = iota // An error has occured in transferProtocol + ReceiverHandshake // Receiver exchange its IP via the tranx server to the sender + SenderHandshake // Sender exchanges IP, port and payload size to the receiver via the tranx server + ReceiverDirectCommunication + SenderDirectAck // Sender ACKs the request for direct communication + ReceiverRelayCommunication // Receiver has tried to probe the sender but cannot find it on the subnet, relay communication will be used + SenderRelayAck // Sender ACKs the request for relay communication + ReceiverRequestPayload // Receiver request the payload from the sender + SenderPayloadSent // Sender announces that the entire file has been transfered + ReceiverPayloadAck // Receiver ACKs that is has received the payload + SenderClosing // Sender announces that it is closing the connection + ReceiverClosingAck // Receiver ACKs the closing of the connection +) + +// TransferMessage specifies a message in the transfer protocol. +type TransferMessage struct { + Type TransferMessageType `json:"type"` + Payload interface{} `json:"payload,omitempty"` +} + +func (t TransferMessage) Bytes() []byte { + return []byte(fmt.Sprintf("%v", t)) +} + +type ReceiverHandshakePayload struct { + IP net.IP `json:"ip"` +} + +// SenderHandshakePayload specifies a payload type for announcing the payload size. +type SenderHandshakePayload struct { + IP net.IP `json:"ip"` + Port int `json:"port"` + PayloadSize int64 `json:"payload_size"` +} + +type WrongMessageTypeError struct { + expected []TransferMessageType + got TransferMessageType +} + +func NewWrongMessageTypeError(expected []TransferMessageType, got TransferMessageType) *WrongMessageTypeError { + return &WrongMessageTypeError{ + expected: expected, + got: got, + } +} + +func (e *WrongMessageTypeError) Error() string { + var expectedMessageTypes []string + + for _, expectedType := range e.expected { + expectedMessageTypes = append(expectedMessageTypes, expectedType.Name()) + } + + oneOfExpected := strings.Join(expectedMessageTypes, ", ") + + return fmt.Sprintf("wrong message type, expected one of: (%s), got: (%s)", oneOfExpected, e.got.Name()) +} + +func (t TransferMessageType) Name() string { + switch t { + case TransferError: + return "TransferError" + + case ReceiverHandshake: + return "ReceiverHandshake" + + case SenderHandshake: + return "SenderHandshake" + + case ReceiverRelayCommunication: + return "ReceiverRelayCommunication" + + case SenderRelayAck: + return "SenderRelayAck" + + case ReceiverRequestPayload: + return "ReceiverRequestPayload" + + case SenderPayloadSent: + return "SenderPayloadSent" + + case ReceiverPayloadAck: + return "ReceiverAckPayload" + + case SenderClosing: + return "SenderClosing" + + case ReceiverClosingAck: + return "ReceiverClosingAck" + + default: + return "" + } +} diff --git a/models/protocol/tranx.go b/models/protocol/tranx.go new file mode 100644 index 0000000..1ad017a --- /dev/null +++ b/models/protocol/tranx.go @@ -0,0 +1,60 @@ +package protocol + +import ( + "net" + + "github.com/gorilla/websocket" +) + +type TranxMessageType int + +const ( + TranxToSenderBind TranxMessageType = iota // An ID for this connection is bound and communicated + SenderToTranxEstablish // Sender has generated and hashed password + ReceiverToTranxEstablish // Passsword has been communicated to receiver who has hashed it + TranxToSenderReady // Tranx announces to sender that receiver is connected + SenderToTranxPAKE // Sender sends PAKE information to tranx + TranxToReceiverPAKE // Tranx forwards PAKE information to receiver + ReceiverToTranxPAKE // Receiver sends PAKE information to tranx + TranxToSenderPAKE // Tranx forwards PAKE information to receiver + SenderToTranxSalt // Sender sends cryptographic salt to tranx + TranxToReceiverSalt // Rendevoux forwards cryptographic salt to receiver + ReceiverToTranxClose // Receiver can connect directly to sender, close receiver connection -> close sender connection + SenderToTranxClose // Transit sequence is completed, close sender connection -> close receiver connection +) + +type TranxMessage struct { + Type TranxMessageType `json:"type"` + Payload interface{} `json:"payload"` +} + +type TranxClient struct { + Conn *websocket.Conn + IP net.IP +} + +type TranxSender struct { + TranxClient + Port int +} + +type TranxReceiver = TranxClient + +/* [💻 Receiver <-> Sender 💻] messages */ + +type PasswordPayload struct { + Password string `json:"password"` +} +type PakePayload struct { + Bytes []byte `json:"pake_bytes"` +} + +type SaltPayload struct { + Salt []byte `json:"salt"` +} + +/* [Tranx -> Sender] messages */ + +type TranxToSenderBindPayload struct { + ID int `json:"id"` +}