Nmap Development mailing list archives

Re: Nsock unconnected sockets


From: David Fifield <david () bamsoftware com>
Date: Mon, 4 Oct 2010 20:18:54 -0700

On Mon, Oct 04, 2010 at 09:17:07PM -0500, Kris Katterjohn wrote:
On 10/04/2010 10:52 AM, David Fifield wrote:
On Sun, Oct 03, 2010 at 10:03:41PM -0500, Kris Katterjohn wrote:
I can't think of a better separate function name right now either, but an API
change of something like

nmap.new_socket(<proto>, <family>)

with optional arguments is what I first thought of as an alternative because
your "setup" is akin to an actual socket() call anyway.

Yes, that's a good interface. It is more magical though. Normally after
calling new_socket you have only an Nsock iod, not a real socket that
you can start sending on. The socket doesn't appear until you connect.
I'm afraid that adding parameters to new_socket will make people think
that they should do

s = nmap.new_socket("tcp")
s:connect(host, port, "tcp")

when that would be wrong and would actually have created a socket twice.

However, I'm not sure if setup() can be called multiple times or not, or if
new sockets should be created (in fact, I'm not sure about connect either).

I think that connect and setup both leak a socket if you call them twice
without closing. But that can be fixed.

Well, given that scripts shouldn't be connecting multiple times (which leads
me to believe there should be one connect() for each new_socket()), then a
possibility is this:

s = nmap.new_socket(<protocol>, <optional family>)
s:connect(host, port) -- remove/deprecate protocol arg

This has a little bit of a problem, though, which is the address family.
Currently you can do

s = nmap.new_socket()
s:connect("::1", 80)

and it will work fine. If OS socket creation always happens when
new_socket is called, then it becomes necessary to declare the address
family in advance (even if implicit). Consider that someone may give an
address in a script argument--then it becomes necessary to analyze its
address family before calling new_socket.

Another thing to consider is that at least one function, bind, needs to
be called before the socket is connected.

Doing it the way you propose would make things easier internally. Having
a real socket would mean that socket options don't have to be cached and
applied later.

I expect that connected sockets will be used far more often. So it makes
sense to make the shorter and simpler code favor that. Having an extra
line for an unconnected socket is a tip-off that something unusual is
going on.

As I was mentioning, scripts (I suppose) aren't changing between TCP and UDP
connect()s on the same socket without closing (or at all).  So specifying the
protocol in new_socket() for the life of the socket shouldn't be a problem for
current scripts.

I think your intuition is right on this.

A socket just created with new_socket() is (I think) essentially useless until
you connect it or "setup" it, so I'm not sure we're losing much in that.
Scripts should know what protocol they want to use by the time they call
new_socket() anyway.  For example, scripts shouldn't call new_socket() and
immediately pass it to some function for connecting when the function can
create it itself (I'm trying to think of any reason why new_socket() calls and
connect() calls may legitimately not be in sync).

The argument against immediate connect/setup is that it leaves no chance
to call bind or set_timeout. I suppose these could be made into
additional arguments to new_socket.

David FIfield
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: