msantos / procket

Erlang interface to low level socket operations
http://blog.listincomprehension.com/search/label/procket
BSD 3-Clause "New" or "Revised" License
283 stars 80 forks source link

Opening an IPPROTO_DIVERT socket binds to *:* #27

Closed nifoc closed 8 years ago

nifoc commented 8 years ago
$ uname -a
FreeBSD testing 11.0-RC2 FreeBSD 11.0-RC2 #0 r304729: Wed Aug 24 08:46:45 UTC 2016     root@releng2.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  i386

$ erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().'  -noshell
"19"

Procket is at version 0.7.0.

I'm trying to open a divert socket using the follwing call to procket:open/2:

procket:open(9001, [{family, inet}, {type, raw}, {protocol, procket:socket_protocol('IPPROTO_DIVERT')}])

This does not fail, but instead of binding to *:9001 it binds to *:*.

$ sockstat -4 -l
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
[...]
tester   beam.smp   14216 20 div4   *:*                   *:*

I'm not sure if that a bug or if I'm simply doing something wrong. Other types of sockets are opened (and bound) correctly, only divert socket seem to now work as expected.

msantos commented 8 years ago

For divert sockets, bind/2 has to be used:

% port parameter is ignored
{ok, FD} = procket:open(0, [{family, inet}, {type, raw}, {protocol, procket:socket_protocol('IPPROTO_DIVERT')},

% make a struct sockaddr
SA = <<(procket:sockaddr_common(inet, 16)):2/bytes, 9001:16/integer-unsigned-big, 0:32, 0:64>>,

% bind the socket
ok  = procket:bind(FD, SA).

Checking netstat:

$ netstat -an | grep 9001
div4       0      0 *.9001                 *.*

The sockaddr struct is from /usr/include/netinet/in.h:

struct sockaddr_in {
    uint8_t sin_len;
    sa_family_t sin_family;
    in_port_t   sin_port;
    struct  in_addr sin_addr;
    char    sin_zero[8];
};

So if you want to bind to a specific IP address, something like this should work:

SA = <<(procket:sockaddr_common(inet, 16)):2/bytes, 9001:16/integer-unsigned-big,  127, 0, 0, 1, 0:64>>

If any of that isn't clear or if you have any questions, please let me know!

(Totally unrelated: thanks for writing Katja! I've been running it for a while now and it has been working great!)

nifoc commented 8 years ago

Thanks for the very quick reply!

Manually calling bind worked perfectly and the socket is now bound to the correct port.