lkml.org 
[lkml]   [1998]   [Oct]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: Fw: sendpkt: Connection refused
On Tue, Oct 13, 1998 at 05:10:16PM +0200, Edgar Toernig wrote:
> Andi Kleen wrote:
> >
> > mblack@csihq.com (Mike Black) writes:
> > ...
> > > >> Oct 10 06:27:18 defiant dhcpd: sendpkt: Connection refused
> > > >
> > > >Because Linux stupidly reports ICMP errors it receives for a given UDP
> > > >port the next time you try to send on a socket bound to that port,
> > > >even though the error has nothing to do with the packet you're trying
> > > >to send. The error is essentially informational at this point - when
> > > >send_packet gets it while transmitting a packet, it just retransmits
> > > >the packet. Utterly bogus, but harmless to you.
> >
> > He should either fix his program to do correct error handling
> > or set the SO_BSDCOMPAT option on the socket.
>
> How should the "correct error handling" look like?
>
> I got the same problem when building a daemon which talks to
> a large number of clients. The problem: You don't know, whether
> the error return of the send is for the current packet or for
> one of the thousand packets before. If you try to resend the
> current packet another icmp-error may have returned in the
> meantime and you get just another -1.

One possibility is to check and clear the pending error first with
getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, sizeof err); first.
Also you get different error codes for local errors and errors
generated by the network, e.g. ENETDOWN or EINVAL or EWOULDBLOCK
is definitely a local error, EPROTO or EHOSTUNREACH a network error.

>
> You may try to resend until you get a success but what, if the
> error _is_ for the current packet and not for an earlier one?
>
> IMO, this interface is broken. I came to the solution, that
> SO_BSDCOMPAT is the Right Thing and should be the default!
> (I don't know, if this would break some 'standard'...)
It breaks RFC1122. The main problem is that the BSD API has no way
to deliver the complete error information, but that is not an excuse
for hiding the error.

The vger kernel has a complete solution that will hopefully appear
in the official 2.2 kernel. The user process can enable an per socket
error queue that buffers incoming errors.

#include <linux/errqueue.h>

struct sock_extended_err
{
__u32 ee_errno; /* standard errno */
__u8 ee_origin; /* see below */
__u8 ee_type; /* ICMP type, code */
__u8 ee_code;
__u8 ee_pad;
__u32 ee_info; /* contains info like the path mtu */
__u32 ee_data;
};

#define SO_EE_ORIGIN_NONE 0
#define SO_EE_ORIGIN_LOCAL 1
#define SO_EE_ORIGIN_ICMP 2
#define SO_EE_ORIGIN_ICMP6 3

#define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1))



int on = 1;
setsockopt(sk, SOL_IP, IP_RECVERR, &on, sizeof on);

err = sendmsg(sk, ..., 0);
if (err < 0) {
char buf[128];
struct sockaddr_in orig_dst;
struct msghdr msgh = {0};

/* OK, process errors */
msgh.msg_control = buf;
msgh.msg_controllen = sizeof buf;
msgh.msg_name = (struct sockaddr *) &orig_dst;
msgh.msg_namelen = sizeof orig_dst;
for (;;) {
struct cmsghdr *cmsg;

err = recvmsg(sk, &msgh, MSG_ERRQUEUE);
if (err < 0) {
if (errno == EAGAIN)
break;
else
continue;
}
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg; cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
if (cmsg->cmsg_level == SOL_IP &&
cmsg->cmsg_type == IP_RECVERR) {
struct sock_extended_err *err;

err = CMSG_DATA(cmsg);

/* *err contains lots of information
now */
switch (err->ee_origin) {
case SO_EE_ORIGIN_LOCAL:
/* local error */
case SO_EE_ORIGIN_ICMP:
/* remote error */
}
}
}
/* orig_dst contains the original destination
of the packet that caused the error */
/* If an iov would have been initialised in msgh
it would contain the data of the original packet
as much as known */
}
}


-Andi









}



>
> Ciao, ET.
>
>
> Don't try to handle something you don't know how to handle.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.127 / U:0.140 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site