Skip to content

Commit

Permalink
Merge pull request #39 from hertzg/refactor-old-coffee-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hertzg authored Jul 19, 2020
2 parents 7e68571 + 881b851 commit 1512351
Show file tree
Hide file tree
Showing 16 changed files with 1,365 additions and 468 deletions.
100 changes: 95 additions & 5 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,58 @@ jobs:
with:
fetch-depth: 0

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: lint-commit-messages-npm-cache
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-${{ matrix.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-build-${{ env.cache-name }}-
npm-${{ runner.os }}-build-
npm-${{ runner.os }}-
npm-
- name: Install dependencies
run: npm i --only=dev
run: npm i --only=dev --prefer-offline --no-audit

- name: Add dependencies for commitlint action
run: echo "::set-env name=NODE_PATH::$GITHUB_WORKSPACE/node_modules"

- name: Lint Commit Messages
uses: wagoid/commitlint-github-action@v1

test-tsd:
runs-on: ubuntu-latest
steps:
- name: Setup Node
uses: actions/setup-node@v2-beta

- name: Checkout
uses: actions/checkout@v2

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: test-tsd-npm-cache
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-build-${{ env.cache-name }}-
npm-${{ runner.os }}-build-
npm-${{ runner.os }}-
npm-
- name: Install dependencies
run: npm i --only=dev --prefer-offline --no-audit

- name: Test TypeScript definitions
run: npm run test:tsd

test:
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -53,11 +96,44 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: test-matrix-npm-cache
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-${{ matrix.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-${{ matrix.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-
npm-${{ runner.os }}-${{ matrix.os }}-build-${{ env.cache-name }}-
npm-${{ runner.os }}-build-${{ env.cache-name }}-
npm-${{ runner.os }}-build-
npm-${{ runner.os }}-
npm-
- name: Install dependencies
run: npm i
run: npm i --prefer-offline --no-audit

- name: Test
run: sudo npm run coverage:test
- name: Test (tsd)
run: npm run test:tsd

- name: Allow sudoless tcpdump (linux only)
if: ${{ success() && startsWith(matrix.os, 'ubuntu-') }}
run: |
sudo groupadd pcap
sudo usermod -a -G pcap $USER
sudo chgrp pcap /usr/sbin/tcpdump
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
sudo ln -s /usr/sbin/tcpdump /usr/bin/tcpdump
- name: Allow sudoless tcpdump (macos only)
if: ${{ success() && startsWith(matrix.os, 'macos-') }}
run: |
sudo chmod o+r /dev/bpf*
- name: Test (run) + Coverage
run: npm run coverage:test

- name: Coverage report
continue-on-error: true
Expand All @@ -82,8 +158,22 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: release
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-build-${{ env.cache-name }}-
npm-${{ runner.os }}-build-
npm-${{ runner.os }}-
npm-
- name: Install dependencies
run: npm i
run: npm i --only=dev --prefer-offline --no-audit

- name: Release
env:
Expand Down
21 changes: 10 additions & 11 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ name: Mark stale issues and pull requests

on:
schedule:
- cron: "0 0 * * *"
- cron: '0 0 * * *'

jobs:
stale:

runs-on: ubuntu-latest

steps:
- uses: actions/stale@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
days-before-stale: 25
days-before-close: 7
- uses: actions/stale@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
days-before-stale: 25
days-before-close: 7
13 changes: 3 additions & 10 deletions .jsdoc.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
{
"source": {
"include": [
"./lib",
"./index.js"
],
"exclude": [
"node_modules"
]
"include": ["./lib", "./index.js"],
"exclude": ["node_modules"]
},
"recurseDepth": 10,
"plugins": [
Expand All @@ -24,9 +19,7 @@
},
"tags": {
"allowUnknownTags": true,
"dictionaries": [
"jsdoc"
]
"dictionaries": ["jsdoc"]
},
"templates": {
"cleverLinks": false,
Expand Down
49 changes: 27 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
[codecov_url]: https://codecov.io/gh/hertzg/node-net-keepalive
[codecov_shield]: https://codecov.io/gh/hertzg/node-net-keepalive/branch/master/graph/badge.svg


# 🔗 net-keepalive

[![NPM](https://nodei.co/npm/net-keepalive.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/net-keepalive/)

The Missing (`TCP_KEEPINTVL` and `TCP_KEEPCNT`) `SO_KEEPALIVE` socket option setters and getters for Node using [`ffi-napi`](https://www.npmjs.com/package/ffi-napi) module.
Expand All @@ -46,6 +46,7 @@ You can find the [full API Reference](https://hertzg.github.io/node-net-keepaliv
Documentation gets generated from JSDoc comments, feel free to improve them by sending pull requests.

## Demo

```Javascript
var Net = require('net')
, NetKeepAlive = require('net-keepalive')
Expand All @@ -66,29 +67,31 @@ srv.listen(1337, function(){
// Connect to that server
var s = Net.createConnection({port:1337}, function(){
console.log('Connected to %j', s.address())

//IMPORTANT: KeepAlive must be enabled for this to work
s.setKeepAlive(true, 1000)

// Set TCP_KEEPINTVL for this specific socket
NetKeepAlive.setKeepAliveInterval(s, 1000)

// Get TCP_KEEPINTVL for this specific socket
NetKeepAlive.getKeepAliveInterval(s) // 1000

// Set TCP_KEEPCNT for this specific socket
// Set TCP_KEEPCNT for this specific socket
NetKeepAlive.setKeepAliveProbes(s, 1)
// Get TCP_KEEPCNT for this specific socket

// Get TCP_KEEPCNT for this specific socket
NetKeepAlive.getKeepAliveProbes(s) // 1
});
```

Now using `iptables` add rule to drop all `tcp` packets on `INPUT` chain to port `1337`.

```bash
$ iptables -I INPUT -m tcp -p tcp --dport 1337 -j DROP
```
If you were monitoring packets on `loopback` with `tcp.srcport == 1337 || tcp.dstport == 1337` filter in `wireshark`. You will see the following output:
```

If you were monitoring packets on `loopback` with `tcp.srcport == 1337 || tcp.dstport == 1337` filter in `wireshark`. You will see the following output:

[![Wireshark screenshot KEEPALIVE](http://hertzg.github.io/node-net-keepalive/images/wireshark.jpg)](http://hertzg.github.io/node-net-keepalive/images/wireshark.jpg)

Expand All @@ -99,7 +102,7 @@ More info about `SO_KEEPALIVE` here: [TCP Keepalive HOWTO](http://tldp.org/HOWTO

## API

***Note: For these methods to work you must enable `SO_KEEPALIVE` and set the `TCP_KEEPIDLE` options for socket using `Net.Socket`-s built in method [`socket.setKeepAlive([enable][, initialDelay])`](https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay) !***
**_Note: For these methods to work you must enable `SO_KEEPALIVE` and set the `TCP_KEEPIDLE` options for socket using `Net.Socket`-s built in method [`socket.setKeepAlive([enable][, initialDelay])`](https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay) !_**

TCP_KEEPIDLE (since Linux 2.4) The time (in seconds) the connection needs to remain idle before TCP starts sending keepalive probes, if the socket option SO_KEEPALIVE has been set on this socket. This option should not be used in code intended to be portable.

Expand All @@ -117,44 +120,46 @@ socket.setKeepAlive(enable, initialDuration) // sets SO_KEEPALIVE
var probeInterval = 1000 // after initialDuration send probes every 1 second
NetSocket.setKeepAliveInterval(socket, probeInterval) //sets TCP_KEEPINTVL

var maxProbesBeforeFail = 10 // after 10 failed probes connection will be dropped
var maxProbesBeforeFail = 10 // after 10 failed probes connection will be dropped
NetSocket.setKeepAliveProbes(socket, maxProbesBeforeFail) // sets TCP_KEEPCNT

// ....
// ....
```

### setKeepAliveInterval(socket, msecs)
* `socket` - `instanceof Net.Socket`- Socket to modify
* `msecs` - `Number` - Time in milliseconds between KeepAlive probes.
* Returns `true` on success

- `socket` - `instanceof Net.Socket`- Socket to modify
- `msecs` - `Number` - Time in milliseconds between KeepAlive probes.
- Returns `true` on success

Sets `TCP_KEEPINTVL` to `msecs` miliseconds (converted to seconds `int` internally) for the `socket` based on its file descriptor (`fd`)

TCP_KEEPINTVL (since Linux 2.4) The time (in seconds) between individual keepalive probes. This option should not be used in code intended to be portable.

### getKeepAliveInterval(socket)
* `socket` - `instanceof Net.Socket`- Socket to modify
* Returns `msecs` - `Number` - Time in milliseconds between KeepAlive probes on success

- `socket` - `instanceof Net.Socket`- Socket to modify
- Returns `msecs` - `Number` - Time in milliseconds between KeepAlive probes on success

Gets `TCP_KEEPINTVL`. The `msecs` miliseconds (converted from seconds `int` internally) set for the `socket` based on its file descriptor (`fd`)

TCP_KEEPINTVL (since Linux 2.4) The time (in seconds) between individual keepalive probes. This option should not be used in code intended to be portable.

### setKeepAliveProbes(socket, count)

### setKeepAliveProbes(socket, count)
* `socket` - `instanceof Net.Socket`- Socket to modify
* `count` - `Number` - Number of probes to send before dropping the connection
* Returns `true` on success
- `socket` - `instanceof Net.Socket`- Socket to modify
- `count` - `Number` - Number of probes to send before dropping the connection
- Returns `true` on success

Sets `TCP_KEEPCNT` to `count` number of probes for the `socket` based on its file descriptor (`fd`)

TCP_KEEPCNT (since Linux 2.4) - The maximum number of keepalive probes TCP should send before dropping the connection. This option should not be used in code intended to be portable.

### getKeepAliveProbes(socket)

### getKeepAliveProbes(socket)
* `socket` - `instanceof Net.Socket`- Socket to modify
* Returns `count` - `Number` - Number of probes to send before dropping the connection on success.
- `socket` - `instanceof Net.Socket`- Socket to modify
- Returns `count` - `Number` - Number of probes to send before dropping the connection on success.

Gets `TCP_KEEPCNT`. The `count` number of probes set for the `socket` based on its file descriptor (`fd`)

Expand Down
24 changes: 18 additions & 6 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@

/// <reference types="node" />

import * as net from "net";
import { Socket } from 'net'

export type NodeJSSocketWithFileDescriptor = net.Socket | { _handle: { _fd: number } }
export type NodeJSSocketWithFileDescriptor =
| Socket
| { _handle: { _fd: number } }

export function setKeepAliveInterval(socket: NodeJSSocketWithFileDescriptor, intvl: number): number
export function setKeepAliveInterval(
socket: NodeJSSocketWithFileDescriptor,
intvl: number
): boolean

export function getKeepAliveInterval(socket: NodeJSSocketWithFileDescriptor): number
export function getKeepAliveInterval(
socket: NodeJSSocketWithFileDescriptor
): number

export function setKeepAliveProbes(socket: NodeJSSocketWithFileDescriptor, cnt: number): number
export function setKeepAliveProbes(
socket: NodeJSSocketWithFileDescriptor,
cnt: number
): boolean

export function getKeepAliveProbes(socket: NodeJSSocketWithFileDescriptor): number
export function getKeepAliveProbes(
socket: NodeJSSocketWithFileDescriptor
): number
12 changes: 12 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as NetKeepAlive from './'
import * as Net from 'net'
import { expectType } from 'tsd'

Net.createServer((incomingSocket) => {
expectType<boolean>(NetKeepAlive.setKeepAliveInterval(incomingSocket, 1000))
expectType<boolean>(NetKeepAlive.setKeepAliveProbes(incomingSocket, 1))
})

const clientSocket = Net.createConnection({port: -1})
expectType<boolean>(NetKeepAlive.setKeepAliveInterval(clientSocket, 1000))
expectType<boolean>(NetKeepAlive.setKeepAliveProbes(clientSocket, 1))
2 changes: 1 addition & 1 deletion lib/commons.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const tryGetUV = (() => {
}
})()

const uvErrName = errno => {
const uvErrName = (errno) => {
const UV = tryGetUV()
return UV && UV.errname ? UV.errname(errno) : 'UNKNOWN'
}
Expand Down
4 changes: 2 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ const Assert = require('assert'),
Ref = require('ref-napi'),
FFIBindings = require('./ffi-bindings')

const _isSocket = socket => socket instanceof Net.Socket
const _isSocket = (socket) => socket instanceof Net.Socket

const _getSocketFD = socket => {
const _getSocketFD = (socket) => {
const fd = socket._handle != null ? socket._handle.fd : undefined
Assert(fd && fd !== -1, 'Unable to get socket fd')
return fd
Expand Down
Loading

0 comments on commit 1512351

Please sign in to comment.