{"record":{"id":"c05e23d785048c55","repo":"XX-net/XX-Net","slug":"send-conn-data-but-not-running","errorCode":null,"errorMessage":"send_conn_data but not running","messagePattern":"send_conn_data but not running","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"code/default/x_tunnel/local/proxy_session.py","lineNumber":529,"sourceCode":"                pass\n        # self.conn_list = {}\n        xlog.debug(\"stop all connection finished\")\n\n    def remove_conn(self, conn_id):\n        try:\n            if conn_id in self.conn_list:\n                conn = self.conn_list[conn_id]\n                # xlog.debug(\"remove conn:%d %s:%d\", conn_id, conn.host, conn.port)\n                del self.conn_list[conn_id]\n        except Exception as e:\n            xlog.warn(\"remove conn:%d except:%r\", conn_id, e)\n\n        if len(self.conn_list) == 0:\n            self.target_on_roads = 0\n\n    def send_conn_data(self, conn_id, data):\n        if not self.running:\n            xlog.warn(\"send_conn_data but not running\")\n            return\n\n        # xlog.debug(\"upload conn:%d, len:%d\", conn_id, len(data))\n        buf = base_container.WriteBuffer()\n        buf.append(struct.pack(\"<II\", conn_id, len(data)))\n        buf.append(data)\n        self.send_buffer.put(buf)\n\n        if self.oldest_received_time == 0:\n            self.oldest_received_time = time.time()\n        elif self.send_buffer.pool_size > g.config.max_payload:\n            # xlog.debug(\"notify on send conn data\")\n            self.wait_queue.notify()\n\n    @staticmethod\n    def sn_payload_head(sn, payload):\n        return struct.pack(\"<II\", sn, len(payload))\n","sourceCodeStart":511,"sourceCodeEnd":547,"githubUrl":"https://github.com/XX-net/XX-Net/blob/cfa5bc17b67676e467f37ec50766127e0ab5f0aa/code/default/x_tunnel/local/proxy_session.py#L511-L547","documentation":"send_conn_data is invoked (from create_conn, transfer_received_data, transfer_ack, or transfer_peer_close) with data for a connection, but proxy_session.running is False — the session is stopped or was never successfully started. The upload is dropped with this warning because there is no transport to send on.","triggerScenarios":"Any client traffic arriving after session stop() (or after a failed start/login), e.g. an in-flight HTTP proxy request whose upload path runs while the session is shutting down or re-logging-in.","commonSituations":"Restart/relogin windows where the local proxy still accepts client connections; requests in flight when the tunnel drops; code that starts the proxy listener before verifying session.start() returned True.","solutions":["Only route client traffic after session.start() succeeds; gate the local proxy listener on session.running.","Retry the request after the session is re-established (login succeeds and running is True).","During shutdown, close accepted client sockets first so handlers don't attempt uploads on a dead session."],"exampleFix":"# before\nsock = listener.accept(); session_conn.send_conn_data(conn_id, data)\n\n# after\nif not session.running:\n    session.start()\nif session.running:\n    session.send_conn_data(conn_id, data)","handlingStrategy":"validation","validationCode":"if not proxy_session.running:\n    proxy_session.start()\nassert proxy_session.running, 'tunnel not running'\nproxy_session.send_conn_data(conn_id, data)","typeGuard":"def session_active(session) -> bool:\n    return bool(getattr(session, 'running', False))","tryCatchPattern":null,"preventionTips":["Start the proxy listener only after session.start() succeeds.","Check session.running before every upload batch.","Close client sockets before stopping the session."],"tags":["lifecycle","session-state","upload"],"backgroundTag":"session-not-running","analyzedSha":"cfa5bc17b67676e467f37ec50766127e0ab5f0aa","analyzedAt":"2026-08-27T19:28:28.225Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}