Opened 9 years ago

Closed 8 years ago

#801 closed enhancement (complete)

Design API for requesting/returning/cleaning-up sockets

Reported by: stephen Owned by: vorner
Priority: medium Milestone: Sprint-20110816
Component: ~Boss of BIND (obsolete) Version:
Keywords: Cc:
CVSS Scoring: Parent Tickets:
Sensitive: no Defect Severity: N/A
Sub-Project: Core Feature Depending on Ticket:
Estimated Difficulty: 5 Add Hours to Ticket: 0
Total Hours: 0 Internal?: no

Description

This is concerned with the interface to the socket creator.

Subtickets

Change History (14)

comment:1 Changed 9 years ago by stephen

  • Defect Severity set to N/A
  • Milestone changed from Year 3 Task Backlog to Sprint-20110802
  • Sub-Project set to DNS

comment:2 Changed 8 years ago by vorner

  • Owner set to vorner
  • Status changed from new to accepted

comment:3 Changed 8 years ago by vorner

  • Owner changed from vorner to UnAssigned
  • Status changed from accepted to reviewing

I'm not entirely sure what level of design and API is required here, but I wrote some idea. It is in trac801, src/bin/bind10/creatorapi.txt.

comment:4 Changed 8 years ago by stephen

  • Estimated Difficulty changed from 0.0 to 5

comment:5 Changed 8 years ago by jinmei

  • Owner changed from UnAssigned to jinmei
  • Status changed from reviewing to accepted
  • Sub-Project changed from DNS to Core

comment:6 follow-up: Changed 8 years ago by jinmei

I don't know which level of "API" is expected here either. I'd
normally expect something like function signatures (even if it's only
for a preliminary reference rather than a fixed proposal) by that
term, but maybe it's intended to be deferred to some subsequent tasks.

Random comments for the design

  • what about a raw socket? DHCP may need it.
  • what about socket options? how/whether can an application specify a socket option? what if two applications request sockets with different option settings but with the same port and protocol?
  • I'm not sure if the boss and other apps need to pre-negotiate it via the command channel (not to say it's a bad idea though). Especially if they keep open a separate channel to exchange FDs, I guess they could do everything on it.
  • I see it would be a difficult problem to keep track of whether specific apps are active. And I think we should consider it as a general issue, possibly as part of the msgq replacement project (e.g. boss and others may have to run some keep-alive protocol).
  • I suspect that the definition of same/different kind of applications is not that trivial. For example, we may run two auth processes, one for "internal", and the other for "external", and these two would listen on different addresses. In this case the corresponding sockets shouldn't be shared by the two processes. But I have no concrete idea of how to cleanly solve this. We should probably make some compromise, and the result may be the simplest same/different kinds such as just the program name in the end.

typo/editorial

  • s/IP/IPv4/ ("IP" would mean a different version in a few years:-)
  • s/at last/at least/

comment:7 Changed 8 years ago by jinmei

  • Owner changed from jinmei to vorner
  • Status changed from accepted to assigned

comment:8 in reply to: ↑ 6 ; follow-up: Changed 8 years ago by vorner

  • Owner changed from vorner to jinmei
  • Status changed from assigned to reviewing

Hello

Replying to jinmei:

I don't know which level of "API" is expected here either. I'd
normally expect something like function signatures (even if it's only
for a preliminary reference rather than a fixed proposal) by that
term, but maybe it's intended to be deferred to some subsequent tasks.

So, should I write some or is the description of commands down there enough, leaving the exact prototypes for whoever will be implementing them?

  • what about a raw socket? DHCP may need it.

I didn't think of it, when I start sockcreator, we didn't have DHCP. But it should be quite simple to add raw socket to it and to the protocol.

But I didn't work with raw sacket yet, aren't root privileges needed to some other manipulation with it?

  • what about socket options? how/whether can an application specify a socket option? what if two applications request sockets with different option settings but with the same port and protocol?

What socket options? Calls socket and bind (which are the two sockcreator is doing) don't seem to have any parameter to specify options. Therefore I think any kind of options can be set later by the application by other calls.

It is true the protocol parameter of socket is hardcoded zero, but is it ever used with anything except raw socket? In case of raw socket, there wouldn't be bind, but we would pass the protocol instead of the address.

  • I'm not sure if the boss and other apps need to pre-negotiate it via the command channel (not to say it's a bad idea though). Especially if they keep open a separate channel to exchange FDs, I guess they could do everything on it.

I've two reasons to do it:

  • We might want to secure connection to the msgq sometime in future, so other applications that just happen to find the unix socket can't connect to the system. The token would provide some level of security and boss wouldn't provide low-port sockets to just anybody (I heard that on some systems, the permissions on the socket file aren't taken into account).
  • Passing data structures (like the parameters of the socket and parameters of sharing) through the msgq is simpler than encoding them manually to the socket.

In this sense it is similar to FTP, the control and data connection.

I'd really like to pass the results through the msgq too, but it doesn't seem easy.

  • I see it would be a difficult problem to keep track of whether specific apps are active. And I think we should consider it as a general issue, possibly as part of the msgq replacement project (e.g. boss and others may have to run some keep-alive protocol).

Well, that's the option one of caching of sockets. Or, more or less it, I think it is better done in the msgq than boss, since it has direct access to the sockets to them and can see things others can't (errors/full write queues/connection resets). And, as I noted, dbus does it already, so it was the reason I wanted to have the msgq replacement (if any) before we start implementing sockcreator.

  • I suspect that the definition of same/different kind of applications is not that trivial. For example, we may run two auth processes, one for "internal", and the other for "external", and these two would listen on different addresses. In this case the corresponding sockets shouldn't be shared by the two processes. But I have no concrete idea of how to cleanly solve this. We should probably make some compromise, and the result may be the simplest same/different kinds such as just the program name in the end.

Well, in that case user would provide different addresses to listen on and they would get different sockets without any problem (the sharing would be, of course, only with sockets bound to same addresses). I was more worried about someone specifying both auth and resolver listening on 0.0.0.0:53, which is what people would want and it seems logic, it just wouldn't work. Having internal and external auth both listening on everything makes no sense from the administrator point of view.

Anyway, wouldn't such internal/external better be done by ACLs?

And, I guess your example assumes some kind of views in place. We didn't yet talk too much how such thing would look like. Maybe in that case the name of application would be the name of the view?

  • s/IP/IPv4/ ("IP" would mean a different version in a few years:-)

Fixed, but I hope this document will be obsolete by then and the sockcreator implemented ;-)

comment:9 in reply to: ↑ 8 ; follow-up: Changed 8 years ago by jinmei

Replying to vorner:

I don't know which level of "API" is expected here either. I'd
normally expect something like function signatures (even if it's only
for a preliminary reference rather than a fixed proposal) by that
term, but maybe it's intended to be deferred to some subsequent tasks.

So, should I write some or is the description of commands down there enough, leaving the exact prototypes for whoever will be implementing them?

To be honest I have no idea as I didn't know what exactly this task
should do in the first place:-) But it wouldn't make much sense to
spend too much of time at this level (at the moment maybe the
important thing is that at least two people consider it), so:

  • Basically, I leave decisions on when to close this ticket to you.
  • I'd provide a couple of actual signatures to show the idea more concretely. Also, code snippet often reveals something we miss.
  • what about a raw socket? DHCP may need it.

[...]

But I didn't work with raw sacket yet, aren't root privileges needed to some other manipulation with it?

I'm not sure if I really understand the question, but if I vaguely
remember that some systems require the root privilege when sending
packets via a raw socket (so the application cannot drop the privilege
after opening the socket).

  • what about socket options? how/whether can an application specify a socket option? what if two applications request sockets with different option settings but with the same port and protocol?

What socket options? Calls socket and bind (which are the two sockcreator is doing) don't seem to have any parameter to specify options. Therefore I think any kind of options can be set later by the application by other calls.

For example, SO_REUSEADDR needs to be set before bind(). And, in the
case of BIND 9, it sets or unsets this option depending on subtle
conditions. We may or may not encounter the same situation, but the
point is that it's quite likely we'll have some limitation on the
usage regarding socket options. This should be clearly documented,
and we should revisit the point as we have more concrete idea on how
specifically we use this API.

I'd also note that if two apps have different policy about whether to
set a particular socket option, when to set the option is irrelevant.

It is true the protocol parameter of socket is hardcoded zero, but is it ever used with anything except raw socket? In case of raw socket, there wouldn't be bind, but we would pass the protocol instead of the address.

This is not my point. What I meant is something like this:

  • Application A wants to have a UDP socket on port 53 with SO_REUSEADDR
  • Application B wants to have a UDP socket on port 53 without SO_REUSEADDR
  • I'm not sure if the boss and other apps need to pre-negotiate it via the command channel (not to say it's a bad idea though). Especially if they keep open a separate channel to exchange FDs, I guess they could do everything on it.

