When a duplicate id is requested the server now allocates a new unique id so that the session can be handled anyway.

This commit is contained in:
Erik Brakkee 2024-07-30 19:45:25 +02:00
parent 64f2460bc9
commit 60d641a1a4
4 changed files with 88 additions and 7 deletions

View File

@ -268,10 +268,26 @@ func main() {
serverInfo, err := comms.AgentInitialization(wsConn, comms.NewAgentInfo()) serverInfo, err := comms.AgentInitialization(wsConn, comms.NewAgentInfo())
if err != nil { if err != nil {
log.Printf("ERROR: %+v", err) log.Printf("ERROR: %v", err)
os.Exit(1) os.Exit(1)
} }
registration, err := comms.ReceiveRegistrationMessage(wsConn)
if err != nil {
log.Printf("ERROR: %v", err)
os.Exit(1)
}
log.Println("Server responded with: ", registration.Message)
if registration.Id != id {
log.Println("==============================================================================")
log.Println("Duplicate agent id detected: the server allocated a new id to be used instead.")
log.Println("")
log.Println(registration.Id)
log.Println("==============================================================================")
}
clientUrl := args[0] + "/client/" + registration.Id
commChannel, err := comms.NewCommChannel(comms.Agent, wsConn) commChannel, err := comms.NewCommChannel(comms.Agent, wsConn)
if err != nil { if err != nil {
panic(err) panic(err)
@ -298,7 +314,6 @@ func main() {
log.Println() log.Println()
log.Printf("Clients should use the following commands to connect to this agent:") log.Printf("Clients should use the following commands to connect to this agent:")
log.Println() log.Println()
clientUrl := strings.ReplaceAll(wsURL, "/agent/", "/client/")
sshCommand := fmt.Sprintf("ssh -oServerAliveInterval=10 -oProxyCommand=\"wsproxy %s\" %s@localhost", sshCommand := fmt.Sprintf("ssh -oServerAliveInterval=10 -oProxyCommand=\"wsproxy %s\" %s@localhost",
clientUrl, serverInfo.UserPassword.Username) clientUrl, serverInfo.UserPassword.Username)
sftpCommand := fmt.Sprintf("sftp -oServerAliveInterval=10 -oProxyCommand=\"wsproxy %s\" %s@localhost", sftpCommand := fmt.Sprintf("sftp -oServerAliveInterval=10 -oProxyCommand=\"wsproxy %s\" %s@localhost",
@ -311,9 +326,13 @@ func main() {
log.Println() log.Println()
urlObject, _ := url.Parse(wsURL) urlObject, _ := url.Parse(wsURL)
extension := ""
if runtime.GOOS == "windows" {
extension = ".exe"
}
log.Printf("wsproxy can be downloaded from %s", log.Printf("wsproxy can be downloaded from %s",
strings.ReplaceAll(urlObject.Scheme, "ws", "http")+ strings.ReplaceAll(urlObject.Scheme, "ws", "http")+
"://"+urlObject.Host+"/docs/wsproxy") "://"+urlObject.Host+"/static/wsproxy"+extension)
log.Println() log.Println()
agent.ConfigureAgent(commChannel, advanceWarningTime, agentExpriryTime, tickerInterval) agent.ConfigureAgent(commChannel, advanceWarningTime, agentExpriryTime, tickerInterval)

View File

@ -236,3 +236,19 @@ func ReceiveClientInfo(conn io.ReadWriter) (ClientInfo, error) {
} }
return clientInfo, nil return clientInfo, nil
} }
// message sent on the initial connection from server to agent to confirm the registration
func SendRegistrationMessage(conn io.ReadWriter, registration AgentRegistration) error {
channel := NewGOBChannel(conn)
return SendWithTimeout(channel, registration)
}
func ReceiveRegistrationMessage(conn io.ReadWriter) (AgentRegistration, error) {
channel := NewGOBChannel(conn)
registration, err := ReceiveWithTimeout[AgentRegistration](channel)
if err != nil {
return AgentRegistration{}, err
}
return registration, nil
}

View File

@ -42,8 +42,6 @@ type HeartBeat struct {
// Empty // Empty
} }
// Message sent from converge server to agent
type ProtocolVersion struct { type ProtocolVersion struct {
Version int Version int
} }
@ -53,10 +51,21 @@ type UserPassword struct {
Password string Password string
} }
// initialization mesaage when agent connects to server
type ServerInfo struct { type ServerInfo struct {
UserPassword UserPassword UserPassword UserPassword
} }
// confirmation message when agent connects
type AgentRegistration struct {
Ok bool
Message string
// final Id assigned by the server. Usually identical to the requested id
// but if there is a conflict, a new id is chosen.
Id string
}
// Generic wrapper message required to send messages of arbitrary type // Generic wrapper message required to send messages of arbitrary type
type ConvergeMessage struct { type ConvergeMessage struct {

View File

@ -95,13 +95,50 @@ func (admin *Admin) logStatus() {
log.Printf("\n") log.Printf("\n")
} }
func (admin *Admin) getFreeId(publicId string) (string, error) {
usedIds := make(map[string]bool)
for _, agent := range admin.agents {
usedIds[agent.PublicId] = true
}
if !usedIds[publicId] {
return publicId, nil
}
if usedIds[publicId] {
for i := 0; i < 100; i++ {
candidate := publicId + "-" + strconv.Itoa(i)
if !usedIds[candidate] {
return candidate, nil
}
}
}
return "", fmt.Errorf("Could not allocate agent id based on requested public id '%s'", publicId)
}
func (admin *Admin) addAgent(publicId string, agentInfo comms.AgentInfo, conn io.ReadWriteCloser) (*AgentConnection, error) { func (admin *Admin) addAgent(publicId string, agentInfo comms.AgentInfo, conn io.ReadWriteCloser) (*AgentConnection, error) {
admin.mutex.Lock() admin.mutex.Lock()
defer admin.mutex.Unlock() defer admin.mutex.Unlock()
newPublicId, err := admin.getFreeId(publicId)
if err == nil {
message := "Requested id is accepted"
if publicId != newPublicId {
message = "The server allocated a new id."
}
publicId = newPublicId
comms.SendRegistrationMessage(conn, comms.AgentRegistration{
Ok: true,
Message: message,
Id: publicId,
})
} else {
comms.SendRegistrationMessage(conn, comms.AgentRegistration{
Ok: false,
Message: err.Error(),
})
}
agent := admin.agents[publicId] agent := admin.agents[publicId]
if agent != nil { if agent != nil {
return nil, fmt.Errorf("A different agent with same PublicId '%s' already registered", publicId) return nil, fmt.Errorf("SHOULD NEVER GET HERE!!!, A different agent with same PublicId '%s' already registered", publicId)
} }
commChannel, err := comms.NewCommChannel(comms.ConvergeServer, conn) commChannel, err := comms.NewCommChannel(comms.ConvergeServer, conn)
@ -188,7 +225,6 @@ func (admin *Admin) RemoveClient(client *ClientConnection) error {
func (admin *Admin) Register(publicId string, conn io.ReadWriteCloser, func (admin *Admin) Register(publicId string, conn io.ReadWriteCloser,
userPassword comms.UserPassword) error { userPassword comms.UserPassword) error {
defer conn.Close()
serverInfo := comms.ServerInfo{ serverInfo := comms.ServerInfo{
UserPassword: userPassword, UserPassword: userPassword,
@ -203,6 +239,7 @@ func (admin *Admin) Register(publicId string, conn io.ReadWriteCloser,
if err != nil { if err != nil {
return err return err
} }
publicId = agent.PublicId
defer func() { defer func() {
admin.RemoveAgent(publicId) admin.RemoveAgent(publicId)
}() }()