Skip to content

Commit

Permalink
Adds a new 'Kick' SYS server API service that listens on `$SYS.REQ.SE…
Browse files Browse the repository at this point in the history
…RVER.%s.KICK` (where %s is the server_id) and takes a JSON payload containing either an "id" or a "name" field. "id" kicks the client connection id, "name" kicks _all_ of the clients connected to the server with that name.

Signed-off-by: Jean-Noël Moyne <jnmoyne@gmail.com>
  • Loading branch information
jnmoyne committed Jul 8, 2023
1 parent 58a4c93 commit f24f068
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion server/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const (
accConnsEventSubjNew = "$SYS.ACCOUNT.%s.SERVER.CONNS"
accConnsEventSubjOld = "$SYS.SERVER.ACCOUNT.%s.CONNS" // kept for backward compatibility
shutdownEventSubj = "$SYS.SERVER.%s.SHUTDOWN"
clientKickReqSubj = "$SYS.REQ.SERVER.%s.KICK"
authErrorEventSubj = "$SYS.SERVER.%s.CLIENT.AUTH.ERR"
authErrorAccountEventSubj = "$SYS.ACCOUNT.CLIENT.AUTH.ERR"
serverStatsSubj = "$SYS.SERVER.%s.STATSZ"
Expand Down Expand Up @@ -1207,6 +1208,11 @@ func (s *Server) initEventTracking() {
if _, err := s.sysSubscribeInternal(accSubsSubj, s.noInlineCallback(s.debugSubscribers)); err != nil {
s.Errorf("Error setting up internal debug service for subscribers: %v", err)
}
// Client connection kick
subject = fmt.Sprintf(clientKickReqSubj, s.info.ID)
if _, err := s.sysSubscribe(subject, s.noInlineCallback(s.kickClient)); err != nil {
s.Errorf("Error setting up client kick service: %v", err)
}
}

// UserInfo returns basic information to a user about bound account and user permissions.
Expand Down Expand Up @@ -2679,8 +2685,22 @@ func (s *Server) nsubsRequest(sub *subscription, c *client, _ *Account, subject,
s.sendInternalMsgLocked(reply, _EMPTY_, nil, nsubs)
}

func (s *Server) kickClient(sub *subscription, c *client, _ *Account, subject, reply string, hdr, msg []byte) {
type kickClientReq struct {
Name string `json:"name"`
Id uint64 `json:"id"`
}

func (s *Server) kickClient(_ *subscription, _ *client, _ *Account, subject, reply string, hdr, msg []byte) {
var req kickClientReq
if err := json.Unmarshal(msg, &req); err != nil {
s.sys.client.Errorf("Error unmarshalling kick client request: %v", err)
return
}
if req.Id != 0 {
s.DisconnectClientByID(req.Id)
} else if req.Name != _EMPTY_ {
s.DisconnectClientsByName(req.Name)
}
}

// Helper to grab account name for a client.
Expand Down

0 comments on commit f24f068

Please sign in to comment.