[Toybox] [New Toys] - tcpsvd, udpsvd

Rob Landley rob at landley.net
Sat Oct 5 15:42:46 PDT 2013


On 09/26/2013 11:44:42 AM, ibid.ag at gmail.com wrote:
> On Wed, Sep 25, 2013 at 05:57:49PM +0900, Ashwini Sharma wrote:
> > Hi Rob, list,
> >
> > Attached is the implementation of tcpsvd and udpsvd.
> > Both the commands are handled in the same file and support __IPv4__  
> and
> > __IPv6__.
> >
> > Let me know for any comments and add it to the hg.
> >
> > regards,
> > Ashwini

Ok, now that job hunting's out of the way and I no longer feel like  
doing nothing but play skyrim with the rest of the time, I need to deal  
with the design issues raised by this submission.

> > /* tcpsvd.c - TCP(UDP)/IP service daemon
> >  *
> >  * Copyright 2013 Ashwini Kumar <ak.ashwini at gmail.com>
> >  * Copyright 2013 Sandeep Sharma <sandeep.jack2756 at gmail.com>
> >  * Copyright 2013 Kyungwan Han <asura321 at gmail.com>
> >  *
> >  * No Standard.
> >
> > USE_TCPSVD(NEWTOY(tcpsvd, "^<3c#=30<1C:b#=20<0u:l:hEv",  
> TOYFLAG_USR|TOYFLAG_BIN))
> > USE_TCPSVD(OLDTOY(udpsvd, tcpsvd, OPTSTR_tcpsvd,  
> TOYFLAG_USR|TOYFLAG_BIN))
> >
> > config TCPSVD
> >   bool "tcpsvd"
> >   default y
> >   help
> >     usage: tcpsvd [-hEv] [-c N] [-C N[:MSG]] [-b N] [-u User] [-l  
> Name] IP Port Prog
> >     udpsvd [-hEv] [-c N] [-u User] [-l Name] IP Port Prog
> >
> >     Create TCP/UDP socket, bind to IP:PORT and listen for incoming  
> connection.
> >     Run PROG for each connection.
> 
> Out of curiousity, what does this do that the netcat "server options"
> can't do?
> 
> Ah. Change user after bind, provide a limited number >1 of  
> connections,
> and set environment variables.
> And I see that the command is from ipsvd, not homegrown.

That's the part that really makes me uncomfortable. If this was a  
standalone command pair, fine. It duplicates stuff netcat already does  
without sharing code with it, having  separate tcpd and udpd variants  
instead of it just being a flag is a bit silly, but those aren't really  
a big deal.

But this is related to a half-dozen other commands that Denys decided  
he liked and glued onto busybox, including a whole new init system  
that's not what android does, not what ubuntu does, not what redhat  
does, and not the conventional sysv one either, and of course unrelated  
to the "oneit" that's already in there. And if I say yes to this, how  
do I say no to all those _other_ commands? This seems like one of those  
"camel's nose under the tent flap" things...

Also, it means being tied to an external command's syntax when that  
command does a _lot_ of different things which should probably be more  
generic:

> Now, the second question...could any of this be shared with netcat?
> 
> >     IP            IP to listen on, 0 = all
> >     PORT          Port to listen on
> >     PROG ARGS     Program to run

Usually the non-option arguments are explained in the initial  
paragraph, and then the options get one per line in something like  
alphabetical order. The existing initial paragraph is pretty good and  
already explains these, but the "Port" vs "PORT" don't quite line up,  
so something like:

   usage: tcpsvd [-hEv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME]  
IP PORT COMMAND...

   Listen for incoming connections on IP:PORT and run COMMAND to  
service each connection.

(The ALL CAPS signifies things that aren't literally supplied but are  
values replaced by the user.)

> >     -l NAME       Local hostname (else looks up local hostname in  
> DNS)

Two questions:

1) Why does it care?

2) If it does care, why would it ever use a different value than the  
one returned by "hostname"?

> >     -u USER[:GRP] Change to user/group after bind

Which requires root access. (Binding to a low port does, up through...  
8192 these days? Something like that. But the higher ports don't.)

There should be a general wrapper to do this. In theory you can do this  
with "su -c". In practice there should be a less awkward way to do that  
which doesn't require a shell invocation to re-parse the command line.

I suppose the toybox su could go su user[:group] [COMMAND...] and exec  
the command line as the user? The whole "do a thing then exec the rest  
of the command line" wrapper pattern is already fairly well established  
by nice, chroot, xargs, time, timeout, detach, nohup, setsid, and of  
course netcat.

> >     -c N          Handle up to N (> 0) connections simultaneously
> >     -b N          (TCP Only) Allow a backlog of approximately N TCP  
> SYNs

First makes sense. The second is a touch micromanaging, but ok.

> >     -C N[:MSG]    (TCP Only) Allow only up to N (> 0) connections  
> from the same IP
> >                   New connections from this IP address are closed
> >                   immediately. MSG is written to the peer before  
> close

Simultaneous connections? Connections over time?

I'm looking at this and going "can this plumbing be re-used to  
implement httpd" (which is what I was already thinking about the need  
to genericize the netcat stuff)?

> >     -h            Look up peer's hostname

Why? (Can't the command do it?)

> >     -E            Don't set up environment variables

What environment variables is this referring to?

> >     -v            Verbose

Again, can't the command do that?

> > */
> 
> On a cursory inspection, it doesn't look bad, though I have a  
> suspicion
> it could be more concise.

I want to implement portions of it differently, but it's embedded in  
another command's expectations which is embedded in a suite of other  
commands which I'll then be expected to merge if I take this one...

Rob
 1381012966.0


More information about the Toybox mailing list