Jump to page: 1 2
Thread overview
Checking if a port is listening
Mar 16, 2016
Lucien
Mar 16, 2016
Anonymouse
Mar 17, 2016
Marc Schütz
Mar 17, 2016
Anonymouse
Mar 17, 2016
Lucien
Mar 18, 2016
Marc Schütz
Mar 19, 2016
Timothee Cour
Mar 19, 2016
Lucien
Mar 19, 2016
Marc Schütz
Mar 19, 2016
Lucien
Mar 23, 2016
Lucien
Mar 24, 2016
Marc Schütz
Mar 24, 2016
Lucien
Mar 26, 2016
Lucien
March 16, 2016
Hello,

I want to know if a port of an ip address is listening, actually, I've this :
http://pastebin.com/pZhm0ujy
(checking port 22/ssh)

It works, but it took me ~10min to scan 30 addresses.

How can reduce the expiration delay ?
March 16, 2016
On Wednesday, 16 March 2016 at 20:44:12 UTC, Lucien wrote:
> Hello,
>
> I want to know if a port of an ip address is listening, actually, I've this :
> http://pastebin.com/pZhm0ujy
> (checking port 22/ssh)
>
> It works, but it took me ~10min to scan 30 addresses.
>
> How can reduce the expiration delay ?

I don't know if they apply here, but you can lower the send and receive timeouts for the socket. I'm not sure which (or if either) of them you want to tweak.

https://dlang.org/library/std/socket/socket_option.html


import core.thread;  // for .seconds
s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds);
s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds);


I guess you could also use a non-blocking socket and decide yourself when enough time has passed to declare it a failed attempt.
March 17, 2016
On Wednesday, 16 March 2016 at 22:22:15 UTC, Anonymouse wrote:
> import core.thread;  // for .seconds

Nitpick: `seconds` is defined in `core.time`; `core.thread` just reexports it.

> s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds);
> s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds);

March 17, 2016
On Thursday, 17 March 2016 at 10:41:55 UTC, Marc Schütz wrote:
> On Wednesday, 16 March 2016 at 22:22:15 UTC, Anonymouse wrote:
>> import core.thread;  // for .seconds
>
> Nitpick: `seconds` is defined in `core.time`; `core.thread` just reexports it.
>
>> s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds);
>> s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds);

Er, yes, didn't think that through properly.
March 17, 2016
On Wednesday, 16 March 2016 at 22:22:15 UTC, Anonymouse wrote:
> On Wednesday, 16 March 2016 at 20:44:12 UTC, Lucien wrote:
>> Hello,
>>
>> I want to know if a port of an ip address is listening, actually, I've this :
>> http://pastebin.com/pZhm0ujy
>> (checking port 22/ssh)
>>
>> It works, but it took me ~10min to scan 30 addresses.
>>
>> How can reduce the expiration delay ?
>
> I don't know if they apply here, but you can lower the send and receive timeouts for the socket. I'm not sure which (or if either) of them you want to tweak.
>
> https://dlang.org/library/std/socket/socket_option.html
>
>
> import core.thread;  // for .seconds
> s.setOption(SocketOptionLevel.SOCKET, SNDTIMEO, 10.seconds);
> s.setOption(SocketOptionLevel.SOCKET, RCVTIMEO, 10.seconds);
>
>
> I guess you could also use a non-blocking socket and decide yourself when enough time has passed to declare it a failed attempt.

When it's non-blocking, all adresses have the open 22 open, but it isn't the case..

When I setOption like you said, it's too long.

Is there a good technique ?
nmap can do it in only ~2 seconds.

My current code :
--------------------------------------------------------

import std.process;
import std.socket;

import core.time;

// ...

// 32 for the moment
for (int i = 1; i < 32; i++) {
    string ip = "192.168.0."~to!string(i);
    Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP);
    s.blocking = false;
    //s.setOption(SocketOptionLevel.SOCKET, SocketOption.SNDTIMEO, 1.seconds);
    //s.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, 1.seconds);
    InternetAddress ia = new InternetAddress(ip, 22);
    try {
        s.connect(ia);
        writeln("\nDONE: ", ip, ":22");
    } catch (Exception e) {
        writeln("\n\nFAIL: ", ip, ":22 is unreachable :\n", e.toString(), "\n");
    }
    s.close();
}

// ...

-------------------------------------
March 18, 2016
Looking at an strace of nmap, it seems it opens a bunch of sockets, puts them into non-blocking mode, calls connect on them (which will return EINPROGRESS), and then uses select(2) to wait for them (in a loop, until all have either been accepted or rejected). select(2) accepts a timeout value, so you can determine how long you want to wait.

Here's an excerpt:

