• Stars
    star
    214
  • Rank 184,678 (Top 4 %)
  • Language
    JavaScript
  • Created about 12 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

TCP proxy that also duplicates traffic to a secondary host

duplicator build status

TCP proxy that also duplicates traffic to a secondary host

I built this because I needed a way to "tap" production traffic and shoot it at a new system to see how it handles load.

usage (cli)

npm install -g duplicator
duplicator -f localhost:80 -d localhost:3000 -p 8080 [-i 127.0.0.1]
  • forward all traffic to localhost:80
  • duplicate all traffic to localhost:3000, ignoring responses
  • listen on port 8080
  • if -i is specified only listen to incoming traffic for ip address 127.0.0.1

Note: the cli automatically uses the cluster API to run several workers to handle connections, and restart workers if they die.

usage (code)

The equivalent to the call above, in node.js:

var duplicator = require('duplicator')

var server = duplicator(function(connection, forward, duplicate) {
  forward('localhost:80')
  duplicate('localhost:3000')
}).listen(8080, ["127.0.0.1"])

reference

duplicator(cb)

Creates a new net.Server. When cb is called on a successful connection, it will receive the connection to the client and two special callback functions, forward and duplicate.

duplicator(function(connection, forward, duplicate) {
  forward('origin:80')
  duplicate(Math.random() < 0.5 ? 'host1:80' : 'host2:80')
})

In this example, we always use origin:80 as the primary server to forward requests to, but we send half the duplicated rquests to host1, and the other half to host2.

forward(host, [stream])

Forward stream to host. stream defaults to the current connection unless otherwise specified.

duplicator(function(connection, forward, duplicate) {
  // forward every connection to localhost:80
  forward('localhost:80')
})

Note that it is not safe to forward the same connection multiple times, as the responses from the different servers may interfere with one another. Therefore if you do call forward multiple times, only the first call will succeed, and subsequent calls will merely duplicate the connection.

duplicate(host, [stream], [rate])

Duplicate on average rate copies of stream to host. stream defaults to the current connection unless otherwise specified, rate defaults to 1.

Rate is the expected number of copies sent per connection, and is interpreted as follows:

  • 0.1 -> send once with 10% probability
  • 1 -> send exactly one copy
  • 5 -> send out 5 copies
  • 2.5 -> send out 2 copies, with a 50% chance of a third

Note that both stream and rate are optional, but have sensible defaults. If only two parameters are specified, the second will be interpreted as rate if it's a number, stream otherwise.

duplicator(function(connection, forward, duplicate) {
  // duplicate 50% of requests to localhost:3000
  duplicate('localhost:3000', 0.5)
  // duplicate all connections to stdout
  duplicate('localhost:3000', process.stdout)
})

specifying hosts

A host can be any one of:

  • an object as net.connect would expect it ({ host: 'google.com', port: 80 })
  • a number representing a port (80, 3000), host is implied to be localhost
  • a string representing a host (localhost:3000, google.com:80)
  • a function that behaves like net.connect (function(cb) { net.connect({ port:80 }, cb) })

contributing and attribution

Thanks to @netroy for contributing the cluster support!

If you'd like to contribute, please open a pull request or file an issue.

mit license

More Repositories

1

agnoster-zsh-theme

A ZSH theme designed to disclose information contextually, with a powerline aesthetic
Shell
3,972
star
2

git-dropbox

The easiest way to use a Dropbox for git repositories
Shell
125
star
3

base32-js

Base32 encoding for JavaScript, based (loosely) on Crockford's Base32
JavaScript
116
star
4

ansi2html

Convert text with ANSI escape sequences to styled HTML
JavaScript
32
star
5

literapi

Literate testing for HTTP APIs using markdown
JavaScript
21
star
6

nodeready

[DEFUNCT] A one-step installer for a fully-functioning node.js development environment
Shell
10
star
7

nosey

Node CI -> nosey. It doesn't get any simpler.
JavaScript
7
star
8

elekk

[DEFUNCT] Elekk is a Ruby gem that provides an interface to data for Blizzard's highly popular MMORPG, World of Warcraft. It currently uses data both from Blizzard's official Armory website at wowarmory.com, as well as the popular community database, WoWhead.com. Future versions may make use of additional sources of information.
Ruby
6
star
9

markdownstream

Streaming markdown parser that allows round-tripping and patching
JavaScript
4
star
10

weshareabrain

Shared todolist for small groups that live together (aka households)
Ruby
4
star
11

jsonexp

RegExp for JSON - powerful, expressive pattern matching for data structures
JavaScript
4
star
12

bumper

Simple release management for npm packages with git
JavaScript
3
star
13

node-uberblic

[DEFUNCT] A wrapper for the uberblic.org API
JavaScript
3
star
14

disputandum

The game of civil discourse
3
star
15

unitology

Easy conversions between units
JavaScript
3
star
16

yanc

A command-line client for the nodester platform
JavaScript
3
star
17

bitcoder

[DEFUNCT] A streaming Node.js addon for encoding/decoding byte streams to alternate bases natively (C++)
C++
2
star
18

ratio

Rational numbers (fractions) for node.js
JavaScript
2
star
19

wunderlist

The awesome and free GTD Tool wunderlist
JavaScript
2
star
20

homebrew-synergykm

Homebrew cask for http://synergykm.com
Ruby
2
star
21

hoboku

Deploy apps locally to Vagrant, Heroku-style.
Ruby
1
star
22

mementropy

A client-side XKCD936-compliant password generator. Easy to remember, hard to crack.
1
star
23

enumtree

Data structure for representing lists with fast insert, remove, and lookup from element to index.
JavaScript
1
star