Archived
1
0
This repository has been archived on 2024-09-09. You can view files and clone it, but cannot push or open issues or pull requests.
code-server/packages/server/src/portScanner.ts
Kyle Carberry 85d2225e0c Featureful (#31)
* Fix loading within the CLI

* Remove app

* Remove promise handle

* Add initial travis file

* Add libxkbfile dependency

* Add libxkbfile-dev

* Add build script

* Fix malformed bash statement

* Remove yarn from script

* Improve build script

* Extract upx before usage

* Only run upx if on linux

* Ensure resource directory exists

* Pack runnable binary

* Export binary with platform

* Improve build process

* Install upx before running install script

* Update typescript version before running nexe

* Add os.release() function for multi-platform support

* Update travis.yml to improve deployment

* Add on CI

* Update to v1.31.0

* Add libsecret

* Update build target

* Skip cleanup

* Fix built-in extensions

* Add basics for apps

* Create custom DNS server

* Fix forking within CLI. Fixes TS language features

* Fix filename resolve

* Fix default extensions path

* Add custom dialog

* Store workspace path

* Remove outfiles

* Cleanup

* Always authed outside of CLI

* Use location.host for client

* Remove useless app interface

* Remove debug file for building wordlist

* Use chromes tcp host

* Update patch

* Build browser app before packaging

* Replace all css containing file:// URLs, fix webviews

* Fix save

* Fix mkdir
2019-02-21 11:55:42 -06:00

106 lines
2.3 KiB
TypeScript

//@ts-ignore
import * as netstat from "node-netstat";
import { Event, Emitter } from "@coder/events";
export interface PortScanner {
readonly ports: ReadonlyArray<number>;
readonly onAdded: Event<ReadonlyArray<number>>;
readonly onRemoved: Event<ReadonlyArray<number>>;
dispose(): void;
}
/**
* Creates a disposable port scanner.
* Will scan local ports and emit events when ports are added or removed.
* Currently only scans TCP ports.
*/
export const createPortScanner = (scanInterval: number = 250): PortScanner => {
const ports = new Map<number, number>();
const addEmitter = new Emitter<number[]>();
const removeEmitter = new Emitter<number[]>();
const scan = (onCompleted: (err?: Error) => void): void => {
const scanTime = Date.now();
const added: number[] = [];
netstat({
done: (err: Error): void => {
const removed: number[] = [];
ports.forEach((value, key) => {
if (value !== scanTime) {
// Remove port
removed.push(key);
ports.delete(key);
}
});
if (removed.length > 0) {
removeEmitter.emit(removed);
}
if (added.length > 0) {
addEmitter.emit(added);
}
onCompleted(err);
},
filter: {
state: "LISTEN",
},
}, (data: {
readonly protocol: string;
readonly local: {
readonly port: number;
readonly address: string;
};
}) => {
// https://en.wikipedia.org/wiki/Registered_port
if (data.local.port <= 1023 || data.local.port >= 49151) {
return;
}
// Only forward TCP ports
if (!data.protocol.startsWith("tcp")) {
return;
}
if (!ports.has(data.local.port)) {
added.push(data.local.port);
}
ports.set(data.local.port, scanTime);
});
};
let lastTimeout: NodeJS.Timer | undefined;
let disposed: boolean = false;
const doInterval = (): void => {
scan(() => {
if (disposed) {
return;
}
lastTimeout = setTimeout(doInterval, scanInterval);
});
};
doInterval();
return {
get ports(): number[] {
return Array.from(ports.keys());
},
get onAdded(): Event<number[]> {
return addEmitter.event;
},
get onRemoved(): Event<number[]> {
return removeEmitter.event;
},
dispose(): void {
if (typeof lastTimeout !== "undefined") {
clearTimeout(lastTimeout);
}
disposed = true;
},
};
};