dgram#RemoteInfo TypeScript Examples

The following examples show how to use dgram#RemoteInfo. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: h1emuserver.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
clientHandler(remote: RemoteInfo, opcode: number): H1emuClient | void {
    let client: H1emuClient;
    const clientId: string = `${remote.address}:${remote.port}`;
    if (!this._clients[clientId]) {
      // if client doesn't exist yet, only accept sessionrequest or sessionreply
      if (opcode !== 0x01 && opcode !== 0x02) return;
      client = this._clients[clientId] = new H1emuClient(remote);
      this.updateClientLastPing(clientId);
    } else {
      client = this._clients[clientId];
    }
    return client;
  }
Example #2
Source File: soeclient.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
constructor(
    remote: RemoteInfo,
    crcSeed: number,
    compression: number,
    cryptoKey: Uint8Array
  ) {
    this.soeClientId = remote.address + ":" + remote.port;
    this.address = remote.address;
    this.port = remote.port;
    this.crcSeed = crcSeed;
    this.compression = compression;
    this.inputStream = new SOEInputStream(cryptoKey);
    this.outputStream = new SOEOutputStream(cryptoKey);
  }
Example #3
Source File: soeserver.ts    From h1z1-server with GNU General Public License v3.0 6 votes vote down vote up
private _createClient(clientId: string, remote: RemoteInfo) {
    this.adjustPacketRate();
    const client = new SOEClient(
      remote,
      this._crcSeed,
      this._compression,
      this._cryptoKey
    );
    this._clients.set(clientId, client);
    return client;
  }
Example #4
Source File: Session.ts    From JSPrismarine with Mozilla Public License 2.0 6 votes vote down vote up
public constructor(listener: RakNetListener, mtuSize: number, rinfo: RemoteInfo, offlineMode = false) {
        this.listener = listener;

        this.mtuSize = mtuSize;
        this.rinfo = rinfo;
        this.offlineMode = offlineMode;

        this.lastUpdate = Date.now();

        this.channelIndex = new Array(MAX_CHANNELS).fill(0);
        this.inputOrderIndex = new Array(MAX_CHANNELS).fill(0);
        this.inputHighestSequenceIndex = new Array(MAX_CHANNELS).fill(0);
    }
Example #5
Source File: stun.spec.ts    From hoprnet with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Creates a STUN server that answers with tweaked STUN responses to simulate
 * ambiguous results from STUN servers
 * @param port fake port
 * @param address fake address
 * @returns STUN server answering with falsy responses
 */
async function getAmbiguousSTUNServer(
  port: number | undefined,
  address: string | undefined = undefined,
  state: { msgReceived: DeferType<void>; contactCount?: number } | undefined,
  reply: boolean = true
) {
  const socket = await bindToUdpSocket(undefined)

  socket.on('message', (msg: Buffer, rinfo: RemoteInfo) => {
    if (reply) {
      handleStunRequest(socket, msg, rinfo, {
        ...rinfo,
        address: address ?? rinfo.address,
        port: port ?? rinfo.port
      })
    }
    if (state?.contactCount != undefined) {
      state.contactCount += 1
    }
    state?.msgReceived.resolve()
  })

  return socket
}
Example #6
Source File: stun.ts    From hoprnet with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Handles STUN requests
 * @param socket Node.JS socket to use
 * @param data received packet
 * @param rinfo Addr+Port of the incoming connection
 * @param __fakeRInfo [testing] overwrite incoming information to intentionally send misleading STUN response
 */
export function handleStunRequest(socket: Socket, data: Buffer, rinfo: RemoteInfo, __fakeRInfo?: RemoteInfo): void {
  const req = createBlank()

  // Overwrite console.log because 'webrtc-stun' package
  // pollutes console output
  const consoleBackup = console.log
  console.log = log

  try {
    if (req.loadBuffer(data)) {
      // if STUN message is BINDING_REQUEST and valid content
      if (req.isBindingRequest({ fingerprint: true })) {
        verbose(`Received STUN request from ${rinfo.address}:${rinfo.port}`)

        const res = req
          .createBindingResponse(true)
          .setXorMappedAddressAttribute(__fakeRInfo ?? rinfo)
          .setFingerprintAttribute()

        socket.send(res.toBuffer(), rinfo.port, rinfo.address)
      } else if (!req.isBindingResponseSuccess()) {
        error(`Received a STUN message that is not a binding request. Dropping message.`)
      }
    } else {
      error(`Received a message that is not a STUN message. Dropping message.`)
    }
  } catch (err) {
    consoleBackup(err)
  } finally {
    console.log = consoleBackup
  }
}
Example #7
Source File: h1emuclient.ts    From h1z1-server with GNU General Public License v3.0 5 votes vote down vote up
constructor(remote: RemoteInfo) {
    this.address = remote.address;
    this.port = remote.port;
    this.clientId = `${remote.address}:${remote.port}`;
  }
