Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ospfclient: fix crash due to streamwriter garbage collect #17700

Merged
merged 1 commit into from
Jan 7, 2025

Conversation

Andrew-Dickinson
Copy link
Contributor

@Andrew-Dickinson Andrew-Dickinson commented Dec 20, 2024

The ospfclient.py script crashes immediately in python >3.10 due to this change to fix a memory leak in the Python sockets API. It causes garbage collected StreamWriter instances to call .close(), which in-turn causes the ospfclient.py script to incorrectly call .close() on the async socket immediately after opening it, since it is currently using a throwaway _ variable to store this writer, which immediately goes out of scope.

Before this patch

> python3.12 ospfclient.py -v
2024-12-20 19:48:28,548 INFO: CLIENT: root ospfclient: starting
2024-12-20 19:48:28,548 DEBUG: CLIENT: asyncio Using selector: EpollSelector
2024-12-20 19:48:28,549 DEBUG: CLIENT: root OspfApiClient(localhost): binding to ports 49152, 49153
2024-12-20 19:48:28,549 DEBUG: CLIENT: root OspfApiClient(localhost): connect to OSPF API
2024-12-20 19:48:28,549 DEBUG: CLIENT: root OspfApiClient(localhost): connecting sync socket to server
2024-12-20 19:48:28,553 DEBUG: CLIENT: root OspfApiClient(localhost): accepting connect from server
2024-12-20 19:48:28,556 DEBUG: CLIENT: root OspfApiClient(localhost): success
2024-12-20 19:48:28,556 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): request LSDB events
2024-12-20 19:48:28,557 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): sending REGISTER_EVENT seq 0x1
2024-12-20 19:48:28,557 DEBUG: CLIENT: root entering async msg handling loop
2024-12-20 19:48:28,557 INFO: CLIENT: root Got EOF from OSPF API server on async notify socket
2024-12-20 19:48:28,557 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): request LSDB sync
2024-12-20 19:48:28,557 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): sending SYNC_LSDB seq 0x2
2024-12-20 19:48:28,559 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): request reachable changes
2024-12-20 19:48:28,559 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): sending MSG_SYNC_REACHABLE seq 0x3
2024-12-20 19:48:28,559 DEBUG: CLIENT: root OspfApiClient(localhost): closing
2024-12-20 19:48:28,559 ERROR: CLIENT: root async_main: unexpected error:
Traceback (most recent call last):
  File "/home/ubuntu/frr/ospfclient/ospfclient.py", line 397, in _msg_read
    mh = await r.readexactly(FMT_APIMSGHDR_SIZE)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/asyncio/streams.py", line 750, in readexactly
    raise exceptions.IncompleteReadError(incomplete, n)
asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 8 expected bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/ubuntu/frr/ospfclient/ospfclient.py", line 1117, in async_main
    await c.req_reachable_routers()
  File "/home/ubuntu/frr/ospfclient/ospfclient.py", line 531, in req_reachable_routers
    await self.msg_send_raises(MSG_SYNC_REACHABLE)
  File "/home/ubuntu/frr/ospfclient/ospfclient.py", line 469, in msg_send_raises
    ecode = await self.msg_send(mt, mp)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/frr/ospfclient/ospfclient.py", line 443, in msg_send
    mt, mp = await OspfApiClient._msg_read(self._r, seq)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/frr/ospfclient/ospfclient.py", line 408, in _msg_read
    raise EOFError
EOFError
2024-12-20 19:48:28,561 INFO: CLIENT: root ospfclient: clean exit

After this patch

> python3.12 ospfclient.py -v
2024-12-20 19:50:53,680 INFO: CLIENT: root ospfclient: starting
2024-12-20 19:50:53,680 DEBUG: CLIENT: asyncio Using selector: EpollSelector
2024-12-20 19:50:53,681 DEBUG: CLIENT: root OspfApiClient(localhost): binding to ports 49152, 49153
2024-12-20 19:50:53,681 DEBUG: CLIENT: root OspfApiClient(localhost): connect to OSPF API
2024-12-20 19:50:53,681 DEBUG: CLIENT: root OspfApiClient(localhost): connecting sync socket to server
2024-12-20 19:50:53,684 DEBUG: CLIENT: root OspfApiClient(localhost): accepting connect from server
2024-12-20 19:50:53,687 DEBUG: CLIENT: root OspfApiClient(localhost): success
2024-12-20 19:50:53,687 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): request LSDB events
2024-12-20 19:50:53,687 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): sending REGISTER_EVENT seq 0x1
2024-12-20 19:50:53,688 DEBUG: CLIENT: root entering async msg handling loop
2024-12-20 19:50:53,688 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): request LSDB sync
2024-12-20 19:50:53,688 DEBUG: CLIENT: root SEND: OspfApiClient(localhost): sending SYNC_LSDB seq 0x2
2024-12-20 19:50:53,689 DEBUG: CLIENT: root _msg_read: got seq: 0x2 on async read
2024-12-20 19:50:53,690 DEBUG: CLIENT: root RECV: OspfApiClient(localhost): calling handler for LSA_UPDATE_NOTIFY
2024-12-20 19:50:53,690 INFO: CLIENT: root RECV: LSA update msg for LSA 10.10.10.10 in area 0.0.0.0 seq 0x8000db78 len 36 age 5
2024-12-20 19:50:53,690 DEBUG: CLIENT: root _msg_read: got seq: 0x2 on async read
...

Signed-off-by: Andrew Dickinson <andrew.dickinson.0216@gmail.com>
Copy link
Member

@riw777 riw777 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@riw777 riw777 merged commit 8ed117a into FRRouting:master Jan 7, 2025
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants