[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 | 
+------------------------------------------------------------------+