@ndn/node-transport
Advanced tools
Comparing version 0.0.20191223-beta.1 to 0.0.20200606
export * from "./tcp-transport"; | ||
export * from "./unix-transport"; | ||
export * from "./udp-transport"; | ||
export * from "./unix-transport"; | ||
export * as udp_helper from "./udp-helper"; |
export * from "./tcp-transport.js"; | ||
export * from "./unix-transport.js"; | ||
export * from "./udp-transport.js"; | ||
export * from "./unix-transport.js"; | ||
import * as udp_helper_1 from "./udp-helper.js"; | ||
export { udp_helper_1 as udp_helper }; |
/// <reference types="node" /> | ||
import { StreamTransport } from "@ndn/l3face"; | ||
import { L3Face, StreamTransport } from "@ndn/l3face"; | ||
import * as net from "net"; | ||
@@ -15,4 +15,16 @@ /** TCP socket transport. */ | ||
} | ||
/** | ||
* Create a transport and connect to remote endpoint. | ||
* @param host remote host, default is "localhost". | ||
* @param port remote port, default is 6363. | ||
* @param opts other options. | ||
*/ | ||
function connect(host?: string, port?: number, opts?: Options): Promise<TcpTransport>; | ||
/** | ||
* Create a transport and connect to remote endpoint. | ||
* @param opts remote endpoint and other options. | ||
*/ | ||
function connect(opts: net.TcpNetConnectOpts & Options): Promise<TcpTransport>; | ||
/** Create a transport and add to forwarder. */ | ||
const createFace: L3Face.CreateFaceFunc<import("@ndn/l3face").Transport, typeof connect>; | ||
} |
@@ -1,5 +0,26 @@ | ||
import { StreamTransport } from "@ndn/l3face"; | ||
/// #if false | ||
import { createRequire } from "module"; | ||
const require = createRequire(import.meta.url); | ||
const { __importDefault } = require("tslib"); | ||
/// #endif | ||
import { L3Face, StreamTransport } from "@ndn/l3face"; | ||
import * as net from "net"; | ||
/// #if false | ||
const PCancelable = __importDefault(require("p-cancelable")).default; | ||
/* | ||
/// #else | ||
import PCancelable from "p-cancelable"; | ||
/// #endif | ||
/// #if false | ||
*/ | ||
/// #endif | ||
/// #if false | ||
const pTimeout = __importDefault(require("p-timeout")).default; | ||
/* | ||
/// #else | ||
import pTimeout from "p-timeout"; | ||
/// #endif | ||
/// #if false | ||
*/ | ||
/// #endif | ||
/** TCP socket transport. */ | ||
@@ -25,3 +46,3 @@ export class TcpTransport extends StreamTransport { | ||
if (typeof arg1 === "object") { | ||
connectTimeout = (_a = arg1.connectTimeout, (_a !== null && _a !== void 0 ? _a : connectTimeout)); | ||
connectTimeout = (_a = arg1.connectTimeout) !== null && _a !== void 0 ? _a : connectTimeout; | ||
} | ||
@@ -41,2 +62,4 @@ return pTimeout(new PCancelable((resolve, reject, onCancel) => { | ||
TcpTransport.connect = connect; | ||
/** Create a transport and add to forwarder. */ | ||
TcpTransport.createFace = L3Face.makeCreateFace(TcpTransport.connect); | ||
})(TcpTransport || (TcpTransport = {})); |
/// <reference types="node" /> | ||
import { Transport } from "@ndn/l3face"; | ||
import * as dgram from "dgram"; | ||
import { L3Face, Transport } from "@ndn/l3face"; | ||
import { AddressInfo } from "net"; | ||
import * as udp from "./udp-helper"; | ||
/** UDP socket transport. */ | ||
export declare class UdpTransport extends Transport { | ||
private readonly sock; | ||
readonly rx: Transport.Rx; | ||
get laddr(): AddressInfo; | ||
get raddr(): AddressInfo; | ||
constructor(sock: dgram.Socket); | ||
readonly isMulticast: boolean; | ||
readonly laddr: AddressInfo; | ||
readonly raddr: AddressInfo; | ||
private readonly rxSock; | ||
private readonly txSock; | ||
constructor(unicast: udp.Socket); | ||
constructor(multicastTx: udp.Socket, multicastRx: udp.Socket); | ||
close(): void; | ||
@@ -16,11 +19,20 @@ tx: (iterable: AsyncIterable<Uint8Array>) => Promise<void>; | ||
export declare namespace UdpTransport { | ||
interface TunnelOptions { | ||
host: string; | ||
port?: number; | ||
bind?: dgram.BindOptions; | ||
recvBufferSize?: number; | ||
sendBufferSize?: number; | ||
} | ||
/** | ||
* Create a unicast transport. | ||
* @param host remote host. | ||
* @param port remote port, default is 6363. | ||
*/ | ||
function connect(host: string, port?: number): Promise<UdpTransport>; | ||
function connect(opts: TunnelOptions): Promise<UdpTransport>; | ||
/** Create a unicast transport. */ | ||
function connect(opts: udp.UnicastOptions): Promise<UdpTransport>; | ||
/** Create a unicast transport and add to forwarder. */ | ||
const createFace: L3Face.CreateFaceFunc<Transport, typeof connect>; | ||
/** Create a multicast transport. */ | ||
function multicast(opts: udp.MulticastOptions): Promise<UdpTransport>; | ||
/** Create a multicast transport and add to forwarder. */ | ||
const createMulticastFace: L3Face.CreateFaceFunc<Transport, typeof multicast>; | ||
/** Create multicast transports on every interface. */ | ||
function multicasts(opts?: Omit<udp.MulticastOptions, "intf">): Promise<UdpTransport[]>; | ||
/** Create multicast transports on every interface. */ | ||
const createMulticastFaces: L3Face.CreateFaceFunc<Transport[], typeof multicasts>; | ||
} |
@@ -1,56 +0,94 @@ | ||
import { rxFromPacketIterable, Transport } from "@ndn/l3face"; | ||
import * as dgram from "dgram"; | ||
import { EventIterator } from "event-iterator"; | ||
/// #if false | ||
import { createRequire } from "module"; | ||
const require = createRequire(import.meta.url); | ||
const { __importDefault } = require("tslib"); | ||
/// #endif | ||
import { L3Face, rxFromPacketIterable, Transport } from "@ndn/l3face"; | ||
/// #if false | ||
const pEvent = __importDefault(require("p-event")).default; | ||
/* | ||
/// #else | ||
import pEvent from "p-event"; | ||
/// #endif | ||
/// #if false | ||
*/ | ||
/// #endif | ||
import * as udp from "./udp-helper.js"; | ||
/** UDP socket transport. */ | ||
export class UdpTransport extends Transport { | ||
constructor(sock) { | ||
constructor(txSock, rxSock) { | ||
super({ | ||
describe: `UDP(${sock.remoteAddress().address})`, | ||
describe: rxSock ? `UDPm(${txSock.address().address})` : `UDP(${txSock.remoteAddress().address})`, | ||
multicast: !!rxSock, | ||
}); | ||
this.sock = sock; | ||
this.tx = async (iterable) => { | ||
for await (const pkt of iterable) { | ||
this.sock.send(pkt); | ||
this.txSock.send(pkt); | ||
} | ||
this.close(); | ||
}; | ||
this.rx = rxFromPacketIterable(new EventIterator((push, stop, fail) => { | ||
sock.addListener("message", push); | ||
sock.addListener("close", stop); | ||
sock.addListener("error", fail); | ||
}, (push, stop, fail) => { | ||
sock.removeListener("message", push); | ||
sock.removeListener("close", stop); | ||
sock.removeListener("error", fail); | ||
if (rxSock) { | ||
this.isMulticast = true; | ||
this.rxSock = rxSock; | ||
this.txSock = txSock; | ||
txSock.once("error", () => this.rxSock.close()); | ||
this.laddr = this.txSock.address(); | ||
this.raddr = this.rxSock.address(); | ||
} | ||
else { | ||
this.isMulticast = false; | ||
this.rxSock = txSock; | ||
this.txSock = txSock; | ||
this.laddr = this.txSock.address(); | ||
this.raddr = this.txSock.remoteAddress(); | ||
} | ||
this.rx = rxFromPacketIterable(pEvent.iterator(this.rxSock, "message", { | ||
resolutionEvents: ["close"], | ||
})); | ||
} | ||
get laddr() { return this.sock.address(); } | ||
get raddr() { return this.sock.remoteAddress(); } | ||
close() { | ||
try { | ||
this.sock.close(); | ||
this.rxSock.close(); | ||
if (this.txSock !== this.rxSock) { | ||
this.txSock.close(); | ||
} | ||
} | ||
catch (err) { } | ||
catch { } | ||
} | ||
} | ||
(function (UdpTransport) { | ||
async function connect(arg1, port1) { | ||
const { host, port: port = 6363, bind: bind = {}, recvBufferSize, sendBufferSize } = typeof arg1 === "string" ? { host: arg1, port: port1 } : | ||
arg1; | ||
return new Promise((resolve, reject) => { | ||
const sock = dgram.createSocket({ | ||
type: "udp4", | ||
reuseAddr: true, | ||
recvBufferSize, | ||
sendBufferSize, | ||
}); | ||
sock.on("error", reject); | ||
sock.on("connect", () => { | ||
sock.off("error", reject); | ||
resolve(new UdpTransport(sock)); | ||
}); | ||
sock.bind(bind, () => sock.connect(port, host)); | ||
}); | ||
async function connect(arg1, arg2) { | ||
const opts = typeof arg1 === "string" ? { host: arg1, port: arg2 } : arg1; | ||
const sock = await udp.openUnicast(opts); | ||
return new UdpTransport(sock); | ||
} | ||
UdpTransport.connect = connect; | ||
/** Create a unicast transport and add to forwarder. */ | ||
UdpTransport.createFace = L3Face.makeCreateFace(connect); | ||
/** Create a multicast transport. */ | ||
async function multicast(opts) { | ||
const tx = await udp.openMulticastTx(opts); | ||
let rx; | ||
try { | ||
rx = await udp.openMulticastRx(opts); | ||
} | ||
catch (err) { | ||
tx.close(); | ||
throw err; | ||
} | ||
return new UdpTransport(tx, rx); | ||
} | ||
UdpTransport.multicast = multicast; | ||
/** Create a multicast transport and add to forwarder. */ | ||
UdpTransport.createMulticastFace = L3Face.makeCreateFace(multicast); | ||
/** Create multicast transports on every interface. */ | ||
async function multicasts(opts = {}) { | ||
const intfs = udp.listMulticastIntfs(); | ||
return (await Promise.allSettled(intfs.map((intf) => multicast({ ...opts, intf })))) | ||
.filter((res) => res.status === "fulfilled") | ||
.map(({ value }) => value); | ||
} | ||
UdpTransport.multicasts = multicasts; | ||
/** Create multicast transports on every interface. */ | ||
UdpTransport.createMulticastFaces = L3Face.makeCreateFace(multicasts); | ||
})(UdpTransport || (UdpTransport = {})); |
/// <reference types="node" /> | ||
import { StreamTransport } from "@ndn/l3face"; | ||
import { L3Face, StreamTransport } from "@ndn/l3face"; | ||
import * as net from "net"; | ||
@@ -11,3 +11,9 @@ /** Unix socket transport. */ | ||
export declare namespace UnixTransport { | ||
/** | ||
* Create a transport and connect to remote endpoint. | ||
* @param pathOrOpts Unix socket path. | ||
*/ | ||
function connect(pathOrOpts: string | net.IpcNetConnectOpts): Promise<UnixTransport>; | ||
/** Create a transport and add to forwarder. */ | ||
const createFace: L3Face.CreateFaceFunc<import("@ndn/l3face").Transport, typeof connect>; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { StreamTransport } from "@ndn/l3face"; | ||
import { L3Face, StreamTransport } from "@ndn/l3face"; | ||
import * as net from "net"; | ||
@@ -17,2 +17,6 @@ /** Unix socket transport. */ | ||
(function (UnixTransport) { | ||
/** | ||
* Create a transport and connect to remote endpoint. | ||
* @param pathOrOpts Unix socket path. | ||
*/ | ||
function connect(pathOrOpts) { | ||
@@ -33,2 +37,4 @@ const connectOpts = typeof pathOrOpts === "string" ? { path: pathOrOpts } : | ||
UnixTransport.connect = connect; | ||
/** Create a transport and add to forwarder. */ | ||
UnixTransport.createFace = L3Face.makeCreateFace(UnixTransport.connect); | ||
})(UnixTransport || (UnixTransport = {})); |
{ | ||
"name": "@ndn/node-transport", | ||
"version": "0.0.20191223-beta.1", | ||
"version": "0.0.20200606", | ||
"description": "NDNts: Low-Level Transports for Node.js", | ||
@@ -24,5 +24,5 @@ "keywords": [ | ||
"dependencies": { | ||
"@ndn/l3face": "0.0.20191223-beta.1", | ||
"event-iterator": "^1.2.0", | ||
"@ndn/l3face": "0.0.20200606", | ||
"p-cancelable": "^2.0.0", | ||
"p-event": "^4.1.0", | ||
"p-timeout": "^3.2.0", | ||
@@ -29,0 +29,0 @@ "tslib": "*" |
126
README.md
@@ -8,7 +8,7 @@ # @ndn/node-transport | ||
```ts | ||
import { TcpTransport, UdpTransport } from "@ndn/node-transport"; | ||
import { TcpTransport, UdpTransport, UnixTransport } from "@ndn/node-transport"; | ||
// other imports for examples | ||
import { L3Face, Transport } from "@ndn/l3face"; | ||
import { Data, Interest } from "@ndn/packet"; | ||
import { Data, Interest, Name } from "@ndn/packet"; | ||
(async () => { | ||
@@ -22,7 +22,19 @@ if (process.env.CI) { return; } | ||
* UnixTransport: Unix socket, or Windows named pipe. | ||
* TcpTransport: TCP tunnel. | ||
* UdpTransport: UDP tunnel. | ||
* UnixTransport: Unix socket or Windows named pipe. | ||
* TcpTransport: TCP tunnel, IPv4 only. | ||
* UdpTransport: UDP unicast tunnel or UDP multicast group, IPv4 only. | ||
The `connect()` function of each transport creates a transport. | ||
```ts | ||
// UnixTransport.connect() establishes a UNIX socket connection. | ||
// It accepts a Unix socket path. | ||
try { | ||
const unix = await UnixTransport.connect("/run/nfd.sock"); | ||
await useInL3Face(unix); | ||
} catch (err) { | ||
// This above would throw an error on Windows or if NFD is not running. | ||
console.warn(err); | ||
} | ||
// TcpTransport.connect() establishes a TCP tunnel. | ||
@@ -37,4 +49,18 @@ // It accepts either host+port or an options object for net.createConnection(). | ||
await useInL3Face(udp); | ||
``` | ||
})(); | ||
To use UDP multicast, each network interface needs to have a separate transport. | ||
It's easiest to let NDNts automatically create transports on every network interface. | ||
```ts | ||
// UdpTransport.multicasts() attempts to create UDP multicast transports on every | ||
// network interface, skipping network interfaces where socket creation fails. | ||
const multicasts = await UdpTransport.multicasts(); | ||
multicasts.forEach(async (transport, i) => { | ||
if (i === 0) { | ||
await useInL3Face(transport); | ||
} else { | ||
transport.close(); | ||
} | ||
}); | ||
``` | ||
@@ -44,3 +70,27 @@ | ||
Transports are normally used to construct **L3Face** objects (from `@ndn/l3face` package). | ||
Transports are normally used to construct **L3Face** objects (from `@ndn/l3face` package), which are in turned add to the **Forwarder** (from `@ndn/fw` package). | ||
Each transport provides a `createFace` convenience function to construct a transport and add it to the forwarder. | ||
See `@ndn/ws-transport` package documentation for a complete example of `createFace` function. | ||
```ts | ||
// UdpTransport.createFace() constructs a UDP unicast transport, and adds it to a forwarder. | ||
// First parameters allows setting L3Face attributes and NDNLP service options, or attaching | ||
// the face to a non-default Forwarder instance. This argument is required. | ||
// Subsequent parameters are same as the corresponding connect() function. | ||
// It returns a FwFace instance (from @ndn/fw package). | ||
const face = await UdpTransport.createFace({}, "hobo.cs.arizona.edu"); | ||
face.addRoute(new Name("/ndn")); | ||
face.close(); | ||
// TcpTransport.createFace() and UnixTransport.createFace() behave similarly. | ||
// UdpTransport.createMulticastFaces() constructs UDP multicast transports on every network | ||
// interface and adds them to a forwarder. | ||
const faces = await UdpTransport.createMulticastFaces({}); | ||
faces.forEach((face) => face.close()); | ||
})(); | ||
``` | ||
## L3Face Low-Level Details | ||
L3Face allows sending and receiving layer-3 packets on a transport. | ||
@@ -55,39 +105,39 @@ L3Face does not provide Interest-Data matching logic, timeout scheduler, etc. | ||
// Transports are normally used in a network layer face. | ||
const face = new L3Face(transport); | ||
// Transports are normally used in a network layer face. | ||
const face = new L3Face(transport); | ||
// We want to know if something goes wrong. | ||
face.on("rxerror", (err) => console.warn(err)); | ||
face.on("txerror", (err) => console.warn(err)); | ||
// We want to know if something goes wrong. | ||
face.on("rxerror", (err) => console.warn(err)); | ||
face.on("txerror", (err) => console.warn(err)); | ||
await Promise.all([ | ||
face.tx({ async *[Symbol.asyncIterator]() { | ||
// Send five Interests. | ||
let seq = Math.floor(Math.random() * 99999999); | ||
for (let i = 0; i < 5; ++i) { | ||
await new Promise((r) => setTimeout(r, 50)); | ||
const interest = new Interest(`/ndn/edu/arizona/ping/NDNts/${seq++}`); | ||
console.log(`${transport} <I ${interest.name}`); | ||
yield interest; | ||
} | ||
await new Promise((r) => setTimeout(r, 200)); | ||
} }), | ||
(async () => { | ||
let nData = 0; | ||
for await (const pkt of face.rx) { | ||
if (!(pkt instanceof Data)) { | ||
continue; | ||
await Promise.all([ | ||
face.tx({ async *[Symbol.asyncIterator]() { | ||
// Send five Interests. | ||
let seq = Math.floor(Math.random() * 99999999); | ||
for (let i = 0; i < 5; ++i) { | ||
await new Promise((r) => setTimeout(r, 50)); | ||
const interest = new Interest(`/ndn/edu/arizona/ping/NDNts/${seq++}`); | ||
console.log(`${transport} <I ${interest.name}`); | ||
yield interest; | ||
} | ||
// Print incoming Data name. | ||
const data: Data = pkt; | ||
console.log(`${transport} >D ${data.name}`); | ||
if (++nData >= 5) { | ||
return; | ||
await new Promise((r) => setTimeout(r, 200)); | ||
} }), | ||
(async () => { | ||
let nData = 0; | ||
for await (const pkt of face.rx) { | ||
if (!(pkt instanceof Data)) { | ||
continue; | ||
} | ||
// Print incoming Data name. | ||
const data: Data = pkt; | ||
console.log(`${transport} >D ${data.name}`); | ||
if (++nData >= 5) { | ||
return; | ||
} | ||
} | ||
} | ||
})(), | ||
]); | ||
})(), | ||
]); | ||
// L3Face and Transport are automatically closed when TX iterable is exhausted. | ||
// L3Face and Transport are automatically closed when TX iterable is exhausted. | ||
} | ||
``` |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
20247
12
418
139
3
4
+ Addedp-event@^4.1.0
+ Added@ndn/fw@0.0.20200606(transitive)
+ Added@ndn/l3face@0.0.20200606(transitive)
+ Added@ndn/lp@0.0.20200606(transitive)
+ Added@ndn/packet@0.0.20200606(transitive)
+ Added@ndn/tlv@0.0.20200606(transitive)
+ Added@types/retry@0.12.5(transitive)
+ Addedget-iterator@1.0.2(transitive)
+ Addedhirestime@6.1.0(transitive)
+ Addedit-keepalive@1.2.0(transitive)
+ Addedloglevel@1.9.2(transitive)
+ Addedmnemonist@0.36.1(transitive)
+ Addedobliterator@1.6.1(transitive)
+ Addedp-defer@3.0.0(transitive)
+ Addedp-event@4.2.0(transitive)
+ Addedp-fifo@1.0.0(transitive)
+ Addedretry@0.12.0(transitive)
+ Addedtyped-emitter@1.4.0(transitive)
- Removedevent-iterator@^1.2.0
- Removed@ndn/l3face@0.0.20191223-beta.1(transitive)
- Removed@ndn/lp@0.0.20191223-beta.1(transitive)
- Removed@ndn/packet@0.0.20191223-beta.1(transitive)
- Removed@ndn/tlv@0.0.20191223-beta.1(transitive)
- Removedevent-iterator@1.2.0(transitive)
- Removedstrict-event-emitter-types@2.0.0(transitive)
Updated@ndn/l3face@0.0.20200606