Hi,

I observed a strange behavior with the minisocks in the linux-2.6.16 kernel.

Here is the scenario:

- The server creates a socket, bind, listen and wait indefinitly.

- The client creates a socket, does a bind, connects to the server, sends data and closes the connection. It waits 61 seconds and does the same again (with same bind address).

Since this moment, any client trying to connect to the server (eg. telnet) receives the SYN|ACK from the server but the ACK is lost by the server and the connection stays in the SYN_RECV state in the server side.

It seems that there are two sockets in the req queue which are <SS_FREE,TCP_CLOSE_WAIT> and <SS_FREE,TCP_CLOSE> with the same tuple (src_addr, src_port, dst_addr, dst_port).

This behavior does not occurs, if the client sets the setsockopt reuse addr option with the second connection.

Joined to this email, client and server written in Python.

 --Daniel
#! /usr/bin/env python

import os
import sys
import socket
import time
import getopt
import string

def usage(procname):
    print(os.path.basename(procname) + " --local=<ip> --remote=<ip> --port=<port>")

try:
    opts, args = getopt.getopt(sys.argv[1:], "", ["local=", "remote=", "port="])

except getopt.GetoptError:
        usage(sys.argv[0])
        sys.exit(2)

local  = ""
remote = ""
port   = ""

for o, a in opts:
    
    if o in ("-l", "--local"):
        local=a
    if o in ("-r", "--remote"):
        remote=a
    if o in ("-p", "--port"):
        port=a

if local == "" or remote == "" or port == "": 
    usage(sys.argv[0])
    sys.exit(2)

# -----------------------------------------------------------------------------
try:
    # first connection
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(1,2,1) # REUSE_ADDR
    s.bind((local,int(port)))
    s.connect((remote,int(port)))
    print "Binded to " + local + ":" + port
    print "Connected to " + remote + ":" + port
    s.send("Hello world ! ")
    s.close()
    print "Disconnected from " + remote + ":" + port

    # Wait some time for FIN_WAIT2
    print "Waiting 61 secs..."
    time.sleep(61)
    
    # second connection
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((local,int(port)))
    s.connect((remote,int(port)))
    s.send("Hello world ! ")
    s.close()

    # server is now in 'strange' state
    print "ok, now try with telnet " + remote + " " + port + " and look in server side "
    time.sleep(3600)
    sys.exit(0)

except socket.error, msg:
    print msg
    sys.exit(1)

#! /usr/bin/env python

import os
import sys
import socket
import time
import getopt
import string

def usage(procname):
    print(os.path.basename(procname) + " --local=ipaddress --port=port")

try:
    opts, args = getopt.getopt(sys.argv[1:], "", [ "local=", "port="])

except getopt.GetoptError:
        usage(sys.argv[0])
        sys.exit(2)

local = ""
port  = ""

for o, a in opts:
        if o in ("-l", "--local"):
            local=a
        if o in ("-p", "--port"):
            port=a

if local == "" or port == "": 
    usage(sys.argv[0])
    sys.exit(2)

# -----------------------------------------------------------------------------
try:
    # Create the listen point
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(1,2,1)
    s.bind((local,int(port)))
    s.listen(10)

    # Does nothing and rely on the TCP stack for incoming connections
    print "Ok, ready."
    time.sleep(3600)

except socket.error, msg:
    print msg


Reply via email to