{"id":13510091,"url":"https://github.com/ggrandes/bouncer","last_synced_at":"2026-01-10T04:57:47.306Z","repository":{"id":5338982,"uuid":"6524587","full_name":"ggrandes/bouncer","owner":"ggrandes","description":"Bouncer is a network TCP port redirector/forward proxy (like rinetd) with extra features like Reverse tunneling (like ssh -R), SSL tunneling (like stunnel), connection Failover, LoadBalancing and Clustering. In pure Java (BIO)","archived":false,"fork":false,"pushed_at":"2024-09-15T09:49:56.000Z","size":441,"stargazers_count":135,"open_issues_count":3,"forks_count":42,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-03-13T03:01:44.354Z","etag":null,"topics":["aes","bouncer","encryption","java","mux","reverse-tunnels","ssl","tcp","tunnel"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ggrandes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-11-03T21:48:56.000Z","updated_at":"2024-11-02T16:26:17.000Z","dependencies_parsed_at":"2022-07-05T22:31:11.097Z","dependency_job_id":null,"html_url":"https://github.com/ggrandes/bouncer","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fbouncer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fbouncer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fbouncer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fbouncer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ggrandes","download_url":"https://codeload.github.com/ggrandes/bouncer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246338609,"owners_count":20761407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aes","bouncer","encryption","java","mux","reverse-tunnels","ssl","tcp","tunnel"],"created_at":"2024-08-01T02:01:23.764Z","updated_at":"2026-01-10T04:57:47.277Z","avatar_url":"https://github.com/ggrandes.png","language":"Java","readme":"# Bouncer (TCP)\n\nBouncer is an open source (Apache License, Version 2.0) Java network proxy. Do not require any external lib.\n\n### Current Stable Version is [2.2.11](https://maven-release.s3.amazonaws.com/release/org/javastack/bouncer/2.2.11/bouncer-2.2.11-bin.zip)\n\n---\n\n## DOC\n\n#### Schema about Forward / Port Redirector (you need ONE bouncer):\n    \n![Forward / Port Redirector](https://raw.github.com/ggrandes/bouncer/master/doc/forward_port.png \"Forward / Port Redirector\")\n\n1. Machine-A (Client) init connection to Machine-B (Bouncer)\n2. Machine-B init connection to Machine-C (Server)\n3. Done: Machine-A is able to speak with Machine-C\n\n###### Notes about security:\n\n* Machine-A (Client) may be in Internal network.\n* Machine-B (Bouncer) may be in DMZ.\n* Machine-C (Server) may be in External network.\n\n#### Schema about Reverse Tunneling (you need TWO bouncers):\n    \n![Reverse Tunneling](https://raw.github.com/ggrandes/bouncer/master/doc/reverse_tunneling.png \"Reverse Tunneling\")\n\n###### Machine-A and Machine-B are Bouncers in Client-Server configuration.\n\n1. Machine-A (MUX-OUT) init connection to Machine-B (MUX-IN)\n2. Machine-D (Client) init connection to Machine-B\n3. Machine-B request to Machine-A new SubChannel over MUX (Tunnel).\n4. Machine-A open connection to Machine-C (Server).\n5. Done: Machine-D is able to speak with Machine-C\n\n###### Notes about security:\n\n* Machine-B (MUX-IN) should be in DMZ.\n* Machine-A (MUX-OUT) and Machine-C (Server) may be in internal network.\n\n---\n\n## System Properties (optional)\n\n    # To redir stdout/stderr to (auto-daily-rotated) files you can use:\n    -Dlog.stdOutFile=/var/log/bouncer.out -Dlog.stdErrFile=/var/log/bouncer.err\n    # To log to stdout too:\n    -Dlog.stdToo=true \n\n###### Filenames are a base-pattern, output files they will be: bouncer.xxx.YEAR-MONTH-DAY (bouncer.xxx.2014-12-01)\n\n## Config (bouncer.conf)\nConfig file must be in class-path `${BOUNCER_HOME}/conf/`, general format is:\n\n    # Forward / Port Redirector\n    # \u003clisten-addr\u003e \u003clisten-port\u003e \u003cremote-addr\u003e \u003cremote-port\u003e [opts]\n    \n    # Reverse Tunneling (Bouncer 2.x syntax)\n    # \u003cmux-in|tun-listen\u003e \u003cmux-name\u003e \u003clisten-addr\u003e \u003clisten-port\u003e [opts]\n    # \u003cmux-out|tun-connect\u003e \u003cmux-name\u003e \u003cremote-addr\u003e \u003cremote-port\u003e [opts]\n    \n    # Note: \u003cremote-addr\u003e can be a coma separated list of addresses, like \"srv1,srv2,192.168.1.1\"\n    \n    # Clustering Config\n    # \u003ccluster-listen\u003e \u003ccluster-id\u003e \u003clisten-addr\u003e \u003clisten-port\u003e [opts]\n    # \u003ccluster-peer\u003e \u003ccluster-id\u003e \u003cremote-addr\u003e \u003cremote-port\u003e [opts]\n\n###### Options are comma separated:\n\n* Options for outgoing connections\n    * Loadbalancing/Failover (only one option can be used)\n        * **LB=ORDER**: active failover-only in order (DNS resolved IP address are sorted, lower first)\n        * **LB=RR**: active LoadBalancing in DNS order (round-robin)\n        * **LB=RAND**: activate LoadBalancing in DNS random order\n    * Sticky Session\n        * **STICKY=MEM:bitmask:elements:ttl[:cluster-id:replication-id]**: activate Sticky session based on IP Source Address. Sessions are stored in MEMory, *bitmask* is a [CIDR](http://en.wikipedia.org/wiki/CIDR) to apply in source-ip-address (16=Class B, 24=Class C, 32=Unique host), *elements* for LRU cache, *ttl* is time to live of elements in cache (seconds), *cluster-id* and *replication-id* in cluster environment is cluster identifier and replication identifier respectively. \n* Options for inbound connections\n    * **PROXY=SEND**: use PROXY protocol (v1), generate header for remote server\n* Options for Forward / Port Redirector (rinetd)\n    * **TUN=SSL**: activate SSL/TLS tunneling outbound (destination is SSL/TLS, like stunnel)\n        * **SSL=client.crt:client.key[:server.crt]**: specify files for SSL/TLS config (client mode) (optional)\n    * **TUN=ENDSSL**: activate SSL/TLS tunneling inbound (origin is SSL/TLS, like stunnel)\n        * **ENDSSL=server.crt:server.key[:client.crt]**: specify files for SSL/TLS config (server mode)\n* Options for Reverse Tunneling (MUX)\n    * **TUN_ID=number**: When use Bouncer 2.x syntax you can create multiple Tunnels over same mux, use this ID for associate both ends.\n    * Select operation of MUX (only one option can be used) in Bouncer 1.x config\n        * **MUX=IN**: activate input-terminator multiplexor (Bouncer 2.x syntax: `mux-in, tun-listen`)\n        * **MUX=OUT**: activate output-initiator multiplexor (Bouncer 2.x syntax: `mux-out, tun-connect`)\n    * Options for encryption (optional -AES or SSL or NONE-):\n        * **MUX=AES**: activate AES encryption in multiplexor (see AES=sharedsecret)\n            * **AES=sharedsecret**: specify the password for AES (no white spaces, no comma sign, no equals sign)\n            * **AESBITS=bits** (optional): specify the keysize for AES (default: `128`)\n            * **AESALG=algorithm** (optional): specify the transformation for AES (default: `AES/CTR/NoPadding`)\n        * **MUX=SSL**: activate SSL/TLS encryption in multiplexor (see SSL=xxx)\n            * **SSL=server.crt:server.key:client.crt**: specify files for SSL/TLS config (server/mux-in)\n            * **SSL=client.crt:client.key:server.crt**: specify files for SSL/TLS config (client/mux-out)\n* Options for Clustering (TCP only)\n    * Options for encryption (optional -AES or SSL or NONE-):\n        * **CLUSTER=AES**: activate AES encryption in cluster (see AES=sharedsecret)\n            * **AES=sharedsecret**: specify the password for AES (no white spaces, no comma sign, no equals sign)\n            * **AESBITS=bits** (optional): specify the keysize for AES (default: `128`)\n            * **AESALG=algorithm** (optional): specify the transformation for AES (default: `AES/CTR/NoPadding`)\n        * **CLUSTER=SSL**: activate SSL/TLS encryption in cluster (see SSL=xxx)\n            * **SSL=server.crt:server.key:client.crt**: specify files for SSL/TLS config (server/cluster-in)\n            * **SSL=client.crt:client.key:server.crt**: specify files for SSL/TLS config (client/cluster-out)\n\n###### Notes about LB policies:\n\n* **LB=ORDER**: ordering of \\\u003cremote-addr\\\u003e is preserved, but DNS resolved records are sorted numerically before create address list, Example config: srv3,srv2,10.1.1.1 (DNS query return {10.1.3.7,10.1.3.8} for srv3 and {10.1.2.**9**,10.1.2.**3**} for srv2), the resulting Address list will be: {10.1.3.7,10.1.3.8,10.1.2.**3**,10.1.2.**9**,10.1.1.1}. All connections will be always for 10.1.3.7, if down, 10.1.3.8, and so on. If Sticky is enabled this have preference over address order (no failback). \n* **LB=RR**: ordering of \\\u003cremote-addr\\\u003e is preserved, and DNS resolved records are not sorted numerically before create address list, Example config: srv3,srv2,10.1.1.1 (DNS query return {10.1.3.7,10.1.3.8} for srv3 and {10.1.2.9,10.1.2.3} for srv2), the resulting Address list will be: {10.1.3.7,10.1.3.8,10.1.2.9,10.1.2.3,10.1.1.1}. The connections are rotative over all addresses for all clients, 10.1.3.7,10.1.3.8,...,10.1.1.1,and again 10.1.3.7,... if an address is down, picks next, and so on.... until a full turn. \n* **LB=RAND**: ordering of \\\u003cremote-addr\\\u003e is not preserved, and DNS resolved records are not sorted numerically before create address list, instead, all addreses are agregated and shuffled on every connection, Example config: srv3,srv2,10.1.1.1 (DNS query return {10.1.3.7,10.1.3.8} for srv3 and {10.1.2.9,10.1.2.3} for srv2), the resulting Address list can be: {10.1.3.8,10.1.1.1,10.1.3.7,10.1.2.9,10.1.2.3}. The connection first try 10.1.3.8, if down, 10.1.1.1, and so on.... until 10.1.2.3. \n\n###### Notes about security:\n\n* If use MUX=SSL or CLUSTER=SSL\n    * Keys/Certificates are pairs, must be configured in the two ends (MUX-IN \u0026 MUX-OUT)\n    * files.crt are X.509 public certificates\n    * files.key are RSA Keys in PKCS#8 format (no encrypted)\n    * files.crt/.key must be in class-path `${BOUNCER_HOME}/keys/`\n    * be careful about permissions of \"files.key\" (unix permission 600 may be good)\n* If use MUX=AES or CLUSTER=AES, you need to protect the \"bouncer.conf\" from indiscrete eyes (unix permission 600 may be good)\n\n##### Example config of Forward / Port Redirector (rinetd style):\n\n    # \u003clisten-addr\u003e \u003clisten-port\u003e \u003cremote-addr\u003e \u003cremote-port\u003e [opts]\n    0.0.0.0 1234 127.1.2.3 9876\n    127.0.0.1 5678 encrypted.google.com 443 LB=RR,STICKY=MEM:24:128:300,TUN=SSL\n    127.0.0.1 8443 encrypted.google.com 443 TUN=ENDSSL,ENDSSL=server.crt:server.key,TUN=SSL\n\n##### Example config of Reverse Tunnels (equivalent ssh -p 5555 192.168.2.1 -R 127.0.0.1:8080:192.168.1.1:80)\n\n###### Machine-A (MUX-OUT):\n\n    ### Bouncer 1.x legacy syntax ###\n    # \u003cremote-addr\u003e \u003cremote-port\u003e \u003cremote-tun-addr\u003e \u003cremote-tun-port\u003e MUX-OUT\n    192.168.1.1 80 192.168.2.1 5555 MUX=OUT\n    \n    ### Bouncer 2.x syntax, with support for multi-port ###\n    # \u003cmux-out|tun-connect\u003e \u003cmux-name\u003e \u003cremote-addr\u003e \u003cremote-port\u003e [opts]\n    mux-out mux1 127.0.0.1 5555\n    tun-connect mux1 192.168.2.1 80 TUN_ID=1\n    tun-connect mux1 192.168.2.1 22 TUN_ID=2\n\n###### Machine-B (MUX-IN):\n \n    ### Bouncer 1.x legacy syntax ###\n    # \u003clisten-tun-addr\u003e \u003clisten-tun-port\u003e \u003clisten-addr\u003e \u003clisten-port\u003e MUX-IN\n    192.168.2.1 5555 127.0.0.1 8080 MUX=IN\n\n    ### Bouncer 2.x syntax, with support for multi-port ###\n    # \u003cmux-in|tun-listen\u003e \u003cmux-name\u003e \u003clisten-addr\u003e \u003clisten-port\u003e [opts]\n    mux-in mux1 192.168.2.1 5555\n    tun-listen mux1 127.0.0.1 8080 TUN_ID=1\n    tun-listen mux1 127.0.0.1 2222 TUN_ID=2\n \n##### Same example config of Reverse tunnels but SSL/TLS\n\n###### Machine-A (MUX-OUT):\n\n    ### Bouncer 1.x legacy syntax ###\n    # \u003cremote-addr\u003e \u003cremote-port\u003e \u003cremote-tun-addr\u003e \u003cremote-tun-port\u003e MUX-OUT\n    192.168.1.1 80 192.168.2.1 5555 MUX=OUT,MUX=SSL,SSL=peerA.crt:peerA.key:peerB.crt\n    \n    ### Bouncer 2.x syntax, with support for multi-port ###\n    # \u003cmux-out|tun-connect\u003e \u003cmux-name\u003e \u003cremote-addr\u003e \u003cremote-port\u003e [opts]\n    mux-out mux1 127.0.0.1 5555 MUX=SSL,SSL=peerA.crt:peerA.key:peerB.crt\n    tun-connect mux1 192.168.2.1 80 TUN_ID=1\n    tun-connect mux1 192.168.2.1 22 TUN_ID=2\n    tun-connect mux1 192.168.2.1 25 TUN_ID=3\n\n###### Machine-B (MUX-IN):\n \n    ### Bouncer 1.x legacy syntax ###\n    # \u003clisten-tun-addr\u003e \u003clisten-tun-port\u003e \u003clisten-addr\u003e \u003clisten-port\u003e MUX-IN\n    192.168.2.1 5555 127.0.0.1 8080 MUX=IN,MUX=SSL,SSL=peerB.crt:peerB.key:peerA.crt\n\n    ### Bouncer 2.x syntax, with support for multi-port ###\n    # \u003cmux-in|tun-listen\u003e \u003cmux-name\u003e \u003clisten-addr\u003e \u003clisten-port\u003e [opts]\n    mux-in mux1 192.168.2.1 5555 MUX=SSL,SSL=peerB.crt:peerB.key:peerA.crt\n    tun-listen mux1 127.0.0.1 8080 TUN_ID=1\n    tun-listen mux1 127.0.0.1 2222 TUN_ID=2\n    tun-listen mux1 127.0.0.1 465 TUN_ID=3,TUN=ENDSSL,ENDSSL=server.crt:server.key\n\n###### For Encryption Tunnels with AES (no SSL/TLS) you can use `MUX=AES,AES=sharedsecret` in both sides \n\n* More examples in [sampleconf](https://github.com/ggrandes/bouncer/blob/master/sampleconf/)\n\n---\n\n## Running (Linux)\n\n    ./bin/bouncer.sh \u003cstart|stop|restart|reload|status\u003e\n\n## Running (command line without config file)\n\n    java -jar bouncer-x.x.x.jar -- \"...config.line.1...\" \"...config.line.2...\"\n    \n    Example:\n    java -jar bouncer-x.x.x.jar -- \"0.0.0.0 1234 127.1.2.3 9876\" \"127.0.0.1 5678 encrypted.google.com 443 TUN=SSL\"\n\n## Running (command line with remote config file)\n\n    java -jar bouncer-x.x.x.jar https://config.acme.com/bouncer.conf\n    \n\n## RSA Key / X.509 Certificate Generation for MUX-SSL (optional)\n\n    ./bin/bouncer.sh keygen \u003cbits\u003e \u003cdays\u003e \u003cCommonName\u003e \u003cfilename-without-extension\u003e\n\n## Enabling Strong Ciphers with BouncyCastleProvider\n\nYou can improve security, simply download **bcprov-jdk15on-`XXX`.jar** from [BouncyCastle](http://www.bouncycastle.org/latest_releases.html) and copy jar file to `${BOUNCER_HOME}/lib/` \n\n---\n\n## TODOs\n\n* NIO? - for [C10K problem](https://en.wikipedia.org/wiki/C10k_problem), in forward mode, try [jrinetd](https://github.com/ggrandes/jrinetd)\n* Use Log4J\n* Limit number of connections\n* Limit absolute timeout/TTL of a connection\n* Configurable retry-sleeps\n\n## DONEs\n\n* Reload config (v1.1)\n* Thread pool/control (v1.2)\n* Reverse tunnels (like ssh -R) over MUX (multiplexed channels) (v1.2)\n* FlowControl in MUX (v1.3)\n* Custom timeout by binding (v1.4)\n* Encryption MUX/Tunnel (AES+PreSharedSecret) (v1.4)\n* Encryption MUX/Tunnel (SSL/TLS) (v1.5)\n* Key Generator for MUX-SSL/TLS (v1.5)\n* Audit threads / connections (v1.5)\n* Improved FlowControl in MUX (v1.5)\n* Allow redir stdout/stderr to File, with auto daily-rotate (v1.5.1)\n* Enable TLSv1.2 ciphers (v1.5.8)\n* Added Elliptic Curve Diffie-Hellman Ephemeral Cipher Suites (v1.5.9)\n* Zip Packaging (Maven Assembly) (v1.5.9)\n* Allow AutoRegister JCE BouncyCastleProvider (v1.5.9)\n* Configurable [CipherSuites](https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider) for SSL/TLS (v1.6.0)\n    * For AES-256 you need [JCE Unlimited Strength](http://www.oracle.com/technetwork/es/java/javase/downloads/jce-7-download-432124.html) \n* Allow different tunnels over same MUX(IN/OUT) (v2.0.1)\n* BufferPool for reduce GC pressure (v2.0.1)\n* PROXY protocol (v1) for Outgoing connections (v2.1.0)\n* Sticky sessions in LoadBalancing (v2.2.1)\n* Statistics/Accounting (v2.2.2)\n* JMX (v2.2.3)\n* Multiple remote-addr (not only multi DNS A-record) (v2.2.4)\n* Replicate Sticky Sessions over multiple Bouncers (HA) (v2.2.5)\n* Allow alternative config names (v2.2.6)\n* Support for End SSL (v2.2.8)\n* Support client authentication in TUN=SSL (v2.2.8)\n* Support basic command line config without file (scripts,containers,etc) (v2.2.9)\n* Support remote config file (http/https) (v2.2.9)\n\n## MISC\nCurrent harcoded values:\n\n* Buffer Pool size: 4 (per thread)\n* Buffer length for I/O: 4096bytes\n* IO-Buffers: 8\n* TCP `SO_SNDBUF`/`SO_RCVBUF`: BufferLength * IO-Buffers \n* Connection timeout: 30seconds\n* DNS cache: 2seconds\n* Read timeout: 5minutes\n* MUX Keep-Alive: 30seconds\n* MUX-IN Error retry sleep: 0.5/1seconds\n* MUX-OUT Error retry sleep: 5seconds\n* Reload config check time interval: 10seconds\n* For MUX-AES [Password-Based Key Derivation Function](https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJCEProvider) for 4 keys (2 for Cipher, 2 for Mac) is PBKDF2WithHmacSHA1\n* For MUX-AES default [Cipher](https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJCEProvider) is AES/CTR/NoPadding (128 bits)\n* For MUX-AES [Mac](https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJCEProvider) for Authenticated encryption (Encrypt-then-MAC) is HmacSHA256\n* For MUX-AES Randomized IV per-message is used. \n* For MUX-AES Rekey is done every 32768 messages (2^15).\n* For MUX-AES Anti-replay window for messages (time): 5minutes\n* For MUX-AES Anti-replay sequence for messages: 31bits\n* For MUX-SSL supported Asymmetric Keys are RSA\n* For MUX-SSL enabled [Protocols](https://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider) are:\n    * `TLSv1.2`\n    * `TLSv1.1`\n    * `TLSv1`\n    * `SSLv3` DISABLED [POODLE CVE-2014-3566](http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3566)\n* Shutdown/Reload timeout: 30seconds\n* Statistics print interval: 30seconds\n\n---\n\n## Latency Benchmark\n\n\u003ctable\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003emicrosecs\u003c/th\u003e\n    \u003cth\u003eDirect\u003c/th\u003e\n    \u003cth\u003eForward\u003c/th\u003e\n    \u003cth\u003eMUX\u003c/th\u003e\n    \u003cth\u003eMUX-AES\u003c/th\u003e\n    \u003cth\u003eMUX-SSL\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003emin\u003c/th\u003e\n    \u003ctd\u003e12\u003c/td\u003e\n    \u003ctd\u003e38\u003c/td\u003e\n    \u003ctd\u003e110\u003c/td\u003e\n    \u003ctd\u003e125\u003c/td\u003e\n    \u003ctd\u003e184\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003emax\u003c/th\u003e\n    \u003ctd\u003e1468\u003c/td\u003e\n    \u003ctd\u003e1016\u003c/td\u003e\n    \u003ctd\u003e1351\u003c/td\u003e\n    \u003ctd\u003e51036\u003c/td\u003e\n    \u003ctd\u003e21771\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003eavg\u003c/th\u003e\n    \u003ctd\u003e19\u003c/td\u003e\n    \u003ctd\u003e46\u003c/td\u003e\n    \u003ctd\u003e120\u003c/td\u003e\n    \u003ctd\u003e153\u003c/td\u003e\n    \u003ctd\u003e213\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Throughput Benchmark\n\n\u003ctable\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003e(transfers)\u003c/th\u003e\n    \u003cth\u003eDirect (x2)\u003c/th\u003e\n    \u003cth\u003eForward (x4)\u003c/th\u003e\n    \u003cth\u003eMUX (x6)\u003c/th\u003e\n    \u003cth\u003eMUX-AES (x6)\u003c/th\u003e\n    \u003cth\u003eMUX-SSL (x6)\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003eMbytes\u003c/th\u003e\n    \u003ctd\u003e256\u003c/td\u003e\n    \u003ctd\u003e128\u003c/td\u003e\n    \u003ctd\u003e51\u003c/td\u003e\n    \u003ctd\u003e17\u003c/td\u003e\n    \u003ctd\u003e19\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr align=\"right\"\u003e\n    \u003cth\u003eMbits\u003c/th\u003e\n    \u003ctd\u003e2048\u003c/td\u003e\n    \u003ctd\u003e1024\u003c/td\u003e\n    \u003ctd\u003e408\u003c/td\u003e\n    \u003ctd\u003e136\u003c/td\u003e\n    \u003ctd\u003e152\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n###### All test run on localhost on a Laptop. Values are not accurate, but orientative. Latency { EchoServer, 1 byte write/read (end-to-end, round-trip), 100K iterations } Lower Better. Throughput { Chargen, 1024bytes read \u0026 write (full-duplex), total 512MBytes } Higher better.\n\n\n---\nInspired in [rinetd](http://www.boutell.com/rinetd/), [stunnel](https://www.stunnel.org/static/stunnel.html) and [openssh](http://www.openssh.org/), this bouncer is Java-minimalistic version.\n","funding_links":[],"categories":["Java","\u003ca id=\"01e6651181d405ecdcd92a452989e7e0\"\u003e\u003c/a\u003e工具","java","网络编程"],"sub_categories":["\u003ca id=\"9d6789f22a280f5bb6491d1353b02384\"\u003e\u003c/a\u003e隧道\u0026\u0026穿透"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fggrandes%2Fbouncer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fggrandes%2Fbouncer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fggrandes%2Fbouncer/lists"}