├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | - '10' 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Mathias Buus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ipv4-peers 2 | 3 | An [abstract-encoding](https://github.com/mafintosh/abstract-encoding) compliant encoder for encoding a list of ipv4 peers to buffers. 4 | 5 | ``` 6 | npm install ipv4-peers 7 | ``` 8 | 9 | [![build status](http://img.shields.io/travis/mafintosh/ipv4-peers.svg?style=flat)](http://travis-ci.org/mafintosh/ipv4-peers) 10 | 11 | ## Usage 12 | 13 | ``` js 14 | var peers = require('ipv4-peers') 15 | 16 | var buf = peers.encode([{ 17 | host: '127.0.0.1', 18 | port: 8080 19 | }, { 20 | host: '127.0.0.1', 21 | port: 9090 22 | }]) 23 | 24 | console.log(buf) // 12 byte buffer 25 | console.log(peers.decode(buf)) // the peer list 26 | ``` 27 | 28 | ## API 29 | 30 | #### `var buf = peers.encode(peerList, [buffer], [offset])` 31 | 32 | Encode a list of ipv4 peers into a buffer. 33 | 34 | #### `var peers = peers.decode(buffer, [offset], [end])` 35 | 36 | Decode a buffer into a list of peers. 37 | 38 | #### `var length = peers.encodingLength(peerList)` 39 | 40 | Returns the amount of bytes needed to encode the peers into a buffer 41 | 42 | #### `peers = peers.idLength(idByteLength)` 43 | 44 | Create a new ipv4-peers decoder that encodes/decodes a fixed size peer id in addition to host/port. The peer id is exposed as the `.id` property on a peer object. 45 | 46 | ## License 47 | 48 | MIT 49 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = create(0) 2 | 3 | function create (idLength) { 4 | if (!idLength) idLength = 0 5 | 6 | var entrySize = idLength + 6 7 | 8 | encode.bytes = decode.bytes = 0 9 | 10 | return { 11 | idLength: create, 12 | encodingLength: encodingLength, 13 | encode: encode, 14 | decode: decode 15 | } 16 | 17 | function encodingLength (peers) { 18 | return peers.length * entrySize 19 | } 20 | 21 | function encode (peers, buf, offset) { 22 | if (!buf) buf = Buffer.allocUnsafe(encodingLength(peers)) 23 | if (!offset) offset = 0 24 | 25 | for (var i = 0; i < peers.length; i++) { 26 | if (idLength) { 27 | peers[i].id.copy(buf, offset) 28 | offset += idLength 29 | } 30 | 31 | var host = peers[i].host.split('.') 32 | var port = peers[i].port 33 | buf[offset++] = parseInt(host[0], 10) 34 | buf[offset++] = parseInt(host[1], 10) 35 | buf[offset++] = parseInt(host[2], 10) 36 | buf[offset++] = parseInt(host[3], 10) 37 | buf.writeUInt16BE(port, offset) 38 | offset += 2 39 | } 40 | 41 | encode.bytes = peers.length * entrySize 42 | return buf 43 | } 44 | 45 | function decode (buf, offset, end) { 46 | if (!offset) offset = 0 47 | if (!end) end = buf.length 48 | 49 | var peers = new Array(Math.floor((end - offset) / entrySize)) 50 | 51 | for (var i = 0; i < peers.length; i++) { 52 | var id = null 53 | if (idLength) { 54 | id = buf.slice(offset, offset + idLength) 55 | offset += idLength 56 | } 57 | var host = buf[offset++] + '.' + buf[offset++] + '.' + buf[offset++] + '.' + buf[offset++] 58 | var port = buf.readUInt16BE(offset) 59 | 60 | if (port === 0) throw new RangeError('Port should be > 0 and < 65536') 61 | 62 | peers[i] = id ? {id: id, host: host, port: port} : {host: host, port: port} 63 | offset += 2 64 | } 65 | 66 | decode.bytes = peers.length * entrySize 67 | return peers 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ipv4-peers", 3 | "version": "2.0.0", 4 | "description": "An abstract-encoding compliant encoder for encoding a list of ipv4 peers to buffers", 5 | "main": "index.js", 6 | "dependencies": {}, 7 | "devDependencies": { 8 | "standard": "^7.1.2", 9 | "tape": "^4.6.0" 10 | }, 11 | "scripts": { 12 | "test": "standard && tape test.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/mafintosh/ipv4-peers.git" 17 | }, 18 | "author": "Mathias Buus (@mafintosh)", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/mafintosh/ipv4-peers/issues" 22 | }, 23 | "homepage": "https://github.com/mafintosh/ipv4-peers" 24 | } 25 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var tape = require('tape') 2 | var peers = require('./') 3 | 4 | tape('encodes', function (t) { 5 | t.same(peers.encode([{host: '127.0.0.1', port: 80}]).length, 6) 6 | t.same(peers.encode([{host: '127.0.0.1', port: 80}, {host: '127.0.0.1', port: 8080}]).length, 12) 7 | t.end() 8 | }) 9 | 10 | tape('encodingLength', function (t) { 11 | t.same(peers.encodingLength([{host: '127.0.0.1', port: 80}]), 6) 12 | t.same(peers.encodingLength([{host: '127.0.0.1', port: 80}, {host: '127.0.0.1', port: 8080}]), 12) 13 | t.end() 14 | }) 15 | 16 | tape('encodes + decodes', function (t) { 17 | var a = [{host: '127.0.0.1', port: 80}] 18 | var b = [{host: '127.0.0.1', port: 80}, {host: '127.0.0.1', port: 8080}] 19 | t.same(peers.decode(peers.encode(a)), a) 20 | t.same(peers.decode(peers.encode(b)), b) 21 | t.end() 22 | }) 23 | 24 | tape('encodes + decodes + offset', function (t) { 25 | var a = [{host: '127.0.0.1', port: 80}] 26 | var b = [{host: '127.0.0.1', port: 80}, {host: '127.0.0.1', port: 8080}] 27 | t.same(peers.decode(peers.encode(a, Buffer.allocUnsafe(8), 2), 2), a) 28 | t.same(peers.decode(peers.encode(b, Buffer.allocUnsafe(14), 2), 2), b) 29 | t.end() 30 | }) 31 | 32 | tape('encodes + decodes + offset + end', function (t) { 33 | var a = [{host: '127.0.0.1', port: 80}] 34 | var b = [{host: '127.0.0.1', port: 80}, {host: '127.0.0.1', port: 8080}] 35 | t.same(peers.decode(peers.encode(a, Buffer.allocUnsafe(100)), 0, 6), a) 36 | t.same(peers.decode(peers.encode(b, Buffer.allocUnsafe(100)), 0, 12), b) 37 | t.end() 38 | }) 39 | 40 | tape('port 0 not allowed', function (t) { 41 | t.plan(1) 42 | var a = [{host: '127.0.0.1', port: 0}] 43 | t.throws(function () { 44 | peers.decode(peers.encode(a)) 45 | }) 46 | t.end() 47 | }) 48 | 49 | tape('encodes with peer id', function (t) { 50 | var p = peers.idLength(5) 51 | var a = [{id: Buffer('hello'), host: '127.0.0.1', port: 80}] 52 | var b = [{id: Buffer('hello'), host: '127.0.0.1', port: 80}, {id: Buffer.from('world'), host: '127.0.0.1', port: 8080}] 53 | 54 | t.same(p.decode(p.encode(a, Buffer.allocUnsafe(100)), 0, 11), a) 55 | t.same(p.decode(p.encode(b, Buffer.allocUnsafe(100)), 0, 22), b) 56 | t.end() 57 | }) 58 | --------------------------------------------------------------------------------