blinksocks/src/transports/udp.js

102 lines
2.3 KiB
JavaScript
Raw Normal View History

2017-10-26 06:05:19 +00:00
import dgram from 'dgram';
2018-02-17 04:19:31 +00:00
import { Inbound, Outbound } from './defs';
import { logger } from '../utils';
2017-10-26 06:05:19 +00:00
export class UdpInbound extends Inbound {
_socket = null;
_rinfo = null;
constructor(props) {
super(props);
2018-06-24 05:30:56 +00:00
this._socket = this._conn;
2017-10-26 06:05:19 +00:00
}
onReceive = (buffer, rinfo) => {
2017-10-26 06:05:19 +00:00
this._rinfo = rinfo;
2018-06-24 05:30:56 +00:00
this.emit('data', buffer);
};
2017-10-26 06:05:19 +00:00
write(buffer) {
2018-02-17 04:19:31 +00:00
const { address, port } = this._rinfo;
const onSendError = (err) => {
2017-10-26 06:05:19 +00:00
if (err) {
logger.warn(`[udp:inbound] [${this.remote}]: ${err.message}`);
2017-10-26 06:05:19 +00:00
}
};
if (this._config.is_client) {
2018-06-24 05:30:56 +00:00
const isSs = this._config.presets.some(({ name }) => 'ss-base' === name);
this._socket.send(buffer, port, address, isSs, onSendError);
} else {
this._socket.send(buffer, port, address, onSendError);
}
2017-10-26 06:05:19 +00:00
}
close() {
2017-10-26 06:05:19 +00:00
if (this._socket !== null && this._socket._handle !== null) {
2018-02-16 08:54:59 +00:00
// NOTE: prevent close shared udp socket
// this._socket.close();
2017-10-26 06:05:19 +00:00
this._socket = null;
this.emit('close');
}
}
}
export class UdpOutbound extends Outbound {
_socket = null;
_targetHost = null;
_targetPort = null;
constructor(props) {
super(props);
this._socket = dgram.createSocket('udp4');
this._socket.on('message', this.onReceive);
}
onReceive = (buffer) => {
2018-06-24 05:30:56 +00:00
this.emit('data', buffer);
};
2017-10-26 06:05:19 +00:00
write(buffer) {
const host = this._targetHost;
const port = this._targetPort;
if (host === null || port === null) {
logger.error('[udp:outbound] fail to send udp data, target address was not initialized.');
}
else if (port <= 0 || port >= 65536) {
logger.error(`[udp:outbound] fail to send udp data, target port "${port}" is invalid.`);
}
else {
this._socket.send(buffer, port, host, (err) => {
if (err) {
logger.warn(`[udp:outbound] [${this.remote}]: ${err.message}`);
}
});
}
2017-10-26 06:05:19 +00:00
}
2018-06-24 05:30:56 +00:00
connect(host, port) {
if (this._config.is_client) {
this._targetHost = this._config.server_host;
this._targetPort = this._config.server_port;
2018-06-24 05:30:56 +00:00
} else {
2017-10-26 06:05:19 +00:00
this._targetHost = host;
this._targetPort = port;
}
}
close() {
2017-10-26 06:05:19 +00:00
if (this._socket !== null && this._socket._handle !== null) {
this._socket.close();
this._socket = null;
this.emit('close');
2017-10-26 06:05:19 +00:00
}
}
}