Skip to content
This repository has been archived by the owner on Sep 27, 2020. It is now read-only.

Commit

Permalink
Merge pull request #17 from Srar/dev
Browse files Browse the repository at this point in the history
new features
  • Loading branch information
Srar authored Apr 25, 2018
2 parents 8476c56 + 07d39a3 commit a91c2e4
Show file tree
Hide file tree
Showing 25 changed files with 1,253 additions and 258 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,28 @@
3) 安装[Npcap](https://nmap.org/npcap/)来用于UDP多倍发包.
4) 使用管理员权限cmd或powershell中在已以下命令运行node-sstap.
```
.\sstap.exe --host [ss host] --port [ss port] --passwd [ss password] --xtudp [x times]
.\sstap.exe --host [ss host] --port [ss port] --passwd [ss password] --xtudp [x times] --method [ss method]
```

* `host`: 默认 Shadowsocks地址(可选)
* `port`: 默认 Shadowsocks端口(可选)
* `passwd`: 默认 Shadowsocks密码(可选)
* `method`: 默认 Shadowsocks加密方式(可选)
* `tcphost`: TCP Shadowsocks地址(可选)
* `tcpport`: TCP Shadowsocks端口(可选)
* `tcppasswd`: TCP Shadowsocks密码(可选)
* `tcpmethod`: TCP Shadowsocks加密方式(可选)
* `udphost`: UDP Shadowsocks地址(可选)
* `udpport`: UDP Shadowsocks端口(可选)
* `udppasswd`: UDP Shadowsocks密码(可选)
* `udpmethod`: UDP Shadowsocks加密方式(可选)
* `xtudp`: UDP 多倍发包倍率(适用于游戏)
* `dns`: 指定DNS(默认8.8.8.8)
* `skipdns`: DNS不经过Shadowsocks转发(默认false)

