How to forcibly reset a socket in Node.js?

戏子无情 提交于 2019-12-07 09:59:32

There's no perfect solution to this, as far as I can tell, but I've found two options for this, and filed a bug against Node to add proper support.

For my problem (start an HTTP request, then RST the socket) I found two solutions:

Destroy the socket just before receiving a packet

const net = require('net');

const socket = new net.Socket();
socket.connect(8000, "127.0.0.1", () => {
    socket.write(
        'GET / HTTP/1.1\n' +
        'Host: example.com\n\n'
    );
    setTimeout(() => socket.destroy(), 0);
});

If you know you're about to receive a packet on this connection, you can destroy() the socket immediately beforehand. This does not send an RST, but will send an RST in response to future packets.

To do this, you need to race to destroy the socket after your message is written, but before the response arrives. For local connections especially this can be tricky - the setTimeout(() => socket.destroy(), 0) is the most reliable solution I've found, but YMMV, and it's certainly not guaranteed. I expected the write() callback to work more reliably, but it doesn't seem to.

Use another language (i.e. Python)

For me, I've now fallen back to using Python for testing, since it has direct control for this. To send a RST packet in Python:

import socket
import time
import struct

TCP_IP = '127.0.0.1'
TCP_PORT = 8000

# Connect to the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s.connect((TCP_IP, TCP_PORT))

# Start an HTTP request
s.send("GET / HTTP/1.1\r\n\
Host: example.com\r\n\
\r\n")
time.sleep(0.1)

# RST the socket without reading the response
# See https://stackoverflow.com/a/6440364/68051 for context
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
s.close()

Hopefully the Node team will take a look at adding similar support soon (see https://github.com/nodejs/node/issues/27428), but the above may be helpful in the meantime.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!