tun2proxy / rust-tun

TUN device creation and handling.
https://docs.rs/tun2/
30 stars 13 forks source link

Fix: channel closed loop #61

Closed RoDmitry closed 2 months ago

RoDmitry commented 2 months ago

When WinSession is dropped Arc<wintun::Session> stays inside the thread so receive_blocking is never finished, but channel is closed. Maybe also need impl Drop for WinSession with self.session.shutdown()?

M0dEx commented 2 months ago

Maybe close the channel before breaking? That way, you can return an Error in the subsequent poll_read and poll_write.

RoDmitry commented 2 months ago

@M0dEx I don't understand what you mean. Breaking and leaving the loop, finishes the thread, so channel will be dropped, which means it will be closed. And also if we have an error trying to send to the channel, it means it's already closed.

M0dEx commented 2 months ago

@M0dEx I don't understand what you mean. Breaking and leaving the loop, finishes the thread, so channel will be dropped, which means it will be closed. And also if we have an error trying to send to the channel, it means it's already closed.

I meant more of in the case the channel is still open, but in which the session returns an error.

cavivie commented 2 months ago

@M0dEx I don't understand what you mean. Breaking and leaving the loop, finishes the thread, so channel will be dropped, which means it will be closed. And also if we have an error trying to send to the channel, it means it's already closed.

I meant more of in the case the channel is still open, but in which the session returns an error.

Sort of like this, but the code waiting for closed might need to do something like blocking_closed, right?

                    if let Err(err) = receiver_tx.send(packet.bytes().to_vec()) {
                        log::error!("{}", err);
                        loop !receiver_tx.is_closed() { } // wait for the receiver channel closed
                        break;
                    }
RoDmitry commented 2 months ago

It's SendError only:

If the receive half of the channel is closed, either due to [close] being called or the [UnboundedReceiver] having been dropped, this function returns an error.

M0dEx commented 2 months ago

@M0dEx I don't understand what you mean. Breaking and leaving the loop, finishes the thread, so channel will be dropped, which means it will be closed. And also if we have an error trying to send to the channel, it means it's already closed.

I meant more of in the case the channel is still open, but in which the session returns an error.

Sort of like this, but the code waiting for closed might need to do something like blocking_closed, right?

                    if let Err(err) = receiver_tx.send(packet.bytes().to_vec()) {
                        log::error!("{}", err);
                        loop !receiver_tx.is_closed() { } // wait for the receiver channel closed
                        break;
                    }

No, I meant the error from the session_reader.receive_blocking() call. Right now, the only action we take is breaking the loop and logging the error, but I think we should be closing the channel as well so that the poll_read and poll_write can then return an error if the session errors out.

RoDmitry commented 2 months ago

@M0dEx As I've wrote previously, the channel will be closed on breaking anywhere in that loop.