-
Notifications
You must be signed in to change notification settings - Fork 29
Add peer_addr() #7
Conversation
Thank you! |
No problem. I've been looking into solutions for breaking UTP reads in a dedicated thread (really rust-lang/rust#23272). Would you have any objection to a FFI function which returns either when a socket has data to read or a timeout passes? I'd supply editions for both Windows and POSIX. I think this solution is nicer than sending magic UDP packets to break reads as it also allows a connection to timeout. Anyway, let me know and if you like it, I can rustle up some implementation code for you. |
Just as an FYI, have you guys seen https://github.com/libpnet/ which may be well suited to this issue. I know it's a dependency but if we maintain as much rust safety as possible it may be nice. Plus helps the language out. |
@dirvine I wasn't aware that libpnet can do async or even non-blocking? It looks to be, from its docs, just as synchronous as Rust std::net. |
Actually, Rust already provides the select() call, it's just not documented anywhere: https://github.com/rust-lang/rust/blob/master/src/libstd/sys/unix/c.rs I'll try patching that into rust-utp and see what happens. |
@ned14: I came across that issue after the IO reform. I also explored setting timeouts on the underlying UDP socket with the As the code stands right now, if one is using two threads to read and write (respectively) on a On the other hand, if there is only one thread controlling the socket, That was a long-winded way to say that the only problem I see right now is the lack of timeouts to send keep-alives and kill the connection. @dirvine: Thanks, I saw libpnet a couple of weeks ago but nothing in its documentation suggested it was asynchronous. |
@dirvine It was worth a try in any case. Thank you for checking. |
@meqif: The problem is shutting down an existing transport ungracefully, so for example if crust has received a connection from someone and we decide that that connection is malicious, we want to drop it immediately and ungracefully. Same as a firewall. rust-utp, and indeed Rust in general, makes this hard for us, but crust currently uses shutdown() on TCP connections to force an early disconnect and there is no equivalent in rust-utp as close() appears to hang until the remote end sends a FIN packet. Hence right now crust hangs randomly during unit testing because it depends on the exact timing of when the reader writers are torn down. What we need instead is a force connection close which breaks any reads in any dedicated threads with a best effort graceful close, but falling back to ungraceful close quickly. Does this make sense? |
@meqif BTW on Windows if a read socket times out its SO_RCVTIMEO value, that socket becomes unusable after if I remember rightly. That probably explains your difficulties. Anyway, no problem with making a select() based timeout, that works everywhere. |
@ned14: Oh, now I see. What I think would be best is having As for Windows support, I didn't even get to the point of trying to implement it, as I got busier around that time and had to freeze my work on that branch. :) |
@meqif Sounds great. Do you need a working socket timed read function still for that? |
@ned14 Yes, a method to set a socket's read timeout in Windows (similarly to the |
@meqif I can give you a replacement for UdpSocket::recv_from() which times out? |
To get through NAT devices we use hole punching, so this means longer than usual connect timeouts for those sockets (UDT actually used SO_ADDREUSE and swapped these for normal timeout sockets after connect). So a question here may be is the timeout related to connection establishment and if so is it possible to have these settable on socket instantiation or similar. |
@dirvine The timeout used in the |
@meqif No replacement for UdpSocket needed. Such a timed_read() function might have function form timed_read(UdpSocket &, u32 timeout) -> Result<(bool, usize, SocketAddr)>. Regarding https://github.com/rust-lang/rust/blob/master/src/libstd/sys/windows/net.rs#L134, that will only work for TCP sockets on Windows at best, and even then. I don't believe timeouts have worked with UDP sockets on Windows for a very long time now. In the end, all i/o on Windows is fundamentally async, and the sync APIs are emulation wrappers around the async APIs. Nobody doing serious programming on Windows uses any of the sync i/o APIs, they don't get much attention from Microsoft. |
@ned14 Alright then, that sounds reasonable. What would be the meaning of the |
@meqif Yeah that's not very Rust idiomatic is it! I was thinking of the bool as being true when a packet was read, else it timed out. I suppose an enum would be more idiomatic there? So let's say a Result<(usize, SocketAddr), CustomErrorType>? Or maybe a Result<Result<(usize, SocketAddr)>>? Whichever you prefer is fine with me. |
@ned14 It looks like |
@meqif That's perfect Ricardo. Thanks for the tip |
@meqif I added a timed_read() function as per my description at ned14@83f8a14, but it currently panics the compiler. I'm out of work hours now, so I'll revisit on Monday and see if I can figure out what's upsetting the compiler. |
@ned14 For what it's worth, it doesn't panic the compiler on OSX ( At a glance, I noticed you're missing a few imports ( The documentation of Aside from a few minor code style criticisms, it seems ok. |
@meqif I can debug Windows for you tomorrow. Thanks for the speedy improvements. |
@ned14 I got it working. :) I forgot to check if |
Version change to 0.6.20
No description provided.