<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div>----- On Oct 20, 2017, at 8:22 PM, Michael L Martin <mmartin4242@gmail.com> wrote:<br></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><p>Posting again to all...</p><p><br></p><p>iex(4)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw,
      0, 15, <<1>>}, {:ip, {10, 138, 69, 63}}])</p></blockquote><div>Very small nitpick (does not impact the function), setsockopt boolean and integer options usually use a 32bit integer. Debugging tools like strace are much easier to read then.</div><div>So I would recommend to write the options as {:raw, 0, 15, <<1:32/native>>}</div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><p>{:ok, #Port<0.1310>}<br>
      iex(5)> :inet.getopts(s, [{:raw, 0, 15, 4}])</p><p>{:ok, [{:raw, 0, 15, <<1, 0, 0, 0>>}]}<br></p><p>iex(6)> :gen_tcp.close(s) :ok<br></p><p>iex(7)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw,
      0, 15, <<1>>}, {:ip, {10, 138, 69, 64}}])</p></blockquote><div>10.138.69.64 does not exist on you system, so attempting to use it will fail (as you just discovered).</div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><p>** (exit) :badarg<br></p><p>(kernel) gen_tcp.erl:149: :gen_tcp.connect/4<br></p><p>iex(7)><br></p><p>I see badarg when trying to connect using a bogus IP address.
      But,  the option is being set now.</p><p>Using IP_TRANSPARENT instead of IP_FREEBIND:</p><p>iex(8)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw,
      0, 19, <<1>>}, {:ip, {10, 138, 69, 64}}])</p></blockquote><div>IP_TRANSPARENT is very different from IP_FREEBIND. You need iptables rules to make it work (and a lot more about what it is supposed to to before playing with it).</div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><p>At this point, :gen_tcp.connect/3 blocks. The ip address does not
      exist, so now I add it:<br></p><p>sudo ip addr add 10.138.69.64 dev eno1</p><p>ip addr list dev eno12: eno1:
      <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
      state UP group default qlen 1000<br>
          link/ether 8c:89:a5:c6:e1:7f brd ff:ff:ff:ff:ff:ff<br>
          inet 10.138.69.63/16 brd 10.138.255.255 scope global eno1<br>
             valid_lft forever preferred_lft forever<br>
          inet 10.138.69.64/32 scope global eno1<br>
             valid_lft forever preferred_lft forever<br>
          inet6 fe80::8e89:a5ff:fec6:e17f/64 scope link <br>
             valid_lft forever preferred_lft forever</p><p>I would think that :gen_tcp.connect would then connect, but it's
      still blocked, and eventually times out.</p><p>After the timeout:</p><p>iex(8)> {:ok, s} = :gen_tcp.connect('localhost', 80, [{:raw,
      0, 19, <<1>>}, {:ip, {10, 138, 69, 64}}])<br>
      {:ok, #Port<0.1300>}<br>
      iex(9)> :inet.getopts(s, [{:raw, 0, 19,
      4}])                                    {:ok, [{:raw, 0, 19,
      <<1, 0, 0, 0>>}]}<br>
      iex(10)></p></blockquote><div>As I have said before, using FREEBIND for connect makes no sense.</div><div>What you probably want it to bind a listening socket to an IP address that will later be added by systemd. For that include the raw option in the listening call.</div><div><br data-mce-bogus="1"></div><div>Regards</div><div>Andreas</div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><p><br></p><p><br></p><p><br></p><blockquote class="gmail_quote"><div class="HOEnZb"><div class="h5"><br><br><br><br>
          On 2017-10-20 11:10 AM, Michael L Martin wrote:<br><blockquote class="gmail_quote" style="margin: 0 0 0            .8ex; border-left: 1px #ccc solid; padding-left: 1ex;" data-mce-style="margin: 0 0 0            .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><br>
            6, 15, <<1>>}, {:ip, {10, 138, 69, 64}}])<br><br>
            ** (MatchError) no match of right hand side value: {:error,
            :eaddrnotavail}<br></blockquote></div></div></blockquote><br><div class="moz-cite-prefix">On 2017-10-20 12:33 PM, Richard Jones
      wrote:<br></div><blockquote cite="mid:CACmxXrAaxBN_21gB=ShK2yHBKoRVVbZar5myoL3LcF7dNaW6mQ@mail.gmail.com"><pre>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 <a class="moz-txt-link-rfc2396E" href="mailto:mmartin4242@gmail.com" target="_blank"><mmartin4242@gmail.com></a> wrote:
</pre><blockquote><pre>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 <a class="moz-txt-link-rfc2396E" href="mailto:mmartin4242@gmail.com" target="_blank"><mmartin4242@gmail.com></a>
wrote:

Raw socket options looks like it should be the answer, but I'm not getting
good results:

iex(<a class="moz-txt-link-abbreviated" href="mailto:worker@10.138.69.63" target="_blank">worker@10.138.69.63</a>)28> {:ok, s} = :gen_tcp.connect('localhost', 80,
[{:raw, 6, 15, <<1>>}, {:ip, {10, 138, 69, 63}}])

{:ok, #Port<0.12110>}

iex(<a class="moz-txt-link-abbreviated" href="mailto:worker@10.138.69.63" target="_blank">worker@10.138.69.63</a>)29> :inet.getopts(s, [{:raw, 6, 15, 32}])

{:ok, []}    <== option not set?

iex(<a class="moz-txt-link-abbreviated" href="mailto:worker@10.138.69.63" target="_blank">worker@10.138.69.63</a>)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(<a class="moz-txt-link-abbreviated" href="mailto:worker@10.138.69.63" target="_blank">worker@10.138.69.63</a>)35> {:ok, s} = :gen_tcp.connect('localhost', 80,
[{:raw, 6, 19, <<1>>}, {:ip, {10, 138, 69, 63}}])

{:ok, #Port<0.12113>}

iex(<a class="moz-txt-link-abbreviated" href="mailto:worker@10.138.69.63" target="_blank">worker@10.138.69.63</a>)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]: <a class="moz-txt-link-freetext" href="http://erlang.org/doc/man/inet.html#setopts-2" target="_blank">http://erlang.org/doc/man/inet.html#setopts-2</a> - {raw, Protocol,
OptionNum, ValueBin}

On 16 October 2017 at 15:09, Michael L Martin <a class="moz-txt-link-rfc2396E" href="mailto:mmartin4242@gmail.com" target="_blank"><mmartin4242@gmail.com></a> wrote:
</pre><blockquote><pre>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
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a></pre></blockquote><pre>
--
Guilherme



_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a>



_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a></pre></blockquote></blockquote><br><br></blockquote></div></div></body></html>