diff options
| author | bt <bt@rctt.net> | 2026-03-19 14:33:47 +0100 |
|---|---|---|
| committer | bt <bt@localhost> | 2026-03-30 22:16:28 +0200 |
| commit | 3f37bbe8d8d7a9829bedf0eb1ec6ea67ad1aeed5 (patch) | |
| tree | 320e5084f7253753a2a2b2eeb4bbf4b31c890e1d | |
| parent | 37190b05b522890388d22f55d11d456635e89559 (diff) | |
| download | solec-3f37bbe8d8d7a9829bedf0eb1ec6ea67ad1aeed5.tar.gz solec-3f37bbe8d8d7a9829bedf0eb1ec6ea67ad1aeed5.zip | |
[daemon] Handle local, private messages
| -rw-r--r-- | cmd/client/main.go | 10 | ||||
| -rw-r--r-- | cmd/daemon/main.go | 13 | ||||
| -rw-r--r-- | core/data.go | 11 | ||||
| -rw-r--r-- | docs/rfc.md | 7 | ||||
| -rw-r--r-- | server/server.go | 71 |
5 files changed, 77 insertions, 35 deletions
diff --git a/cmd/client/main.go b/cmd/client/main.go index 2612267..8c2258a 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -18,7 +18,7 @@ var ( ) func main() { - prompt.Commands["*"] = broadcast + prompt.Commands["send"] = sendMessage flag.StringVar(&serverAddr, "a", "localhost:9999", "Server address:port") flag.StringVar(&user, "u", "user", "username") @@ -74,16 +74,14 @@ func handleMessage(conn net.Conn, msg core.Message) { log.Println("received message", msg.Source, "->", msg.Target, msg.Content) } -func broadcast(args []string) { +func sendMessage(args []string) { msg := core.Message{ Source: user, - Target: "*", + Target: args[0], Timestamp: time.Now(), - Content: strings.Join(args[0:], " "), + Content: strings.Join(args[1:], " "), } - log.Println(msg.Content) - if err := core.Send(conn, msg); err != nil { panic(err) } diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index 32b3954..d0e4d1c 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -14,8 +14,9 @@ import ( ) var ( - cmds = map[string]func(args []string){} - + cmds = map[string]func(args []string){ + "broadcast": sendBroadcast, + } serv *server.Server ) @@ -24,9 +25,10 @@ func main() { fmt.Println("Commands:", slices.Sorted(maps.Keys(cmds))) addr := flag.String("a", "localhost:9999", "listening address:port") + name := flag.String("n", "localhost", "server name") flag.Parse() - serv = server.NewServer(*addr) + serv = server.NewServer(*addr, *name) go func() { if err := serv.Start(); err != nil { @@ -56,3 +58,8 @@ func readCmds() { log.Println(err) } } + +func sendBroadcast(args []string) { + msg := strings.Join(args[0:], " ") + serv.SendBroadcast(msg) +} diff --git a/core/data.go b/core/data.go index b25b853..9783c47 100644 --- a/core/data.go +++ b/core/data.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "fmt" "io" + "strings" "time" ) @@ -29,6 +30,7 @@ type ErrorType uint8 const ( ErrorUnknown ErrorType = 0x00 ErrorAuthFailed = 0x01 + ErrorNotFound = 0x02 ) type Frame struct { @@ -176,3 +178,12 @@ func decodeString(buf io.Reader, ptr *string) error { *ptr = string(strBytes) return nil } + +func ReadAddr(addr string) (string, string, error) { + channel, host, ok := strings.Cut(addr, "@") + if !ok { + return "", "", fmt.Errorf("invalid address") + } + + return channel, host, nil +} diff --git a/docs/rfc.md b/docs/rfc.md index 6f902b0..eb8f5c1 100644 --- a/docs/rfc.md +++ b/docs/rfc.md @@ -175,9 +175,10 @@ Payload is always empty for this type. #### Error types -| Type | Description | -|------|--------------------------------------------| -| 0x01 | Auth failed. Invalid username or password. | +| Type | Description | +|------|-----------------------------------------------------------| +| 0x01 | Auth failed. Invalid username or password. | +| 0x02 | Not found. User or channel cannot access user or channel. | ### Handshake diff --git a/server/server.go b/server/server.go index 51e71b1..bbfb676 100644 --- a/server/server.go +++ b/server/server.go @@ -6,12 +6,14 @@ import ( "log" "net" "sync" + "time" "git.sr.ht/~rctt/solec/core" ) type Server struct { listenAddr string + name string users map[string]User mu sync.Mutex } @@ -21,9 +23,20 @@ type User struct { Conns map[net.Conn]struct{} } -func NewServer(listenAddr string) *Server { +func (u *User) Send(payload core.Wrapper) error { + for c := range u.Conns { + if err := core.Send(c, payload); err != nil { + return err + } + } + + return nil +} + +func NewServer(listenAddr string, name string) *Server { return &Server{ listenAddr: listenAddr, + name: name, users: make(map[string]User), } } @@ -46,6 +59,27 @@ func (s *Server) Start() error { } } +func (s *Server) SendBroadcast(msg string) { + payload := core.Message{ + Source: "op@example.org", + Target: "*@example.org", + Timestamp: time.Now(), + Content: msg, + } + data, err := core.Encode(payload) + if err != nil { + panic(err) + } + + for _, u := range s.users { + for c := range u.Conns { + if _, err := c.Write(data); err != nil { + log.Println("cannot send", err) + } + } + } +} + func (s *Server) handleConn(conn net.Conn) { if err := s.performHandshake(conn); err != nil { log.Println("handshake error", err) @@ -157,32 +191,23 @@ func (s *Server) handlePayload(conn net.Conn, user User, payload any) error { func (s *Server) handleMessage(conn net.Conn, user User, msg core.Message) error { log.Println("message:", user.Name, "->", msg.Target, msg.Content) - if msg.Target == "*" { - return s.broadcastMessage(conn, user, msg) + channel, host, err := core.ReadAddr(msg.Target) + if err != nil { + return err } - return nil -} - -func (s *Server) broadcastMessage(conn net.Conn, user User, msg core.Message) error { - for _, u := range s.users { - if u.Name == user.Name { - continue - } - - for c := range u.Conns { - if err := core.Send(c, msg); err != nil { - log.Println("cannot send", err) - } - } + if host == s.name { + return s.handleLocalMessage(channel, msg) } - // Forward message for other connections from the same user - for c := range s.users[user.Name].Conns { - if err := core.Send(c, msg); err != nil { - log.Println("cannot send", err) - } + return fmt.Errorf("not supported") +} + +func (s *Server) handleLocalMessage(channel string, msg core.Message) error { + user, ok := s.users[channel] + if !ok { + return errors.New("target not found") } - return nil + return user.Send(msg) } |