...
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 50
fcntl(50, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation not permitted)
setsockopt(50, SOL_IP, IP_TTL, [-1], 4) = 0
connect(50, {sa_family=AF_INET, sin_port=htons(32778), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 51
fcntl(51, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation not permitted)
setsockopt(51, SOL_IP, IP_TTL, [-1], 4) = 0
connect(51, {sa_family=AF_INET, sin_port=htons(1029), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 52
fcntl(52, F_GETFL)                      = 0x2 (flags O_RDWR)
fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation not permitted)
setsockopt(52, SOL_IP, IP_TTL, [-1], 4) = 0
connect(52, {sa_family=AF_INET, sin_port=htons(2013), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
select(53, [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], {0, 0}) = 100 (in [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], out [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], left {0, 0})
...

I'm pretty sure the setsockopt() calls aren't essential.
March 18, 2016
see also:
https://github.com/rejectedsoftware/vibe.d/issues/1431 api to find an
available port




On Fri, Mar 18, 2016 at 2:50 AM, Marc Schütz via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:

> Looking at an strace of nmap, it seems it opens a bunch of sockets, puts
> them into non-blocking mode, calls connect on them (which will return
> EINPROGRESS), and then uses select(2) to wait for them (in a loop, until
> all have either been accepted or rejected). select(2) accepts a timeout
> value, so you can determine how long you want to wait.
>
> Here's an excerpt:
>
> ...
> socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 50
> fcntl(50, F_GETFL)                      = 0x2 (flags O_RDWR)
> fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
> setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
> setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation
> not permitted)
> setsockopt(50, SOL_IP, IP_TTL, [-1], 4) = 0
> connect(50, {sa_family=AF_INET, sin_port=htons(32778),
> sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in
> progress)
> socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 51
> fcntl(51, F_GETFL)                      = 0x2 (flags O_RDWR)
> fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
> setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
> setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation
> not permitted)
> setsockopt(51, SOL_IP, IP_TTL, [-1], 4) = 0
> connect(51, {sa_family=AF_INET, sin_port=htons(1029),
> sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in
> progress)
> socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 52
> fcntl(52, F_GETFL)                      = 0x2 (flags O_RDWR)
> fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
> setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
> setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation
> not permitted)
> setsockopt(52, SOL_IP, IP_TTL, [-1], 4) = 0
> connect(52, {sa_family=AF_INET, sin_port=htons(2013),
> sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in
> progress)
> select(53, [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
> 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
> 51 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
> 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
> 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
> 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
> 52], {0, 0}) = 100 (in [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
> 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
> 47 48 49 50 51 52], out [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
> 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
> 47 48 49 50 51 52], left {0, 0})
> ...
>
> I'm pretty sure the setsockopt() calls aren't essential.
>


March 19, 2016
On Friday, 18 March 2016 at 09:50:12 UTC, Marc Schütz wrote:
> Looking at an strace of nmap, it seems it opens a bunch of sockets, puts them into non-blocking mode, calls connect on them (which will return EINPROGRESS), and then uses select(2) to wait for them (in a loop, until all have either been accepted or rejected). select(2) accepts a timeout value, so you can determine how long you want to wait.
>
> Here's an excerpt:
>
> ...
> socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 50
> fcntl(50, F_GETFL)                      = 0x2 (flags O_RDWR)
> fcntl(50, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
> setsockopt(50, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
> setsockopt(50, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation not permitted)
> setsockopt(50, SOL_IP, IP_TTL, [-1], 4) = 0
> connect(50, {sa_family=AF_INET, sin_port=htons(32778), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
> socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 51
> fcntl(51, F_GETFL)                      = 0x2 (flags O_RDWR)
> fcntl(51, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
> setsockopt(51, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
> setsockopt(51, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation not permitted)
> setsockopt(51, SOL_IP, IP_TTL, [-1], 4) = 0
> connect(51, {sa_family=AF_INET, sin_port=htons(1029), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
> socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 52
> fcntl(52, F_GETFL)                      = 0x2 (flags O_RDWR)
> fcntl(52, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
> setsockopt(52, SOL_SOCKET, SO_LINGER, {onoff=1, linger=0}, 8) = 0
> setsockopt(52, SOL_SOCKET, SO_BINDTODEVICE, [0], 4) = -1 EPERM (Operation not permitted)
> setsockopt(52, SOL_IP, IP_TTL, [-1], 4) = 0
> connect(52, {sa_family=AF_INET, sin_port=htons(2013), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
> select(53, [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], {0, 0}) = 100 (in [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], out [3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52], left {0, 0})
> ...
>
> I'm pretty sure the setsockopt() calls aren't essential.

I tried:

------------------------------------------
// ...
    const int MAX = 64;
    Socket[] sockets = new Socket[MAX];
    string ipb = "192.168.0.";

    for (int i = 1; i < MAX; i++) {
        string ip = ipb~to!string(i);

        Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP);
        s.blocking = false;
        sockets[i] = s;
        InternetAddress ia = new InternetAddress(ip, 22);
        s.connect(ia);
    }

    foreach (int i, Socket s; sockets)
    {
        SocketSet ss = new SocketSet();
        //ss.add(s);
        if (s.select(ss, null, null, 500.msecs) > 0)
        {
            writeln("\n\nDONE: ", ipb~to!string(i), ":22");
        }
        else
        {
            writeln("\n\nFAIL: ", ipb~to!string(i), ":22 is unreachable !\n");
        }
    }
    writeln("DONE");
------------------------------------------

When I uncomment ss.add(s); , I got the error -11.
Any suggestions ?
March 19, 2016
On Saturday, 19 March 2016 at 09:55:13 UTC, Lucien wrote:
>     const int MAX = 64;
>     Socket[] sockets = new Socket[MAX];
>     string ipb = "192.168.0.";
>
>     for (int i = 1; i < MAX; i++) {

Here's the reason for your SEGV: You need to start at 0, because otherwise `sockets[0]` is `null`. When you add that to the SocketSet, it will trigger the segfault. I guess you want to skip the 0 because it represents the subnet address; in that case, you simply mustn't add `sockets[0]` to the set.

But then there is another problems: You're using `select()` the wrong way. The point of using select() is that you can check things asynchronously. Your code should be structured like this (pseudo code):

auto ss = new SocketSet();
for(i; 1 .. MAX) {
    auto s = new Socket(...);
    s.blocking = false;
    s.connect(...);
    ss.add(s);
}

while(ss.count > 0) {
    auto write_ss = ss.dup;
    auto status = Socket.select(null /* read */, write_ss /* write */, null /* error */, 500.msecs);
    // for a connect()ing socket, writeability means connected
    if(status < 0)
        writeln("interrupted, retrying");
    else if(status == 0)
        writeln("timeout, retrying");
    else {
        writeln(status, " socket(s) changed state");
        for(fd; 0 .. write_ss.maxfd+1) {
            // check whether this socket has changed
            if(!write_ss.isSet(fd)) continue;
            // if yes, remove it from the original SocketSet
            ss.remove(fd);
            writeln("successfully connected to 192.168.0.", fd+1);
        }
    }
}
March 19, 2016
On Saturday, 19 March 2016 at 18:24:38 UTC, Marc Schütz wrote:
> On Saturday, 19 March 2016 at 09:55:13 UTC, Lucien wrote:
>>     const int MAX = 64;
>>     Socket[] sockets = new Socket[MAX];
>>     string ipb = "192.168.0.";
>>
>>     for (int i = 1; i < MAX; i++) {
>
> Here's the reason for your SEGV: You need to start at 0, because otherwise `sockets[0]` is `null`. When you add that to the SocketSet, it will trigger the segfault. I guess you want to skip the 0 because it represents the subnet address; in that case, you simply mustn't add `sockets[0]` to the set.
>
> But then there is another problems: You're using `select()` the wrong way. The point of using select() is that you can check things asynchronously. Your code should be structured like this (pseudo code):
>
> auto ss = new SocketSet();
> for(i; 1 .. MAX) {
>     auto s = new Socket(...);
>     s.blocking = false;
>     s.connect(...);
>     ss.add(s);
> }
>
> while(ss.count > 0) {
>     auto write_ss = ss.dup;
>     auto status = Socket.select(null /* read */, write_ss /* write */, null /* error */, 500.msecs);
>     // for a connect()ing socket, writeability means connected
>     if(status < 0)
>         writeln("interrupted, retrying");
>     else if(status == 0)
>         writeln("timeout, retrying");
>     else {
>         writeln(status, " socket(s) changed state");
>         for(fd; 0 .. write_ss.maxfd+1) {
>             // check whether this socket has changed
>             if(!write_ss.isSet(fd)) continue;
>             // if yes, remove it from the original SocketSet
>             ss.remove(fd);
>             writeln("successfully connected to 192.168.0.", fd+1);
>         }
>     }
> }

thanks, but what's the type of fd ?

current code:
--------------------------------
const int MAX = 64;
// usefull ?
Socket[] sockets = new Socket[MAX];
string ipb = "192.168.0.";
SocketSet ss = new SocketSet();

for (int i = 0; i < MAX; i++) {
    string ip = ipb~to!string(i+1);

    Socket s = new Socket(AddressFamily.INET, std.socket.SocketType.STREAM, ProtocolType.TCP);
    s.blocking = false;
    InternetAddress ia = new InternetAddress(ip, 22);
    sockets[i] = s;
    s.connect(ia);
    ss.add(s);
}

while (ss.max > 0)
{
    SocketSet write_ss = ss;
    auto status = Socket.select(null, write_ss, null, 50.msecs);
    // for a connect()ing socket, writeability means connected
    if(status < 0)
        writeln("interrupted, retrying");
    else if(status == 0)
        writeln("timeout, retrying");
    else {
        writeln(status, " socket(s) changed state");
        for (int i = 0; i < write_ss.tupleof[1]; i++) {
            // tried to do something
            //Socket fd = write_ss.tupleof[0][i];
            string ip = ipb~to!string(i+1);
            if(!write_ss.isSet(fd))
                continue;
            ss.remove(fd);
            writeln("successfully connected to ", ip);
        }
    }
}

--------------------------------
« First   ‹ Prev
1 2