Rust driver v1.0.0 tls handshake eof

I’m trying to update my app to v1.0.0 from using v0.3.12 and I want to use the sync API for now (just because It’s easier and is what I’ve already built for). I’m trying to use Client with_uri_str so that I can just pass it a mongo connection string and be on my way, but I’m getting this panic when I do so:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <server_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:715:18

My server apparently requires tls, but It’s unclear to me how to enable it with sync API. I shouldn’t need any certs or anything since my connection string works fine in the mongo cli. How does one go about connecting using TLS this way? Can I somehow pass client options while using a URL? Also wondering about parse, but that’s async, so I can’t use it AFAIK. Any help is appreciated!

Hi Will,

When you provide a URI to configure the Client, tls is automatically set to true. My theory is that your server isn’t configured with TLS support, which would explain why your TLS handshake is failing. To fix this you can add the param tls=false to your URI, although it would probably be better to enable TLS on your server for security instead.

Here’s the documentation on MongoDB URIs

Hope this helps!

2 Likes

Oh, okay, cool!

So I did that, but now it’s giving me a different, and slightly more vague eof-related error.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <server_address>:27017, Type: Unknown, Error: unexpected end of file }, ] }" } }', src/lib.rs:716:18

Thoughts?

Okay, so I did some experiments with the mongo CLI tool, and found that I had to have ssl=true or tls=true in order to connect. Otherwise, it’d give me an error that looked something like this:

MongoDB shell version v4.2.6
connecting to: mongodb://<ip_address>:27017/<db_name>?compressors=disabled&gssapiServiceName=mongodb&tls=false
2020-08-16T16:06:40.982+0000 I  NETWORK  [js] DBClientConnection failed to receive message from <ip_address>:27017 - HostUnreachable: Connection closed by peer
2020-08-16T16:06:40.983+0000 E  QUERY    [js] Error: network error while attempting to run command 'isMaster' on host '<ip_address>:27017'  :
connect@src/mongo/shell/mongo.js:341:17
@(connect):2:6
2020-08-16T16:06:40.986+0000 F  -        [main] exception: connect failed
2020-08-16T16:06:40.986+0000 E  -        [main] exiting with code 1

Not sure what’s wrong now. I should just be able to connect with that URL, just like I can with the CLI, right?

1 Like

I’m confused! Didn’t you say you could connect with tls=true in the URI? Or was that only in the CLI, and not from the Rust driver?

When you try to connect with the Rust driver, with tls=true, what’s the error that you get now?

Apologies, it seems I need tls (or SSL, which I guess is an alias?) to be enabled to connect. So the connection string I think I need is this:

mongodb://<db>:<password>@<ip_address>/<db>?ssl=true

but that gives me this

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <ip_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:716:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

When I do this:

 let coll = mongo_client
     .database("<db>")
     .collection(&collection);
 let mut namespace_table = Vec::new(); // The vec of namespace information we're gonna send back.

 // Find the document and receive a cursor
 dbg!(&coll);
 let cursor = coll.find(None, None).unwrap();

And I believe it’s panicing on that unwrap.

The source code can be found here, if you want to take a look.

Thanks again!

Um, would this possibly be happening on Ubuntu?

Why, yes. 18.04 Server, I believe. Why? Is this a known bug? :fearful: :fearful: :fearful: :fearful:

I’ve found weirdness with the certs. You might try sudo apt install ca-cacert

No dice. Perhaps I should try running this on my Fedora box, just for the lolz.

Weather Update: That did not work. Same error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <ip_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:716:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

What I actually did that made things work is this:
export SSL_CERT_FILE=$(python3 -c "import certifi; print(certifi.where())")
and then all my Mongo stuff started working, mongo and mongosh and PHP and Python.
I dunno, something is flakey with the certs, not sure what the problem is, but I’ve got it working, and it wasn’t working before :man_shrugging:

No dice, unfortunately. Same error.

Weird. I’m out of stupid ideas :slight_smile: Good luck with that!

@wilnil Could you run this again with RUST_BACKTRACE=1 and paste the stack trace?

@wilnil It’s worth noting that the mongodb crate has been rewritten since 0.3.12. It would be worth looking at the 1.1 release and maybe porting your code. I don’t think it would take much more effort than a few search&replaces, and you’ll be getting a fully supported up-to-date driver.

1 Like

Here you go:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: ServerSelectionError { message: "Server selection timeout: No available servers. Topology: { Type: Unknown, Servers: [ { Address: <ip_address>:27017, Type: Unknown, Error: tls handshake eof }, ] }" } }', src/lib.rs:716:18
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:486
  11: rust_begin_unwind
             at src/libstd/panicking.rs:388
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:101
  13: core::option::expect_none_failed
             at src/libcore/option.rs:1272
  14: core::result::Result<T,E>::unwrap
             at /rustc/d3fb005a39e62501b8b0b356166e515ae24e2e54/src/libcore/result.rs:1005
  15: shelflife::get_db
             at src/lib.rs:716
  16: shelflife::view_db
             at src/lib.rs:757
  17: shelflife::main
             at src/bin/main.rs:233
  18: std::rt::lang_start::{{closure}}
             at /rustc/d3fb005a39e62501b8b0b356166e515ae24e2e54/src/libstd/rt.rs:67
  19: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
  20: std::panicking::try::do_call
             at src/libstd/panicking.rs:297
  21: std::panicking::try
             at src/libstd/panicking.rs:274
  22: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  23: std::rt::lang_start_internal
             at src/libstd/rt.rs:51
  24: std::rt::lang_start
             at /rustc/d3fb005a39e62501b8b0b356166e515ae24e2e54/src/libstd/rt.rs:67
  25: main
  26: __libc_start_main
  27: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

And as to your second point, I thought it would work the way it is, but at this point, yeah. I’ll have to go through it and port my logic.

It’s this block here that it’s failing on. Is there a “new” way to do that?

let coll = mongo_client
    .database("shelflife")
    .collection(&collection);
let mut namespace_table = Vec::new(); // The vec of namespace information we're gonna send back.

// Find the document and receive a cursor
dbg!(&coll);
let cursor = coll.find(None, None).unwrap();

I see that there is a sync api example. Do you think it’ll work if I copy it? I’ll try it out after work today and report back. Thanks for the help! :call_me_hand:

A post was split to a new topic: Rust driver 2.0.0 problems when ssl=true and tls=true