Mio : TcpStream::Connect sends RST


#1

Hello,

I’m quite new to Rust. I’m working a networking app and I need to connect through TCP to a remote host. However, connection never succeeds. I am aware to subject Mio : TcpStream::Connect always return success. Here is my code :

fn connect_network(listen : &str, remote : &str){

let socket = &listen.parse().unwrap();
//
// // Setup the server socket
let server = match TcpListener::bind(socket) {
    Err(err) => panic!("Could not bind to {}: {}", listen, err),
    Ok(s) => s
};

// Create a poll instance
let poll = match Poll::new(){
    Err(err) => panic!("Could not poll to {}: {}", socket, err),
    Ok(p) => p
};

// Start listening for incoming connections
poll.register(&server, SERVER, Ready::readable(), PollOpt::level()).unwrap();

let mut events = Events::with_capacity(1024);
let id = 0;


match TcpStream::connect(&remote.parse().unwrap()) {
    Ok(stream) => {
        poll.register(&stream, Token(0), Ready::readable() | Ready::writable(), PollOpt::level()).unwrap();
        println!("Trying to connect from {:?} to {}", stream.local_addr(), remote);
        // match (stream.local_addr(), stream.peer_addr()) {
        //     (Ok(local), Ok(peer)) => {
        //         println!("{}:New Connection {} -- {}", id, local, peer);
        //         // Some(Connection{id : id, status : RefCell::new(ConnectionStatus::Disconnected), stream : RefCell::new(stream), logger : logger})
        //     },
        //     (Ok(local), Err(e)) => {
        //         println!("{}:Error 1 while connecting from {} to {}:{}", id, local, remote, e);
        //         // None
        //     },
        //     (Err(e), Ok(peer))=> {
        //         println!("{}:Error 2 while connecting to {} {} {}", id, remote, peer, e);
        //         // None
        //     },
        //     (Err(e1), Err(e2))=> {
        //         println!("{}:Error 3 while connecting to {}\n{}\n{}", id, remote, e1, e2);
        //         // None
        //     },
        // }
    },
    Err(e) => {
        println!("{}:Error 4 while connecting to {} : {}", id, remote, e);
        // None
    }
};

loop {
    match poll.poll(&mut events, None) {
        Err(e) => println!("Error during poll(): {}", e),
        Ok(_) => {}
    }

    for event in events.iter() {
        println!("event={:?}", event);
        match event.token() {
            SERVER => {
                // Accept and drop the socket immediately, this will close
                // the socket and notify the client of the EOF.

                let (stream, _client_addr) = match server.accept() {
                    Ok((stream, client_addr)) => {
                        println!("0\tAccepting connection... {:?} from {:?}", stream, client_addr);
                        (stream, client_addr)
                    },
                    Err(e) => panic!("got an error when accepting a connection: {}", e),
                };

                // do some stuff
            }
            Token(c) => {
                let r = event.readiness();

                if r.is_readable() {
                    println!("Client {} received bytes",c);
                }
                if r.is_writable() {
                    println!("Client {} might write",c);
                }
            }
        }
    }
}

}

When I run it, i use wireshark to sniff the network. I can see that my program opens a connection to the remote host and sends a SYN. The remote host answers with a SYN+ACK message, and right after I see a RST message. I do not understand.

This problem does not occur when the remote host is 127.0.0.1.
Do you have any clue about this ?


#2

What platform are you on? I think rust just delegates to system calls that handle the actual setting up of the connection etc.


#3

On linux / ubuntu.
When I use netcat, I dot not have the problem of RST…


#4

I’m not an expert with networking so take what I say with a pinch of salt.

Have you tried strace to see what syscalls are being made?


#5

It looks like you’re dropping the TcpStream after connect succeeds? So it’s quite expected that the connection gets closed again…


#6

Actually, it is the same behavior if I store the TCPStream in a local variable: stream.peer_addr() returns an error with code 107 : Transport endpoint is not connected (os error 107)


#7

Well, then I second @derekdreery 's suggestion to check what syscalls are being made. strace -e network should be a good starting point.


#8

It seems that calling stream.peer_addr() in the loop upon reception of an event is OK. I guess I call it to early.