osdir.com
mailing list archive F.A.Q. -since 2001!



Subject: Re: prim_inet:accept() bug with {fd, N} socket
option? - msg#00010

List: lang.erlang.bugs

Mail Archive Navigation:
by Date: Prev Next Date Index by Thread: Prev Next Thread Index

Serge Aleynikov <saleyn@xxxxxxxxx> wrote:
>
>Per Hedeland wrote:
>> Serge Aleynikov <saleyn@xxxxxxxxx> wrote:
>>> gen_tcp:connect/2, gen_tcp:listen/2 functions expose an option {fd,
>>> FileDescriptor} that allows to take an elsewhere opened file descriptor
>>> and make it usable in the gen_tcp module. This is a very convenient
>>> option, however, what I discovered was that the default options that are
>>> being set on a socket by prim_inet:accept_opts/2 call involved in
>>> gen_tcp:accept/1 try to get/set a 'priority' option that may not be
>>> supported
>>
>> Well, it's rather dubious to pass in a non-inet socket to the inet
>> modules/driver,
>
>What else would be the use of the {fd, N} option in gen_tcp:connect/2,
>gen_tcp:listen/2?

Primarily the case where you need to bind a socket to a "privileged"
port, but don't want to run the whole Erlang system as root. You can
then (create and) bind the socket in an external process, and pass it to
Erlang via sendmsg(2) and a driver. You could also have "inherited" the
socket descriptor somehow, e.g. if you start Erlang via [x]inetd,
stdin/out/err is a socket - this can also be a way to handle the
privileged port case: Bind the socket in a setuid-root or root-started
program that then setuid()s to an unprivileged uid and execs the Erlang
runtime system.

> I would think that Unix Domain Sockets (UDS) is a
>rather good example or else one would need to mirror all
>gen_tcp/inet_tcp/prim_inet functionality to support UDS.
>
>Ideally the inet_drv along with gen_tcp/inet_tcp/prim_inet would be
>extended to be able to support UDS on Unix-like platforms.

Yeah, it's nice to get all that stuff for "UDS", but I think it's clear
from the code that this was not the intention. The inet driver clearly
assumes AF_INET[6] sockets, not just by way of its name. And UDS doesn't
do TCP (or UDP) - of course the difference from generic SOCK_STREAM or
SOCK_DGRAM is pretty minimal (mainly the set of available options), but
gen_tcp and gen_udp would at least be "inappropriate" names...

>> Below is a patch that addresses this - it's against R10B-10 though, and
>> won't apply against current versions since even though the code is
>> essentially the same there, it has moved around a bit. But maybe you can
>> convert it - or just comment out the whole setopt_prio_tos_trick() thing
>> there.:-)
>
>Thank you very much, this is very helpful!

I converted the patch to match R11B-5, it was pretty trivial, but let me
know if you want it (untested though).

>> I have subsequently hacked prim_inet and inet_drv to handle arbitrary
>> non-inet sockets "properly", i.e. allow for passing in 'unspec' (as in
>> AF_UNSPEC) as the address family, and in that case refrain from doing
>> *any* AF_INET/AF_INET6-specific get/setsockopts, as well as
>> getsockname() and getpeername() (since the address format is unknown).
>> It's perhaps still a bit dubious to "abuse" the inet code this way
>> though, but you sure get a lot of stuff for free that way...
>
>Perhaps you could send these patches as well and the OTP team could
>consider including them in the distribution?

If they want them, sure (actually the EPL says that I must:-), but I'm
not sure that they do... In any case you don't really need them for UDS,
the inet driver is very "tolerant" of failing get/setsockopts (except in
the case of SO_PRIORITY/IP_TOS:-), so it "just works".

I had a broader requirement though, to support any SOCK_STREAM type,
allowing the customer to plug in the needed interface code, and didn't
want to have to answer questions about why we were attempting to do
INET-specific things with it.:-) More seriously, there is a very real
possibility that getsockname()/getpeername() calls assuming AF_INET[6]
will fail in the case of an address family that is neither INET nor
UNIX/LOCAL - the inet driver does these w/o being asked in some cases
(in particular when passing in an existing file descriptor:-), and
failure there is fatal.

