MagicStack / MagicStack/uvloop

tranport.get_extra_info('peername') occasionally returns None

オープン
#560 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

主要言語
Cython
スター
11.9k
フォーク
616
PR マージ指標
30日以内にマージされた PR はありません

説明

uvloop version: 0.17.0
Python version: 3.11.4
Platform: Linux

I believe the root cause of this issue is that:

  • libuv doesn't retrieve peer address while calling accept()
  • getpeername() fails if the client disconnected already (which is unlikely, but possible)

Here's strace log:

561904 setsockopt(19, SOL_TCP, TCP_NODELAY, [1], 4) = 0
561904 accept4(18, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK) = -1 EAGAIN (Resource temporarily unavailable)
561904 getsockname(19, {sa_family=AF_INET, sin_port=htons(32111), sin_addr=inet_addr("127.0.0.1")}, [128 => 16]) = 0
561904 getpeername(19, {sa_family=AF_INET, sin_port=htons(39898), sin_addr=inet_addr("127.0.0.1")}, [128 => 16]) = 0
561904 getpid()                         = 561904

Please note, that standard asyncio loop uses accept4() call to get the peer address:

564955 accept4(13, {sa_family=AF_INET, sin_port=htons(35516), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_CLOEXEC) = 16
564955 getsockname(16, {sa_family=AF_INET, sin_port=htons(32111), sin_addr=inet_addr("127.0.0.1")}, [128 => 16]) = 0
564955 ioctl(16, FIONBIO, [1])          = 0

Said that, there's an issue raised in libuv repo which should be addressed first, I suppose: https://github.com/libuv/libuv/issues/3339

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、Linux 上で uvloop 0.17.0、Python 3.11.4 のケースを再現し、レポートに示されている accept/getpeername の動作を追跡します。次に、リンクされている libuv の issue #3339 を確認します。原因が確認され、実行可能な修正または依存関係の解決後に peername の動作が検証されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
networking
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
説明が足りない
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。