mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 18:19:12 +01:00
@@ -34,6 +34,92 @@ class ExtensionTunnel implements vscode.Tunnel {
|
||||
}
|
||||
}
|
||||
|
||||
export function getSockets(stdout: string): { pid: number, socket: number }[] {
|
||||
const lines = stdout.trim().split('\n');
|
||||
const mapped: { pid: number, socket: number }[] = [];
|
||||
lines.forEach(line => {
|
||||
const match = /\/proc\/(\d+)\/fd\/\d+ -> socket:\[(\d+)\]/.exec(line)!;
|
||||
if (match && match.length >= 3) {
|
||||
mapped.push({
|
||||
pid: parseInt(match[1], 10),
|
||||
socket: parseInt(match[2], 10)
|
||||
});
|
||||
}
|
||||
});
|
||||
return mapped;
|
||||
}
|
||||
|
||||
export function loadListeningPorts(...stdouts: string[]): { socket: number, ip: string, port: number }[] {
|
||||
const table = ([] as Record<string, string>[]).concat(...stdouts.map(loadConnectionTable));
|
||||
return [
|
||||
...new Map(
|
||||
table.filter(row => row.st === '0A')
|
||||
.map(row => {
|
||||
const address = row.local_address.split(':');
|
||||
return {
|
||||
socket: parseInt(row.inode, 10),
|
||||
ip: parseIpAddress(address[0]),
|
||||
port: parseInt(address[1], 16)
|
||||
};
|
||||
}).map(port => [port.ip + ':' + port.port, port])
|
||||
).values()
|
||||
];
|
||||
}
|
||||
|
||||
export function parseIpAddress(hex: string): string {
|
||||
let result = '';
|
||||
if (hex.length === 8) {
|
||||
for (let i = hex.length - 2; i >= 0; i -= 2) {
|
||||
result += parseInt(hex.substr(i, 2), 16);
|
||||
if (i !== 0) {
|
||||
result += '.';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = hex.length - 4; i >= 0; i -= 4) {
|
||||
result += parseInt(hex.substr(i, 4), 16).toString(16);
|
||||
if (i !== 0) {
|
||||
result += ':';
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function loadConnectionTable(stdout: string): Record<string, string>[] {
|
||||
const lines = stdout.trim().split('\n');
|
||||
const names = lines.shift()!.trim().split(/\s+/)
|
||||
.filter(name => name !== 'rx_queue' && name !== 'tm->when');
|
||||
const table = lines.map(line => line.trim().split(/\s+/).reduce((obj, value, i) => {
|
||||
obj[names[i] || i] = value;
|
||||
return obj;
|
||||
}, {} as Record<string, string>));
|
||||
return table;
|
||||
}
|
||||
|
||||
export async function findPorts(tcp: string, tcp6: string, procSockets: string, processes: { pid: number, cwd: string, cmd: string }[]) {
|
||||
const connections: { socket: number, ip: string, port: number }[] = loadListeningPorts(tcp, tcp6);
|
||||
const sockets = getSockets(procSockets);
|
||||
|
||||
const socketMap = sockets.reduce((m, socket) => {
|
||||
m[socket.socket] = socket;
|
||||
return m;
|
||||
}, {} as Record<string, typeof sockets[0]>);
|
||||
const processMap = processes.reduce((m, process) => {
|
||||
m[process.pid] = process;
|
||||
return m;
|
||||
}, {} as Record<string, typeof processes[0]>);
|
||||
|
||||
const ports: { host: string, port: number, detail: string }[] = [];
|
||||
connections.filter((connection => socketMap[connection.socket])).forEach(({ socket, ip, port }) => {
|
||||
const command = processMap[socketMap[socket].pid].cmd;
|
||||
if (!command.match(/.*\.vscode-server-[a-zA-Z]+\/bin.*/) && (command.indexOf('out/vs/server/main.js') === -1)) {
|
||||
ports.push({ host: ip, port, detail: processMap[socketMap[socket].pid].cmd });
|
||||
}
|
||||
});
|
||||
return ports;
|
||||
}
|
||||
|
||||
export class ExtHostTunnelService extends Disposable implements IExtHostTunnelService {
|
||||
readonly _serviceBrand: undefined;
|
||||
private readonly _proxy: MainThreadTunnelServiceShape;
|
||||
@@ -137,9 +223,7 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
async findCandidatePorts(): Promise<{ host: string, port: number, detail: string }[]> {
|
||||
const ports: { host: string, port: number, detail: string }[] = [];
|
||||
let tcp: string = '';
|
||||
let tcp6: string = '';
|
||||
try {
|
||||
@@ -170,89 +254,6 @@ export class ExtHostTunnelService extends Disposable implements IExtHostTunnelSe
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
const connections: { socket: number, ip: string, port: number }[] = this.loadListeningPorts(tcp, tcp6);
|
||||
const sockets = this.getSockets(procSockets);
|
||||
|
||||
const socketMap = sockets.reduce((m, socket) => {
|
||||
m[socket.socket] = socket;
|
||||
return m;
|
||||
}, {} as Record<string, typeof sockets[0]>);
|
||||
const processMap = processes.reduce((m, process) => {
|
||||
m[process.pid] = process;
|
||||
return m;
|
||||
}, {} as Record<string, typeof processes[0]>);
|
||||
|
||||
connections.filter((connection => socketMap[connection.socket])).forEach(({ socket, ip, port }) => {
|
||||
const command = processMap[socketMap[socket].pid].cmd;
|
||||
if (!command.match(/.*\.vscode-server-[a-zA-Z]+\/bin.*/) && (command.indexOf('out/vs/server/main.js') === -1)) {
|
||||
ports.push({ host: ip, port, detail: processMap[socketMap[socket].pid].cmd });
|
||||
}
|
||||
});
|
||||
|
||||
return ports;
|
||||
}
|
||||
|
||||
private getSockets(stdout: string): { pid: number, socket: number }[] {
|
||||
const lines = stdout.trim().split('\n');
|
||||
const mapped: { pid: number, socket: number }[] = [];
|
||||
lines.forEach(line => {
|
||||
const match = /\/proc\/(\d+)\/fd\/\d+ -> socket:\[(\d+)\]/.exec(line)!;
|
||||
if (match && match.length >= 3) {
|
||||
mapped.push({
|
||||
pid: parseInt(match[1], 10),
|
||||
socket: parseInt(match[2], 10)
|
||||
});
|
||||
}
|
||||
});
|
||||
return mapped;
|
||||
}
|
||||
|
||||
private loadListeningPorts(...stdouts: string[]): { socket: number, ip: string, port: number }[] {
|
||||
const table = ([] as Record<string, string>[]).concat(...stdouts.map(this.loadConnectionTable));
|
||||
return [
|
||||
...new Map(
|
||||
table.filter(row => row.st === '0A')
|
||||
.map(row => {
|
||||
const address = row.local_address.split(':');
|
||||
return {
|
||||
socket: parseInt(row.inode, 10),
|
||||
ip: this.parseIpAddress(address[0]),
|
||||
port: parseInt(address[1], 16)
|
||||
};
|
||||
}).map(port => [port.ip + ':' + port.port, port])
|
||||
).values()
|
||||
];
|
||||
}
|
||||
|
||||
private parseIpAddress(hex: string): string {
|
||||
let result = '';
|
||||
if (hex.length === 8) {
|
||||
for (let i = hex.length - 2; i >= 0; i -= 2) {
|
||||
result += parseInt(hex.substr(i, 2), 16);
|
||||
if (i !== 0) {
|
||||
result += '.';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = hex.length - 4; i >= 0; i -= 4) {
|
||||
result += parseInt(hex.substr(i, 4), 16).toString(16);
|
||||
if (i !== 0) {
|
||||
result += ':';
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private loadConnectionTable(stdout: string): Record<string, string>[] {
|
||||
const lines = stdout.trim().split('\n');
|
||||
const names = lines.shift()!.trim().split(/\s+/)
|
||||
.filter(name => name !== 'rx_queue' && name !== 'tm->when');
|
||||
const table = lines.map(line => line.trim().split(/\s+/).reduce((obj, value, i) => {
|
||||
obj[names[i] || i] = value;
|
||||
return obj;
|
||||
}, {} as Record<string, string>));
|
||||
return table;
|
||||
return findPorts(tcp, tcp6, procSockets, processes);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user