Comparison Test of Port Forwarding between Socat and Brook: Who is Stronger and Weaker?

Publish: 2021-01-14 | Modify: 2021-01-14

Common port forwarding programs include socat, Brook, nginx, rinetd, iptables, etc. Most of them have been introduced in my blog. Interested students can refer to my previous articles.

There are very few online reviews of port forwarding software. Recently, I packaged socat and Brook as Docker images. Today, I will compare the two and test their efficiency. (Non-authoritative testing, results for reference only)

Test Environment

The web server (Nginx) has been installed on the target server 163.172.35.xxx, and socat and Brook have been deployed on the relay server 137.175.30.xxx to forward ports to port 80 on the target. The information is as follows:

  • Target server: 163.172.35.xxx:80
  • Relay server: 137.175.30.xxx:32771 (socat)
  • Relay server: 137.175.30.xxx:32770 (Brook)

Initial Environment (Round 1)

Socat and Brook are deployed using Docker. After deployment, with no connections, the memory usage is as follows:

Socat uses less than 800Kb of memory

Brook uses 1.8Mb of memory

hey HTTP Load Testing (Round 2)

Next, I will use the hey tool to perform concurrent HTTP load testing on two different forwarding ports. The test command is:

./hey -n 10000 -c 1000 -m GET http://xxx/

The above command sends 10,000 requests to the relay server with a concurrency of 1,000.


Socat load test results: Peak memory usage of 154Mb, peak CPU usage of 32%, total time of 67s, average time of 1.5347s, error count of 238 times

Summary:
  Total:        67.5975 secs
  Slowest:      19.9194 secs
  Fastest:      0.3516 secs
  Average:      1.5347 secs
  Requests/sec: 147.9345

Response time histogram:
  0.352 [1]     |
  2.308 [8318]  |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  4.265 [738]   |■■■■
  6.222 [227]   |■
  8.179 [166]   |■
  10.136 [100]  |
  12.092 [48]   |
  14.049 [53]   |
  16.006 [31]   |
  17.963 [39]   |
  19.919 [41]   |

Latency distribution:
  10% in 0.3608 secs
  25% in 0.3721 secs
  50% in 0.7243 secs
  75% in 1.4874 secs
  90% in 3.3814 secs
  95% in 6.0845 secs
  99% in 14.1610 secs

Details (average, fastest, slowest):
  DNS+dialup:   0.0225 secs, 0.3516 secs, 19.9194 secs
  DNS-lookup:   0.0000 secs, 0.0000 secs, 0.0000 secs
  req write:    0.0001 secs, 0.0000 secs, 0.0309 secs
  resp wait:    1.4584 secs, 0.3515 secs, 19.9191 secs
  resp read:    0.0002 secs, 0.0001 secs, 0.0270 secs

Status code distribution:
  [200] 9762 responses

Error distribution:
  [238] Get "http://137.175.30.xxx:32771/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Brook load test results: Peak memory usage of 25Mb, peak CPU usage of 64%, total time of 44s, average time of 1.0304s, error count of 67 times

Summary:
  Total:        44.2130 secs
  Slowest:      19.4560 secs
  Fastest:      0.3522 secs
  Average:      1.0304 secs
  Requests/sec: 226.1777

Response time histogram:
  0.352 [1]     |
  2.263 [9106]  |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  4.173 [528]   |■■
  6.083 [158]   |■
  7.994 [69]    |
  9.904 [22]    |
  11.814 [17]   |
  13.725 [7]    |
  15.635 [11]   |
  17.546 [9]    |
  19.456 [5]    |

Latency distribution:
  10% in 0.3605 secs
  25% in 0.3687 secs
  50% in 0.5565 secs
  75% in 1.0805 secs
  90% in 2.0481 secs
  95% in 2.8718 secs
  99% in 7.2565 secs

Details (average, fastest, slowest):
  DNS+dialup:   0.0192 secs, 0.3522 secs, 19.4560 secs
  DNS-lookup:   0.0000 secs, 0.0000 secs, 0.0000 secs
  req write:    0.0001 secs, 0.0000 secs, 0.0117 secs
  resp wait:    0.9539 secs, 0.3519 secs, 19.4558 secs
  resp read:    0.0002 secs, 0.0001 secs, 0.0316 secs

Status code distribution:
  [200] 9933 responses

Error distribution:
  [67]  Get "http://137.175.30.xxx:32770/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

xiaoz repeated the tests several times, and the data directions were basically consistent.

axel Multithreaded Download Test (Round 3)

Test command:

time axel -n 32 "http://137.175.30.xxx:32771/test"

The test file is 200M, and 32 threads are used for downloading using axel.


Socat test results: Time taken of 48m44s, peak memory usage of around 5.8Mb.

real    48m44.111s
user    0m1.934s
sys     0m10.616s

Brook test results: Time taken of 36m3.646s, peak memory usage of around 2.9Mb.

real    36m3.646s
user    0m1.730s
sys     0m8.930s

Data Summary

Software/Test ItemsocatBrook
Initial Memory800Kb1.8Mb
hey Load Test (Time)67s44s
hey Load Test (max(cpu))32%64%
hey Load Test (Error Count)23867
hey Load Test (max(mem))154Mb25Mb
axel 32-thread Download (Time)48m44s36m3s
axel 32-thread Download (max(mem))5.8Mb2.9Mb
  • Socat has lower initial memory usage than Brook
  • Under high concurrency, socat has higher memory usage than Brook
  • Under high concurrency, Brook has higher CPU usage than socat
  • For multi-threaded downloads, Brook is more efficient than socat

Conclusion

The above results are only for HTTP forwarding load testing. Due to factors such as environment and network, and not having studied socat parameters in detail, I cannot guarantee the accuracy of the data 100%. Interested students can test it themselves. Based on the above test data, xiaoz provides the following suggestions:

  • If it is for personal use with low machine configuration, socat is recommended
  • If there is high concurrency and higher efficiency is required, Brook is recommended

Next, I will compare and test other port forwarding software. Stay tuned.


Comments