views:

2969

answers:

4

Ok first of all I like to mention what im doing is completely ethical and yes I am port scanning.

The program runs fine when the port is open but when I get to a closed socket the program halts for a very long time because there is no time-out clause. Below is the following code

int main(){

 int err, net;
 struct hostent *host;
 struct sockaddr_in sa;

 sa.sin_family = AF_INET;

 sa.sin_port = htons(xxxx);
 sa.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");

 net = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 err = connect(net, (struct sockaddr *)&sa, sizeof(sa));

 if(err >= 0){ cout << "Port is Open"; }
 else { cout << "Port is Closed"; }

}

I found this on stack overflow but it just doesn't make sense to me using a select() command.

Question is can we make the connect() function timeout so we dont wait a year for it to come back with an error?

+5  A: 

The easiest is to setup an alarm and have connect be interrupted with a signal (see UNP 14.2):


signal( SIGALRM, connect_alarm ); /* connect_alarm is you signal handler */
alarm( secs ); /* secs is your timeout in seconds */
if ( connect( fs, addr, addrlen ) < 0 )
{
    if ( errno == EINTR ) /* timeout */
        ...
}
alarm( 0 ); /* cancel alarm */

Though using select is not much harder :)
You might want to learn about raw sockets too.

Nikolai N Fetissov
Thanks, That worked i had to look at the alarm and the signal thing to understand how that works but none the less, it does what i asked on the tin. Thanks :D
Shahmir Javaid
`sigaction` should be generally preferred to `signal`, which has different behaviors on different UNIXes.
ephemient
That's true, the code was directly quoted from Stevens.
Nikolai N Fetissov
@Shahmir Javaid: Did you manage to make the connect_alarm? I am seeing it and I don't understand how it works...
NeDark
Didnt work for me, I ended up using Rude Sockets
Shahmir Javaid
Hmm, what exactly did not work?
Nikolai N Fetissov
+2  A: 

If you're dead-set on using blocking IO to get this done, you should investigate the setsockopt() call, specifically the SO_SNDTIMEO flag (or other flags, depending on your OS).

Be forewarned these flags are not reliable/portable and may be implemented differently on different platforms or different versions of a given platform.

The traditional/best way to do this is via the nonblocking approach which uses select(). In the event you're new to sockets, one of the very best books is TCP/IP Illustrated, Volume 1: The Protocols. It's at Amazon at: http://www.amazon.com/TCP-Illustrated-Protocols-Addison-Wesley-Professional/dp/0201633469

DarkSquid
+1  A: 

RudeSocket Solved the Problem

I found a lib file that is tested in linux Fedora (Not Sure about Windows) that gives me the option of timeout. Below you can find a very simple Example.

#include <rude/socket.h>
#include <iostream>

using namespace std;
using namespace rude;

Socket soc;
soc.setTimeout(30, 5);

//Try connecting
if (soc.connect("xxx.xxx.xxx.xxx", 80)){

 cout << "Connected to xxx.xxx.xxx.xxx on Port " << 80 << "\n";
}

//connections Failed
else{
 cout << "Timeout to xxx.xxx.xxx.xxx on Port " << 80 << "\n";
}

soc.close();

Here is a link to the DevSite

Shahmir Javaid
A: 

http://rudeserver.com/socket/download.html The link of download .RPM is broken :-s

zkizzik
Oh god.. havent done this in ages. you should be able to yum install rudesocket-1.3.0-2fc9 and rudesocket-devel-1.3.0-2.fc9 You , you need bothe of them
Shahmir Javaid
if you go to rudeserver.com and email the developer he was nice enough to attach the copies and email me. And yes to confirm the link is broken
Shahmir Javaid