0

I'm trying to make a python function that scans a range of addresses. I started a socket and pass the socket as an argument to the function that connects to it:

def scan(socket, address, port):
    c = socket.connect_ex((address, port))
    print(c)

then I call scan for each address, each in its own thread. I'm getting Error 114: Operation already in progress..

Do I need to start a new socket for each connection? I'm trying to read about socket reusage, and I found that there exists flags like SO_ADDREUSE or something like that. I tried to insert but it didn't work.

I'm trying to think how a socket works. I think the moment I create one, it choses a tcp source port, and then when I create a connection, it sends to a destination port. I think I can't reuse the same socket because the source port would be the same for all destination ports, so the clients would answer to the same port and would cause confusion.

So do I need to create a new socket for each connection?

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Read [ALP](http://www.cse.hcmut.edu.vn/~hungnq/courses/nap/alp.pdf) & [socket(7)](http://man7.org/linux/man-pages/man7/socket.7.html) & [ip(7)](http://man7.org/linux/man-pages/man7/ip.7.html) & [tcp(7)](http://man7.org/linux/man-pages/man7/tcp.7.html) – Basile Starynkevitch Jan 10 '18 at 05:47

3 Answers3

1

Do I need to start a new socket for each connection?

Yes.

I'm trying to read about socket reusage

There is no such thing as 'socket reusage'. There is port reuse. Not the same thing. You cannot reconnect an existing socket once you've tried to connect it, even if the connect attempt failed.

I found that there exists flags like SO_ADDREUSE or something like that

SO_REUSEADDR means to reuse the port. Not the socket.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
user207421
  • 305,947
  • 44
  • 307
  • 483
1

You can not connect stream socket multiple times.

One of the connect possible errors is EISCONN.

The socket is already connected.

This goes for stream sockets.

man bind also has this:

[EINVAL] The socket is already bound to an address, and the protocol does not support binding to a new address; or the socket has been shut down.

Again, this goes for stream sockets.

From the man connect:

Generally, stream sockets may successfully connect() only once; datagram sockets may use connect() multiple times to change their association.

I made emphasis on the important line.

stream sockets can not be connected multiple times. datagram sockets can be connected multiple times. Generally speaking, BSD sockets have multiple protocols, types, domains avaible. You shall read documentation for your particular case.

P.S Get yourself familiar with the readings that were suggested in the comment to your question. That will explain enough to manipulate socket family of functions.

user14063792468
  • 839
  • 12
  • 28
0

I'm trying to think how a socket works. I think the moment I create one, it choses a tcp source port,

Between creating a socket using the socket() system call and using it to create an outgoing connection with the connect() system call, there is an opportunity to optionally use the bind() system call to set source IP address and/or port if you want to. If you don't use bind(), the operating system will automatically bind the socket to the first available port in the appropriate range when you use the connect() system call. In this case, the source IP address is normally selected to match the network interface that provides the shortest route to the specified destination according to the routing table.

At least, that's how it works at the system call level. Some programming languages or libraries may choose to combine some of these operations into one.

To your actual question, man 7 ip says:

A TCP local socket address that has been bound is unavailable for some time after closing, unless the SO_REUSEADDR flag has been set. Care should be taken when using this flag as it makes TCP less reliable.

The idea is to delay the re-use of a port until any possible re-sent copies of packages that belonged to the closed connection have for sure expired on the network.

According to the bind() man page, trying to re-bind a socket that is already bound to an address will result in an EINVAL error. So "recycling" a socket using bind(socket, INADDR_ANY, 0) (after ending a connection that used SO_REUSEADDR) does not seem to be possible.

And even if that would be possible, when you're using multiple threads on a modern multi-core system, you end up (very probably) doing multiple things in parallel. A socket can be used for just one outgoing connection at a time. Each of your scan threads will need its own socket.

telcoM
  • 229
  • 3
  • 12
  • 1
    I think `SO_REUSEADDR` is about reusing the TCP/IP address, not the socket as a system construct. – ilkkachu Jan 09 '18 at 14:33
  • There is no such thing as 'the re-use of a socket'. You are confusing socket reuse, which doesn't exist, with port reuse, which does. – user207421 Jan 10 '18 at 05:51
  • Duh! I was trying to point that out, but had a brainfart in one essential sentence. Fixed. – telcoM Jan 10 '18 at 07:13