[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
OpenLDAP/NT error handling
Hello,
I have been working with the NT port of OpenLDAP for a couple of weeks and
have come to understand a lot about how it is all put together. Now one
issue has come up that I believe requires the attention of the OpenLDAP
developer community at large.
I've been trying to resolve some issues around the abnormal disconnection of
clients and have really come to a temporary dead end. The problem lies
primarily in error handling from the socket functions and the use of errno
all through the source code.
In order to make a really good "single source" distribution of OpenLDAP that
works on with Unix sockets and NT sockets, I believe that we need to
abstract the socket error handling functions in some way.
I'm thinking that we need some macro definitions that can be applied through
ALL the source. Some things like
#define getsockerrstr( err )
#define getlastsockerrstr()
#define getlastsockerr()
#define setsockerr( err )
#define geterrstr( err )
#define getlasterrstr()
#define getlasterr()
#define seterr( err )
I've included the code that I've started with but I don't want to go through
the process of changing the source everywhere (I know that someone has to
sometime and I will do what I can to help there)
If ALL the code base used these macros then evaluating the results of error
functions would be much easier. To add another layer, we could abstract the
error codes into LDAP_ERR_xxxxx values.
I believe this type of global change to the OpenLDAP source requires some
input from those enhancing/maintaing the unix source as well. They may also
have some additional ideas as they have been working with it for longer (a
presumption)
If we dont make this type of global change, there will be a considerable
number of #ifdef HAVE_WINSOCK declarations around all socket functions in
the source. As an example, I started some if this in slapd/connection.c but
found I had to make changes in liblber/io.c, liblber/sockbuf.c and so on.
//---- inclusion - portable_err.h -------
// includes
#ifdef WIN32
#include <winsock2.h>
#else
#include <errno.h>
#endif
// some common abstract error codes
#define LDAP_PVT_ERR_AGAIN EAGAIN
#define LDAP_PVT_ERR_RANGE ERANGE
// abstract error codes
#ifdef WIN32
#define LDAP_PVT_ERR_ACCES WSAEACCES
#define LDAP_PVT_ERR_ADDRINUSE WSAEADDRINUSE
#define LDAP_PVT_ERR_ADDRNOTAVAIL WSAEADDRNOTAVAIL
#define LDAP_PVT_ERR_AFNOSUPPORT WSAEAFNOSUPPORT
#define LDAP_PVT_ERR_ALREADY WSAEALREADY
#define LDAP_PVT_ERR_BADF WSAEBADF
#define LDAP_PVT_ERR_CANCELLED WSAECANCELLED
#define LDAP_PVT_ERR_CONNABORTED WSAECONNABORTED
#define LDAP_PVT_ERR_CONNREFUSED WSAECONNREFUSED
#define LDAP_PVT_ERR_CONNRESET WSAECONNRESET
#define LDAP_PVT_ERR_DESTADDRREQ WSAEDESTADDRREQ
#define LDAP_PVT_ERR_DISCON WSAEDISCON
#define LDAP_PVT_ERR_DQUOT WSAEDQUOT
#define LDAP_PVT_ERR_FAULT WSAEFAULT
#define LDAP_PVT_ERR_HOST_NOT_FOUND WSAHOST_NOT_FOUND
#define LDAP_PVT_ERR_HOSTDOWN WSAEHOSTDOWN
#define LDAP_PVT_ERR_HOSTUNREACH WSAEHOSTUNREACH
#define LDAP_PVT_ERR_INPROGRESS WSAEINPROGRESS
#define LDAP_PVT_ERR_INTR WSAEINTR
#define LDAP_PVT_ERR_INVAL WSAEINVAL
#define LDAP_PVT_ERR_INVALIDPROCTABLE WSAEINVALIDPROCTABLE
#define LDAP_PVT_ERR_INVALIDPROVIDER WSAEINVALIDPROVIDER
#define LDAP_PVT_ERR_ISCONN WSAEISCONN
#define LDAP_PVT_ERR_LOOP WSAELOOP
#define LDAP_PVT_ERR_MFILE WSAEMFILE
#define LDAP_PVT_ERR_MSGSIZE WSAEMSGSIZE
#define LDAP_PVT_ERR_NAMETOOLONG WSAENAMETOOLONG
#define LDAP_PVT_ERR_NETDOWN WSAENETDOWN
#define LDAP_PVT_ERR_NETRESET WSAENETRESET
#define LDAP_PVT_ERR_NETUNREACH WSAENETUNREACH
#define LDAP_PVT_ERR_NO_DATA WSANO_DATA
#define LDAP_PVT_ERR_NO_RECOVERY WSANO_RECOVERY
#define LDAP_PVT_ERR_NO_MORE WSA_E_NO_MORE
#define LDAP_PVT_ERR_NOMORE WSAENOMORE
#define LDAP_PVT_ERR_NOBUFS WSAENOBUFS
#define LDAP_PVT_ERR_NOPROTOOPT WSAENOPROTOOPT
#define LDAP_PVT_ERR_NOTCONN WSAENOTCONN
#define LDAP_PVT_ERR_NOTEMPTY WSAENOTEMPTY
#define LDAP_PVT_ERR_NOTINITIALISED WSANOTINITIALISED
#define LDAP_PVT_ERR_NOTSOCK WSAENOTSOCK
#define LDAP_PVT_ERR_OPNOTSUPP WSAEOPNOTSUPP
#define LDAP_PVT_ERR_PFNOSUPPORT WSAEPFNOSUPPORT
#define LDAP_PVT_ERR_PROCLIM WSAEPROCLIM
#define LDAP_PVT_ERR_PROTONOSUPPORT WSAEPROTONOSUPPORT
#define LDAP_PVT_ERR_PROTOTYPE WSAEPROTOTYPE
#define LDAP_PVT_ERR_REFUSED WSAEREFUSED
#define LDAP_PVT_ERR_REMOTE WSAEREMOTE
#define LDAP_PVT_ERR_SERVICE_NOT_FOUND WSASERVICE_NOT_FOUND
#define LDAP_PVT_ERR_SHUTDOWN WSAESHUTDOWN
#define LDAP_PVT_ERR_SOCKTNOSUPPORT WSAESOCKTNOSUPPORT
#define LDAP_PVT_ERR_STAKE WSAESTALE
#define LDAP_PVT_ERR_SYSCALLFAILURE WSASYSCALLFAILURE
#define LDAP_PVT_ERR_SYSNOTREADY WSASYSNOTREADY
#define LDAP_PVT_ERR_TIMEDOUT WSAETIMEDOUT
#define LDAP_PVT_ERR_TOOMANYREFS WSAETOOMANYREFS
#define LDAP_PVT_ERR_TRY_AGAIN WSATRY_AGAIN
#define LDAP_PVT_ERR_TYPE_NOT_FOUND WSATYPE_NOT_FOUND
#define LDAP_PVT_ERR_USERS WSAEUSERS
#define LDAP_PVT_ERR_VERNOTSUPPORTED WSAVERNOTSUPPORTED
#define LDAP_PVT_ERR_WOULDBLOCK WSAEWOULDBLOCK
#else
/*
Unhandled to date due to my limited knowledge of Unix
connect() can return ENOTDIR, EIO, ENOENT if address family is AF_UNIX
connect() may return ENAMETOOLONG, ENOSR
socket() can return EMFILE, ENOMEM
send() can return EPIPE, EAGAIN
*/
#define LDAP_PVT_ERR_ACCESS EACCES
#define LDAP_PVT_ERR_ADDRINUSE EADDRINUSE
#define LDAP_PVT_ERR_ADDRNOTAVAIL EADDRNOTAVAIL
#define LDAP_PVT_ERR_AFNOSUPPORT EAFNOSUPPORT
#define LDAP_PVT_ERR_ALREADY EALREADY
#define LDAP_PVT_ERR_BADF EBADF
#define LDAP_PVT_ERR_CANCELLED (-1)
#define LDAP_PVT_ERR_CONNABORTED (-1)
#define LDAP_PVT_ERR_CONNREFUSED ECONNREFUSED
#define LDAP_PVT_ERR_CONNRESET ECONNRESET
#define LDAP_PVT_ERR_DESTADDRREQ EDESTADDRREQ
#define LDAP_PVT_ERR_DISCON (-1)
#define LDAP_PVT_ERR_DQUOT (-1)
#define LDAP_PVT_ERR_FAULT EFAULT
#define LDAP_PVT_ERR_HOST_NOT_FOUND (-1)
#define LDAP_PVT_ERR_HOSTDOWN (-1)
#define LDAP_PVT_ERR_HOSTUNREACH EHOSTUNREACH
#define LDAP_PVT_ERR_INPROGRESS EINPROGRESS
#define LDAP_PVT_ERR_INTR EINTR
#define LDAP_PVT_ERR_INVAL EINVAL
#define LDAP_PVT_ERR_INVALIDPROCTABLE (-1)
#define LDAP_PVT_ERR_INVALIDPROVIDER (-1)
#define LDAP_PVT_ERR_ISCONN EISCONN
#define LDAP_PVT_ERR_LOOP ELOOP
#define LDAP_PVT_ERR_MFILE EMEMFILE
#define LDAP_PVT_ERR_MSGSIZE EMSGSIZE
#define LDAP_PVT_ERR_NAMETOOLONG ENAMETOOLONG
#define LDAP_PVT_ERR_NETDOWN ENETDOWN
#define LDAP_PVT_ERR_NETRESET (-1)
#define LDAP_PVT_ERR_NETUNREACH ENETUNREACH
#define LDAP_PVT_ERR_NO_DATA (-1)
#define LDAP_PVT_ERR_NO_RECOVERY (-1)
#define LDAP_PVT_ERR_NO_MORE (-1)
#define LDAP_PVT_ERR_NOMORE (-1)
#define LDAP_PVT_ERR_NOBUFS ENOBUFS
#define LDAP_PVT_ERR_NOPROTOOPT (-1)
#define LDAP_PVT_ERR_NOTCONN ENOTCONN
#define LDAP_PVT_ERR_NOTEMPTY (-1)
#define LDAP_PVT_ERR_NOTINITIALISED (-1)
#define LDAP_PVT_ERR_NOTSOCK ENOTSOCK
#define LDAP_PVT_ERR_OPNOTSUPP EOPNOTSUPP
#define LDAP_PVT_ERR_PFNOSUPPORT (-1)
#define LDAP_PVT_ERR_PROCLIM (-1)
#define LDAP_PVT_ERR_PROTONOSUPPORT EPROTONOTSUPPORT
#define LDAP_PVT_ERR_PROTOTYPE EPROTOTYPE
#define LDAP_PVT_ERR_RANGE ERANGE
#define LDAP_PVT_ERR_REFUSED (-1)
#define LDAP_PVT_ERR_REMOTE (-1)
#define LDAP_PVT_ERR_SERVICE_NOT_FOUND (-1)
#define LDAP_PVT_ERR_SHUTDOWN (-1)
#define LDAP_PVT_ERR_SOCKTNOSUPPORT (-1)
#define LDAP_PVT_ERR_STAKE (-1)
#define LDAP_PVT_ERR_SYSCALLFAILURE (-1)
#define LDAP_PVT_ERR_SYSNOTREADY (-1)
#define LDAP_PVT_ERR_TIMEDOUT ETIMEDOUT
#define LDAP_PVT_ERR_TOOMANYREFS (-1)
#define LDAP_PVT_ERR_TRY_AGAIN (-1)
#define LDAP_PVT_ERR_TYPE_NOT_FOUND (-1)
#define LDAP_PVT_ERR_USERS (-1)
#define LDAP_PVT_ERR_VERNOTSUPPORTED (-1)
#define LDAP_PVT_ERR_WOULDBLOCK EWOULDBLOCK
#endif
#ifdef WIN32
#define ldap_pvt_setsockerr( err ) \
WSASetLastError(err)
#else
#define ldap_pvt_setsockerr( err ) \
errno=err
#endif
#ifdef WIN32
#define ldap_pvt_getlastsockerr() \
WSAGetLastError()
#else
#define ldap_pvt_getlastsockerr() \
errno
#endif
char *ldap_pvt_getsockerrstr( int err );
#define ldap_pvt_getlastsockerrstr() \
ldap_pvt_getsockerrstr(ldap_pvt_getlastsockerr())
#ifdef WIN32
#define ldap_pvt_seterr(err) \
SetLastError(err)
#else
#define ldap_pvt_seterr(err) \
errno=err
#endif
#ifdef WIN32
#define ldap_pvt_getlasterr() \
GetLastError()
#else
#define ldap_pvt_getlasterr() \
errno
#endif
char *ldap_pvt_geterrstr( int err );
#define ldap_pvt_getlasterrstr() \
ldap_pvt_geterrstr(ldap_pvt_getlasterr())
//---- end inclusion - portable_err.h ---
//---- inclusion - portable_err.c -------
#include "portable_err.h"
#define UNKNOWN_ERROR_STRING "unknown"
#define __RETSTR2( x, y ) case x: return #x"("y")";
char *ldap_pvt_getsockerrstr( int err )
{
#ifdef WIN32
switch( err )
{
__RETSTR2( LDAP_PVT_ERR_INTR, "WSAEINTR" )
__RETSTR2( LDAP_PVT_ERR_BADF, "WSAEBADF" )
__RETSTR2( LDAP_PVT_ERR_ACCES, "WSAEACCES" )
__RETSTR2( LDAP_PVT_ERR_FAULT, "WSAEFAULT" )
__RETSTR2( LDAP_PVT_ERR_INVAL, "WSAEINVAL" )
__RETSTR2( LDAP_PVT_ERR_MFILE, "WSAEMFILE" )
__RETSTR2( LDAP_PVT_ERR_WOULDBLOCK, "WSAEWOULDBLOCK" )
__RETSTR2( LDAP_PVT_ERR_INPROGRESS, "WSAEINPROGRESS" )
__RETSTR2( LDAP_PVT_ERR_ALREADY, "WSAEALREADY" )
__RETSTR2( LDAP_PVT_ERR_NOTSOCK, "WSAENOTSOCK" )
__RETSTR2( LDAP_PVT_ERR_DESTADDRREQ, "WSAEDESTADDRREQ" )
__RETSTR2( LDAP_PVT_ERR_MSGSIZE, "WSAEMSGSIZE" )
__RETSTR2( LDAP_PVT_ERR_PROTOTYPE, "WSAEPROTOTYPE" )
__RETSTR2( LDAP_PVT_ERR_NOPROTOOPT, "WSAENOPROTOOPT" )
__RETSTR2( LDAP_PVT_ERR_PROTONOSUPPORT, "WSAEPROTONOSUPPORT"
)
__RETSTR2( LDAP_PVT_ERR_SOCKTNOSUPPORT, "WSAESOCKTNOSUPPORT"
)
__RETSTR2( LDAP_PVT_ERR_OPNOTSUPP, "WSAEOPNOTSUPP" )
__RETSTR2( LDAP_PVT_ERR_PFNOSUPPORT, "WSAEPFNOSUPPORT" )
__RETSTR2( LDAP_PVT_ERR_AFNOSUPPORT, "WSAEAFNOSUPPORT" )
__RETSTR2( LDAP_PVT_ERR_ADDRINUSE, "WSAEADDRINUSE" )
__RETSTR2( LDAP_PVT_ERR_ADDRNOTAVAIL, "WSAEADDRNOTAVAIL" )
__RETSTR2( LDAP_PVT_ERR_NETDOWN, "WSAENETDOWN" )
__RETSTR2( LDAP_PVT_ERR_NETUNREACH, "WSAENETUNREACH" )
__RETSTR2( LDAP_PVT_ERR_NETRESET, "WSAENETRESET" )
__RETSTR2( LDAP_PVT_ERR_CONNABORTED, "WSAECONNABORTED" )
__RETSTR2( LDAP_PVT_ERR_CONNRESET, "WSAECONNRESET" )
__RETSTR2( LDAP_PVT_ERR_NOBUFS, "WSAENOBUFS" )
__RETSTR2( LDAP_PVT_ERR_ISCONN, "WSAEISCONN" )
__RETSTR2( LDAP_PVT_ERR_NOTCONN, "WSAENOTCONN" )
__RETSTR2( LDAP_PVT_ERR_SHUTDOWN, "WSAESHUTDOWN" )
__RETSTR2( LDAP_PVT_ERR_TOOMANYREFS, "WSAETOOMANYREFS" )
__RETSTR2( LDAP_PVT_ERR_TIMEDOUT, "WSAETIMEDOUT" )
__RETSTR2( LDAP_PVT_ERR_CONNREFUSED, "WSAECONNREFUSED" )
__RETSTR2( LDAP_PVT_ERR_LOOP, "WSAELOOP" )
__RETSTR2( LDAP_PVT_ERR_NAMETOOLONG, "WSAENAMETOOLONG" )
__RETSTR2( LDAP_PVT_ERR_HOSTDOWN, "WSAEHOSTDOWN" )
__RETSTR2( LDAP_PVT_ERR_HOSTUNREACH, "WSAEHOSTUNREACH" )
__RETSTR2( LDAP_PVT_ERR_NOTEMPTY, "WSAENOTEMPTY" )
__RETSTR2( LDAP_PVT_ERR_PROCLIM, "WSAEPROCLIM" )
__RETSTR2( LDAP_PVT_ERR_USERS, "WSAEUSERS" )
__RETSTR2( LDAP_PVT_ERR_DQUOT, "WSAEDQUOT" )
__RETSTR2( LDAP_PVT_ERR_STAKE, "WSAESTALE" )
__RETSTR2( LDAP_PVT_ERR_REMOTE, "WSAEREMOTE" )
__RETSTR2( LDAP_PVT_ERR_SYSNOTREADY, "WSASYSNOTREADY" )
__RETSTR2( LDAP_PVT_ERR_VERNOTSUPPORTED,
"WSAVERNOTSUPPORTED" )
__RETSTR2( LDAP_PVT_ERR_NOTINITIALISED, "WSANOTINITIALISED"
)
__RETSTR2( LDAP_PVT_ERR_DISCON, "WSAEDISCON" )
__RETSTR2( LDAP_PVT_ERR_NOMORE , "WSAENOMORE" )
__RETSTR2( LDAP_PVT_ERR_CANCELLED, "WSAECANCELLED" )
__RETSTR2( LDAP_PVT_ERR_INVALIDPROCTABLE,
"WSAEINVALIDPROCTABLE" )
__RETSTR2( LDAP_PVT_ERR_INVALIDPROVIDER,
"WSAEINVALIDPROVIDER" )
__RETSTR2( LDAP_PVT_ERR_SYSCALLFAILURE, "WSASYSCALLFAILURE"
)
__RETSTR2( LDAP_PVT_ERR_SERVICE_NOT_FOUND,
"WSASERVICE_NOT_FOUND" )
__RETSTR2( LDAP_PVT_ERR_TYPE_NOT_FOUND, "WSATYPE_NOT_FOUND"
)
__RETSTR2( LDAP_PVT_ERR_NO_MORE, "WSA_E_NO_MORE" )
__RETSTR2( LDAP_PVT_ERR_REFUSED, "WSAEREFUSED" )
__RETSTR2( LDAP_PVT_ERR_HOST_NOT_FOUND, "WSAHOST_NOT_FOUND"
)
__RETSTR2( LDAP_PVT_ERR_TRY_AGAIN, "WSATRY_AGAIN" )
__RETSTR2( LDAP_PVT_ERR_NO_RECOVERY, "WSANO_RECOVERY" )
__RETSTR2( LDAP_PVT_ERR_NO_DATA, "WSANO_DATA" )
}
return UNKNOWN_ERROR_STRING;
#else
return ( err > -1 && err < sys_nerr ) ? sys_errlist[errno] :
UNKNOWN_ERROR_STRING;
#endif
}
char *ldap_pvt_geterrstr( int err )
{
#ifdef WIN32
return UNKNOWN_ERROR_STRING;
#else
return ( err > -1 && err < sys_nerr ) ? sys_errlist[errno] :
UNKNOWN_ERROR_STRING;
#endif
}
#undef __RETSTR2
//---- end inclusion - portable_err.c ---
Paul
+------------------------------------------------------------------+
| Paul Higgs (NA/EBC/PEEW/F) |
| Ericsson Business Networks AB tel: +46 (8) 4221734 |
| S131 89 Stockholm, Sweden fax: +46 (8) 4221010 |
| Office: Augustendalsvagan 21 |
| Nacka Strand e-mail: paul.higgs@ebc.ericsson.se |
+------------------------------------------------------------------+