Commit 7d5ae443 authored by 神楽坂玲奈's avatar 神楽坂玲奈

test

parent 688ab046
/.idea/ /.idea/
\ No newline at end of file /node_modules/
{ {
"server_address": "127.0.0.1", "server_address": "127.0.0.1",
"server_port": 9999, "server_port": 500,
"port": 9998, "port": 495,
"timeout": 10, "timeout": 10,
"interval": 1000 "interval": 1000,
"table": 1,
"proto": 250
} }
[
{
"id": 1,
"address": "10.198.0.1",
"interface": "mc-yangtze",
"subnets": [
"192.168.1.0/24",
"10.198.1.0/24",
"10.198.2.0/24"
]
},
{
"id": 3,
"address": "10.198.0.3",
"interface": "mc-south",
"subnets": [
"10.198.3.0/24"
]
},
{
"id": 7,
"address": "10.198.0.7",
"interface": "mc-fractal",
"subnets": [
"10.198.7.0/24"
]
},
{
"id": 9,
"address": "10.198.0.9",
"interface": "mc-marcia",
"subnets": [
"10.198.9.0/24"
]
}
]
{ {
"name": "railgun-network-client", "name": "railgun-routing-client",
"version": "1.0.0", "version": "0.0.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "railgun-network-client", "version": "0.0.1",
"version": "1.0.0",
"devDependencies": { "devDependencies": {
"@types/node": "^14.14.14", "@types/node": "^16.6.1",
"ts-node": "^9.1.1" "ts-node": "^10.2.0",
"typescript": "^4.3.5"
} }
}, },
"node_modules/@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"dev": true,
"engines": {
"node": ">= 12"
}
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
"integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
"dev": true,
"dependencies": {
"@cspotcode/source-map-consumer": "0.8.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"dev": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"dev": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"dev": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"dev": true
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "14.14.14", "version": "16.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
"integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==", "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==",
"dev": true "dev": true
}, },
"node_modules/acorn": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
"integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz",
"integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==",
"dev": true,
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/arg": { "node_modules/arg": {
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true "dev": true
}, },
"node_modules/buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"node_modules/create-require": { "node_modules/create-require": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
...@@ -51,57 +111,55 @@ ...@@ -51,57 +111,55 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true "dev": true
}, },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/ts-node": { "node_modules/ts-node": {
"version": "9.1.1", "version": "10.2.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.0.tgz",
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "integrity": "sha512-FstYHtQz6isj8rBtYMN4bZdnXN1vq4HCbqn9vdNQcInRqtB86PePJQIxE6es0PhxKWhj2PHuwbG40H+bxkZPmg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@cspotcode/source-map-support": "0.6.1",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0", "arg": "^4.1.0",
"create-require": "^1.1.0", "create-require": "^1.1.0",
"diff": "^4.0.1", "diff": "^4.0.1",
"make-error": "^1.1.1", "make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1" "yn": "3.1.1"
}, },
"bin": { "bin": {
"ts-node": "dist/bin.js", "ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-script": "dist/bin-script.js", "ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js", "ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js" "ts-script": "dist/bin-script-deprecated.js"
}, },
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=12.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7" "typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "4.1.3", "version": "4.3.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
"dev": true, "dev": true,
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
...@@ -121,10 +179,61 @@ ...@@ -121,10 +179,61 @@
} }
}, },
"dependencies": { "dependencies": {
"@cspotcode/source-map-consumer": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
"integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
"dev": true
},
"@cspotcode/source-map-support": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
"integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
"dev": true,
"requires": {
"@cspotcode/source-map-consumer": "0.8.0"
}
},
"@tsconfig/node10": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
"integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
"dev": true
},
"@tsconfig/node12": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
"integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
"dev": true
},
"@tsconfig/node14": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
"integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
"dev": true
},
"@tsconfig/node16": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
"integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
"dev": true
},
"@types/node": { "@types/node": {
"version": "14.14.14", "version": "16.6.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.6.1.tgz",
"integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==", "integrity": "sha512-Sr7BhXEAer9xyGuCN3Ek9eg9xPviCF2gfu9kTfuU2HkTVAMYSDeX40fvpmo72n5nansg3nsBjuQBrsS28r+NUw==",
"dev": true
},
"acorn": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
"integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
"dev": true
},
"acorn-walk": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz",
"integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==",
"dev": true "dev": true
}, },
"arg": { "arg": {
...@@ -133,12 +242,6 @@ ...@@ -133,12 +242,6 @@
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true "dev": true
}, },
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"create-require": { "create-require": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
...@@ -157,42 +260,31 @@ ...@@ -157,42 +260,31 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true "dev": true
}, },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-support": {
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"ts-node": { "ts-node": {
"version": "9.1.1", "version": "10.2.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.0.tgz",
"integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "integrity": "sha512-FstYHtQz6isj8rBtYMN4bZdnXN1vq4HCbqn9vdNQcInRqtB86PePJQIxE6es0PhxKWhj2PHuwbG40H+bxkZPmg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@cspotcode/source-map-support": "0.6.1",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0", "arg": "^4.1.0",
"create-require": "^1.1.0", "create-require": "^1.1.0",
"diff": "^4.0.1", "diff": "^4.0.1",
"make-error": "^1.1.1", "make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1" "yn": "3.1.1"
} }
}, },
"typescript": { "typescript": {
"version": "4.1.3", "version": "4.3.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
"integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
"dev": true, "dev": true
"peer": true
}, },
"yn": { "yn": {
"version": "3.1.1", "version": "3.1.1",
......
{ {
"name": "railgun-network-client", "name": "railgun-routing-client",
"version": "1.0.0", "version": "0.0.1",
"description": "", "author": "zh99998 <zh99998@gmail.com>",
"scripts": { "scripts": {
"start": "ts-node src/main.ts" "start": "ts-node src/main.ts"
}, },
"main": "index.js", "main": "index.js",
"devDependencies": { "devDependencies": {
"@types/node": "^14.14.14", "@types/node": "^16.6.1",
"ts-node": "^9.1.1" "ts-node": "^10.2.0",
"typescript": "^4.3.5"
} }
} }
{
"id": 3,
"peers": [
{
"id": 23,
"address": "10.200.23.3",
"subnets": ["10.198.0.25"],
"mark": 18003
}
]
}
// 这个文件两端共用
export interface PeerQuality {
delay: number;
jitter: number;
reliability: number;
}
// 路由器向中心服务器发送的消息
export interface UploadMessage {
id: number; // router id
ack: number;
peers?: Record<number, PeerQuality>;
}
// 中心服务器向路由器发送的消息
export interface DownloadMessage {
seq: number,
to: number,
nextHop: number;
}
// 路由器向路由器发送的消息
export interface PeerMessage {
id: number;
seq: number;
time: number;
}
import config from '../config.json'; import config from '../config.json';
import { Socket } from 'dgram'; import { PeerMessage, PeerQuality } from '../protocol';
import { PeerMeasure } from './protocol';
export interface PeerHello { export interface RouterConfig {
id: number;
seq: number;
time: number;
}
export interface PeerConfig {
id: number; id: number;
address: string; address: string;
subnets: string[]; subnets: string[];
} }
export class Peer implements PeerHello, PeerMeasure, PeerConfig { export class Peer implements PeerMessage, PeerQuality, RouterConfig {
id: number; id: number;
address: string; address: string;
subnets: string[]; subnets: string[];
delay: number = 0; delay: number = 0;
jitter: number = 0;
reliability: number = 0; reliability: number = 0;
seq: number = 0; seq: number = 0;
time: number = 0; time: number = 0;
constructor(config: PeerConfig) { constructor(config: RouterConfig) {
Object.assign(this, config); Object.assign(this, config);
} }
...@@ -37,7 +29,7 @@ export class Peer implements PeerHello, PeerMeasure, PeerConfig { ...@@ -37,7 +29,7 @@ export class Peer implements PeerHello, PeerMeasure, PeerConfig {
this.time = 0; this.time = 0;
} }
onMessage(data: PeerHello) { onMessage(data: PeerMessage) {
if (data.seq == 0 || data.seq < this.seq - config.timeout || data.seq > this.seq + config.timeout) { if (data.seq == 0 || data.seq < this.seq - config.timeout || data.seq > this.seq + config.timeout) {
// 收到 seq = 0 或 seq 与之前差距较大,就 reset // 收到 seq = 0 或 seq 与之前差距较大,就 reset
this.reset(); this.reset();
...@@ -57,23 +49,14 @@ export class Peer implements PeerHello, PeerMeasure, PeerConfig { ...@@ -57,23 +49,14 @@ export class Peer implements PeerHello, PeerMeasure, PeerConfig {
this.time = data.time; this.time = data.time;
} }
update(socket: Socket, self: PeerHello) { update(time: number) {
if (this.reliability == 0) { if (this.reliability == 0) {
return; return;
} }
// 有几个包没到 // 有几个包没到
const step = Math.floor((self.time - this.time + this.delay - config.interval) / config.interval); const step = Math.floor((time - this.time + this.delay - config.interval) / config.interval);
if (step > config.timeout) { if (step > config.timeout) {
this.reset(); this.reset();
return;
} }
// if(self.time - this.time )
socket.send(JSON.stringify(self), config.port, this.address, (error, bytes) => error && console.warn(error));
} }
// pickServer(): PeerMeasure {
// const { id, delay, reliability } = this;
// return { id, delay, reliability };
// }
} }
import { Peer } from './Peer'; import config from '../config.json';
import routers from '../routers.json';
const tableOffset = 10000;
const groupTableOffset = 11000;
export class RouteWriter { export class RouteWriter {
routes: Route[];
constructor() {}
reset() {
// TODO: 所有 neighbor 重设为直连,不是 neighbor 的设为 unreachable
// 只是记下来,commit的时候再写入
}
add(to: Peer, via: Peer) { static reset() {
for (const subnet of to.subnets) { console.log(`route flush table ${config.table} proto ${config.proto}`);
this.routes.push({ to: subnet, via: via.address, table: 'main' }); for (const peer of routers.filter(r => r.interface)) {
this.set(peer.id, peer.id);
} }
this.routes.push({ to: 'default', via: via.address, table: tableOffset + to.id });
} }
// groupAdd(to: Peer, via: Peer) { static set(toId: number, viaId: number) {
// this.routes.push({ to: 'default', via: via.address, table: groupTableOffset + to.id }); const to = routers.find(r => r.id == toId);
// } const via = routers.find(r => r.id == viaId);
for (const address of [to.address, ...to.subnets]) {
commit() { console.log(`route replace ${address} dev ${via.interface}`);
// TODO: 写进系统,用 ip -batch }
} }
} }
export interface Route {
to: string;
via: string;
table: number | string;
}
import { RouteWriter } from './RouteWriter';
import { Peer, PeerHello, PeerMeasure } from './Peer';
import { Socket } from 'dgram'; import { Socket } from 'dgram';
import config from '../config.json'; import config from '../config.json';
import { RouteWriter } from './RouteWriter';
import { Peer } from './Peer';
import { DownloadMessage, PeerMessage, PeerQuality, UploadMessage } from '../protocol';
export class Server { export class Server {
ack = 0; ack = 0;
onMessage(data: ServerMessage, socket: Socket, self: PeerHello, peers: Map<number, Peer>) { onMessage(socket: Socket, message: DownloadMessage, self: PeerMessage) {
if (data.seq && this.ack != data.seq) { if (message.seq && this.ack != message.seq) {
return; return;
} }
const routeWriter = new RouteWriter(); if (message.seq === 0) {
RouteWriter.reset();
if (data.seq === 0) {
routeWriter.reset();
} }
for (const [to, via] of Object.entries(data.routes).map(([to, via]) => [peers.get(parseInt(to)), peers.get(via)])) {
routeWriter.add(to, via);
}
// for (const [to, via] of Object.entries(data.groups).map(([to, via]) => [peers.get(parseInt(to)), peers.get(via)])) {
// routeWriter.groupAdd(to, via);
// }
this.ack = data.seq + 1; RouteWriter.set(message.to, message.nextHop);
this.ack = message.seq + 1;
const response: UploadMessage = {
id: self.id,
ack: this.ack
};
socket.send( socket.send(JSON.stringify(response), config.server_port, config.server_address);
JSON.stringify({
id: self.id,
ack: this.ack,
}),
config.server_port,
config.server_address
);
} }
update(socket: Socket, self: PeerHello, peers: Map<number, Peer>) { update(socket: Socket, self: PeerMessage, peers: Peer[]) {
const p: PeerMeasure[] = []; const p: Record<number, PeerQuality> = {};
for (const peer of peers.values()) { for (const peer of peers) {
if (peer.reliability === 0) { if (peer.reliability === 0) {
continue; continue;
} }
...@@ -52,15 +46,12 @@ export class Server { ...@@ -52,15 +46,12 @@ export class Server {
const reliability = (peer.reliability * (config.timeout - step)) / config.timeout; const reliability = (peer.reliability * (config.timeout - step)) / config.timeout;
const { id, delay } = peer; const { id, delay } = peer;
p.push({ id, delay, reliability });
// jitter 还没算
p[id] = { delay, jitter: 0, reliability };
} }
socket.send(JSON.stringify({ id: self.id, ack: this.ack, peers: p }), config.server_port, config.server_address); const message: UploadMessage = { id: self.id, ack: this.ack, peers: p };
socket.send(JSON.stringify(message), config.server_port, config.server_address);
} }
} }
export interface ServerMessage {
seq: number;
routes: { [to: number]: number };
groups: { [to: number]: number };
}
import dgram from 'dgram'; import dgram from 'dgram';
import assert from 'assert'; import assert from 'assert';
import { Peer, PeerHello } from './Peer';
import config from '../config.json'; import config from '../config.json';
import { Server, ServerMessage } from './Server'; import routers from '../routers.json';
import { id, peers as peersConfig } from '../peers.json'; import { Server } from './Server';
import { Peer } from './Peer';
import { DownloadMessage, PeerMessage } from '../protocol';
const self: PeerHello = { id, seq: 0, time: 0 }; const self: PeerMessage = { id: parseInt(process.env.RAILGUN_ID), seq: 0, time: 0 };
const server = new Server(); const server = new Server();
const peers = new Map<number, Peer>(); const peers = routers.filter(r => r.id !== self.id && r.interface).map(r => new Peer(r));
for (const peer of peersConfig) {
peers.set(peer.id, new Peer(peer));
}
const socket = dgram.createSocket('udp4'); const socket = dgram
socket.on('message', (msg, rinfo) => { .createSocket('udp4')
try { .on('listening', () => {
if (rinfo.address == config.server_address && rinfo.port == config.server_port) { const address = socket.address();
// from server console.log(`listening ${address.address}:${address.port}`);
const hello: ServerMessage = JSON.parse(msg.toString()); })
server.onMessage(hello, socket, self, peers); .on('message', (msg, rinfo) => {
} else { try {
// from client if (rinfo.address == config.server_address && rinfo.port == config.server_port) {
const hello: PeerHello = JSON.parse(msg.toString()); // from server
assert.ok(hello.id); const message: DownloadMessage = JSON.parse(msg.toString());
const peer = peers.get(hello.id); server.onMessage(socket, message, self);
assert.ok(peer && rinfo.address == peer.address && rinfo.port == config.port); } else {
peer.onMessage(hello); // from client
const message: PeerMessage = JSON.parse(msg.toString());
assert(message.id);
const peer = peers.find(p => p.id === message.id);
assert(peer && rinfo.address == peer.address && rinfo.port == config.port);
peer.onMessage(message);
}
} catch (e) {
console.warn(e);
} }
} catch (e) { });
console.warn(e);
}
});
socket.on('listening', () => { socket.bind(config.port, routers.find(r => r.id == self.id).address);
const address = socket.address();
console.log(`listening ${address.address}:${address.port}`);
});
socket.bind(config.port);
setInterval(() => { setInterval(() => {
self.time = Date.now(); self.time = Date.now();
for (const peer of peers.values()) { const message = JSON.stringify(self);
peer.update(socket, self); for (const peer of peers) {
peer.update(self.time);
socket.send(message, config.port, peer.address);
} }
server.update(socket, self, peers); server.update(socket, self, peers);
self.seq++; self.seq++;
......
export interface PeerMeasure {
id: number;
delay: number;
reliability: number;
}
export interface ServerMessage {
id: number;
ack: number;
peers: PeerMeasure[];
}
{ {
"compilerOptions": { "compilerOptions": {
"module": "commonjs", "module": "commonjs",
"target": "es2020", "target": "esnext",
"sourceMap": true, "sourceMap": true,
"esModuleInterop": true, "esModuleInterop": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"lib": [] "lib": []
}, }
"exclude": [
"node_modules"
]
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment