jnr / jnr-netdb

Network services database access for java
Other
12 stars 4 forks source link

Service for port 443 not found #5

Open lucasbonin opened 7 years ago

lucasbonin commented 7 years ago

Machine information:

Linux lucasb-centos7 3.10.0-514.26.2.el7.x86_64 #1 SMP Tue Jul 4 15:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Version of jnr-netdb: 1.1.6.

Test program:

package essai;

import jnr.netdb.Service;

public class Experience1 {

    public static void main(String[] args) {
        Service serv = Service.getServiceByPort(443, null);
        System.out.println("Service for port 443 is " + serv);
    }
}

Output:

Service for port 443 is null

I would have expected something like:

Service for port 443 is <Service: Name: https, Port: 443, Proto: tcp, Aliases: []>

instead.

lucasbonin commented 7 years ago

I modified my test program in the following way:

package essai;

import jnr.netdb.Service;

public class Experience1 {

    public static void main(String[] args) {
        for (int i = 0; i < 1024; i++) {
            Service serv = Service.getServiceByPort(i, null);
            System.out.println("Service for port " + i + " is " + serv);
        }
    }
}

to see what port numbers had the same behaviour.

Sample output:

Service for port 0 is null
Service for port 1 is <Service: Name: tcpmux, Port: 1, Proto: tcp, Aliases: []>
Service for port 2 is <Service: Name: nbp, Port: 2, Proto: ddp, Aliases: []>
Service for port 3 is null
Service for port 4 is <Service: Name: echo, Port: 4, Proto: ddp, Aliases: []>
Service for port 5 is <Service: Name: rje, Port: 5, Proto: tcp, Aliases: []>
...

This looks fine, until you reach port numbers in the ⟦128*(2k+1);128*2(k+1)⟧, k ∈ ⟦0;3⟧ ranges, where Service.getServiceByPort() always return null.

In these ranges the highest bit of the least significant byte is always 1. When the port number is converted from host to network order, the bytes are swapped and you end up with a number that has the highest bit of the most significant byte set to 1. It can then be interpreted as a negative number. For instance 443 is 1011 1011 0001 0000 in little-endian host order. It is then turned into 0001 0000 1011 1011 big-endian network order, which on a little-endian system can be interpreted as 47873 (unsigned) or -17663 (signed). Maybe it is that -17663 that is passed to the underlying C function, which then returns null.