85694

How can I reset a TCP socket in Python?

Question:

I have a socket proxy written in Python which when it receives a RST from a pair of communicating peers will close the connection to both peers by letting the sockets be garbage collected. This results in the other peer seeing a FIN rather than a RST.

This means the proxy effectively translates RST into FIN, which I don't think is ideal.

I found that in Linux it possible to <a href="https://stackoverflow.com/a/46264137/3476849" rel="nofollow">reset a TCP connnection</a> by calling connect with an address of family AF_UNSPEC. But I haven't found a way to do this from a Python program.

How do I connect to an AF_UNSPEC address in Python?

<strong>What I have tried so far</strong>

I tried looking at the help output for the relevant connect method and found this:

Help on built-in function connect: connect(...) connect(address) Connect the socket to a remote address. For IP sockets, the address is a pair (host, port).

Unfortunately that doesn't tell me what the address argument has to be in order to construct a AF_UNSPEC address.

I attempted to wrap the original socket fd in a new socket object with family AF_UNSPEC like this:

socket.fromfd(s.fileno(), socket.AF_UNSPEC, 0)

The resulting object produce the same help text and any attempt to call connect on the newly constructed socket object results in

socket.error: getsockaddrarg: bad family

So it looks like using socket.fromfd is probably not the answer to my question.

Answer1:

Looking at the current socket package <a href="https://github.com/python/cpython/blob/6f9bc72c79c3262e5d0f2c0e96b016477399cfb1/Modules/socketmodule.c#L3183" rel="nofollow">implementation</a> in CPython, there is really no pythonic way (to connect a socket to an AF_UNSPEC address, as of 2019-01 (i.e. to <a href="https://stackoverflow.com/a/46264137/427158" rel="nofollow">reset the connection on Linux</a>).

The next best thing is to set the SO_LINGER option on the accepted socket (either directly or via inheritance). When lingering is enabled (and set to a zero timeout) closing the socket yields a reset of the connection.

You have to be careful to set the SO_LINGER option on the right sockets API level and to use the right encoding for the option value (it's a struct).

Example:

import socket import struct import time s = socket.socket(socket.AF_INET6) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) # if we want to inherit this option: #s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) s.bind(('', 2323)) s.listen() con, addr = s.accept() con.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) time.sleep(1) con.close() time.sleep(3)

Connecting to this port with curl:

$ curl localhost:2323 curl: (56) Recv failure: Connection reset by peer

Connecting to this port without sending anything:

$ socat - tcp:localhost:2323

When dumping the packets with e.g.

$ tshark -i lo -f 'tcp port 2323'

the last packet should be a RST (sent from server to client), in both cases - for example:

39 9758.478140247 127.0.0.1 → 127.0.0.1 TCP 66 2323 → 34494 [RST, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=2787120418 TSecr=2787119417

Answer2:

You can try to use the SO_LINGER socket option ( setsockopt ) with linger time set to 0. close on socket with SO_LINGER set with 0 seconds lingering time will result in RST instead of FIN.

Recommend

  • Send/Receive Intents in the same class
  • Moving an Android Studio project causes an error
  • Show Spinner When Teble Row Click
  • /.git/hooks/: No such file or directory protocol error: expected control record on Mac osx
  • C function always returns zero to Objective C
  • Input field doesn't receive keyboard events when rendering with value property?
  • Linq-to-SQL to search only DATE portions of a date
  • Taxonomy is not working
  • What I can use subquery instead for search MAX()?
  • Comparing a large set of images by content
  • Bash script to bring up and down an interface on loop
  • Vue.js 2: Vue cannot find files from /assets folder (v-for)
  • .htaccess redirect domain.com to www.domain.com
  • Simultaneous animation when entering editing mode of UITableViewCell
  • internal javascript not works in angular2
  • Synchronous Calls with jqGrid?
  • Find all parks for a given zipcode with google maps
  • readmore button or show/hide for php
  • how can i get selectedRange.location value?
  • SQL Server 2012 not showing unicode character in results
  • Multiplying polynomials/simplifying like terms
  • Creating 2d platforms using JavaScript
  • Tensorflow Dataset API restore Iterator after completing one epoch
  • How to define something in JavaScript [closed]
  • How to split wav file into two or more parts using c#
  • Is there a better way for handling SpatialPolygons that cross the antimeridian (date line)?
  • Calculate time from document
  • Amazon Elastick BeanStalk error: Failed to create the AWS Elastic Beanstalk application version
  • Android: Unable to detect vertical plane
  • How to decleare char *const argv[] in swift [duplicate]
  • What is the best way to cache and reuse immutable singleton objects in Java?
  • calling IO Operations from thread in ruby c extension will cause ruby to hang
  • Excel VBA : conditional formatting of sheet1 cells from sheet2 values in excel 2007
  • Grails - How to implement a foreign key relationship not using an id column?
  • Sql - ON DUPLICATE KEY UPDATE
  • Firebase: How to read from external DB?
  • WPF custom control and direct content support
  • Create/delete users from text file using Bash script
  • Time Complexity of Fibonacci Algorithm [duplicate]
  • How to check if object is null in Java?