Example #8
Source File: Listener.ts    From JSPrismarine with Mozilla Public License 2.0 5 votes vote down vote up
public addSession(rinfo: RemoteInfo, mtuSize: number) {
        this.sessions.set(`${rinfo.address}:${rinfo.port}`, new RakNetSession(this, mtuSize, rinfo, this.onlineMode));
    }
Example #9
Source File: Listener.ts    From JSPrismarine with Mozilla Public License 2.0 5 votes vote down vote up
private getSession(rinfo: RemoteInfo): RakNetSession | null {
        return this.sessions.get(`${rinfo.address}:${rinfo.port}`) ?? null;
    }
Example #10
Source File: Listener.ts    From JSPrismarine with Mozilla Public License 2.0 5 votes vote down vote up
public sendPacket<T extends Packet>(packet: T, rinfo: RemoteInfo): void {
        packet.encode();
        this.sendBuffer(packet.getBuffer(), rinfo);
    }
Example #11
Source File: Listener.ts    From JSPrismarine with Mozilla Public License 2.0 5 votes vote down vote up
public sendBuffer(buffer: Buffer, rinfo: RemoteInfo): void {
        this.socket.send(buffer, rinfo.port, rinfo.address);
    }
Example #12
Source File: Session.ts    From JSPrismarine with Mozilla Public License 2.0 5 votes vote down vote up
protected readonly rinfo: RemoteInfo;
Example #13
Source File: UnconnectedHandler.ts    From JSPrismarine with Mozilla Public License 2.0 5 votes vote down vote up
public handle(msg: Buffer, rinfo: RemoteInfo): void {
        const id = msg[0];
        switch (id) {
            case MessageHeaders.QUERY:
                this.listener.emit('raw', msg, new InetAddress(rinfo.address, rinfo.port));
                break;
            case MessageHeaders.UNCONNECTED_PING:
                const ping = new UnconnectedPing(msg);
                ping.decode();

                const pong = new UnconnectedPong();
                pong.timestamp = ping.timestamp;

                const guid = this.listener.getServerGuid();

                pong.serverGuid = guid;
                pong.serverName = 'MCPE;JSPrismarine;503;1.18.30;0;20;' + guid + ';Second line;Creative;';
                this.listener.sendPacket(pong, rinfo);
                break;
            case MessageHeaders.OPEN_CONNECTION_REQUEST_1:
                const request1 = new OpenConnectionRequest1(msg);
                request1.decode();

                if (request1.protocol !== MINECRAFT_PROTOCOL) {
                    const packet = new IncompatibleProtocolVersion();
                    packet.protocol = MINECRAFT_PROTOCOL;
                    packet.serverGUID = this.listener.getServerGuid();
                    this.listener.sendPacket(request1, rinfo);
                    return;
                }

                const reply1 = new OpenConnectionReply1();
                reply1.serverGUID = this.listener.getServerGuid();
                reply1.mtuSize = request1.mtuSize;
                this.listener.sendPacket(reply1, rinfo);
                break;
            case MessageHeaders.OPEN_CONNECTION_REQUEST_2:
                const request2 = new OpenConnectionRequest2(msg);
                request2.decode();

                const reply2 = new OpenConnectionReply2();
                reply2.serverGuid = this.listener.getServerGuid();

                const mtu = Math.min(request2.mtuSize, MAX_MTU_SIZE);

                reply2.mtuSize = mtu;
                reply2.clientAddress = new InetAddress(rinfo.address, rinfo.port, 4);

                this.listener.addSession(rinfo, mtu);
                this.listener.sendPacket(reply2, rinfo);
                break;
            default:
                throw new Error(`Unknown unconnected packet with ID=${id.toString(16)}`);
        }
    }
