package server import ( "fmt" "log" "net" "time" "go.rctt.net/solec/core" ) 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) handleMessage(sender net.Conn, connType core.ConnType, senderUser *User, msg core.Message) error { if connType == core.ConnTypeUser { msg.Timestamp = time.Now() } log.Println("message:", msg.Source, "->", msg.Target, msg.Content) addr, err := core.ReadAddr(msg.Target) if err != nil { return err } if err := s.Storage.AddMessage(msg); err != nil { log.Println("cannot write to database", err) } if addr.Host == s.cfg.Name { return s.handleLocalMessage(sender, senderUser, addr, msg) } return s.handleOutboundMessage(addr, msg) } func (s *Server) handleLocalMessage(sender net.Conn, senderUser *User, addr core.Addr, msg core.Message) error { perm, err := s.Storage.GetPermission(senderUser.Addr, addr.String()) if err != nil { log.Println("cannot get channel permissions:", err) return core.Send(sender, core.Error{core.ErrorNotFound}) } if !perm.Write { log.Println("user not authorized") return core.Send(sender, core.Error{core.ErrorNotFound}) } if addr.Type == core.AddrUser { s.handleUserMessage(addr, sender, msg) return nil } users, err := s.Storage.GetChannelUsers(addr.String()) if err != nil { log.Println("cannot get channel users:", err) return core.Send(sender, core.Error{core.ErrorUnknown}) } for _, u := range users { addr, err := core.ReadAddr(u) if err != nil { log.Println("cannot read user address:", err) continue } if addr.Host != s.cfg.Name { err := s.handleOutboundMessage(addr, msg) if err != nil { log.Println("cannot send group message to remote user:", err) } continue } err = s.handleUserMessage(addr, sender, msg) if err != nil { log.Println("cannot send group message to local user:", err) } } return nil } func (s *Server) handleOutboundMessage(addr core.Addr, msg core.Message) error { remote, err := s.getRemote(addr.Host) if err != nil { return fmt.Errorf("cannot access remote server: %w", err) } return core.Send(remote.Conn, msg) } func (s *Server) handleUserMessage(addr core.Addr, sender net.Conn, msg core.Message) error { s.usersMu.RLock() user, ok := s.users[addr.String()] if !ok { log.Println("user not found") return core.Send(sender, core.Error{core.ErrorNotFound}) } s.usersMu.RUnlock() return user.Send(sender, msg) }