Compare commits

..

52 Commits

Author SHA1 Message Date
Jacob Heun
49c7f33375 chore: release version v0.13.1
License: MIT
Signed-off-by: Jacob Heun <jacobheun@gmail.com>
2019-08-08 13:27:01 +02:00
Jacob Heun
89bceb461f chore: update contributors 2019-08-08 13:27:01 +02:00
Jacob Heun
44f9e32d07 chore: update deps (#110)
* chore: add node 12 to travis
* test: just use spec files
2019-08-08 12:48:13 +02:00
Vasco Santos
c26cc70c65 chore: add discourse badge (#106) 2019-04-26 17:44:28 +02:00
Linus Unnebäck
3ab43a3604 chore: prefer const over let (#99)
Prefer const over let when the binding is static, in order to comply with an upcoming Standard rule.
2018-10-31 08:35:55 +00:00
Jacob Heun
3aad2ed243 chore: release version v0.13.0
License: MIT
Signed-off-by: Jacob Heun <jacobheun@gmail.com>
2018-09-12 19:40:49 +02:00
Jacob Heun
01cfbda2e7 chore: update contributors 2018-09-12 19:40:49 +02:00
Jacob Heun
eba0b48744 feat: add support for dialing over dns
License: MIT
Signed-off-by: Jacob Heun <jacobheun@gmail.com>
2018-09-12 19:38:02 +02:00
Jacob Heun
a0c23e49f7 chore: release version v0.12.1
License: MIT
Signed-off-by: Jacob Heun <jacobheun@gmail.com>
2018-07-31 14:13:11 +02:00
Jacob Heun
66ab208182 chore: update contributors 2018-07-31 14:13:10 +02:00
Jacob Heun
168d111158 chore: update deps and fix test runner
License: MIT
Signed-off-by: Jacob Heun <jacobheun@gmail.com>
2018-07-31 14:08:31 +02:00
TomCoded
4b04b17dfa fix: invalid ip address and daemon can be crashed by remote user
Per the nodeJS documentation, a Net socket.remoteAddress value may
be undefined if the socket is destroyed, as by a client disconnect.
A multiaddr cannot be created for an invalid IP address (such as
the undefined remote address of a destroyed socket). Currently
the attempt results in a crash that can be triggered remotely. This
commit catches the exception in get-multiaddr and returns an
undefined value to listener rather than throwing an exception when
trying to process defective or destroyed socket data. Listener then
terminates processing of the incoming p2p connections that generate
this error condition.

fixes: https://github.com/libp2p/js-libp2p-tcp/issues/93
fixes: https://github.com/ipfs/js-ipfs/issues/1447
2018-07-31 13:51:27 +02:00
Tom White
6c36a46831 test: fixes listen-dial test "dial and destroy on listener" (#97) 2018-07-31 13:46:12 +02:00
Jacob Heun
d39ec2db40 chore: add lead maintainer (#94)
* chore: add lead maintainer

License: MIT
Signed-off-by: Jacob Heun <jacobheun@gmail.com>

* Update package.json
2018-06-26 17:58:30 +02:00
David Dias
79428f3e62 chore: release version v0.12.0 2018-04-05 17:00:33 +01:00
David Dias
8a394b5286 chore: update contributors 2018-04-05 17:00:33 +01:00
David Dias
b7f73bcda1 test: fix dial error test 2018-04-05 17:00:19 +01:00
David Dias
8b44aa28ee chore: update deps 2018-04-05 16:56:23 +01:00
Diogo Silva
ded1f6831c feat: add class-is module 2018-04-05 16:55:54 +01:00
Drew Stone
5ef24695fc docs: fixing the broken example in README (#91)
* Working example fix

* Char fix

* Corrected output, and add yarn to gitignore
2018-04-05 16:55:25 +01:00
David Dias
df0aa059ca chore: release version v0.11.6 2018-02-20 10:27:27 +00:00
David Dias
bf74e9acad chore: update contributors 2018-02-20 10:27:26 +00:00
David Dias
83c4617e8d chore: update deps 2018-02-20 10:27:17 +00:00
David Dias
3b7e68bc8a docs: update and polish 2018-02-20 10:25:18 +00:00
David Dias
de1d7fe75c chore: tiny refactor 2018-02-07 06:40:00 +00:00
David Dias
9c77a69ae3 chore: tiny refactor 2018-02-07 06:26:02 +00:00
David Dias
50840a8067 test: refactor 2018-02-07 06:06:15 +00:00
David Dias
d194ff0a3b chore: release version v0.11.5 2018-02-07 05:59:57 +00:00
David Dias
41ca37e9ce chore: update contributors 2018-02-07 05:59:56 +00:00
David Dias
71a28bb177 test: refactor 2018-02-07 05:59:34 +00:00
David Dias
0d1861a1f8 chore: release version v0.11.4 2018-02-07 05:58:11 +00:00
David Dias
929408eb38 chore: update contributors 2018-02-07 05:58:11 +00:00
David Dias
b94f9c5d51 test: refactor 2018-02-07 05:56:55 +00:00
David Dias
4b0851b4a4 chore: release version v0.11.3 2018-02-07 05:45:42 +00:00
David Dias
74771b9504 chore: update contributors 2018-02-07 05:45:42 +00:00
David Dias
48eefa1b40 chore: update deps 2018-02-07 05:45:30 +00:00
Pedro Teixeira
f8f52665f7 fix: clearing timeout when closes (#87) 2018-02-07 05:43:15 +00:00
David Dias
d804244239 chore: release version v0.11.2 2018-01-12 12:30:45 +00:00
David Dias
31c720f285 chore: update contributors 2018-01-12 12:30:45 +00:00
David Dias
c553e0448f chore: fix release script 2018-01-12 12:30:38 +00:00
David Dias
533835d22f test: do not run IPv6 tests on CI (#86)
* test: do not run IPv6 tests on CI

* Updating CI files (#83)

This commit updates all CI scripts to the latest version

* chore: use env variable instead

* skip the other IPv6 tests
2018-01-12 12:27:39 +00:00
Alan Shaw
74a88f6868 fix: missing dependency debug, fixes #84 2018-01-12 12:01:54 +00:00
David Dias
1de9f18894 chore: update gitignore 2017-10-13 17:17:54 +02:00
David Dias
2673ae48b0 chore: release version v0.11.1 2017-10-13 17:17:16 +02:00
David Dias
9a4425f5ba chore: update contributors 2017-10-13 17:17:16 +02:00
David Dias
50d6a7b7cf chre: fix linting 2017-10-13 17:17:11 +02:00
David Dias
0a515f8fda chore: update deps and CI config 2017-10-13 17:15:36 +02:00
Dmitriy Ryajov
11c4f451f4 feat: relay filtering
* feat: filter IPFS addrs correctly

* feat: mafmt addrs now support /ipfs no need for ad-hoc filtering

* feat: skip p2p-circuit addresses
2017-10-13 17:13:28 +02:00
David Dias
7572279838 chore: release version v0.11.0 2017-09-03 10:02:33 +01:00
David Dias
181ce4eef2 chore: update contributors 2017-09-03 10:02:33 +01:00
David Dias
f8075be92a docs: update badge on readme 2017-09-03 10:02:10 +01:00
David Dias
a54bb83657 feat: p2p addrs situation (#82)
* chore: update gitignore

* chore: update CI configs

* chore: update deps

* chore: small refactor
2017-09-03 10:01:16 +01:00
18 changed files with 1061 additions and 649 deletions

23
.gitignore vendored
View File

@@ -1,7 +1,18 @@
docs
**/node_modules/
**/*.log
test/repo-tests*
**/bundle.js
# yarn
yarn.lock
# Logs # Logs
logs logs
*.log *.log
coverage
# Runtime data # Runtime data
pids pids
*.pid *.pid
@@ -19,9 +30,17 @@ coverage
# node-waf configuration # node-waf configuration
.lock-wscript .lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html) build
build/Release
# Dependency directory # Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules node_modules
lib
dist
test/test-data/go-ipfs-repo/LOCK
test/test-data/go-ipfs-repo/LOG
test/test-data/go-ipfs-repo/LOG.old
# while testing npm5
package-lock.json

View File

@@ -1,33 +1,35 @@
sudo: false
language: node_js language: node_js
matrix: cache: npm
include: sudo: false
- node_js: 4
env: CXX=g++-4.8
- node_js: 6
env: CXX=g++-4.8
- node_js: stable
env: CXX=g++-4.8
# Make sure we have new NPM. stages:
before_install: - check
- npm install -g npm - test
- cov
script: node_js:
- npm run lint - '10'
- npm test - '12'
- npm run coverage
os:
- linux
- osx
- windows
before_script: before_script:
- export DISPLAY=:99.0 - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'; fi
- sh -e /etc/init.d/xvfb start script: npx nyc -s npm run test:node -- --bail
after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov
after_success: jobs:
- npm run coverage-publish include:
- stage: check
os: linux
script:
- npx aegir build --bundlesize
- npx aegir commitlint --travis
- npx aegir dep-check
- npm run lint
addons: notifications:
apt: email: false
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8

268
CHANGELOG.md Normal file
View File

@@ -0,0 +1,268 @@
<a name="0.13.1"></a>
## [0.13.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.13.0...v0.13.1) (2019-08-08)
<a name="0.13.0"></a>
# [0.13.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.12.1...v0.13.0) (2018-09-12)
### Features
* add support for dialing over dns ([eba0b48](https://github.com/libp2p/js-libp2p-tcp/commit/eba0b48))
<a name="0.12.1"></a>
## [0.12.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.12.0...v0.12.1) (2018-07-31)
### Bug Fixes
* invalid ip address and daemon can be crashed by remote user ([4b04b17](https://github.com/libp2p/js-libp2p-tcp/commit/4b04b17))
<a name="0.12.0"></a>
# [0.12.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.6...v0.12.0) (2018-04-05)
### Features
* add class-is module ([ded1f68](https://github.com/libp2p/js-libp2p-tcp/commit/ded1f68))
<a name="0.11.6"></a>
## [0.11.6](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.5...v0.11.6) (2018-02-20)
<a name="0.11.5"></a>
## [0.11.5](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.4...v0.11.5) (2018-02-07)
<a name="0.11.4"></a>
## [0.11.4](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.3...v0.11.4) (2018-02-07)
<a name="0.11.3"></a>
## [0.11.3](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.2...v0.11.3) (2018-02-07)
### Bug Fixes
* clearing timeout when closes ([#87](https://github.com/libp2p/js-libp2p-tcp/issues/87)) ([f8f5266](https://github.com/libp2p/js-libp2p-tcp/commit/f8f5266))
<a name="0.11.2"></a>
## [0.11.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.1...v0.11.2) (2018-01-12)
### Bug Fixes
* missing dependency debug, fixes [#84](https://github.com/libp2p/js-libp2p-tcp/issues/84) ([74a88f6](https://github.com/libp2p/js-libp2p-tcp/commit/74a88f6))
<a name="0.11.1"></a>
## [0.11.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.11.0...v0.11.1) (2017-10-13)
### Features
* relay filtering ([11c4f45](https://github.com/libp2p/js-libp2p-tcp/commit/11c4f45))
<a name="0.11.0"></a>
# [0.11.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.10.2...v0.11.0) (2017-09-03)
### Features
* p2p addrs situation ([#82](https://github.com/libp2p/js-libp2p-tcp/issues/82)) ([a54bb83](https://github.com/libp2p/js-libp2p-tcp/commit/a54bb83))
<a name="0.10.2"></a>
## [0.10.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.10.1...v0.10.2) (2017-07-22)
<a name="0.10.1"></a>
## [0.10.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.10.0...v0.10.1) (2017-04-13)
### Bug Fixes
* catch errors on incomming sockets ([e204517](https://github.com/libp2p/js-libp2p-tcp/commit/e204517))
<a name="0.10.0"></a>
# [0.10.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.9.4...v0.10.0) (2017-03-27)
### Bug Fixes
* **dial:** proper error handling on dial ([#77](https://github.com/libp2p/js-libp2p-tcp/issues/77)) ([4d4f295](https://github.com/libp2p/js-libp2p-tcp/commit/4d4f295))
<a name="0.9.4"></a>
## [0.9.4](https://github.com/libp2p/js-libp2p-tcp/compare/v0.9.3...v0.9.4) (2017-03-21)
<a name="0.9.3"></a>
## [0.9.3](https://github.com/libp2p/js-libp2p-tcp/compare/v0.9.2...v0.9.3) (2017-02-09)
<a name="0.9.2"></a>
## [0.9.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.9.1...v0.9.2) (2017-02-09)
<a name="0.9.1"></a>
## [0.9.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.9.0...v0.9.1) (2016-11-03)
<a name="0.9.0"></a>
# [0.9.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.8.1...v0.9.0) (2016-11-03)
### Bug Fixes
* **deps:** remove unused pull dep ([06689e3](https://github.com/libp2p/js-libp2p-tcp/commit/06689e3))
<a name="0.8.1"></a>
## [0.8.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.8.0...v0.8.1) (2016-09-06)
<a name="0.8.0"></a>
# [0.8.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.7.4...v0.8.0) (2016-09-06)
### Features
* **deps:** update to published deps ([da8ee21](https://github.com/libp2p/js-libp2p-tcp/commit/da8ee21))
* **pull:** migration to pull-streams ([5e89a26](https://github.com/libp2p/js-libp2p-tcp/commit/5e89a26))
* **readme:** add pull-streams documentation ([d9f65e0](https://github.com/libp2p/js-libp2p-tcp/commit/d9f65e0))
<a name="0.7.4"></a>
## [0.7.4](https://github.com/libp2p/js-libp2p-tcp/compare/v0.7.3...v0.7.4) (2016-08-03)
<a name="0.7.3"></a>
## [0.7.3](https://github.com/libp2p/js-libp2p-tcp/compare/v0.7.2...v0.7.3) (2016-06-26)
<a name="0.7.2"></a>
## [0.7.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.7.1...v0.7.2) (2016-06-23)
<a name="0.7.1"></a>
## [0.7.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.7.0...v0.7.1) (2016-06-23)
### Bug Fixes
* error was passed in duplicate ([9ac5cca](https://github.com/libp2p/js-libp2p-tcp/commit/9ac5cca))
<a name="0.7.0"></a>
# [0.7.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.6.2...v0.7.0) (2016-06-22)
<a name="0.6.2"></a>
## [0.6.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.6.1...v0.6.2) (2016-06-01)
### Bug Fixes
* address cr ([2ed01e8](https://github.com/libp2p/js-libp2p-tcp/commit/2ed01e8))
* destroy hanging connections after timeout ([4a12169](https://github.com/libp2p/js-libp2p-tcp/commit/4a12169))
<a name="0.6.1"></a>
## [0.6.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.6.0...v0.6.1) (2016-05-29)
<a name="0.6.0"></a>
# [0.6.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.5.3...v0.6.0) (2016-05-22)
<a name="0.5.3"></a>
## [0.5.3](https://github.com/libp2p/js-libp2p-tcp/compare/v0.5.2...v0.5.3) (2016-05-22)
<a name="0.5.2"></a>
## [0.5.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.5.1...v0.5.2) (2016-05-09)
<a name="0.5.1"></a>
## [0.5.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.5.0...v0.5.1) (2016-05-08)
<a name="0.5.0"></a>
# [0.5.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.4.0...v0.5.0) (2016-04-25)
<a name="0.4.0"></a>
# [0.4.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.3.0...v0.4.0) (2016-03-14)
<a name="0.3.0"></a>
# [0.3.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.2.1...v0.3.0) (2016-03-10)
<a name="0.2.1"></a>
## [0.2.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.2.0...v0.2.1) (2016-03-04)
<a name="0.2.0"></a>
# [0.2.0](https://github.com/libp2p/js-libp2p-tcp/compare/v0.1.2...v0.2.0) (2016-03-04)
<a name="0.1.2"></a>
## [0.1.2](https://github.com/libp2p/js-libp2p-tcp/compare/v0.1.1...v0.1.2) (2015-10-29)
<a name="0.1.1"></a>
## [0.1.1](https://github.com/libp2p/js-libp2p-tcp/compare/v0.1.0...v0.1.1) (2015-09-17)
<a name="0.1.0"></a>
# 0.1.0 (2015-09-16)

View File

@@ -1,31 +1,29 @@
# js-libp2p-tcp # js-libp2p-tcp
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) [![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) [![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](http://libp2p.io/)
[![Build Status](https://travis-ci.org/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://travis-ci.org/libp2p/js-libp2p-tcp) [![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p)
[![Coverage Status](https://coveralls.io/repos/github/libp2p/js-libp2p-tcp/badge.svg?branch=master)](https://coveralls.io/github/libp2p/js-libp2p-tcp?branch=master) [![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
[![](https://img.shields.io/codecov/c/github/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://codecov.io/gh/libp2p/js-libp2p-tcp)
[![](https://img.shields.io/travis/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://travis-ci.com/libp2p/js-libp2p-tcp)
[![Dependency Status](https://david-dm.org/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-tcp) [![Dependency Status](https://david-dm.org/libp2p/js-libp2p-tcp.svg?style=flat-square)](https://david-dm.org/libp2p/js-libp2p-tcp)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
![](https://img.shields.io/badge/npm-%3E%3D3.0.0-orange.svg?style=flat-square)
![](https://img.shields.io/badge/Node.js-%3E%3D4.0.0-orange.svg?style=flat-square)
![](https://raw.githubusercontent.com/libp2p/interface-connection/master/img/badge.png) [![](https://raw.githubusercontent.com/libp2p/interface-transport/master/img/badge.png)](https://github.com/libp2p/interface-transport)
![](https://raw.githubusercontent.com/libp2p/interface-transport/master/img/badge.png) [![](https://raw.githubusercontent.com/libp2p/interface-connection/master/img/badge.png)](https://github.com/libp2p/interface-connection)
> Node.js implementation of the TCP module that libp2p uses, which implements the [interface-connection](https://github.com/libp2p/interface-connection) interface for dial/listen.
`libp2p-tcp` in Node.js is a very thin shim that adds support for dialing to a `multiaddr`. This small shim will enable libp2p to use other different transports. > JavaScript implementation of the TCP module for libp2p. It exposes the [interface-transport](https://github.com/libp2p/interface-connection) for dial/listen. `libp2p-tcp` is a very thin shim that adds support for dialing to a `multiaddr`. This small shim will enable libp2p to use other different transports.
**Note:** This module uses [pull-streams](https://pull-stream.github.io) for all stream based interfaces. ## Lead Maintainer
[Jacob Heun](https://github.com/jacobheun)
## Table of Contents ## Table of Contents
- [Install](#install) - [Install](#install)
- [npm](#npm) - [npm](#npm)
- [Usage](#usage) - [Usage](#usage)
- [Example](#example)
- [This module uses `pull-streams`](#this-module-uses-pull-streams)
- [Converting `pull-streams` to Node.js Streams](#converting-pull-streams-to-nodejs-streams)
- [API](#api) - [API](#api)
- [Contribute](#contribute) - [Contribute](#contribute)
- [License](#license) - [License](#license)
@@ -35,24 +33,21 @@
### npm ### npm
```sh ```sh
> npm i libp2p-tcp > npm install libp2p-tcp
``` ```
## Usage ## Usage
### Example
```js ```js
const TCP = require('libp2p-tcp') const TCP = require('libp2p-tcp')
const multiaddr = require('multiaddr') const multiaddr = require('multiaddr')
const pull = require('pull-stream') const pull = require('pull-stream')
const mh1 = multiaddr('/ip4/127.0.0.1/tcp/9090') const mh = multiaddr('/ip4/127.0.0.1/tcp/9090')
const mh2 = multiaddr('/ip6/::/tcp/9092')
const tcp = new TCP() const tcp = new TCP()
const listener = tcp.createListener(mh1, (socket) => { const listener = tcp.createListener((socket) => {
console.log('new connection opened') console.log('new connection opened')
pull( pull(
pull.values(['hello']), pull.values(['hello']),
@@ -60,15 +55,21 @@ const listener = tcp.createListener(mh1, (socket) => {
) )
}) })
listener.listen(() => { listener.listen(mh, () => {
console.log('listening') console.log('listening')
pull( pull(
tcp.dial(mh1), tcp.dial(mh),
pull.log, pull.collect((err, values) => {
pull.onEnd(() => { if (!err) {
tcp.close() console.log(`Value: ${values.toString()}`)
}) } else {
console.log(`Error: ${err}`)
}
// Close connection after reading
listener.close()
}),
) )
}) })
``` ```
@@ -78,35 +79,13 @@ Outputs:
```sh ```sh
listening listening
new connection opened new connection opened
hello Value: hello
``` ```
### This module uses `pull-streams`
We expose a streaming interface based on `pull-streams`, rather then on the Node.js core streams implementation (aka Node.js streams). `pull-streams` offers us a better mechanism for error handling and flow control guarantees. If you would like to know more about why we did this, see the discussion at this [issue](https://github.com/ipfs/js-ipfs/issues/362).
You can learn more about pull-streams at:
- [The history of Node.js streams, nodebp April 2014](https://www.youtube.com/watch?v=g5ewQEuXjsQ)
- [The history of streams, 2016](http://dominictarr.com/post/145135293917/history-of-streams)
- [pull-streams, the simple streaming primitive](http://dominictarr.com/post/149248845122/pull-streams-pull-streams-are-a-very-simple)
- [pull-streams documentation](https://pull-stream.github.io/)
#### Converting `pull-streams` to Node.js Streams
If you are a Node.js streams user, you can convert a pull-stream to a Node.js stream using the module [`pull-stream-to-stream`](https://github.com/dominictarr/pull-stream-to-stream), giving you an instance of a Node.js stream that is linked to the pull-stream. For example:
```js
const pullToStream = require('pull-stream-to-stream')
const nodeStreamInstance = pullToStream(pullStreamInstance)
// nodeStreamInstance is an instance of a Node.js Stream
```
To learn more about this utility, visit https://pull-stream.github.io/#pull-stream-to-stream.
## API ## API
### Transport
[![](https://raw.githubusercontent.com/libp2p/interface-transport/master/img/badge.png)](https://github.com/libp2p/interface-transport) [![](https://raw.githubusercontent.com/libp2p/interface-transport/master/img/badge.png)](https://github.com/libp2p/interface-transport)
`libp2p-tcp` accepts TCP addresses both IPFS and non IPFS encapsulated addresses, i.e: `libp2p-tcp` accepts TCP addresses both IPFS and non IPFS encapsulated addresses, i.e:
@@ -116,6 +95,10 @@ To learn more about this utility, visit https://pull-stream.github.io/#pull-stre
Both for dialing and listening. Both for dialing and listening.
### Connection
[![](https://raw.githubusercontent.com/libp2p/interface-connection/master/img/badge.png)](https://github.com/libp2p/interface-connection)
## Contribute ## Contribute
Contributions are welcome! The libp2p implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out: Contributions are welcome! The libp2p implementation in JavaScript is a work in progress. As such, there's a few things you can do right now to help out:

View File

@@ -1,12 +0,0 @@
machine:
node:
version: stable
dependencies:
pre:
- google-chrome --version
- wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
- sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
- sudo apt-get update
- sudo apt-get --only-upgrade install google-chrome-stable
- google-chrome --version

View File

@@ -1,18 +1,20 @@
{ {
"name": "libp2p-tcp", "name": "libp2p-tcp",
"version": "0.10.2", "version": "0.13.1",
"description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces", "description": "Node.js implementation of the TCP module that libp2p uses, which implements the interface-connection and interface-transport interfaces",
"leadMaintainer": "Jacob Heun <jacobheun@gmail.com>",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {
"lint": "aegir-lint", "lint": "aegir lint",
"test": "aegir-test --env node", "test": "aegir test -t node",
"release": "aegir-release --env no-build", "test:node": "aegir test -t node",
"release-minor": "aegir-release --type minor --env no-build", "release": "aegir release -t node --no-build",
"release-major": "aegir-release --type major --env no-build", "release-minor": "aegir release -t node --type minor --no-build",
"coverage": "aegir-coverage", "release-major": "aegir-release -t node --type major --no-build",
"coverage-publish": "aegir-coverage publish" "coverage": "aegir coverage",
"coverage-publish": "aegir coverage --provider coveralls"
}, },
"pre-commit": [ "pre-push": [
"lint", "lint",
"test" "test"
], ],
@@ -23,42 +25,52 @@
"keywords": [ "keywords": [
"IPFS" "IPFS"
], ],
"author": "David Dias <daviddias@ipfs.io>",
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/libp2p/js-libp2p-tcp/issues" "url": "https://github.com/libp2p/js-libp2p-tcp/issues"
}, },
"homepage": "https://github.com/libp2p/js-libp2p-tcp", "homepage": "https://github.com/libp2p/js-libp2p-tcp",
"engines": { "engines": {
"node": ">=4.0.0" "node": ">=6.0.0",
"npm": ">=3.0.0"
}, },
"devDependencies": { "devDependencies": {
"aegir": "^11.0.2", "aegir": "^20.0.0",
"chai": "^4.1.0", "chai": "^4.2.0",
"dirty-chai": "^2.0.1", "dirty-chai": "^2.0.1",
"interface-transport": "~0.3.5", "interface-transport": "~0.3.6",
"lodash.isfunction": "^3.0.8", "pull-stream": "^3.6.14"
"pre-commit": "^1.2.2",
"pull-stream": "^3.6.0"
}, },
"dependencies": { "dependencies": {
"interface-connection": "~0.3.2", "class-is": "^1.1.0",
"ip-address": "^5.8.8", "debug": "^4.1.1",
"interface-connection": "~0.3.3",
"ip-address": "^6.1.0",
"lodash.includes": "^4.3.0", "lodash.includes": "^4.3.0",
"lodash.isfunction": "^3.0.8", "lodash.isfunction": "^3.0.9",
"mafmt": "^2.1.8", "mafmt": "^6.0.7",
"multiaddr": "^2.3.0", "multiaddr": "^6.1.0",
"once": "^1.4.0", "once": "^1.4.0",
"stream-to-pull-stream": "^1.7.2" "stream-to-pull-stream": "^1.7.3"
}, },
"contributors": [ "contributors": [
"Alan Shaw <alan@tableflip.io>",
"David Dias <daviddias.p@gmail.com>", "David Dias <daviddias.p@gmail.com>",
"Diogo Silva <fsdiogo@gmail.com>",
"Dmitriy Ryajov <dryajov@gmail.com>",
"Drew Stone <drewstone329@gmail.com>",
"Evan Schwartz <evan.mark.schwartz@gmail.com>", "Evan Schwartz <evan.mark.schwartz@gmail.com>",
"Friedel Ziegelmayer <dignifiedquire@gmail.com>", "Friedel Ziegelmayer <dignifiedquire@gmail.com>",
"Greenkeeper <support@greenkeeper.io>", "Greenkeeper <support@greenkeeper.io>",
"Jacob Heun <jacobheun@gmail.com>",
"Jacob Heun <jake@andyet.net>",
"João Antunes <j.goncalo.antunes@gmail.com>", "João Antunes <j.goncalo.antunes@gmail.com>",
"Linus Unnebäck <linus@folkdatorn.se>",
"Pedro Teixeira <i@pgte.me>",
"Prashanth Chandra <coolshanth94@gmail.com>", "Prashanth Chandra <coolshanth94@gmail.com>",
"Richard Littauer <richard.littauer@gmail.com>", "Richard Littauer <richard.littauer@gmail.com>",
"Stephen Whitmore <stephen.whitmore@gmail.com>" "Stephen Whitmore <stephen.whitmore@gmail.com>",
"TomCoded <tomtinkerer@gmail.com>",
"Vasco Santos <vasco.santos@moxy.studio>"
] ]
} }

View File

@@ -2,21 +2,32 @@
const multiaddr = require('multiaddr') const multiaddr = require('multiaddr')
const Address6 = require('ip-address').Address6 const Address6 = require('ip-address').Address6
const debug = require('debug')
const log = debug('libp2p:tcp:get-multiaddr')
module.exports = (socket) => { module.exports = (socket) => {
var mh let ma
if (socket.remoteFamily === 'IPv6') { try {
var addr = new Address6(socket.remoteAddress) if (socket.remoteFamily === 'IPv6') {
if (addr.v4) { const addr = new Address6(socket.remoteAddress)
var ip4 = addr.to4().correctForm()
mh = multiaddr('/ip4/' + ip4 + '/tcp/' + socket.remotePort) if (addr.v4) {
const ip4 = addr.to4().correctForm()
ma = multiaddr('/ip4/' + ip4 +
'/tcp/' + socket.remotePort
)
} else {
ma = multiaddr('/ip6/' + socket.remoteAddress +
'/tcp/' + socket.remotePort
)
}
} else { } else {
mh = multiaddr('/ip6/' + socket.remoteAddress + '/tcp/' + socket.remotePort) ma = multiaddr('/ip4/' + socket.remoteAddress +
'/tcp/' + socket.remotePort)
} }
} else { } catch (err) {
mh = multiaddr('/ip4/' + socket.remoteAddress + '/tcp/' + socket.remotePort) log(err)
} }
return ma
return mh
} }

View File

@@ -3,6 +3,7 @@
const net = require('net') const net = require('net')
const toPull = require('stream-to-pull-stream') const toPull = require('stream-to-pull-stream')
const mafmt = require('mafmt') const mafmt = require('mafmt')
const withIs = require('class-is')
const includes = require('lodash.includes') const includes = require('lodash.includes')
const isFunction = require('lodash.isfunction') const isFunction = require('lodash.isfunction')
const Connection = require('interface-connection').Connection const Connection = require('interface-connection').Connection
@@ -21,9 +22,8 @@ class TCP {
options = {} options = {}
} }
callback = callback || noop callback = once(callback || noop)
callback = once(callback)
const cOpts = ma.toOptions() const cOpts = ma.toOptions()
log('Connecting to %s %s', cOpts.port, cOpts.host) log('Connecting to %s %s', cOpts.port, cOpts.host)
@@ -58,7 +58,7 @@ class TCP {
options = {} options = {}
} }
handler = handler || (() => {}) handler = handler || noop
return createListener(handler) return createListener(handler)
} }
@@ -67,13 +67,19 @@ class TCP {
if (!Array.isArray(multiaddrs)) { if (!Array.isArray(multiaddrs)) {
multiaddrs = [multiaddrs] multiaddrs = [multiaddrs]
} }
return multiaddrs.filter((ma) => { return multiaddrs.filter((ma) => {
if (includes(ma.protoNames(), 'p2p-circuit')) {
return false
}
if (includes(ma.protoNames(), 'ipfs')) { if (includes(ma.protoNames(), 'ipfs')) {
ma = ma.decapsulate('ipfs') ma = ma.decapsulate('ipfs')
} }
return mafmt.TCP.matches(ma) return mafmt.TCP.matches(ma)
}) })
} }
} }
module.exports = TCP module.exports = withIs(TCP, { className: 'TCP', symbolName: '@libp2p/js-libp2p-tcp/tcp' })

View File

@@ -14,6 +14,7 @@ const getMultiaddr = require('./get-multiaddr')
const IPFS_CODE = 421 const IPFS_CODE = 421
const CLOSE_TIMEOUT = 2000 const CLOSE_TIMEOUT = 2000
function noop () {} function noop () {}
module.exports = (handler) => { module.exports = (handler) => {
@@ -24,6 +25,15 @@ module.exports = (handler) => {
socket.on('error', noop) socket.on('error', noop)
const addr = getMultiaddr(socket) const addr = getMultiaddr(socket)
if (!addr) {
if (socket.remoteAddress === undefined) {
log('connection closed before p2p connection made')
} else {
log('error interpreting incoming p2p connection')
}
return
}
log('new connection', addr.toString()) log('new connection', addr.toString())
const s = toPull.duplex(socket) const s = toPull.duplex(socket)
@@ -54,23 +64,19 @@ module.exports = (handler) => {
callback = callback || noop callback = callback || noop
options = options || {} options = options || {}
let closed = false const timeout = setTimeout(() => {
server.close(callback)
server.once('close', () => {
closed = true
})
setTimeout(() => {
if (closed) {
return
}
log('unable to close graciously, destroying conns') log('unable to close graciously, destroying conns')
Object.keys(server.__connections).forEach((key) => { Object.keys(server.__connections).forEach((key) => {
log('destroying %s', key) log('destroying %s', key)
server.__connections[key].destroy() server.__connections[key].destroy()
}) })
}, options.timeout || CLOSE_TIMEOUT) }, options.timeout || CLOSE_TIMEOUT)
server.close(callback)
server.once('close', () => {
clearTimeout(timeout)
})
} }
let ipfsId let ipfsId

View File

@@ -3,16 +3,17 @@
const tests = require('interface-transport') const tests = require('interface-transport')
const multiaddr = require('multiaddr') const multiaddr = require('multiaddr')
const Tcp = require('../src') const TCP = require('../src')
describe('interface-transport compliance', () => { describe('interface-transport compliance', () => {
tests({ tests({
setup (cb) { setup (cb) {
let tcp = new Tcp() const tcp = new TCP()
const addrs = [ const addrs = [
multiaddr('/ip4/127.0.0.1/tcp/9091'), multiaddr('/ip4/127.0.0.1/tcp/9091'),
multiaddr('/ip4/127.0.0.1/tcp/9092'), multiaddr('/ip4/127.0.0.1/tcp/9092'),
multiaddr('/ip4/127.0.0.1/tcp/9093') multiaddr('/ip4/127.0.0.1/tcp/9093'),
multiaddr('/dns4/ipfs.io')
] ]
cb(null, tcp, addrs) cb(null, tcp, addrs)
}, },

View File

@@ -0,0 +1,121 @@
/* eslint-env mocha */
'use strict'
const pull = require('pull-stream')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const TCP = require('../src')
const multiaddr = require('multiaddr')
const Connection = require('interface-connection').Connection
describe('Connection Wrap', () => {
let tcp
let listener
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090')
beforeEach((done) => {
tcp = new TCP()
listener = tcp.createListener((conn) => {
pull(conn, conn)
})
listener.on('listening', done)
listener.listen(ma)
})
afterEach((done) => {
listener.close(done)
})
it('simple wrap', (done) => {
const conn = tcp.dial(ma)
conn.setPeerInfo('peerInfo')
const connWrap = new Connection(conn)
pull(
pull.values(['hey']),
connWrap,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([Buffer.from('hey')])
connWrap.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('peerInfo')
done()
})
})
)
})
it('buffer wrap', (done) => {
const conn = tcp.dial(ma)
const connWrap = new Connection()
pull(
pull.values(['hey']),
connWrap,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([Buffer.from('hey')])
done()
})
)
connWrap.setInnerConn(conn)
})
it('overload wrap', (done) => {
const conn = tcp.dial(ma)
const connWrap = new Connection(conn)
connWrap.getPeerInfo = (callback) => {
callback(null, 'none')
}
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.exist()
})
connWrap.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('none')
})
pull(
pull.values(['hey']),
connWrap,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([Buffer.from('hey')])
done()
})
)
})
it('dial error', (done) => {
tcp.dial(multiaddr('/ip4/127.0.0.1/tcp/22234'), (err) => {
expect(err).to.exist()
done()
})
})
it('matryoshka wrap', (done) => {
const conn = tcp.dial(ma)
const connWrap1 = new Connection(conn)
const connWrap2 = new Connection(connWrap1)
const connWrap3 = new Connection(connWrap2)
conn.getPeerInfo = (callback) => {
callback(null, 'inner doll')
}
pull(
pull.values(['hey']),
connWrap3,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.eql([Buffer.from('hey')])
connWrap3.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('inner doll')
done()
})
})
)
})
})

111
test/connection.spec.js Normal file
View File

@@ -0,0 +1,111 @@
/* eslint-env mocha */
'use strict'
const pull = require('pull-stream')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const TCP = require('../src')
const multiaddr = require('multiaddr')
describe('valid Connection', () => {
let tcp
beforeEach(() => {
tcp = new TCP()
})
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090')
it('get observed addrs', (done) => {
let dialerObsAddrs
const listener = tcp.createListener((conn) => {
expect(conn).to.exist()
conn.getObservedAddrs((err, addrs) => {
expect(err).to.not.exist()
dialerObsAddrs = addrs
pull(pull.empty(), conn)
})
})
listener.listen(ma, () => {
const conn = tcp.dial(ma)
pull(
conn,
pull.onEnd(endHandler)
)
function endHandler () {
conn.getObservedAddrs((err, addrs) => {
expect(err).to.not.exist()
pull(pull.empty(), conn)
closeAndAssert(listener, addrs)
})
}
function closeAndAssert (listener, addrs) {
listener.close(() => {
expect(addrs[0]).to.deep.equal(ma)
expect(dialerObsAddrs.length).to.equal(1)
done()
})
}
})
})
it('get Peer Info', (done) => {
const listener = tcp.createListener((conn) => {
expect(conn).to.exist()
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.exist()
expect(peerInfo).to.not.exist()
pull(pull.empty(), conn)
})
})
listener.listen(ma, () => {
const conn = tcp.dial(ma)
pull(conn, pull.onEnd(endHandler))
function endHandler () {
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.exist()
expect(peerInfo).to.not.exist()
listener.close(done)
})
}
})
})
it('set Peer Info', (done) => {
const listener = tcp.createListener((conn) => {
expect(conn).to.exist()
conn.setPeerInfo('batatas')
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('batatas')
pull(pull.empty(), conn)
})
})
listener.listen(ma, () => {
const conn = tcp.dial(ma)
pull(conn, pull.onEnd(endHandler))
function endHandler () {
conn.setPeerInfo('arroz')
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('arroz')
listener.close(done)
})
}
})
})
})

15
test/constructor.spec.js Normal file
View File

@@ -0,0 +1,15 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const TCP = require('../src')
describe('Constructor', () => {
it('create an instance', () => {
const tcp = new TCP()
expect(tcp).to.exist()
})
})

44
test/filter.spec.js Normal file
View File

@@ -0,0 +1,44 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const TCP = require('../src')
const multiaddr = require('multiaddr')
describe('filter addrs', () => {
const base = '/ip4/127.0.0.1'
const ipfs = '/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw'
let tcp
before(() => {
tcp = new TCP()
})
it('filter valid addrs for this transport', () => {
const ma1 = multiaddr(base + '/tcp/9090')
const ma2 = multiaddr(base + '/udp/9090')
const ma3 = multiaddr(base + '/tcp/9090/http')
const ma4 = multiaddr(base + '/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const ma5 = multiaddr(base + '/tcp/9090/http' + ipfs)
const ma6 = multiaddr('/ip4/127.0.0.1/tcp/9090/p2p-circuit' + ipfs)
const ma7 = multiaddr('/dns4/libp2p.io/tcp/9090')
const ma8 = multiaddr('/dnsaddr/libp2p.io/tcp/9090')
const valid = tcp.filter([ma1, ma2, ma3, ma4, ma5, ma6, ma7, ma8])
expect(valid.length).to.equal(4)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma4)
})
it('filter a single addr for this transport', () => {
const ma1 = multiaddr(base + '/tcp/9090')
const valid = tcp.filter(ma1)
expect(valid.length).to.equal(1)
expect(valid[0]).to.eql(ma1)
})
})

View File

@@ -0,0 +1,54 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const getMultiaddr = require('../src/get-multiaddr')
const goodSocket4 = {
remoteAddress: '127.0.0.1',
remotePort: '9090',
remoteFamily: 'IPv4'
}
const goodSocket6 = {
remoteAddress: '::1',
remotePort: '9090',
remoteFamily: 'IPv6'
}
const badSocket = {}
const badSocketData = {
remoteAddress: 'aewmrn4awoew',
remotePort: '234',
remoteFamily: 'Hufflepuff'
}
describe('getMultiaddr multiaddr creation', () => {
it('creates multiaddr from valid socket data', (done) => {
expect(getMultiaddr(goodSocket4))
.to.exist()
done()
})
it('creates multiaddr from valid IPv6 socket data', (done) => {
expect(getMultiaddr(goodSocket6))
.to.exist()
done()
})
it('returns undefined multiaddr from missing socket data', (done) => {
expect(getMultiaddr(badSocket))
.to.equal(undefined)
done()
})
it('returns undefined multiaddr from unparseable socket data', (done) => {
expect(getMultiaddr(badSocketData))
.to.equal(undefined)
done()
})
})

View File

@@ -1,504 +0,0 @@
/* eslint-env mocha */
'use strict'
const pull = require('pull-stream')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const TCP = require('../src')
const net = require('net')
const multiaddr = require('multiaddr')
const Connection = require('interface-connection').Connection
describe('instantiate the transport', () => {
it('create', () => {
const tcp = new TCP()
expect(tcp).to.exist()
})
})
describe('listen', () => {
let tcp
beforeEach(() => {
tcp = new TCP()
})
it('close listener with connections, through timeout', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const listener = tcp.createListener((conn) => {
pull(conn, conn)
})
listener.listen(mh, () => {
const socket1 = net.connect(9090)
const socket2 = net.connect(9090)
socket1.write('Some data that is never handled')
socket1.end()
socket1.on('error', () => {})
socket2.on('error', () => {})
socket1.on('connect', () => {
listener.close(done)
})
})
})
it('listen on port 0', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/0')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.close(done)
})
})
it('listen on IPv6 addr', (done) => {
const mh = multiaddr('/ip6/::/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.close(done)
})
})
it('listen on any Interface', (done) => {
const mh = multiaddr('/ip4/0.0.0.0/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.close(done)
})
})
it('getAddrs', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length).to.equal(1)
expect(multiaddrs[0]).to.deep.equal(mh)
listener.close(done)
})
})
})
it('getAddrs on port 0 listen', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/0')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length).to.equal(1)
listener.close(done)
})
})
})
it('getAddrs from listening on 0.0.0.0', (done) => {
const mh = multiaddr('/ip4/0.0.0.0/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length > 0).to.equal(true)
expect(multiaddrs[0].toString().indexOf('0.0.0.0')).to.equal(-1)
listener.close(done)
})
})
})
it('getAddrs from listening on 0.0.0.0 and port 0', (done) => {
const mh = multiaddr('/ip4/0.0.0.0/tcp/0')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length > 0).to.equal(true)
expect(multiaddrs[0].toString().indexOf('0.0.0.0')).to.equal(-1)
listener.close(done)
})
})
})
it('getAddrs preserves IPFS Id', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length).to.equal(1)
expect(multiaddrs[0]).to.deep.equal(mh)
listener.close(done)
})
})
})
})
describe('dial', () => {
let tcp
let listener
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090')
beforeEach((done) => {
tcp = new TCP()
listener = tcp.createListener((conn) => {
pull(
conn,
pull.map((x) => new Buffer(x.toString() + '!')),
conn
)
})
listener.listen(ma, done)
})
afterEach((done) => {
listener.close(done)
})
it('dial on IPv4', (done) => {
pull(
pull.values(['hey']),
tcp.dial(ma),
pull.collect((err, values) => {
expect(err).to.not.exist()
expect(values).to.eql([new Buffer('hey!')])
done()
})
)
})
it('dial to non existent listener', (done) => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/8989')
pull(
tcp.dial(ma),
pull.onEnd((err) => {
expect(err).to.exist()
done()
})
)
})
it('dial on IPv6', (done) => {
const ma = multiaddr('/ip6/::/tcp/9066')
const listener = tcp.createListener((conn) => {
pull(conn, conn)
})
listener.listen(ma, () => {
pull(
pull.values(['hey']),
tcp.dial(ma),
pull.collect((err, values) => {
expect(err).to.not.exist()
expect(values).to.be.eql([new Buffer('hey')])
listener.close(done)
})
)
})
})
it.skip('dial and destroy on listener', (done) => {
// TODO: why is this failing
let count = 0
const closed = ++count === 2 ? finish() : null
const ma = multiaddr('/ip6/::/tcp/9067')
const listener = tcp.createListener((conn) => {
pull(
pull.empty(),
conn,
pull.onEnd(closed)
)
})
listener.listen(ma, () => {
pull(tcp.dial(ma), pull.onEnd(closed))
})
function finish () {
listener.close(done)
}
})
it('dial and destroy on dialer', (done) => {
let count = 0
const destroyed = () => ++count === 2 ? finish() : null
const ma = multiaddr('/ip6/::/tcp/9068')
const listener = tcp.createListener((conn) => {
pull(conn, pull.onEnd(destroyed))
})
listener.listen(ma, () => {
pull(
pull.empty(),
tcp.dial(ma),
pull.onEnd(destroyed)
)
})
function finish () {
listener.close(done)
}
})
it('dial on IPv4 with IPFS Id', (done) => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const conn = tcp.dial(ma)
pull(
pull.values(['hey']),
conn,
pull.collect((err, res) => {
expect(err).to.not.exist()
expect(res).to.be.eql([new Buffer('hey!')])
done()
})
)
})
})
describe('filter addrs', () => {
let tcp
before(() => {
tcp = new TCP()
})
it('filter valid addrs for this transport', () => {
const mh1 = multiaddr('/ip4/127.0.0.1/tcp/9090')
const mh2 = multiaddr('/ip4/127.0.0.1/udp/9090')
const mh3 = multiaddr('/ip4/127.0.0.1/tcp/9090/http')
const mh4 = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const valid = tcp.filter([mh1, mh2, mh3, mh4])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(mh1)
expect(valid[1]).to.deep.equal(mh4)
})
it('filter a single addr for this transport', () => {
const mh1 = multiaddr('/ip4/127.0.0.1/tcp/9090')
const valid = tcp.filter(mh1)
expect(valid.length).to.equal(1)
expect(valid[0]).to.deep.equal(mh1)
})
})
describe('valid Connection', () => {
let tcp
beforeEach(() => {
tcp = new TCP()
})
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090')
it('get observed addrs', (done) => {
let dialerObsAddrs
const listener = tcp.createListener((conn) => {
expect(conn).to.exist()
conn.getObservedAddrs((err, addrs) => {
expect(err).to.not.exist()
dialerObsAddrs = addrs
pull(pull.empty(), conn)
})
})
listener.listen(ma, () => {
const conn = tcp.dial(ma)
pull(
conn,
pull.onEnd(endHandler)
)
function endHandler () {
conn.getObservedAddrs((err, addrs) => {
expect(err).to.not.exist()
pull(pull.empty(), conn)
closeAndAssert(listener, addrs)
})
}
function closeAndAssert (listener, addrs) {
listener.close(() => {
expect(addrs[0]).to.deep.equal(ma)
expect(dialerObsAddrs.length).to.equal(1)
done()
})
}
})
})
it('get Peer Info', (done) => {
const listener = tcp.createListener((conn) => {
expect(conn).to.exist()
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.exist()
expect(peerInfo).to.not.exist()
pull(pull.empty(), conn)
})
})
listener.listen(ma, () => {
const conn = tcp.dial(ma)
pull(conn, pull.onEnd(endHandler))
function endHandler () {
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.exist()
expect(peerInfo).to.not.exist()
listener.close(done)
})
}
})
})
it('set Peer Info', (done) => {
const listener = tcp.createListener((conn) => {
expect(conn).to.exist()
conn.setPeerInfo('batatas')
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('batatas')
pull(pull.empty(), conn)
})
})
listener.listen(ma, () => {
const conn = tcp.dial(ma)
pull(conn, pull.onEnd(endHandler))
function endHandler () {
conn.setPeerInfo('arroz')
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('arroz')
listener.close(done)
})
}
})
})
})
describe.skip('turbolence', () => {
it('dialer - emits error on the other end is terminated abruptly', (done) => {})
it('listener - emits error on the other end is terminated abruptly', (done) => {})
})
describe('Connection wrap', () => {
let tcp
let listener
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090')
beforeEach((done) => {
tcp = new TCP()
listener = tcp.createListener((conn) => {
pull(conn, conn)
})
listener.on('listening', done)
listener.listen(ma)
})
afterEach((done) => {
listener.close(done)
})
it('simple wrap', (done) => {
const conn = tcp.dial(ma)
conn.setPeerInfo('peerInfo')
const connWrap = new Connection(conn)
pull(
pull.values(['hey']),
connWrap,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([new Buffer('hey')])
connWrap.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('peerInfo')
done()
})
})
)
})
it('buffer wrap', (done) => {
const conn = tcp.dial(ma)
const connWrap = new Connection()
pull(
pull.values(['hey']),
connWrap,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([new Buffer('hey')])
done()
})
)
connWrap.setInnerConn(conn)
})
it('overload wrap', (done) => {
const conn = tcp.dial(ma)
const connWrap = new Connection(conn)
connWrap.getPeerInfo = (callback) => {
callback(null, 'none')
}
conn.getPeerInfo((err, peerInfo) => {
expect(err).to.exist()
})
connWrap.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('none')
})
pull(
pull.values(['hey']),
connWrap,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([new Buffer('hey')])
done()
})
)
})
it('dial error', (done) => {
tcp.dial(multiaddr('/ip4/999.0.0.1/tcp/1234'), (err) => {
expect(err).to.exist()
done()
})
})
it('matryoshka wrap', (done) => {
const conn = tcp.dial(ma)
const connWrap1 = new Connection(conn)
const connWrap2 = new Connection(connWrap1)
const connWrap3 = new Connection(connWrap2)
conn.getPeerInfo = (callback) => {
callback(null, 'inner doll')
}
pull(
pull.values(['hey']),
connWrap3,
pull.collect((err, chunks) => {
expect(err).to.not.exist()
expect(chunks).to.be.eql([new Buffer('hey')])
connWrap3.getPeerInfo((err, peerInfo) => {
expect(err).to.not.exist()
expect(peerInfo).to.equal('inner doll')
done()
})
})
)
})
})

259
test/listen-dial.spec.js Normal file
View File

@@ -0,0 +1,259 @@
/* eslint-env mocha */
'use strict'
const pull = require('pull-stream')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const TCP = require('../src')
const net = require('net')
const multiaddr = require('multiaddr')
const isCI = process.env.CI
describe('listen', () => {
let tcp
beforeEach(() => {
tcp = new TCP()
})
it('close listener with connections, through timeout', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const listener = tcp.createListener((conn) => {
pull(conn, conn)
})
listener.listen(mh, () => {
const socket1 = net.connect(9090)
const socket2 = net.connect(9090)
socket1.write('Some data that is never handled')
socket1.end()
socket1.on('error', () => {})
socket2.on('error', () => {})
socket1.on('connect', () => {
listener.close(done)
})
})
})
it('listen on port 0', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/0')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.close(done)
})
})
it('listen on IPv6 addr', (done) => {
if (isCI) { return done() }
const mh = multiaddr('/ip6/::/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.close(done)
})
})
it('listen on any Interface', (done) => {
const mh = multiaddr('/ip4/0.0.0.0/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.close(done)
})
})
it('getAddrs', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length).to.equal(1)
expect(multiaddrs[0]).to.deep.equal(mh)
listener.close(done)
})
})
})
it('getAddrs on port 0 listen', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/0')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length).to.equal(1)
listener.close(done)
})
})
})
it('getAddrs from listening on 0.0.0.0', (done) => {
const mh = multiaddr('/ip4/0.0.0.0/tcp/9090')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length > 0).to.equal(true)
expect(multiaddrs[0].toString().indexOf('0.0.0.0')).to.equal(-1)
listener.close(done)
})
})
})
it('getAddrs from listening on 0.0.0.0 and port 0', (done) => {
const mh = multiaddr('/ip4/0.0.0.0/tcp/0')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length > 0).to.equal(true)
expect(multiaddrs[0].toString().indexOf('0.0.0.0')).to.equal(-1)
listener.close(done)
})
})
})
it('getAddrs preserves IPFS Id', (done) => {
const mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const listener = tcp.createListener((conn) => {})
listener.listen(mh, () => {
listener.getAddrs((err, multiaddrs) => {
expect(err).to.not.exist()
expect(multiaddrs.length).to.equal(1)
expect(multiaddrs[0]).to.deep.equal(mh)
listener.close(done)
})
})
})
})
describe('dial', () => {
let tcp
let listener
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090')
beforeEach((done) => {
tcp = new TCP()
listener = tcp.createListener((conn) => {
pull(
conn,
pull.map((x) => Buffer.from(x.toString() + '!')),
conn
)
})
listener.listen(ma, done)
})
afterEach((done) => {
listener.close(done)
})
it('dial on IPv4', (done) => {
pull(
pull.values(['hey']),
tcp.dial(ma),
pull.collect((err, values) => {
expect(err).to.not.exist()
expect(values).to.eql([Buffer.from('hey!')])
done()
})
)
})
it('dial to non existent listener', (done) => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/8989')
pull(
tcp.dial(ma),
pull.onEnd((err) => {
expect(err).to.exist()
done()
})
)
})
it('dial on IPv6', (done) => {
if (isCI) { return done() }
const ma = multiaddr('/ip6/::/tcp/9066')
const listener = tcp.createListener((conn) => {
pull(conn, conn)
})
listener.listen(ma, () => {
pull(
pull.values(['hey']),
tcp.dial(ma),
pull.collect((err, values) => {
expect(err).to.not.exist()
expect(values).to.be.eql([Buffer.from('hey')])
listener.close(done)
})
)
})
})
it('dial and destroy on listener', (done) => {
let count = 0
const closed = () => ++count === 2 ? finish() : null
const ma = multiaddr('/ip6/::/tcp/9067')
const listener = tcp.createListener((conn) => {
pull(
pull.empty(),
conn,
pull.onEnd(closed)
)
})
listener.listen(ma, () => {
pull(tcp.dial(ma), pull.onEnd(closed))
})
function finish () {
listener.close(done)
}
})
it('dial and destroy on dialer', (done) => {
if (isCI) { return done() }
let count = 0
const destroyed = () => ++count === 2 ? finish() : null
const ma = multiaddr('/ip6/::/tcp/9068')
const listener = tcp.createListener((conn) => {
pull(conn, pull.onEnd(destroyed))
})
listener.listen(ma, () => {
pull(
pull.empty(),
tcp.dial(ma),
pull.onEnd(destroyed)
)
})
function finish () {
listener.close(done)
}
})
it('dial on IPv4 with IPFS Id', (done) => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const conn = tcp.dial(ma)
pull(
pull.values(['hey']),
conn,
pull.collect((err, res) => {
expect(err).to.not.exist()
expect(res).to.be.eql([Buffer.from('hey!')])
done()
})
)
})
})

16
test/turbolence.spec.js Normal file
View File

@@ -0,0 +1,16 @@
/* eslint-env mocha */
'use strict'
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
// const TCP = require('../src')
describe.skip('turbolence', () => {
it('dialer - emits error on the other end is terminated abruptly', (done) => {
expect('ok').to.equal('ok')
})
it('listener - emits error on the other end is terminated abruptly', (done) => {})
})