npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@kumori/tcp-proxy

v1.0.3

Published

Proxy for tunneling TCP connections through Kumori's channels

Downloads

9

Readme

semantic-release

Tcp Proxy

Proxy for tunneling TCP connection through Kumori's platform channels

Description

This module proxifies a legacy tcp server connections through Kumori's channels (see Kumori's documentation for more information about channels and Kumori's service application model).

Table of Contents

Installation

Install it as a npm package

npm install -g @kumori/tcp-proxy

Usage

In general, we may have situations in which a component functionality is actually provided by an existing server program, expecting access to IP networks, and such that it is either costly, impractical or outright impossible to carry out any sort of change in their code.

As was the case of the Http Proxy, the component should be properly specified, with the channels that make sense to how it is to be connected, and the configuration needed for semantically consistent set up of the legacy server.

Besides this configuration, however, we will need a way to convert the IP-based configuration directly supported by the legacy server to interact with other roles within the deployed service.

Just as in the case of the web server, the approach will require the component module to act as an adapter, launching the legacy server to interact with the +localhost+ network interface, through adequate network ports.

Unlike the case of the legacy web server, we now can have an arbitrary protocol being spoken by the legacy server, thus we need a "neutral" solution. For this case {ecloud} provides a @kumori/tcp-proxy module that can be used by the adapter/component to tunnel IP protocols through {ecloud} channels transparently to the legacy server code.

In this case, the channel protocol knows nothing about the higher level protocol supported by the server, limiting itself to ship the bytes being pushed back and forth by legacy pieces of software.

The following shows an example of how to generally set up this kind of legacy support.

Component = require 'component'
TcpProxy = require('@kumori/tcp-proxy').TcpProxy  #<1>
child = require 'child-process'

module.exports = class MyComponent extends Component
  ...
  run: () ->
    [server, parameters, channels] = @computeServerParametersAndChannels() #<2>

    @proxy = new TcpProxy @iid, @role, channels      #<3>

    @proxy.on 'ready', (@bindIp) =>                  #<4>
      @startLegacyServer server, bindIp, parameters

    @proxy.on 'error', (err) =>                      #<5>
      @processProxyError err

    @proxy.on 'change', (data) =>                    #<6>
      @reconfigLegacyServer server, bindIp, parameters, data

    @proxy.on 'close', () =>                         #<7>
      @stopLegacyServer server, parameters

  shutdown: ->
    @proxy.shutdown()                                #<8>
  ...
  1. We now require the generic @kumori/tcp-proxy module.
  2. Assuming method computeServerParametersAndChannels returns as in Http Proxy the server program and parameters to pass to it. But, in addition, it returns an object relating the component's channels to the legacy server ports/connections/bindings.
  3. TcpProxy object initialization requires the role and ID of the instance, and the list of channels (with additional information) to be proxied.
  4. TcpProxy object issues an event when it is ready to process requests, providing the local IP address to be assigned to the legacy server. For TcpProxy to function properly, legacy server must be bound to that IP.
  5. TcpProxy object issues an event when an error occurs.
  6. TcpProxy object issues an event, during its life cycle, when any change occurs that should result in a reconfiguration of the legacy server.
  7. TcpProxy object issues an event when it's closed.
  8. TcpProxy object finalization.

While method computeServerParameters is straightforward to write, needing only to know how to start the legacy server, writing method computeServerParametersAndChannels will require knowing how to configure the TcpProxy object too.

Configuring the TcpProxy object

TcpProxy object initialization requires an object relating the component's channels to the legacy server ports/connections/bindings.

This object is a dictionary whose key is the channel name, and values contains:

  • A reference to the channel object
  • TCP port to be proxied
  • In case of duplex channels, its operating mode (bind/connect)

Example configuration for a TcpProxy that proxies four channels:

{
  'myDuplex1': {
    channel: myDuplex1,
    port: 9100,
    mode: 'bind'
  },
  'myDuplex2': {
    channel: myDuplex2,
    port: 9100,
    mode: 'connect'
  },
  'myRequest3': {
    channel: myRequest3,
    port: 9200
  },
  'myReply4': {
    channel: myReply4,
    port: 9200
  }
}

Ready event

When TcpProxy object is ready to process requests, a 'ready' event is emitted,

Data associated with this event is the local IP address to be used by the legacy server.

Typically, this IP address is used when starting the legacy server with duplex/bind or a reply channels. Typically, this information is not used with duplex/connect or a request channels.

@proxy.on 'ready', (bindIp) =>
  @_startLegacyServer bindIp, ...

Error event

TcpProxy object can issue error events, basically during the creation of internal connections initializing the proxy.

@proxy.on 'error', (err) =>
  ...

Change event

During its life cycle, TcpProxy object emits change events when any change occurs, which may result in a reconfiguration of the legacy server.

Data associated with this event will vary depending on the channel that caused it.

@proxy.on 'change', (data) ->
  @reconfigLegacyServer server, bindIp, parameters, data

Request

When a request channel is proxied, a TCP port is opened in a local IP address. A change event is issued when TcpProxy is ready and listening on this port. An event is issued too, when the port is closed (this happens when the instance is shutting down, so usually an action on the legacy server is not required). Event data contains parameters that legacy server could need to be reconfigured:

  • Listening (true/false)
  • Channel name
  • IP
  • Port

For example:

{
  channel: 'myRequest3',
  listening: true,
  ip: ip:'127.0.0.7',
  port: 9300
}

Reply

Never issues change events.

Duplex

When the set of instances attached to the complete connector (duplex channels) changes, TcpProxy issues a change event. Event data is a list of current members with the information that the legacy server could need to be reconfigured:

  • Channel name
  • Instance ID
  • IP
  • Port

For example:

{
  channel: 'myDuplex1',
  members: [
    {iid:'A_10', ip:'127.0.0.7', port:9100},
    {iid:'A_11', ip:'127.0.0.8', port:9100},
    {iid:'A_12', ip:'127.0.0.9', port:9100}
  ]
]

Close event

After TcpProxy.shutdown() method is invoked, a 'close' event is emitted when operation is finished.

@proxy.on 'close', () =>
  ...

License

MIT © Kumori Systems