Example #14
Source File: session.ts    From eufy-security-client with MIT License 4 votes vote down vote up
private handleMsg(msg: Buffer, rinfo: RemoteInfo): void {
        if (hasHeader(msg, ResponseMessageType.LOOKUP_ADDR)) {
            const port = msg.slice(6, 8).readUInt16LE();
            const ip = `${msg[11]}.${msg[10]}.${msg[9]}.${msg[8]}`;

            this.log.debug(`Station ${this.rawStation.station_sn} - LOOKUP_ADDR - Got response`, { remoteAddress: rinfo.address, remotePort: rinfo.port, response: { ip: ip, port: port }});

            if (ip === "0.0.0.0") {
                this.log.debug(`Station ${this.rawStation.station_sn} - LOOKUP_ADDR - Got invalid ip address 0.0.0.0, ignoring response...`);
                return;
            }
            if (!this.connected) {
                if (this.connectionType === P2PConnectionType.ONLY_LOCAL) {
                    if (isPrivateIp(ip)) {
                        this._clearLookupTimeout();
                        this._clearLookupRetryTimeout();
                        this.log.debug(`Station ${this.rawStation.station_sn} - ONLY_LOCAL - Try to connect to ${ip}:${port}...`);
                        this._connect({ host: ip, port: port });
                    }
                } else if (this.connectionType === P2PConnectionType.QUICKEST) {
                    this._clearLookupTimeout();
                    this._clearLookupRetryTimeout();
                    this.log.debug(`Station ${this.rawStation.station_sn} - QUICKEST - Try to connect to ${ip}:${port}...`);
                    this._connect({ host: ip, port: port });
                }

            } else {

            }
        } else if (hasHeader(msg, ResponseMessageType.CAM_ID) || hasHeader(msg, ResponseMessageType.CAM_ID2)) {
            // Answer from the device to a CAM_CHECK message
            if (!this.connected) {
                this.log.debug(`Station ${this.rawStation.station_sn} - CAM_ID - Connected to station ${this.rawStation.station_sn} on host ${rinfo.address} port ${rinfo.port}`);
                this._clearLookupRetryTimeout();
                this._clearLookupTimeout();
                this._clearConnectTimeout();
                this.connected = true;
                this.connectTime = new Date().getTime();
                this.lastPong = null;

                this.connectAddress = { host: rinfo.address, port: rinfo.port };

                this.heartbeatTimeout = setTimeout(() => {
                    this.scheduleHeartbeat();
                }, this.getHeartbeatInterval());

                if (this.energySavingDevice) {
                    this.keepaliveTimeout = setTimeout(() => {
                        this.scheduleP2PKeepalive();
                    }, this.KEEPALIVE_INTERVAL);
                }

                this.emit("connect", this.connectAddress);

                if (Device.isLockAdvanced(this.rawStation.device_type) || Device.isLockAdvancedNoFinger(this.rawStation.device_type)) {
                    const tmpSendQueue: Array<P2PQueueMessage> = [ ...this.sendQueue ];
                    this.sendQueue = [];
                    this.sendCommandWithoutData(CommandType.CMD_GATEWAYINFO, 255);
                    this.sendCommandWithStringPayload({
                        commandType: CommandType.CMD_SET_PAYLOAD,
                        value: JSON.stringify({
                            "account_id": this.rawStation.member.admin_user_id,
                            "cmd": CommandType.P2P_QUERY_STATUS_IN_LOCK,
                            "mChannel": 0,
                            "mValue3": 0,
                            "payload": {
                                "timezone": this.rawStation.time_zone === undefined || this.rawStation.time_zone === "" ? getAdvancedLockTimezone(this.rawStation.station_sn) : this.rawStation.time_zone,
                            }}),
                        channel: 0
                    } as P2PCommand);
                    tmpSendQueue.forEach(element => {
                        this.sendQueue.push(element);
                    });
                }
                this.sendQueuedMessage();
            } else {
                this.log.debug(`Station ${this.rawStation.station_sn} - CAM_ID - Already connected, ignoring...`);
            }
        } else if (hasHeader(msg, ResponseMessageType.PONG)) {
            // Response to a ping from our side
            this.lastPong = new Date().getTime();
            return;
        } else if (hasHeader(msg, ResponseMessageType.PING)) {
            // Response with PONG to keep alive
            sendMessage(this.socket, { host: rinfo.address, port: rinfo.port }, RequestMessageType.PONG).catch((error) => {
                this.log.error(`Station ${this.rawStation.station_sn} - Error:`, error);
            });
            return;
        } else if (hasHeader(msg, ResponseMessageType.END)) {
            // Connection is closed by device
            this.log.debug(`Station ${this.rawStation.station_sn} - END - received from host ${rinfo.address}:${rinfo.port}`);
            //this._disconnected();
            this.onClose();
            return;
        } else if (hasHeader(msg, ResponseMessageType.ACK)) {
            // Device ACK a message from our side
            // Number of Acks sended in the message

            const dataTypeBuffer = msg.slice(4, 6);
            const dataType = this.getDataType(dataTypeBuffer);
            const numAcksBuffer = msg.slice(6, 8);
            const numAcks = numAcksBuffer.readUIntBE(0, numAcksBuffer.length);
            for (let i = 1; i <= numAcks; i++) {
                const idx = 6 + i * 2;
                const seqBuffer = msg.slice(idx, idx + 2);
                const ackedSeqNo = seqBuffer.readUIntBE(0, seqBuffer.length);
                // -> Message with seqNo was received at the station
                this.log.debug(`Station ${this.rawStation.station_sn} - ACK ${P2PDataType[dataType]} - received from host ${rinfo.address}:${rinfo.port} for sequence ${ackedSeqNo}`);
                const msg_state = this.messageStates.get(ackedSeqNo);
                if (msg_state && !msg_state.acknowledged) {
                    this._clearTimeout(msg_state.timeout);
                    if (msg_state.commandType === CommandType.CMD_PING || msg_state.commandType === CommandType.CMD_GET_DEVICE_PING) {
                        this.messageStates.delete(ackedSeqNo);
                    } else {
                        msg_state.acknowledged = true;
                        msg_state.timeout = setTimeout(() => {
                            //TODO: Retry command in these case?
                            this.log.warn(`Station ${this.rawStation.station_sn} - Result data for command not received`, { message: { sequence: msg_state.sequence, commandType: msg_state.commandType, nestedCommandType: msg_state.nestedCommandType, channel: msg_state.channel, acknowledged: msg_state.acknowledged, retries: msg_state.retries, returnCode: msg_state.returnCode, data: msg_state.data } });
                            this.messageStates.delete(ackedSeqNo);
                            this.emit("command", {
                                command_type: msg_state.nestedCommandType !== undefined ? msg_state.nestedCommandType : msg_state.commandType,
                                channel: msg_state.channel,
                                return_code: ErrorCode.ERROR_COMMAND_TIMEOUT,
                                property: msg_state.property
                            } as CommandResult);
                            this.sendQueuedMessage();
                            this.closeEnergySavingDevice();
                        }, this.MAX_COMMAND_RESULT_WAIT);
                        this.messageStates.set(ackedSeqNo, msg_state);
                    }
                }
            }
        } else if (hasHeader(msg, ResponseMessageType.DATA)) {
            if (this.connected) {
                const seqNo = msg.slice(6, 8).readUInt16BE();
                const dataTypeBuffer = msg.slice(4, 6);
                const dataType = this.getDataType(dataTypeBuffer);

                const message: P2PMessage = {
                    bytesToRead: msg.slice(2, 4).readUInt16BE(),
                    type: dataType,
                    seqNo: seqNo,
                    data: msg.slice(8)
                };

                this.sendAck({ host: rinfo.address, port: rinfo.port}, dataTypeBuffer, seqNo);
                this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[message.type]} - received from host ${rinfo.address}:${rinfo.port} - Processing sequence ${message.seqNo}...`);

                if (message.seqNo === this.expectedSeqNo[dataType]) {
                    // expected seq packet arrived

                    const timeout = this.currentMessageState[dataType].waitForSeqNoTimeout;
                    if (!!timeout) {
                        clearTimeout(timeout);
                        this.currentMessageState[dataType].waitForSeqNoTimeout = undefined;
                    }

                    this.expectedSeqNo[dataType] = this._incrementSequence(this.expectedSeqNo[dataType]);
                    this.parseDataMessage(message);

                    this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[message.type]} - Received expected sequence (seqNo: ${message.seqNo} queuedData.size: ${this.currentMessageState[dataType].queuedData.size})`);

                    for (const element of this.currentMessageState[dataType].queuedData.values()) {
                        if (this.expectedSeqNo[dataType] === element.seqNo) {
                            this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[element.type]} - Work off queued data (seqNo: ${element.seqNo} queuedData.size: ${this.currentMessageState[dataType].queuedData.size})`);
                            this.expectedSeqNo[dataType]++;
                            this.parseDataMessage(element);
                            this.currentMessageState[dataType].queuedData.delete(element.seqNo);
                        } else {
                            this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[element.type]} - Work off missing data interrupt queue dismantle (seqNo: ${element.seqNo} queuedData.size: ${this.currentMessageState[dataType].queuedData.size})`);
                            break;
                        }
                    }
                } else if (this.expectedSeqNo[dataType] > message.seqNo) {
                    // We have already seen this message, skip!
                    // This can happen because the device is sending the message till it gets a ACK
                    // which can take some time.
                    this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[message.type]} - Received already processed sequence (seqNo: ${message.seqNo} queuedData.size: ${this.currentMessageState[dataType].queuedData.size})`);
                    return;
                } else {
                    if (!this.currentMessageState[dataType].waitForSeqNoTimeout)
                        this.currentMessageState[dataType].waitForSeqNoTimeout = setTimeout(() => {
                            //TODO: End stream doesn't stop device for sending video and audio data
                            this.endStream(dataType);
                            this.currentMessageState[dataType].waitForSeqNoTimeout = undefined;
                        }, this.MAX_EXPECTED_SEQNO_WAIT);

                    if (!this.currentMessageState[dataType].queuedData.get(message.seqNo)) {
                        this.currentMessageState[dataType].queuedData.set(message.seqNo, message);
                        this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[message.type]} - Received not expected sequence, added to the queue for future processing (seqNo: ${message.seqNo} queuedData.size: ${this.currentMessageState[dataType].queuedData.size})`);
                    } else {
                        this.log.debug(`Station ${this.rawStation.station_sn} - DATA ${P2PDataType[message.type]} - Received not expected sequence, discarded since already present in queue for future processing (seqNo: ${message.seqNo} queuedData.size: ${this.currentMessageState[dataType].queuedData.size})`);
                    }
                }
            }
        } else if (hasHeader(msg, ResponseMessageType.LOOKUP_ADDR2)) {
            if (!this.connected) {
                const port = msg.slice(6, 8).readUInt16LE();
                const ip = `${msg[11]}.${msg[10]}.${msg[9]}.${msg[8]}`;
                const data = msg.slice(20, 24);

                this._clearLookupTimeout();
                this._clearLookupRetryTimeout();

                this.log.debug(`Station ${this.rawStation.station_sn} - LOOKUP_ADDR2 - Got response`, { remoteAddress: rinfo.address, remotePort: rinfo.port, response: { ip: ip, port: port, data: data.toString("hex") }});
                this.log.debug(`Station ${this.rawStation.station_sn} - CHECK_CAM2 - Connecting to host ${ip} on port ${port}...`);

                for (let i = 0; i < 4; i++)
                    this.sendCamCheck2({ host: ip, port: port }, data);

                this._startConnectTimeout();

                sendMessage(this.socket, { host: ip, port: port }, RequestMessageType.UNKNOWN_70).catch((error) => {
                    this.log.error(`Station ${this.rawStation.station_sn} - UNKNOWN_70 - Error:`, error);
                });
            }
        } else if (hasHeader(msg, ResponseMessageType.UNKNOWN_71)) {
            if (!this.connected) {
                this.log.debug(`Station ${this.rawStation.station_sn} - UNKNOWN_71 - Got response`, { remoteAddress: rinfo.address, remotePort: rinfo.port, response: { message: msg.toString("hex"), length: msg.length }});

                sendMessage(this.socket, { host: rinfo.address, port: rinfo.port }, RequestMessageType.UNKNOWN_71).catch((error) => {
                    this.log.error(`Station ${this.rawStation.station_sn} - UNKNOWN_71 - Error:`, error);
                });
            }
        } else if (hasHeader(msg, ResponseMessageType.UNKNOWN_73)) {
            if (!this.connected) {
                const port = msg.slice(8, 10).readUInt16BE();
                const data = msg.slice(4, 8);

                this.log.debug(`Station ${this.rawStation.station_sn} - UNKNOWN_73 - Got response`, { remoteAddress: rinfo.address, remotePort: rinfo.port, response: { port: port, data: data.toString("hex") }});

                this.lookup2({ host: rinfo.address, port: port }, data);
            }
        } else if (hasHeader(msg, ResponseMessageType.UNKNOWN_81) || hasHeader(msg, ResponseMessageType.UNKNOWN_83)) {
            // Do nothing / ignore
        } else if (hasHeader(msg, ResponseMessageType.LOOKUP_RESP)) {
            if (!this.connected) {
                const responseCode = msg.slice(4, 6).readUInt16LE();

                this.log.debug(`Station ${this.rawStation.station_sn} - LOOKUP_RESP - Got response`, { remoteAddress: rinfo.address, remotePort: rinfo.port, response: { responseCode: responseCode }});

                if (responseCode !== 0 && this.lookupTimeout !== undefined && this.lookupRetryTimeout === undefined) {
                    this.lookupRetryTimeout = setTimeout(() => {
                        this.lookupRetryTimeout = undefined;
                        this.cloudAddresses.map((address) => this.lookupByAddress(address));
                    }, this.LOOKUP_RETRY_TIMEOUT);
                }
            }
        } else {
            this.log.debug(`Station ${this.rawStation.station_sn} - received unknown message`, { remoteAddress: rinfo.address, remotePort: rinfo.port, response: { message: msg.toString("hex"), length: msg.length }});
        }
    }