DCC use of connect() and sendto() on FreeBSD

Jamie Clark jamie@zeroth.org
Thu Sep 23 02:39:17 UTC 2004


Vernon Schryver wrote:

>>I've been attempting to use the FreeBSD port of the DCC package on
>>FreeBSD 4.10-STABLE and I have noticed a few issues. I'm using
>>dccm and the public servers.
>>    
>>
>
>What "FreeBSD port" is that?  There is at least one FreeBSD "port"
>or "package" floating around.
>
A recently cvsup'd /usr/ports/mail/dcc-dccd

>   I've not looked at (or for) a version
>of it for several months, but when I did, it contained changes that
>seemed undesirable to me.  Since then other people have reported
>problems with one or perhaps another such package.
>  
>
There's nothing sinister in the port. It uses the 1.2.48 distribution 
tarball from
http://www.rhyolite.com/. It applies no patches (in the patch(1) sense)
however it does a global regex to replace the hardwired string literal
'/usr/local' with ${PREFIX} to conform to package building requirements.
It also makes a required change to the PTHREAD_LDFLAGS to build
across the BSDs. Nothing that changes the way the code should work.

In any case, I downloaded the raw 1.2.54 tarball, built, and observed the
same behaviour before I sent the email to the list.

>It's good that to question local changes, but I think preliminary
>questions are also wise, including:
>
>  - Is my configuration novel or unusual?  Do other people have my
>      trouble with configurations similar to mine?  If not, then is
>      my proposed change a good idea?
>  
>
Like I said, this is 4.10-STABLE. Nothing special. I spent a lot of
time looking at this, examining the kernel source, particularly
udp_usrreq.c, checking for any recent changes in the STABLE
branch that may be having an effect.

In particular the connect() manpage and this kernel code
from netinet/udp_usrreq.c lead me to believe that an intervening
operation is needed to disassociate the socket before
reconnecting:

static int
udp_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
{
        struct inpcb *inp;
        int s, error;
        struct sockaddr_in *sin;

        inp = sotoinpcb(so);
        if (inp == 0)
                return EINVAL;
        if (inp->inp_faddr.s_addr != INADDR_ANY)
                return EISCONN;
[...]
}

In other words "if UDP socket is connected then a subsequent connect will
return EISCONN".  I wrote test code to confirm this. An intervening 
connect()
to invalid address does seem to disconnect the socket so that a later
connect() will succeed.

It seemed that the dcc client code was not consistently disassociating the
socket before reconnect or sendto. You can see in my truss output.

I have ipfw and jails running on this machine, but I have eliminated 
these as
sources of trouble. The ipfw is 'OPEN' as I only use it on occasion to 
control
or log unwanted traffic. dccm behaviour is subtly different inside and 
outside
of a jail, but problematic in both cases.

I've been developing on FreeBSD since 1994 so I'm not exactly a newbie.
I am not proclaiming to have solved this problem, nor suggesting that I
have taken the time to fully understand the logic within clnt_send.c.

What I am saying is that I have observed the truss output (syscall trace)
from a failing dccm and cdcc and I can see that connect() and sendto()
are failing on already connected sockets. Something is wrong.

Perhaps it's something local to my servers, I don't know. If someone
else can run a truss of "cdcc rtt" on their 'BSD 4.10-STABLE then
we would see.

>     FreeBSD was the second target of the DCC source.  It remains
>     among the most popular.  I always install versions on systems
>     currently running 4.9-RELEASE and 5.2.1-RELEASE before publishing
>     the tarball.
>
>  - Do I really understand the effects of my propsed change?
>
>      Your change basically inverts the meaning of that switch.  If
>      you read the code, I think you'll see that you've simply told
>      the DCC client library to not use connected UDP sockets.
>
That's exactly what I thought I was doing. Good to hear.

>  That breaks the quick detection of some sick or unreachable DCC
>      servers.  They will still be detected, but within seconds instead
>      of milliseconds.
>  
>
That may be so, but previously dccm was having most of it's
queries fail. Now it has close to 100% success. I no longer have
these messages in my logs:

/var/log/maillog.2.gz:Sep 20 22:18:48 argon dccm[18105]: no answer from 
dcc1.dcc-servers.net (208.201.249.233,6277) after 0 ms
/var/log/maillog.2.gz:Sep 20 22:18:49 argon dccm[18105]: continue not 
asking DCC 7 seconds after failure

>While your change may or may not be a good idea in some unsanctioned
>versions of the DCC source, it is neither necessary nor desirable in
>what I consider the official version. 
>
See above for origin of source.

Here is the relevent portion of a truss output of "cdcc rtt" run
outside of any jail, straight from the source tree of a clean,
build of dcc-dccd-1.2.54 downloaded from rhyolite.com yesterday:

connect(0x4,{ AF_INET 194.109.153.82:6277 },16)  = 0 (0x0)
sendto(0x4,0xbfbfda58,0x28,0x0,0x0,0x0)          = 40 (0x28)
connect(0x4,{ sa_len = 16, sa_family = 0, sa_data = { 0x18, 0x85, 0xc2, 
0x6d, 0x99, 0x52, 00, 00, 00, 00, 00, 00, 00, 00,,0) ERR#22 'Invalid 
argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#56 'Socket is 
already connected'
fcntl(0x3,0x8,0xbfbfc6a8)                        = 0 (0x0)
poll(0xbfbfc6e8,0x1,0x1f4)                       = 0 (0x0)
gettimeofday(0x8064004,0x0)                      = 0 (0x0)
fcntl(0x3,0x9,0xbfbfc6a8)                        = 0 (0x0)
connect(0x4,{ AF_INET 194.109.153.82:6277 },16)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
sendto(0x4,0xbfbfda58,0x28,0x0,0xbfbfc804,0x10)  ERR#22 'Invalid argument'
fcntl(0x3,0x8,0xbfbfc6a8)                        = 0 (0x0)
poll(0xbfbfc6e8,0x1,0x3e8)                       = 1 (0x1)
gettimeofday(0x8064004,0x0)                      = 0 (0x0)
fcntl(0x3,0x9,0xbfbfc6a8)                        = 0 (0x0)
recvfrom(0x4,0xbfbfd9b0,0xa8,0x0,0xbfbfc6c4,0xbfbfc670) = 108 (0x6c)
recvfrom(0x4,0xbfbfd9b0,0xa8,0x0,0xbfbfc6c4,0xbfbfc670) ERR#35 'Resource 
temporarily unavailable'
connect(0x4,{ AF_INET 152.20.240.35:6277 },16)   ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 208.201.249.233:6277 },16) ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 212.203.14.116:6277 },16)  ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 38.144.80.234:6277 },16)   ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 137.118.60.88:6277 },16)   ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 142.27.70.214:6277 },16)   ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 205.166.61.174:6277 },16)  ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 217.20.119.18:6277 },16)   ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 203.147.165.193:6277 },16) ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 216.244.192.216:6277 },16) ERR#22 'Invalid argument'
connect(0x4,{ AF_INET 194.85.132.210:6277 },16)  ERR#22 'Invalid argument'








More information about the DCC mailing list

Contact vjs@rhyolite.com by mail or use the form.