I've two reasons to do it:

  • We might want to secure connection to the msgq sometime in future, so other applications that just happen to find the unix socket can't connect to the system. The token would provide some level of security and boss wouldn't provide low-port sockets to just anybody (I heard that on some systems, the permissions on the socket file aren't taken into account).
  • Passing data structures (like the parameters of the socket and parameters of sharing) through the msgq is simpler than encoding them manually to the socket.

I don't object to that, but these rationales should be documented, and
it should be based on a fact, not a rumor (i.e., not only say "I heard
X...", but we say "ABC OS doesn't take into count xxx").

  • I suspect that the definition of same/different kind of applications is not that trivial. For example, we may run two auth processes, one for "internal", and the other for "external", and these two would listen on different addresses. In this case the corresponding sockets shouldn't be shared by the two processes. But I have no concrete idea of how to cleanly solve this. We should probably make some compromise, and the result may be the simplest same/different kinds such as just the program name in the end.

Well, in that case user would provide different addresses to listen on and they would get different sockets without any problem (the sharing would be, of course, only with sockets bound to same addresses). I was more worried about someone specifying both auth and resolver listening on 0.0.0.0:53, which is what people would want and it seems logic, it just wouldn't work. Having internal and external auth both listening on everything makes no sense from the administrator point of view.

My example was certainly inspired by views, but my point was more
generic. What I wanted to point out is that the definition of "same
kind" may not be so obvious, and since full generality wouldn't make
sense or would be too difficult to implement, we'll have to make some
restriction/compromise. So we have to give our own definition of
"same kind", and explain restrictions due to that.

Besides, it's actually not so uncommon that two views listen on the
same address/port: they behave differently based on the "from
address".

  • s/IP/IPv4/ ("IP" would mean a different version in a few years:-)

Fixed, but I hope this document will be obsolete by then and the sockcreator implemented ;-)

Maybe you forgot to push? The branch doesn't seem to be updated. The
other typo wasn't fixed either.

comment:10 Changed 8 years ago by jinmei

  • Owner changed from jinmei to vorner

comment:11 in reply to: ↑ 9 Changed 8 years ago by vorner

  • Owner changed from vorner to jinmei

Hello

Replying to jinmei:

  • Basically, I leave decisions on when to close this ticket to you.
  • I'd provide a couple of actual signatures to show the idea more concretely. Also, code snippet often reveals something we miss.

I added a snippet that shows it somehow, I hope it will be clear about the idea how to use it and the exact details can be left for the implementator.

[...]

But I didn't work with raw sacket yet, aren't root privileges needed to some other manipulation with it?

I'm not sure if I really understand the question, but if I vaguely
remember that some systems require the root privilege when sending
packets via a raw socket (so the application cannot drop the privilege
after opening the socket).

Yes, that was exactly my concern ‒ if it needs root privileges to do anything useful with it (like send packets), it can as well just create the socket itself and not bother itself with asking some other component to do it. Well, let's wait and see if they are needed.

What socket options? Calls socket and bind (which are the two sockcreator is doing) don't seem to have any parameter to specify options. Therefore I think any kind of options can be set later by the application by other calls.

For example, SO_REUSEADDR needs to be set before bind(). And, in the
case of BIND 9, it sets or unsets this option depending on subtle
conditions. We may or may not encounter the same situation, but the
point is that it's quite likely we'll have some limitation on the
usage regarding socket options. This should be clearly documented,
and we should revisit the point as we have more concrete idea on how
specifically we use this API.

Hmm, crap, I didn't know about these. Well, let's leave them out for now (we don't use them now) and hope they won't be needed. If they are, we will have to extend it later.

I'd also note that if two apps have different policy about whether to
set a particular socket option, when to set the option is irrelevant.

In case of SO_REUSEADDR yes, but in case of blocking/nonblocking, it is set on the one single copy of socket (I guess sending a socket trough the connection acts similar as dup in this).

  • Application A wants to have a UDP socket on port 53 with SO_REUSEADDR
  • Application B wants to have a UDP socket on port 53 without SO_REUSEADDR

Hopefully these would be different application that wouldn't be willing to share the socket with each other and the problem would solve out itself anyway. But let's worry about that if we have the options.

I don't object to that, but these rationales should be documented, and
it should be based on a fact, not a rumor (i.e., not only say "I heard
X...", but we say "ABC OS doesn't take into count xxx").

I documented the rationale and I found a link hinting what I said, that some OSes do ignore the permissions, but it still isn't authoritative source of information and doesn't say which OSes they are. But that's a minor point in the rationale anyway, so I hope it isn't so much of a problem.

Besides, it's actually not so uncommon that two views listen on the
same address/port: they behave differently based on the "from
address".

Well, then they either could not be in different processes (therefore there would be no need to share it) or they couldn't share it (because the packet could end up in the wrong application). We will need to solve this problem somehow when we get to it, possibly by the receptionist or something like that.

Maybe you forgot to push? The branch doesn't seem to be updated. The
other typo wasn't fixed either.

I did, I pushed now.

comment:12 Changed 8 years ago by jinmei

  • Please add the usage conflict issue (such as the one about socket options) for the same socket to the "Known limitations" section.
  • Please add a note to "the commands" section that the precise definition of "same kind" may not be trivial, and it's an open issue for now.

I think at this point we can close this ticket.

comment:13 Changed 8 years ago by jinmei

  • Owner changed from jinmei to vorner

comment:14 Changed 8 years ago by vorner

  • Resolution set to complete
  • Status changed from reviewing to closed

OK, I added it, merged the branch into master (so the file is preserved) and closing. Thanks.

Note: See TracTickets for help on using tickets.