Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket Timeout in C++ Linux

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?

like image 818
Angel.King.47 Avatar asked May 31 '09 23:05

Angel.King.47


3 Answers

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.

like image 168
Nikolai Fetissov Avatar answered Oct 20 '22 12:10

Nikolai Fetissov


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

like image 27
DarkSquid Avatar answered Oct 20 '22 12:10

DarkSquid


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

like image 1
Angel.King.47 Avatar answered Oct 20 '22 12:10

Angel.King.47