> 目前仅支持 RC4-MD5 加密方式.
> 启动添加路由时出现`对象已存在``找不到元素`为正常现象.
> 目前支持 `rc4-md5`, `aes-256-cfb`, `aes-128-gcm`, `aes-192-gcm`, `aes-256-gcm` 加密方式.
如果已经成功运行你应该会看到以下信息:
![snapshort.png](https://i.loli.net/2018/03/31/5abf7da82d4d1.png)
Expand All @@ -47,3 +54,4 @@
* [uIP](https://en.wikipedia.org/wiki/UIP_(micro_IP))
* [badvpn](https://github.com/ambrop72/badvpn)
* [gotun2socks](https://github.com/yinghuocho/gotun2socks)
* [blinksocks](https://github.com/blinksocks/blinksocks)
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"dependencies": {
"@types/node": "^8.5.7",
"cap": "^0.2.0",
"iconv-lite": "^0.4.19",
"ip6": "^0.1.5",
"nan": "^2.7.0",
"node-gyp": "^3.6.2",
"optimist": "^0.6.1",
Expand Down
14 changes: 13 additions & 1 deletion test/PacketsStruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,19 @@ export interface IpPacket extends BasePacket {
protocol?: IpProtocol,
checksum?: number,
sourceIp?: Buffer,
destinationIp?: Buffer
destinationIp?: Buffer,
tcpipPayload?: Buffer,
}

export interface Ipv6Packet extends BasePacket {
/* 4 bits version, 8 bits TC, 20 bits flow-ID */
flow?: number
payloadLength?: number,
protocol?: IpProtocol,
hopLimit?: number,
sourceIp?: Buffer,
destinationIp?: Buffer,
tcpipPayload?: Buffer,
}

export interface TcpPacket extends IpPacket {
Expand Down
84 changes: 84 additions & 0 deletions test/TAPControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@

const native = require("../index.js");
import * as NativeTypes from "./NativeTypes"

const TAP_IOCTL_GET_MTU = CTL_CODE(0x00000022, 3, 0, 0);
const TAP_IOCTL_SET_MEDIA_STATUS = CTL_CODE(0x00000022, 6, 0, 0);
const TAP_WIN_IOCTL_CONFIG_DHCP_MASQ = CTL_CODE(0x00000022, 7, 0, 0);
const TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT = CTL_CODE(0x00000022, 9, 0, 0);
const TAP_IOCTL_CONFIG_TUN = CTL_CODE(0x00000022, 10, 0, 0);

const TRUE = new Buffer([0x01, 0x00, 0x00, 0x00]);
const FALSE = new Buffer([0x00, 0x00, 0x00, 0x00]);

function CTL_CODE(deviceType, func, method, access) {
return ((deviceType) << 16) | ((access) << 14) | ((func) << 2) | (method)
}

export class NotFoundError extends Error {
constructor(public message: string) {
super();
}
}

export default class TAPControl {

private static tapControlObject: TAPControl = null;

private deviceHandle: number = null;
private deviceInfo: NativeTypes.DeviceInfo = null;
private rwProcess = null;

private constructor() {
const allDevicesInfo: Array<NativeTypes.DeviceInfo> = <Array<NativeTypes.DeviceInfo>>native.N_GetAllDevicesInfo();
for (const device of allDevicesInfo) {
if (device.description.toLocaleLowerCase().indexOf("tap-windows adapter v9") != -1) {
this.deviceInfo = device;
}
}
if (this.deviceInfo === null) {
throw new NotFoundError("Openvpn adapter not found.");
}
}

public static init(): TAPControl {
if(this.tapControlObject === null) {
this.tapControlObject = new TAPControl();
}
return TAPControl.tapControlObject;
}

public getAdapterInfo(): NativeTypes.DeviceInfo {
return this.deviceInfo;
}

public getAdapterHandle(): number {
return this.deviceHandle;
}

public read(): Promise<Buffer> {
return new Promise((resolve, reject) => {
this.rwProcess.read(function (err, data) {
err ? reject(err) : resolve(data);
});
});
}

public write(data: Buffer) {
this.rwProcess.writeSync(data);
}

public enable(): number {
if (this.deviceHandle !== null) {
throw new Error("Openvpn adapter has been enabled.");
}
this.deviceHandle = native.N_CreateDeviceFile(this.deviceInfo.name);
native.N_DeviceControl(this.deviceHandle, TAP_IOCTL_SET_MEDIA_STATUS, TRUE, 32);
this.rwProcess = new native.RwEventProcess(this.deviceHandle);
return this.deviceHandle;
}

public disable() {
// unsupported.
}
}
7 changes: 0 additions & 7 deletions test/filters/ARP.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import PacketUtils from "../PacketUtils"
import {
BasePacket,
IpPacket,
TcpPacket,
IpProtocol,
ArpPacket
} from "../PacketsStruct"
import ArpPacketFormatter from "../formatters/ArpPacketFormatter"
import DeviceConfiguration from "../DeviceConfiguration"

Expand Down
12 changes: 6 additions & 6 deletions test/filters/TCP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
TcpPacket,
IpProtocol
} from "../PacketsStruct"
import ShadowsocksClientSocket from "../shadowsocks/client"
import ShadowsocksTcpClient from "../shadowsocks/ShadowsocksTcpClient"
import IpacketFormatter from "../formatters/IpPacketFormatter"
import TcpPacketFormatter from "../formatters/TcpPacketFormatter"
import * as EventEmitter from "events"
Expand Down Expand Up @@ -38,7 +38,7 @@ enum TcpConnectionState {
class TcpServerSession extends EventEmitter {

private state: TcpConnectionState;
private shadowsocks: ShadowsocksClientSocket;
private shadowsocks: ShadowsocksTcpClient;

private currentIdNum: number;
private currentSeqNum: number = 0;
Expand Down Expand Up @@ -67,11 +67,11 @@ class TcpServerSession extends EventEmitter {
this.routers[TcpConnectionState.RemoteCloseWating_1] = this.tcpClientRequestToClose.bind(this);
this.routers[TcpConnectionState.LocalCloseWating] = this.tcpShadowsocksClosed.bind(this);
this.routers[TcpConnectionState.LocalCloseWating_1] = this.tcpShadowsocksClosed.bind(this);
this.shadowsocks = new ShadowsocksClientSocket(
this.shadowsocks = new ShadowsocksTcpClient(
Config.get("ShadowsocksTcpHost"),
Config.get("ShadowsocksTcpPort"),
Config.get("ShadowsocksTcpPasswd"),
"RC4MD5"
Config.get("ShadowsocksTcpMethod"),
);
}

Expand Down Expand Up @@ -104,7 +104,7 @@ class TcpServerSession extends EventEmitter {
var tcpAckpacket: Buffer = TcpPacketFormatter.build(ack);
this.nativeWrite(tcpAckpacket);
this.state = TcpConnectionState.HandShake_ACK;
this.shadowsocks.connect(PacketUtils.ipAddressToString(this.connection.localIp), this.connection.localPort);
this.shadowsocks.connect(PacketUtils.isIPv4(data), PacketUtils.ipAddressToString(this.connection.localIp), this.connection.localPort);
this.shadowsocks.on("data", this.tcpShadowsocksData.bind(this));
this.shadowsocks.on("disconnected", this.tcpShadowsocksClosed.bind(this));
return;
Expand Down Expand Up @@ -270,7 +270,7 @@ class TcpServerSession extends EventEmitter {
}

public buildBaseTcpPacket(dataLength: number = 0): TcpPacket {
this.currentIdNum = PacketUtils.increaseNumber( this.currentIdNum, 65536);
this.currentIdNum = PacketUtils.increaseNumber(this.currentIdNum, 65536);
return {
version: 4,
TTL: 64,
Expand Down
53 changes: 30 additions & 23 deletions test/filters/TimesUDP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,33 @@ import * as raw from "raw-socket"
import Config from "../Config"
import PacketUtils from "../PacketUtils"

console.log("XTUdp:", Config.get("XTUdp"));
console.log("Default ip of adapter:", Config.get("DefaultIp"));
console.log("Default gateway of adapter:", Config.get("DefaultGateway"));

/* 注册Pcap */
var cap = new Cap();
var device = Cap.findDevice(Config.get("DefaultIp"));
var filter = `udp and dst host ${Config.get("ShadowsocksUdpHost")}`;
var bufSize = 10 * 1024 * 1024;
var buffer = Buffer.alloc(65535);
var linkType = cap.open(device, filter, bufSize, buffer);
cap.setMinBytes && cap.setMinBytes(0);

/* 注册RawScoket */
var rawsocket = raw.createSocket({
protocol: raw.Protocol.UDP
});
rawsocket.setOption(raw.SocketLevel.IPPROTO_IP, raw.SocketOption.IP_HDRINCL, new Buffer([0x00, 0x00, 0x00, 0x01]), 4);

const SPECIAL_TTL: number = 0x7B; // 123
const XTUdp: number = Config.get("XTUdp");
if (XTUdp > 1) {
function registerXTUdp() {
const XTUdp: number = Config.get("XTUdp");
if (XTUdp <= 1) {
console.log("XTUdp: disabled");
return;
}

console.log("XTUdp:", Config.get("XTUdp"));
console.log("Default ip of adapter:", Config.get("DefaultIp"));
console.log("Default gateway of adapter:", Config.get("DefaultGateway"));

/* 注册Pcap */
var cap = new Cap();
var device = Cap.findDevice(Config.get("DefaultIp"));
var filter = `udp and dst host ${Config.get("ShadowsocksUdpHost")}`;
var bufSize = 10 * 1024 * 1024;
var buffer = Buffer.alloc(65535);
var linkType = cap.open(device, filter, bufSize, buffer);
cap.setMinBytes && cap.setMinBytes(0);

/* 注册RawScoket */
var rawsocket = raw.createSocket({
protocol: raw.Protocol.UDP
});
rawsocket.setOption(raw.SocketLevel.IPPROTO_IP, raw.SocketOption.IP_HDRINCL, new Buffer([0x00, 0x00, 0x00, 0x01]), 4);

const SPECIAL_TTL: number = 0x7B; // 123
cap.on("packet", function (nbytes, trunc) {
/* Ethernet + IP/TCP */
if (nbytes < 34) return;
Expand All @@ -35,14 +40,16 @@ if (XTUdp > 1) {
var targetIpAddress: string = PacketUtils.ipAddressToString(sendingBuffer.slice(16, 21));
for (var i = 1; i < XTUdp; i++) {
rawsocket.send(sendingBuffer, 0, sendingBuffer.length, targetIpAddress, function (error, bytes) {
if(error) {
if (error) {
console.error(error);
}
});
}
});
}

registerXTUdp();

export default function (data: Buffer, write: Function, next: Function) {
next();
}
Loading

0 comments on commit a91c2e4

Please sign in to comment.