From e9aebac1a2a4732763c2f7e4428a23983d4eb6a3 Mon Sep 17 00:00:00 2001 From: bt Date: Fri, 10 Apr 2026 19:31:31 +0200 Subject: [common] Exchange messages between servers --- server/remote.go | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 server/remote.go (limited to 'server/remote.go') diff --git a/server/remote.go b/server/remote.go new file mode 100644 index 0000000..2449511 --- /dev/null +++ b/server/remote.go @@ -0,0 +1,112 @@ +package server + +import ( + "log" + "net" + + "go.rctt.net/solec/core" +) + +type RemoteServer struct { + Name string + Conn net.Conn +} + +func NewRemoteServer(name string, conn net.Conn) RemoteServer { + return RemoteServer{name, conn} +} + +func (s *Server) handleServerConn(conn net.Conn) { + defer conn.Close() + + name, err := s.performServerAuth(conn) + if err != nil { + log.Println("server auth error:", err) + return + } + + s.serversMu.RLock() + if _, ok := s.servers[name]; ok { + log.Println("server already connected") + return + } + s.serversMu.RUnlock() + + rs := NewRemoteServer(name, conn) + s.serversMu.Lock() + s.servers[name] = rs + s.serversMu.Unlock() + log.Println("connection from server:", name) + + defer func() { + s.serversMu.Lock() + log.Println("server disconnected: ", rs.Name) + delete(s.servers, rs.Name) + s.serversMu.Unlock() + }() + + if err := s.readInput(conn); err != nil { + log.Println(err) + } +} + +func (s *Server) performServerAuth(conn net.Conn) (string, error) { + payload, err := core.Decode(conn) + if err != nil { + return "", err + } + auth, ok := payload.(core.ServerAuth) + if !ok { + return "", core.ErrUnexpectedPayloadType + } + + if err := core.Send(conn, core.Success{}); err != nil { + return "", err + } + + return auth.Name, nil +} + +func (s *Server) getRemote(name string) (RemoteServer, error) { + s.serversMu.RLock() + remote, ok := s.servers[name] + s.serversMu.RUnlock() + + if ok { + return remote, nil + } + + conn, err := s.initRemoteConn(name) + if err != nil { + return RemoteServer{}, err + } + + rs := NewRemoteServer(name, conn) + s.serversMu.Lock() + s.servers[name] = rs + s.serversMu.Unlock() + log.Println("connected to server:", name) + + return rs, nil +} + +func (s *Server) initRemoteConn(name string) (net.Conn, error) { + conn, err := net.Dial("tcp", name+":9999") + if err != nil { + return conn, err + } + + hs := core.Handshake{0, 1, core.ConnTypeServer} + if err := core.Send(conn, hs); err != nil { + conn.Close() + return conn, err + } + + auth := core.ServerAuth{Name: s.name} + if err := core.Send(conn, auth); err != nil { + conn.Close() + return conn, err + } + + return conn, nil +} -- cgit v1.2.3