Return to BSD News archive
Newsgroups: comp.unix.bsd.freebsd.misc,comp.unix.solaris Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!munnari.OZ.AU!metro!metro!news.nsw.CSIRO.AU!marka From: marka@syd.dms.CSIRO.AU (Mark Andrews) Subject: Re: named/Connection lags on Solaris.. X-Nntp-Posting-Host: pride.syd.dms.csiro.au Message-ID: <845519879.509524@pride.syd.dms.CSIRO.AU> Sender: news@news.nsw.CSIRO.AU Organization: CSIRO Division of Mathematics and Statistics, Australia References: <540rpq$rhj@netaxs.com> Cache-Post-Path: pride.syd.dms.CSIRO.AU!unknown@drugs.syd.dms.csiro.au Distribution: inet Date: Thu, 17 Oct 1996 02:38:00 GMT Lines: 149 Xref: euryale.cc.adfa.oz.au comp.unix.bsd.freebsd.misc:29399 comp.unix.solaris:86131 In article <540rpq$rhj@netaxs.com> heller@cdnow.com writes: > > Strange topic to post here but its related... trust me.. > > >I've got a Solaris 2.5.1 box that is running as a secondary name server >to a FreeBSD 2.1.5 box primary name server. > > I'm experiencing connection lags to and from the solaris box to other >machines. The connection eventually will go through but will sit for >a very long time before connecting. It is also random ( or so ) and I >can't reproduce it other than when someone screams why they can't get to >some machine. > > You can telnet to some host and it will just sit there.. then go through. >This lag can be a few seconds to over 30. I am assuming that this is some >kind of Solaris problem as it existed when it was the primary name server. This is related to a bug/feature in the SunOS (both 4 and 5) kernels and the workaround in the resolver library. It will only impact you if the first server queried takes a long time to resolve the message. 1. the resolver uses "connected" UDP sockets to detect dead named processes on the DNS server. fast fall over. 2. when it moves onto the second server it attempts to put this socket into an "unconnected" state. This is possible on BSD 4.3 or later derived kernels but not on BSD 4.2 derived kernels or in the IP stack in SunOS 5. The workaround in the resolver is to open a new UDP socket. The ICMP unreachables are the result of the server finally getting an answer to the first query, or SERVFAIL, and responding to the now non-existent UDP port. The code below demonstates the problem using the UDP echo port. The third getpeername() should fail but doesn't. Mark #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> main() { int fd; int size; int count; struct sockaddr_in none, remote, set, echo; char buf[100]; alarm(10); if ((fd = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP)) < 0) { perror("socket"); } none.sin_family = AF_INET; none.sin_port = 0; none.sin_addr.s_addr = 0; if (bind(fd,(struct sockaddr *)&none,sizeof(none)) < 0) { perror("bind"); } /* * UNCONNECTED */ /* * getpeername should fail */ size = sizeof(remote); if (getpeername(fd,(struct sockaddr *)& remote, &size ) < 0) { perror("getpeername 1"); } else { printf("getpeername 1: %s.%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); } echo.sin_family = AF_INET; echo.sin_port = htons(7); /* echo */ echo.sin_addr.s_addr = inet_addr("127.0.0.1"); if (sendto(fd, "Message 1", 9, 0,(struct sockaddr *) &echo, sizeof(echo)) < 0) { perror("sendto 1"); } size = 0; if ((count = recvfrom(fd, buf, 100, 0, (struct sockaddr *)0, &size)) < 0) { perror("recvfrom 1"); } else { printf("Got back %0.*s\n", count, buf); } /* * CONNECT */ set.sin_family = AF_INET; set.sin_port = htons(53); set.sin_addr.s_addr = inet_addr("10.0.2.1"); if (connect(fd,(struct sockaddr *)&set, sizeof(set)) < 0) { perror("connect 1"); } size = sizeof(remote); if (getpeername(fd,(struct sockaddr *)& remote, &size ) < 0) { perror("getpeername 2"); } else { printf("getpeername 2: %s.%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); } /* * UNCONNECT */ set.sin_family = AF_INET; set.sin_port = htons(0); set.sin_addr.s_addr = htonl(0); if (connect(fd,(struct sockaddr *)&set, sizeof(set)) < 0) { perror("connect 2"); } /* * getpeername should fail. */ size = sizeof(remote); if (getpeername(fd,(struct sockaddr *)& remote, &size ) < 0) { perror("getpeername 3"); } else { printf("getpeername 3: %s.%d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); } echo.sin_family = AF_INET; echo.sin_port = htons(7); echo.sin_addr.s_addr = inet_addr("127.0.0.1"); if (sendto(fd, "Message 2", 9, 0,(struct sockaddr *) &echo, sizeof(echo)) < 0) { perror("sendto 1:"); } size = 0; if ((count = recvfrom(fd, buf, 100, 0, (struct sockaddr *)0, &size)) < 0) { perror("recvfrom 2"); } else { printf("Got back %0.*s\n", count, buf); } }