Repository: tweedegolf/mailcrab (language: rust)

Issue:
How many connections mailcrab can open?
I have a strange situation when using mailcrab docker image with php and symfony. 

I’ve started a mailcrab container, symfony consumer container and symfony cli container. 

When consumer is started I can not open a connection from cli container. I get request timeout. If I stop the consumer container everything is working from cli. 

It seems that consumer container connects to mailcrab and makes its port busy so mailcrab can not open more connections for other clients at the same time. 

Mailcrab has only one thread? Or this is only mine problem ?

thanks


Discussion / hints:
On Tue, Apr 11, 2023 at 10:24:55AM -0700, jokaorgua wrote:

> Or this is only mine problem ?

@jokaorgua Please help answering that question
by documenting how to reproduce the "problem".

I’m not sure if you are familiar with symfony consumers. 
1. Make a container with mailcrab
2. Make another container with symfony consumer which will consume async queue and send emails. Start it. 
3. Start one more container with bash
4. Try to open port 1025 with telnet from bash container and send couple of commands directly to mailcrab. 

I guess that section 2 can be replaced with cli container where connection to mailcrab will be left opened. But I’m not sure as I haven’t tested such a way. 
On Tue, Apr 11, 2023 at 10:39:11AM -0700, jokaorgua wrote:
> I’m not sure if you are familiar with symfony consumers.

I'm sure it is not fair to expect such tooling at hand.


> But I’m not sure as I haven’t tested such a way. 

FWIW:  My setup doesn't currently work, something I have to fix first.
(I have clue / idea  
     but have other things planned for the next 48hours)



Regards
Geert Stappers
Who wouldn't be surprised if "single thread is a Docker thing"

I have no experience in rust. But I’m sure there is a possibility to work with multiple socket connections in docker. I just want to understand does mailcrab support multiple concurrent connections? 

Maybe this is just my problem (maybe I have done something with my setup) 
Currently Mailcrab uses [mailin](https://crates.io/crates/mailin-embedded) to handle SMTP connections. Mailin does use a threadpool to handle connections. By default it starts up [4 threads](https://gitlab.com/alienscience/mailin/-/blob/master/mailin-embedded/src/lib.rs#L73) This means Mailcrab can handle at most 4 connections concurrently, so make sure to properly close any SMTP connections when they are finished.
If you use docker compose could you post your `docker-compose.yml` - your problem might be in the network configuration.
@marlonbaeten I've made a minimal docker-compose which can reproduce a problem

```
version: '3.9'

services:
    nginx:
        image: nginx:1.23-alpine

    nginx1:
        image: nginx:1.23-alpine

    nginx2:
        image: nginx:1.23-alpine

    nginx3:
        image: nginx:1.23-alpine

    nginx4:
        image: nginx:1.23-alpine

    mailcrab:
        image: marlonb/mailcrab
        expose:
            - 1025
            - 1080

```

steps to reproduce
1. run `docker-compose up`
2. open new terminal and run `docker-compose exec nginx /bin/sh`
3. in opened shell to nginx container run `apk add update` after that `apk add busybox-extras` and after that `telnet mailcrab 1025`. You will see `Connected to mailcrab
220 mailcrab-backend ESMTP`
4. leave the terminal open in section 3 and leave connection open
5. open new terminal, repeat everything in section 3 but for container nginx1. after running it you will see `Connected to mailcrab`. No `220 mailcrab-backend ESMTP`. I guess this means the connection has not been established
6. Close connection that you have created in section 3 and you will see 220 code in connection from section 5
On Tue, Apr 11, 2023 at 11:23:46PM -0700, jokaorgua wrote:
> I've made a minimal docker-compose which can reproduce a problem


I can reproduce the reported issue without docker-compose:

  *  cargo run backend
  *  go to second terminal
  *  telnet 127.0.0.1 1025
  *  SMTP banner appears
  *  go to third terminal
  *  telnet 127.0.0.1 1025
  *  no SMTP banner
  *  go back to second terminal
  *  type `quit` and enter  ( to end SMTP session )
  *  go back to third terminal
  *  do see that the SMTP banner appeared


Groeten
Geert Stappers
Has no idea what could cause the blocking
-- 
Silence is hard to parse

@stappersg thanks for narrowing the problem. so it exists not only for me
Check - I can reproduce the issue.
I've narrowed the problem down to the threaded connection handling in mailin and created a fix: https://gitlab.com/alienscience/mailin/-/merge_requests/30
When I run Mailcrab with the patch applied to mailin it handles connections concurrently.
Once this is merged upstream I will release a new version of Mailcrab containing the fix.

Fix patch:
diff --git a/backend/Cargo.lock b/backend/Cargo.lock
index 5129c61..442935e 100644
--- a/backend/Cargo.lock
+++ b/backend/Cargo.lock
@@ -104,6 +104,15 @@ version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
 
+[[package]]
+name = "base64-compat"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a8d4d2746f89841e49230dd26917df1876050f95abafafbe34f47cb534b88d7"
+dependencies = [
+ "byteorder",
+]
+
 [[package]]
 name = "bitflags"
 version = "1.3.2"
@@ -895,11 +904,11 @@ dependencies = [
 
 [[package]]
 name = "mailin"
-version = "0.6.1"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24d0411d6d3cf6baacae37461dc5b0a32b9c68ae99ddef61bcd88174b8da890a"
+checksum = "d7f3483ec615b5179c8923e55a0c5caca26c6f4bfb375fb699054f84ca77ba44"
 dependencies = [
- "base64 0.13.1",
+ "base64-compat",
  "either",
  "log",
  "nom",
@@ -908,12 +917,12 @@ dependencies = [
 
 [[package]]
 name = "mailin-embedded"
-version = "0.7.1"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2f29d14249fb45f7795bc8564175ca7b963254217f24e8cde84ba40d38b58cc"
+checksum = "6afb9280cdf7039eb3a11b781ec710ba6bf3bb64990cf28e6f241b89104a997a"
 dependencies = [
  "bufstream",
- "lazy_static",
+ "cfg-if",
  "log",
  "mailin",
  "rustls",
diff --git a/backend/Cargo.toml b/backend/Cargo.toml
index a1c98a4..7a79b75 100644
--- a/backend/Cargo.toml
+++ b/backend/Cargo.toml
@@ -11,7 +11,7 @@ chrono = "0.4"
 humansize = "2.0"
 mail-parser = "0.8"
 mailin = "0.6"
-mailin-embedded = { version = "0.7", features = ["rtls"] }
+mailin-embedded = "0.8"
 rcgen = "0.10"
 rust-embed = "6.6"
 serde = { version = "1.0", features = ["derive"] }
@@ -27,4 +27,4 @@ uuid = { version = "1.2", features = ["v4", "serde"] }
 lettre = { version = "0.10", default-features = false, features=["smtp-transport", "hostname", "builder"] }
 fake = { version = "2.5", features=["derive"]}
 reqwest = { version = "0.11", features = ["json"] }
-local-ip-address = "0.5"
\ No newline at end of file
+local-ip-address = "0.5"


Test patch: