[erlang-questions] Socket option FREEBIND

Michael L Martin mmartin4242@REDACTED
Fri Oct 20 20:22:31 CEST 2017


Posting again to all...


iex(4)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw, 0, 15, 
<<1>>}, {:ip, {10, 138, 69, 63}}])
{:ok, #Port<0.1310>}
iex(5)> :inet.getopts(s, [{:raw, 0, 15, 4}])

{:ok, [{:raw, 0, 15, <<1, 0, 0, 0>>}]}

iex(6)> :gen_tcp.close(s) :ok

iex(7)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw, 0, 15, 
<<1>>}, {:ip, {10, 138, 69, 64}}])

** (exit) :badarg

(kernel) gen_tcp.erl:149: :gen_tcp.connect/4

iex(7)>

I see badarg when trying to connect using a bogus IP address. But,  the 
option is being set now.

Using IP_TRANSPARENT instead of IP_FREEBIND:

iex(8)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw, 0, 19, 
<<1>>}, {:ip, {10, 138, 69, 64}}])


At this point, :gen_tcp.connect/3 blocks. The ip address does not exist, 
so now I add it:

sudo ip addr add 10.138.69.64 dev eno1

ip addr list dev eno12: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 
qdisc pfifo_fast state UP group default qlen 1000
     link/ether 8c:89:a5:c6:e1:7f brd ff:ff:ff:ff:ff:ff
     inet 10.138.69.63/16 brd 10.138.255.255 scope global eno1
        valid_lft forever preferred_lft forever
     inet 10.138.69.64/32 scope global eno1
        valid_lft forever preferred_lft forever
     inet6 fe80::8e89:a5ff:fec6:e17f/64 scope link
        valid_lft forever preferred_lft forever

I would think that :gen_tcp.connect would then connect, but it's still 
blocked, and eventually times out.

After the timeout:

iex(8)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw, 0, 19, 
<<1>>}, {:ip, {10, 138, 69, 64}}])
{:ok, #Port<0.1300>}
iex(9)> :inet.getopts(s, [{:raw, 0, 19, 
4}])                                    {:ok, [{:raw, 0, 19, <<1, 0, 0, 
0>>}]}
iex(10)>








    On 2017-10-20 11:10 AM, Michael L Martin wrote:


        6, 15, <<1>>}, {:ip, {10, 138, 69, 64}}])

        ** (MatchError) no match of right hand side value: {:error,
        :eaddrnotavail}


On 2017-10-20 12:33 PM, Richard Jones wrote:
> I'm able to make outbound connections bound to an arbitrary IP from my
> range by specifying a socket option like: {raw, 0, 15, <<1>>}
>
> note that that protocol part of {raw, ???, _, _} is 0, not 6, since
> it's an IP level socket option (not tcp-level).
>
> btw there's also a system-wide option so you don't need to specify
> ip_freebind per socket:
>
> echo 1 > /proc/sys/net/ipv6/ip_nonlocal_bind
>
>
> RJ
>
> On 20 October 2017 at 17:17, Michael L Martin <mmartin4242@REDACTED> wrote:
>> Thanks for the quick response. As for what I'm  attempting to achieve, well,
>> I'm not really sure.
>>
>> I have a customer that is adamant that we use IP_FREEBIND, so I've been
>> poking around in :gen_tcp and :inet trying to see how to do that.
>>
>> Here's what happens when I try to open a listen socket:
>>
>> iex(5)> {:ok, s} = :gen_tcp.listen(8000, [{:raw, 6, 15, <<1 :: size(32)>>},
>> {:ip, {10, 138, 69, 63}}])
>> {:ok, #Port<0.1305>}
>> iex(6)> :inet.getopts(s, [{:raw, 6, 15, 4}])
>> {:ok, []}
>> iex(7)> :gen_tcp.close(s)
>> :ok
>> iex(8)> {:ok, s} = :gen_tcp.listen(8000, [{:raw, 6, 15, <<1 :: size(32)>>},
>> {:ip, {10, 138, 69, 64}}])
>> ** (MatchError) no match of right hand side value: {:error, :eaddrnotavail}
>>
>> iex(8)>
>>
>> So it looks like it's not working for listen sockets, either. Could very
>> well be that I simply don't know what the heck I'm doing...
>>
>>
>>
>> On 2017-10-20 12:04 PM, Andreas Schultz wrote:
>>
>> Hi,
>>
>> ----- On Oct 20, 2017, at 5:10 PM, Michael L Martin <mmartin4242@REDACTED>
>> wrote:
>>
>> Raw socket options looks like it should be the answer, but I'm not getting
>> good results:
>>
>> iex(worker@REDACTED)28> {:ok, s} = :gen_tcp.connect('localhost', 80,
>> [{:raw, 6, 15, <<1>>}, {:ip, {10, 138, 69, 63}}])
>>
>> {:ok, #Port<0.12110>}
>>
>> iex(worker@REDACTED)29> :inet.getopts(s, [{:raw, 6, 15, 32}])
>>
>> {:ok, []}    <== option not set?
>>
>> iex(worker@REDACTED)29> {:ok, s} = :gen_tcp.connect('localhost', 80,
>> [{:raw, 6, 15, <<1>>}, {:ip, {10, 138, 69, 64}}])
>>
>> ** (MatchError) no match of right hand side value: {:error, :eaddrnotavail}
>>
>>
>> IP_FREEBIND on connect doesn't make sense, it's only really useful on listen
>> sockets.
>>
>> The option lets you bind to an IP address that does not yet exist on the
>> host. That is ok for listen, but when you attempt to build an outgoing
>> connection from that IP, then it has to be configured.
>>
>> It appears that the IP_FREEBIND option is simply not set. If I use
>> IP_TRANSPARENT instead:
>>
>> iex(worker@REDACTED)35> {:ok, s} = :gen_tcp.connect('localhost', 80,
>> [{:raw, 6, 19, <<1>>}, {:ip, {10, 138, 69, 63}}])
>>
>> {:ok, #Port<0.12113>}
>>
>> iex(worker@REDACTED)34> :inet.getopts(s, [{:raw, 6, 19, 32}])
>>
>> {:ok, [{:raw, 6, 19, <<0, 0, 0, 0>>}]}
>>
>>
>> IP_TRANSPARENT needs special iptables rules to work correctly and is for a
>> very specific use case. I don't think it would be very useful for an Erlang
>> application to use that.
>>
>> In this case, the raw option 19 (IP_TRANSPARENT) is set, but to false rather
>> than true. I believe this is because the beam file needs root or
>> CAP_NET_ADMIN.
>>
>> You need root and a specific iptables setup for it to work.
>>
>> Any thoughts?
>>
>>
>> What are you attempting to achieve anyway?
>>
>> Regards
>> Andreas
>>
>>
>>
>>
>> On 2017-10-16 01:18 PM, Guilherme Andrade wrote:
>>
>> I believe you can use raw socket options[1] for that, but it won't be
>> portable.
>>
>> [1]: http://erlang.org/doc/man/inet.html#setopts-2 - {raw, Protocol,
>> OptionNum, ValueBin}
>>
>> On 16 October 2017 at 15:09, Michael L Martin <mmartin4242@REDACTED> wrote:
>>> Hi all,
>>>
>>> Is there a way to specify the FREEBIND option when opening a socket? I
>>> don't see any reference to it in the documentation.
>>>
>>>
>>> Thanks,
>>>
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-questions@REDACTED
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>>
>> --
>> Guilherme
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20171020/f9b0a268/attachment.htm>


More information about the erlang-questions mailing list