Protocol version is now checked when the agent connects to the converge server. Next up: sending connection metadata and username password from server to agent and sending environment information back to the server. This means then that the side channel will only be used for expiry time messages and session type with the client id passed in so the converge server can than correlate the results back to the correct channel.
63 lines
1.4 KiB
Go
63 lines
1.4 KiB
Go
package comms
|
|
|
|
import (
|
|
"encoding/gob"
|
|
"io"
|
|
"log"
|
|
)
|
|
|
|
type GOBChannel struct {
|
|
// can be any connection, including the ssh connnection before it is
|
|
// passed on to SSH during initialization of converge to agent communication
|
|
Peer io.ReadWriter
|
|
Encoder *gob.Encoder
|
|
Decoder *gob.Decoder
|
|
}
|
|
|
|
func NewGOBChannel(conn io.ReadWriter) GOBChannel {
|
|
return GOBChannel{
|
|
Peer: conn,
|
|
Encoder: gob.NewEncoder(conn),
|
|
Decoder: gob.NewDecoder(conn),
|
|
}
|
|
}
|
|
|
|
// Asynchronous send and receive on a single connection is guaranteed to preserver ordering of
|
|
// messages. We use asynchronous to void blocking indefinitely or depending on network timeouts.
|
|
|
|
func (channel GOBChannel) SendAsync(obj any, done chan<- any, errors chan<- error) {
|
|
go func() {
|
|
err := channel.Send(obj)
|
|
if err != nil {
|
|
errors <- err
|
|
} else {
|
|
done <- true
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (channel GOBChannel) ReceiveAsync(result chan<- any, errors chan<- error) {
|
|
go func() {
|
|
value, err := channel.Receive()
|
|
if err != nil {
|
|
errors <- err
|
|
} else {
|
|
result <- value
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (channel GOBChannel) Send(object any) error {
|
|
err := channel.Encoder.Encode(ConvergeMessage{Value: object})
|
|
if err != nil {
|
|
log.Printf("Encoding error %v", err)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (channel GOBChannel) Receive() (any, error) {
|
|
var target ConvergeMessage
|
|
err := channel.Decoder.Decode(&target)
|
|
return target.Value, err
|
|
}
|