diff --git a/rrcd/router.py b/rrcd/router.py index 72fb343..0d279f6 100644 --- a/rrcd/router.py +++ b/rrcd/router.py @@ -324,10 +324,6 @@ class MessageRouter: new_nick = n2 sess["nick"] = n2 - # Update nick index if nick changed - if old_nick != new_nick: - self.hub._update_nick_index(link, old_nick, new_nick) - self.log.info( "HELLO peer=%s nick=%r link_id=%s", self.hub._fmt_hash(peer_hash), @@ -335,29 +331,14 @@ class MessageRouter: self.hub._fmt_link_id(link), ) - sess["welcomed"] = True - self.hub._queue_welcome( - outgoing, + # Send welcome message and MOTD + self.hub.session_manager.send_welcome( link, + outgoing, peer_hash=peer_hash, - motd=self.hub.config.greeting, + old_nick=old_nick, + new_nick=new_nick, ) - - # Send MOTD after WELCOME (outside of outgoing queue to enable resource transfer) - # The outgoing queue will be sent first, then this callback will send the MOTD - if self.hub.config.greeting: - def send_motd(): - self.hub.message_helper.send_text_smart( - link, - msg_type=T_NOTICE, - text=self.hub.config.greeting, - room=None, - kind=RES_KIND_MOTD, - ) - # Store callback to be executed after outgoing packets are sent - if not hasattr(outgoing, '_post_send_callbacks'): - outgoing._post_send_callbacks = [] # type: ignore - outgoing._post_send_callbacks.append(send_motd) # type: ignore def _handle_re_hello( self, @@ -406,10 +387,6 @@ class MessageRouter: new_nick = n2 sess["nick"] = n2 - # Update nick index if nick changed - if old_nick != new_nick: - self.hub._update_nick_index(link, old_nick, new_nick) - self.log.info( "Re-HELLO peer=%s nick=%r link_id=%s", self.hub._fmt_hash(peer_hash), @@ -417,12 +394,13 @@ class MessageRouter: self.hub._fmt_link_id(link), ) - sess["welcomed"] = True - self.hub._queue_welcome( - outgoing, + # Send welcome message and MOTD + self.hub.session_manager.send_welcome( link, + outgoing, peer_hash=peer_hash, - motd=self.hub.config.greeting, + old_nick=old_nick, + new_nick=new_nick, ) def _handle_join( @@ -787,7 +765,7 @@ class MessageRouter: old_session_nick = sess.get("nick") if old_session_nick != n: sess["nick"] = n - self.hub._update_nick_index(link, old_session_nick, n) + self.hub.session_manager.update_nick_index(link, old_session_nick, n) env[K_NICK] = n else: # Invalid nickname provided - remove it diff --git a/rrcd/service.py b/rrcd/service.py index 3ca0b83..5be44a5 100644 --- a/rrcd/service.py +++ b/rrcd/service.py @@ -554,56 +554,6 @@ class HubService: except Exception: pass - def _welcome(self, link: RNS.Link, sess: dict[str, Any]) -> None: - if self.identity is None: - return - - sess["welcomed"] = True - # Use the queued path so we can preflight MTU sizing and optionally - # follow up with MOTD via resource or chunks. - outgoing: list[tuple[RNS.Link, bytes]] = [] - self._queue_welcome( - outgoing, - link, - peer_hash=sess.get("peer"), - motd=self.config.greeting, - ) - - # Send queued WELCOME first - for out_link, payload in outgoing: - self.stats_manager.inc("bytes_out", len(payload)) - try: - RNS.Packet(out_link, payload).send() - except OSError as e: - self.log.warning( - "Send failed link_id=%s bytes=%s err=%s", - self._fmt_link_id(out_link), - len(payload), - e, - ) - except Exception: - self.log.debug( - "Send failed link_id=%s bytes=%s", - self._fmt_link_id(out_link), - len(payload), - exc_info=True, - ) - - # Now send MOTD via resource or chunks (after WELCOME is sent) - if self.config.greeting: - self.log.debug( - "Sending MOTD link_id=%s len=%s", - self._fmt_link_id(link), - len(self.config.greeting), - ) - self._send_text_smart( - link, - msg_type=T_NOTICE, - text=self.config.greeting, - room=None, - kind=RES_KIND_MOTD, - ) - def _on_close(self, link: RNS.Link) -> None: peer = None nick = None @@ -654,17 +604,6 @@ class HubService: """Delegate to message_helper for notice emission.""" self.message_helper.emit_notice(outgoing, link, room, text) - def _queue_welcome( - self, - outgoing: list[tuple[RNS.Link, bytes]], - link: RNS.Link, - *, - peer_hash: Any, - motd: str | None, - ) -> None: - """Delegate to message_helper for queuing welcome.""" - self.message_helper.queue_welcome(outgoing, link, peer_hash=peer_hash, motd=motd) - def _norm_room(self, room: str) -> str: r = room.strip().lower() if not r: diff --git a/rrcd/session.py b/rrcd/session.py index a62b716..f2b95cd 100644 --- a/rrcd/session.py +++ b/rrcd/session.py @@ -220,3 +220,60 @@ class SessionManager: "indexed_by_hash": len(self._index_by_hash), "indexed_by_nick": len(self._index_by_nick), } + + def send_welcome( + self, + link: RNS.Link, + outgoing: list[tuple[RNS.Link, bytes]], + *, + peer_hash: bytes, + old_nick: str | None = None, + new_nick: str | None = None, + ) -> None: + """ + Send WELCOME message to a client and optionally MOTD. + + This handles: + - Setting session as welcomed + - Updating nick index if needed + - Queueing WELCOME message + - Setting up MOTD callback for post-send delivery + + Must be called with state lock held. + """ + from .constants import RES_KIND_MOTD, T_NOTICE + + sess = self.sessions.get(link) + if sess is None: + return + + # Update nick index if nick changed + if old_nick != new_nick: + self.update_nick_index(link, old_nick, new_nick) + + # Mark session as welcomed + sess["welcomed"] = True + + # Queue WELCOME message + self.hub.message_helper.queue_welcome( + outgoing, + link, + peer_hash=peer_hash, + motd=self.hub.config.greeting, + ) + + # Send MOTD after WELCOME (outside of outgoing queue to enable resource transfer) + # The outgoing queue will be sent first, then this callback will send the MOTD + if self.hub.config.greeting: + def send_motd(): + self.hub.message_helper.send_text_smart( + link, + msg_type=T_NOTICE, + text=self.hub.config.greeting, + room=None, + kind=RES_KIND_MOTD, + ) + # Store callback to be executed after outgoing packets are sent + if not hasattr(outgoing, '_post_send_callbacks'): + outgoing._post_send_callbacks = [] # type: ignore + outgoing._post_send_callbacks.append(send_motd) # type: ignore