View Full Version : Errno 25 on accept call
klong
04-08-2003, 05:18 AM
I would like to find if anyone has information about intermittent errno 25 being set after a call to accept within. It seems that the application (which functions normally most of the time) occasionally receives this error.
Errno 25, is "Inappropriate ioctl for device" hmmm. I was wondering why this occurs and what causes it. But most importantly how to avoid or handle this error.
The OS is solaris 8.
Thanks in advance,
Ken
RobSeace
04-08-2003, 01:53 PM
Odd... I don't think I've ever seen that on an accept()... But, one thing
that could certainly make accept() fail is if a client connects but drops its
connection immediately, before you can accept()... (Some OSs will not
bother informing you of it, so your accept() will never return at all; but,
others will return failure in that case...) Personally, on accept() failures
of any variety (aside from 'normal' stuff like EINTR), I generally close
my listening socket and re-create it again from scratch... That's probably
major overkill in most cases, as you could probably safely just do accept()
again after most failures... But, better safe than sorry, just in case the
listening socket itself were somehow screwed up...
klong
04-08-2003, 03:20 PM
I don't think the client is disconnecting. The client is running on the same host as the server process. And seems to be hanging as well. I've not yet determined if the hang is at the connect on if the client thinks a connect is completed and is trying to send... I'm going to put some diagnostic info into the client to get more insight on this.
Thanks
klong
04-09-2003, 03:25 PM
Ok, here are some more details about this.
I am using the SSL ( simple sockets library ) on a Sun Ultra 5 running solaris 8...
Server pseudo code:
Create server socket.
loop
Accept client connection ( This is where I get the errno 25 )
if success ful connect
process
end if
end loop
Client p code:
Set up an alarm handler ( to make the connect timeout in 20 secs )
connect to server.
write some data to socket.
read some data from socket. ( This is where the client hangs)
close the socket..
A few questions:
1. How can the client think it has a usable connected socket, when the server accept has failed ?
2. How should I go about resolving the issue ?
Any help on these would be greatly appreciated.
Thanks,
Ken
RobSeace
04-09-2003, 07:25 PM
Well, the server machine's TCP/IP stack will accept a number of
incoming connections and place them on the listen queue before the
actual server ever does an accept()... So, it's certainly conceivable
that the client would seem to connect fine before the server has
really accept()'d it... However, I'm not sure why the accept() would
be failing... Are there any other clients trying to connect at the same
time as the problem client? Ie: is it possible another one prior to the
one that hangs trying to read is really the one that caused the accept()
failure? If not, then I'm just not sure... I don't know anything about
that library, but maybe it's doing something strange in its accept() code?
Have you tried just doing your own accept(), without using the library?
zapdog
04-10-2003, 06:07 AM
G'day Rob
Here is the Saccept() code from the simple socket library:
/* Just put in another line */
/* Saccept.c: this file contains the Socket accept support */
#include <stdio.h>
#include <errno.h>
#include "sockets.h"
/* ------------------------------------------------------------------------- */
/* Saccept: this routine uses a server Socket to accept connections
* The accept() function clones a socket for use with a client connect.
* One may close the Saccept generated socket without affecting the
* server socket.
*/
#ifdef __PROTOTYPE__
Socket *Saccept(Socket *skt)
#else
Socket *Saccept(skt)
Socket *skt;
#endif
{
#ifdef _AIX
size_t addrlen;
#else
int addrlen;
#endif
#ifndef SSLNOSETSOCKOPT
int status=1;
#endif
struct sockaddr addr;
Socket *acceptskt= NULL;
/* sanity check */
if(!skt) {
return acceptskt;
}
/* allocate a Socket */
acceptskt= makeSocket(skt->hostname,skt->sktname,PM_ACCEPT);
if(!acceptskt) {
return acceptskt;
}
/* accept a connection */
addrlen = sizeof (addr);
acceptskt->skt= accept(skt->skt, &addr, &addrlen);
if(acceptskt->skt <= 0) { /* failure to accept */
freeSocket(acceptskt);
return (Socket *) NULL;
}
/* turn off TCP's buffering algorithm so small packets don't get delayed */
#ifndef SSLNOSETSOCKOPT
if(setsockopt(skt->skt,IPPROTO_TCP,TCP_NODELAY,(char *) &status,sizeof(status)) < 0) {
}
#endif /* #ifndef SSLNOSETSOCKOPT ... */
return acceptskt;
}
/* ---------------------------------------------------------------------
* vim: ts=4
*/
My two cents:
This library does not seem to add much value.
This function will fail if accept() returns 0. This is a perfectly valid file descriptor. Especially if you fclose(stdin) and fclose(stdout) like I do in all server deamons.
I find it unlikely that the errno = 25 has anything to do with the accept() call. Most likely the library code has made some other system call, like a failed printf(), before it returns to the caller.
RobSeace
04-10-2003, 01:09 PM
Hmmmm... Yeah, I personally wouldn't use any lib written like that
for anything, that's for sure... Besides incorrectly treating 0 as a failure
return, which zapdog points out, the code also incorrectly uses a generic
"struct sockaddr" for holding the connecting client's address... Now, it
just so happpens that sockaddr and sockaddr_in are the same size, and
probably always will be on any platform, but it's still dead wrong to do...
Also, you better not want to ever have IPv6 support, or even Unix domain
support, because that code won't allow it... (I quite strongly believe that
anyone writing new sockets code in this day and age who isn't coding for
IPv6 support should be beaten severely... ;-/) Also, the TCP_NODELAY
code seems to just be setting the opt on the listening socket, rather than
the newly accepted one!
So, I guess my recommendation would be: ditch the library, and I bet
the problem will go away... ;-)
klong
04-10-2003, 02:19 PM
Thanks to both Zapdog, and Rob for taking the time to review this. I am going to test Zapdogs suggestion about the printf... By not running as a daemon.
Do either of you have any recomendations about libraries that could be utilized in place of the ssl library.
Thanks,
Ken
RobSeace
04-10-2003, 08:10 PM
I don't know of any good publically available socket cover libraries...
I have my own that I always use... (But, releasing the source would
be somewhat problematic, as much as I might like to...) Your best
bet would just be to write your own, as well... Then, you'll know exactly
what is going on with it, for one thing... And, you can be sure it behaves
how you want it to... (Yes, it's also somewhat a bit of reinventing the
wheel, if everyone uses their own private socket libs... But, until there's
a good, high-quality, wide-spread, commonly-used lib to use instead,
that's really the best approach, IMHO... *shrug*)
klong
04-11-2003, 04:40 PM
Just for any one else who may be watching this thread:
Found that the SSL library utilized fprintf, vfprintf function calls utilzing stderr as the output path. I re-wrote these modules. Also corrected the error checking throughout ( ie <= 0 converted to <0 ) where appropriate.
The server daemon seems to now function correctly.
Thanks again for your help.
Ken
vBulletin® v3.7.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.