Note also that I don't use gen_tcp for passing in the descriptor and so
haven't modified it for the 'unspec' family - a mostly-wrapper module
with the same interface as gen_tcp talks to the driver that creates the
socket, and passes the descriptor in via inet:fdopen/5 - maybe
marginally "cleaner", but of course it just turns around and calls
gen_tcp for accept/recv/send etc, and you still get 'tcp' in the tuples
received in active mode.

--Per


Thread at a glance:

Previous Message by Date:

Re: prim_inet:accept() bug with {fd, N} socket option?

Per Hedeland wrote: > Serge Aleynikov <saleyn@xxxxxxxxx> wrote: >> gen_tcp:connect/2, gen_tcp:listen/2 functions expose an option {fd, >> FileDescriptor} that allows to take an elsewhere opened file descriptor >> and make it usable in the gen_tcp module. This is a very convenient >> option, however, what I discovered was that the default options that are >> being set on a socket by prim_inet:accept_opts/2 call involved in >> gen_tcp:accept/1 try to get/set a 'priority' option that may not be >> supported > > Well, it's rather dubious to pass in a non-inet socket to the inet > modules/driver, What else would be the use of the {fd, N} option in gen_tcp:connect/2, gen_tcp:listen/2? I would think that Unix Domain Sockets (UDS) is a rather good example or else one would need to mirror all gen_tcp/inet_tcp/prim_inet functionality to support UDS. Ideally the inet_drv along with gen_tcp/inet_tcp/prim_inet would be extended to be able to support UDS on Unix-like platforms. > but anyway the problem you're running into isn't really > that 'priority' isn't supported (SO_PRIORITY is a Linux-specific thing > AFAIK, but it's a socket-level option and so works for any type of > socket), but rather that the driver does some pretty ugly things in an > attempt to make 'priority' and 'tos' appear to be independent, even > though they aren't at the OS level (it's a mistake to do this I think, > but let's ignore that for the moment). Ah, I suspected that after reading comments in setopt_prio_tos_trick(). ;-) > This has the effect that it ends up trying to set the IP_TOS option on > your unix-domain socket, which doesn't work of course, and then it gives > up on the whole thing even though it was actually SO_PRIORITY that was > requested (from the prim_inet code you quoted). > > Below is a patch that addresses this - it's against R10B-10 though, and > won't apply against current versions since even though the code is > essentially the same there, it has moved around a bit. But maybe you can > convert it - or just comment out the whole setopt_prio_tos_trick() thing > there.:-) Thank you very much, this is very helpful! > I have subsequently hacked prim_inet and inet_drv to handle arbitrary > non-inet sockets "properly", i.e. allow for passing in 'unspec' (as in > AF_UNSPEC) as the address family, and in that case refrain from doing > *any* AF_INET/AF_INET6-specific get/setsockopts, as well as > getsockname() and getpeername() (since the address format is unknown). > It's perhaps still a bit dubious to "abuse" the inet code this way > though, but you sure get a lot of stuff for free that way... Perhaps you could send these patches as well and the OTP team could consider including them in the distribution? Regards, Serge

Next Message by Date:

documentation bug(s) - mnesia:lock/2

In the documentation for mnesia:lock/2, http://www.erlang.org/doc/man/mnesia.html#lock/2 one can read the following: Currently, two kinds of LockItem's are supported by this function: "{table, Tab} This acquires a lock of type LockKind on the entire table Tab. {global, GlobalKey, Nodes} This acquires a lock of type LockKind on the global resource GlobalKey. The lock is acquired on all active nodes in the Nodes list. " but the function also supports a third kind of LockItem (perhaps the most interesting): {record, Tab, Key} Furthermore, it states that stick_write is not supported by the function, but looking at the source, not only is sticky_write (note the spelling) supported, but also 'none'. Finally, looking at the function prototype: lock(LockItem, LockKind) -> GoodNodes | transaction abort This doesn't seem to be correct either. The function returns the result of mnesia:read({Tab,Key}), or something to that effect. BR, Ulf W BR, Ulf W _______________________________________________ erlang-bugs mailing list erlang-bugs@xxxxxxxxxx http://www.erlang.org/mailman/listinfo/erlang-bugs

Previous Message by Thread:

Re: prim_inet:accept() bug with {fd, N} socket option?

Per Hedeland wrote: > Serge Aleynikov <saleyn@xxxxxxxxx> wrote: >> gen_tcp:connect/2, gen_tcp:listen/2 functions expose an option {fd, >> FileDescriptor} that allows to take an elsewhere opened file descriptor >> and make it usable in the gen_tcp module. This is a very convenient >> option, however, what I discovered was that the default options that are >> being set on a socket by prim_inet:accept_opts/2 call involved in >> gen_tcp:accept/1 try to get/set a 'priority' option that may not be >> supported > > Well, it's rather dubious to pass in a non-inet socket to the inet > modules/driver, What else would be the use of the {fd, N} option in gen_tcp:connect/2, gen_tcp:listen/2? I would think that Unix Domain Sockets (UDS) is a rather good example or else one would need to mirror all gen_tcp/inet_tcp/prim_inet functionality to support UDS. Ideally the inet_drv along with gen_tcp/inet_tcp/prim_inet would be extended to be able to support UDS on Unix-like platforms. > but anyway the problem you're running into isn't really > that 'priority' isn't supported (SO_PRIORITY is a Linux-specific thing > AFAIK, but it's a socket-level option and so works for any type of > socket), but rather that the driver does some pretty ugly things in an > attempt to make 'priority' and 'tos' appear to be independent, even > though they aren't at the OS level (it's a mistake to do this I think, > but let's ignore that for the moment). Ah, I suspected that after reading comments in setopt_prio_tos_trick(). ;-) > This has the effect that it ends up trying to set the IP_TOS option on > your unix-domain socket, which doesn't work of course, and then it gives > up on the whole thing even though it was actually SO_PRIORITY that was > requested (from the prim_inet code you quoted). > > Below is a patch that addresses this - it's against R10B-10 though, and > won't apply against current versions since even though the code is > essentially the same there, it has moved around a bit. But maybe you can > convert it - or just comment out the whole setopt_prio_tos_trick() thing > there.:-) Thank you very much, this is very helpful! > I have subsequently hacked prim_inet and inet_drv to handle arbitrary > non-inet sockets "properly", i.e. allow for passing in 'unspec' (as in > AF_UNSPEC) as the address family, and in that case refrain from doing > *any* AF_INET/AF_INET6-specific get/setsockopts, as well as > getsockname() and getpeername() (since the address format is unknown). > It's perhaps still a bit dubious to "abuse" the inet code this way > though, but you sure get a lot of stuff for free that way... Perhaps you could send these patches as well and the OTP team could consider including them in the distribution? Regards, Serge

Next Message by Thread:

documentation bug(s) - mnesia:lock/2

In the documentation for mnesia:lock/2, http://www.erlang.org/doc/man/mnesia.html#lock/2 one can read the following: Currently, two kinds of LockItem's are supported by this function: "{table, Tab} This acquires a lock of type LockKind on the entire table Tab. {global, GlobalKey, Nodes} This acquires a lock of type LockKind on the global resource GlobalKey. The lock is acquired on all active nodes in the Nodes list. " but the function also supports a third kind of LockItem (perhaps the most interesting): {record, Tab, Key} Furthermore, it states that stick_write is not supported by the function, but looking at the source, not only is sticky_write (note the spelling) supported, but also 'none'. Finally, looking at the function prototype: lock(LockItem, LockKind) -> GoodNodes | transaction abort This doesn't seem to be correct either. The function returns the result of mnesia:read({Tab,Key}), or something to that effect. BR, Ulf W BR, Ulf W _______________________________________________ erlang-bugs mailing list erlang-bugs@xxxxxxxxxx http://www.erlang.org/mailman/listinfo/erlang-bugs
blog comments powered by Disqus

Home | News | Sitemap | FAQ | advertise | OSDir is an Inevitable website. GBiz is too!